improvements
This commit is contained in:
@@ -77,13 +77,12 @@ clay.draw = function draw(size, fn, config = {})
|
||||
box.boundingbox = Object.assign({}, box.content);
|
||||
|
||||
var padding = normalizeSpacing(box.config.padding || 0);
|
||||
if (padding.l || padding.r || padding.t || padding.b) {
|
||||
// Adjust the boundingbox to include the padding
|
||||
box.boundingbox.x -= padding.l;
|
||||
box.boundingbox.y -= padding.t;
|
||||
box.boundingbox.width += padding.l + padding.r;
|
||||
box.boundingbox.height += padding.t + padding.b;
|
||||
}
|
||||
|
||||
box.boundingbox.x -= padding.l;
|
||||
box.boundingbox.y -= padding.t;
|
||||
box.boundingbox.width += padding.l + padding.r;
|
||||
box.boundingbox.height += padding.t + padding.b;
|
||||
|
||||
box.marginbox = Object.assign({}, box.content);
|
||||
var margin = normalizeSpacing(box.config.margin || 0);
|
||||
box.marginbox.x -= margin.l;
|
||||
|
||||
@@ -121,4 +121,28 @@ Ease.elastic = {
|
||||
Ease.elastic.c4 = (2 * Math.PI) / 3
|
||||
Ease.elastic.c5 = (2 * Math.PI) / 4.5
|
||||
|
||||
Ease.zoom = {
|
||||
// Creates a smooth zoom that maintains constant perceptual speed
|
||||
// ratio is the zoom factor (e.g., 10 for 10x zoom)
|
||||
smooth(ratio) {
|
||||
return function(t) {
|
||||
if (t == 0) return 0
|
||||
if (t == 1) return 1
|
||||
if (Math.abs(ratio - 1) < 0.001) return t
|
||||
// Position interpolation formula: (r^t - 1) / (r - 1)
|
||||
return (Math.pow(ratio, t) - 1) / (ratio - 1)
|
||||
}
|
||||
},
|
||||
// Exponential interpolation for zoom values
|
||||
// Interpolates in logarithmic space for smooth visual zoom
|
||||
exp(startZoom, endZoom) {
|
||||
return function(t) {
|
||||
if (t == 0) return startZoom
|
||||
if (t == 1) return endZoom
|
||||
// Scale := Exp(LinearInterpolate(Ln(Scale1), Ln(Scale2), t))
|
||||
return Math.exp(Math.log(startZoom) + t * (Math.log(endZoom) - Math.log(startZoom)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ease
|
||||
@@ -199,15 +199,55 @@ function translate_draw_commands(commands) {
|
||||
cmd.rect.width = cmd.rect.width * cmd.scale.x
|
||||
cmd.rect.height = cmd.rect.height * cmd.scale.y
|
||||
cmd.rect = worldToScreenRect(cmd.rect, camera)
|
||||
|
||||
renderer_commands.push({
|
||||
op: "texture",
|
||||
data: {
|
||||
texture_id: gpu,
|
||||
dst: cmd.rect,
|
||||
src: img.rect
|
||||
|
||||
if (cmd.info && (cmd.info.tile_x || cmd.info.tile_y)) {
|
||||
// Use tiling functionality
|
||||
var tile_buffer = geometry.tile(
|
||||
img,
|
||||
img.rect, // source rect in UV coords
|
||||
cmd.rect, // destination rect in screen coords
|
||||
{
|
||||
repeat_x: cmd.info.tile_x || false,
|
||||
repeat_y: cmd.info.tile_y || false
|
||||
}
|
||||
)
|
||||
|
||||
if (tile_buffer) {
|
||||
// Transform XY coordinates using camera matrix
|
||||
var camera_params = [camera.a, camera.c, camera.e, camera.f]
|
||||
var transformed_xy = geometry.transform_xy_blob(tile_buffer.xy, camera_params)
|
||||
|
||||
// Create transformed geometry object
|
||||
var transformed_geom = {
|
||||
xy: transformed_xy,
|
||||
xy_stride: tile_buffer.xy_stride,
|
||||
uv: tile_buffer.uv,
|
||||
uv_stride: tile_buffer.uv_stride,
|
||||
color: tile_buffer.color,
|
||||
color_stride: tile_buffer.color_stride,
|
||||
indices: tile_buffer.indices,
|
||||
num_vertices: tile_buffer.num_vertices,
|
||||
num_indices: tile_buffer.num_indices,
|
||||
size_indices: tile_buffer.size_indices,
|
||||
texture_id: gpu
|
||||
}
|
||||
|
||||
renderer_commands.push({
|
||||
op: "geometry_raw",
|
||||
data: transformed_geom
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// Normal non-tiled rendering
|
||||
renderer_commands.push({
|
||||
op: "texture",
|
||||
data: {
|
||||
texture_id: gpu,
|
||||
dst: cmd.rect,
|
||||
src: img.rect
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
|
||||
@@ -158,7 +158,8 @@ tilemap.prototype =
|
||||
this._dirty = false;
|
||||
},
|
||||
|
||||
draw(pos = {x: 0, y: 0}) {
|
||||
draw() {
|
||||
var pos = this.pos || {x:0,y:0}
|
||||
// Rebuild cache if dirty or position changed
|
||||
if (this._dirty || Object.keys(this._geometry_cache).length == 0 || this._last_pos?.x != pos.x || this._last_pos?.y != pos.y) {
|
||||
this._build_geometry_cache(pos);
|
||||
|
||||
@@ -40,8 +40,18 @@ function Tween(obj) {
|
||||
|
||||
Tween.prototype.to = function(props, duration, start_time) {
|
||||
for (var key in props) {
|
||||
this.startVals[key] = this.obj[key]
|
||||
this.endVals[key] = props[key]
|
||||
var value = props[key]
|
||||
if (typeof value == 'object' && value != null && !Array.isArray(value)) {
|
||||
// Handle nested objects by flattening them
|
||||
for (var subkey in value) {
|
||||
var flatKey = key + '.' + subkey
|
||||
this.startVals[flatKey] = this.obj[key] ? this.obj[key][subkey] : undefined
|
||||
this.endVals[flatKey] = value[subkey]
|
||||
}
|
||||
} else {
|
||||
this.startVals[key] = this.obj[key]
|
||||
this.endVals[key] = value
|
||||
}
|
||||
}
|
||||
this.duration = duration
|
||||
|
||||
@@ -85,7 +95,23 @@ Tween.prototype.seek = function(global_time) {
|
||||
for (var key in this.endVals) {
|
||||
var start = this.startVals[key]
|
||||
var end = this.endVals[key]
|
||||
this.obj[key] = start + (end - start) * eased
|
||||
var value = start + (end - start) * eased
|
||||
|
||||
if (key.includes('.')) {
|
||||
// Handle nested object properties
|
||||
var parts = key.split('.')
|
||||
var objKey = parts[0]
|
||||
var subKey = parts[1]
|
||||
|
||||
// Ensure the nested object exists
|
||||
if (!this.obj[objKey]) {
|
||||
this.obj[objKey] = {}
|
||||
}
|
||||
|
||||
this.obj[objKey][subKey] = value
|
||||
} else {
|
||||
this.obj[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
if (t == 1 && this.engine) {
|
||||
|
||||
@@ -312,7 +312,7 @@ graphics.texture = function texture(path) {
|
||||
if (!cache[id]) {
|
||||
var ipath = res.find_image(id)
|
||||
if (!ipath)
|
||||
throw new Error(`unknown image ${id}`)
|
||||
return graphics.texture('notex')
|
||||
|
||||
var result = create_image(ipath)
|
||||
cache[id] = result
|
||||
|
||||
Reference in New Issue
Block a user