log.console("test_shape2d starting") var time = use('time') var core = use('core') var shape2d = use('shape2d') var compositor = use('compositor') var film2d = use('film2d') var math = use('math/radians') var shapes = [] var t = 0 var camera = { pos: {x: 400, y: 300}, width: 800, height: 600, anchor: {x: 0.5, y: 0.5} } var compositor_config = { clear: {r: 0.1, g: 0.1, b: 0.15, a: 1}, planes: [ { name: 'main', plane: 'main', camera: camera, resolution: {width: 800, height: 600}, presentation: 'stretch', clear: {r: 0.1, g: 0.1, b: 0.15, a: 1} } ] } function init() { // Row 1: Basic shapes - rect, circle, ellipse, pill // Rectangle with rounded corners shapes[] = shape2d.rect({ plane: 'main', layer: 0, pos: {x: 100, y: 500}, width: 120, height: 80, radius: 10, fill: {r: 0.2, g: 0.6, b: 0.9, a: 1} }) // Circle shapes[] = shape2d.circle({ plane: 'main', layer: 0, pos: {x: 250, y: 500}, radius: 50, fill: {r: 0.9, g: 0.3, b: 0.3, a: 1} }) // Ellipse shapes[] = shape2d.ellipse({ plane: 'main', layer: 0, pos: {x: 400, y: 500}, width: 140, height: 80, fill: {r: 0.3, g: 0.9, b: 0.4, a: 1} }) // Pill (stadium) shapes[] = shape2d.pill({ plane: 'main', layer: 0, pos: {x: 550, y: 500}, width: 140, height: 60, fill: {r: 0.9, g: 0.7, b: 0.2, a: 1} }) // Row 2: Stroke variations // Rect with stroke only shapes[] = shape2d.rect({ plane: 'main', layer: 0, pos: {x: 100, y: 380}, width: 100, height: 80, radius: 5, fill: {r: 0, g: 0, b: 0, a: 0}, stroke: {r: 1, g: 1, b: 1, a: 1}, stroke_thickness: 3, stroke_align: 'center', dash_len: 14, gap_len: 6 }) // Circle with thick stroke shapes[] = shape2d.circle({ plane: 'main', layer: 0, pos: {x: 250, y: 380}, radius: 45, fill: {r: 0.2, g: 0.2, b: 0.3, a: 1}, stroke: {r: 0.5, g: 0.8, b: 1, a: 1}, stroke_thickness: 6, stroke_align: 'outside', dash_len: 14, gap_len: 6 }) // Ellipse with inside stroke shapes[] = shape2d.ellipse({ plane: 'main', layer: 0, pos: {x: 400, y: 380}, width: 120, height: 70, fill: {r: 0.4, g: 0.2, b: 0.5, a: 1}, stroke: {r: 1, g: 0.5, b: 0.8, a: 1}, stroke_thickness: 4, stroke_align: 'inside', dash_len: 14, gap_len: 6 }) // Pill with dashed stroke shapes[] = shape2d.pill({ plane: 'main', layer: 0, pos: {x: 550, y: 380}, width: 130, height: 50, fill: {r: 0.1, g: 0.3, b: 0.2, a: 1}, stroke: {r: 0.3, g: 1, b: 0.5, a: 1}, stroke_thickness: 3, dash_len: 15, gap_len: 8 }) // Row 3: Feather / soft edges // Soft rect shapes[] = shape2d.rect({ plane: 'main', layer: 0, pos: {x: 100, y: 260}, width: 100, height: 80, radius: 20, fill: {r: 0.8, g: 0.4, b: 0.1, a: 1}, feather: 10 }) // Soft circle (glow effect) shapes[] = shape2d.circle({ plane: 'main', layer: 0, pos: {x: 250, y: 260}, radius: 40, fill: {r: 1, g: 0.9, b: 0.3, a: 1}, feather: 20 }) // Soft ellipse shapes[] = shape2d.ellipse({ plane: 'main', layer: 0, pos: {x: 400, y: 260}, width: 120, height: 60, fill: {r: 0.3, g: 0.5, b: 1, a: 0.8}, feather: 15 }) // Sharp vs soft comparison shapes[] = shape2d.pill({ plane: 'main', layer: 0, pos: {x: 550, y: 260}, width: 120, height: 50, fill: {r: 1, g: 0.2, b: 0.6, a: 1}, feather: 5 }) // Row 4: Opacity and blending // Semi-transparent overlapping shapes shapes[] = shape2d.rect({ plane: 'main', layer: 0, pos: {x: 80, y: 130}, width: 100, height: 80, fill: {r: 1, g: 0, b: 0, a: 0.6}, opacity: 1 }) shapes[] = shape2d.rect({ plane: 'main', layer: 1, pos: {x: 120, y: 130}, width: 100, height: 80, fill: {r: 0, g: 1, b: 0, a: 0.6}, opacity: 1 }) shapes[] = shape2d.rect({ plane: 'main', layer: 2, pos: {x: 100, y: 150}, width: 100, height: 80, fill: {r: 0, g: 0, b: 1, a: 0.6}, opacity: 1 }) // Animated opacity circle shapes[] = shape2d.circle({ plane: 'main', layer: 0, pos: {x: 280, y: 130}, radius: 50, fill: {r: 1, g: 1, b: 1, a: 1}, opacity: 1 }) // Different corner radii shapes[] = shape2d.rect({ plane: 'main', layer: 0, pos: {x: 420, y: 130}, width: 100, height: 80, radius: 0, fill: {r: 0.5, g: 0.5, b: 0.5, a: 1} }) shapes[] = shape2d.rect({ plane: 'main', layer: 0, pos: {x: 540, y: 130}, width: 100, height: 80, radius: 20, fill: {r: 0.6, g: 0.6, b: 0.6, a: 1} }) shapes[] = shape2d.rect({ plane: 'main', layer: 0, pos: {x: 660, y: 130}, width: 100, height: 80, radius: 40, fill: {r: 0.7, g: 0.7, b: 0.7, a: 1} }) // Row 5: Large decorative shapes // Background panel shapes[] = shape2d.rect({ plane: 'main', layer: -1, pos: {x: 700, y: 400}, width: 160, height: 350, radius: 15, fill: {r: 0.15, g: 0.15, b: 0.2, a: 1}, stroke: {r: 0.3, g: 0.3, b: 0.4, a: 1}, stroke_thickness: 2 }) // Decorative circles inside panel shapes[] = shape2d.circle({ plane: 'main', layer: 0, pos: {x: 700, y: 500}, radius: 30, fill: {r: 0.8, g: 0.2, b: 0.3, a: 1} }) shapes[] = shape2d.circle({ plane: 'main', layer: 0, pos: {x: 700, y: 420}, radius: 25, fill: {r: 0.2, g: 0.8, b: 0.3, a: 1} }) shapes[] = shape2d.circle({ plane: 'main', layer: 0, pos: {x: 700, y: 350}, radius: 20, fill: {r: 0.2, g: 0.3, b: 0.8, a: 1} }) log.console("test_shape2d initialized with " + text(length(shapes)) + " shapes") } function update(dt) { t += dt // Animate opacity on the white circle (index 16) if (shapes[16]) { shapes[16].opacity = 0.3 + 0.7 * (0.5 + 0.5 * math.sine(t * 2)) } // Animate the glow circle size (index 10) var scale = null if (shapes[10]) { scale = 1 + 0.2 * math.sine(t * 3) shapes[10].width = 80 * scale shapes[10].height = 80 * scale } // Rotate the dashed pill stroke (index 7) if (shapes[7]) { shapes[4].dash_offset = t * 30 shapes[5].dash_offset = t * 30 shapes[6].dash_offset = t * 30 shapes[7].dash_offset = t * 30 } // Pulse the decorative circles if (shapes[21]) { shapes[21].fill.r = 0.5 + 0.5 * math.sine(t * 1.5) } if (shapes[22]) { shapes[22].fill.g = 0.5 + 0.5 * math.sine(t * 1.5 + 2.094) } if (shapes[23]) { shapes[23].fill.b = 0.5 + 0.5 * math.sine(t * 1.5 + 4.188) } } function render() { var plan = compositor.compile(compositor_config) return compositor.execute(plan) } init() core.start({ width: 800, height: 600, title: "Test Shape2D - SDF Shapes", framerate: 60, update: update, render: render })