improvements

This commit is contained in:
2025-07-21 14:42:26 -05:00
parent ff7b2f4db7
commit f389609bd9
6 changed files with 110 additions and 20 deletions

View File

@@ -77,13 +77,12 @@ clay.draw = function draw(size, fn, config = {})
box.boundingbox = Object.assign({}, box.content); box.boundingbox = Object.assign({}, box.content);
var padding = normalizeSpacing(box.config.padding || 0); 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.x -= padding.l;
box.boundingbox.y -= padding.t; box.boundingbox.y -= padding.t;
box.boundingbox.width += padding.l + padding.r; box.boundingbox.width += padding.l + padding.r;
box.boundingbox.height += padding.t + padding.b; box.boundingbox.height += padding.t + padding.b;
}
box.marginbox = Object.assign({}, box.content); box.marginbox = Object.assign({}, box.content);
var margin = normalizeSpacing(box.config.margin || 0); var margin = normalizeSpacing(box.config.margin || 0);
box.marginbox.x -= margin.l; box.marginbox.x -= margin.l;

View File

@@ -121,4 +121,28 @@ Ease.elastic = {
Ease.elastic.c4 = (2 * Math.PI) / 3 Ease.elastic.c4 = (2 * Math.PI) / 3
Ease.elastic.c5 = (2 * Math.PI) / 4.5 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 return Ease

View File

@@ -200,6 +200,45 @@ function translate_draw_commands(commands) {
cmd.rect.height = cmd.rect.height * cmd.scale.y cmd.rect.height = cmd.rect.height * cmd.scale.y
cmd.rect = worldToScreenRect(cmd.rect, camera) cmd.rect = worldToScreenRect(cmd.rect, camera)
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({ renderer_commands.push({
op: "texture", op: "texture",
data: { data: {
@@ -208,6 +247,7 @@ function translate_draw_commands(commands) {
src: img.rect src: img.rect
} }
}) })
}
break break

View File

@@ -158,7 +158,8 @@ tilemap.prototype =
this._dirty = false; 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 // 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) { 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); this._build_geometry_cache(pos);

View File

@@ -40,8 +40,18 @@ function Tween(obj) {
Tween.prototype.to = function(props, duration, start_time) { Tween.prototype.to = function(props, duration, start_time) {
for (var key in props) { for (var key in props) {
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.startVals[key] = this.obj[key]
this.endVals[key] = props[key] this.endVals[key] = value
}
} }
this.duration = duration this.duration = duration
@@ -85,7 +95,23 @@ Tween.prototype.seek = function(global_time) {
for (var key in this.endVals) { for (var key in this.endVals) {
var start = this.startVals[key] var start = this.startVals[key]
var end = this.endVals[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) { if (t == 1 && this.engine) {

View File

@@ -312,7 +312,7 @@ graphics.texture = function texture(path) {
if (!cache[id]) { if (!cache[id]) {
var ipath = res.find_image(id) var ipath = res.find_image(id)
if (!ipath) if (!ipath)
throw new Error(`unknown image ${id}`) return graphics.texture('notex')
var result = create_image(ipath) var result = create_image(ipath)
cache[id] = result cache[id] = result