1import { Pattern, silence, register, pure, createParams } from '@strudel/core'; 2import { getDrawContext } from './draw.mjs'; 3 4let clearColor = '#22222210'; 5 6Pattern.prototype.animate = function ({ callback, sync = false, smear = 0.5 } = {}) { 7 window.frame && cancelAnimationFrame(window.frame); 8 const ctx = getDrawContext(); 9 let { clientWidth: ww, clientHeight: wh } = ctx.canvas; 10 ww *= window.devicePixelRatio; 11 wh *= window.devicePixelRatio; 12 let smearPart = smear === 0 ? '99' : Number((1 - smear) * 100).toFixed(0); 13 smearPart = smearPart.length === 1 ? `0${smearPart}` : smearPart; 14 clearColor = `#200010${smearPart}`; 15 const render = (t) => { 16 let frame; 17 /* if (sync) { 18 t = scheduler.now(); 19 frame = this.queryArc(t, t); 20 } else { */ 21 t = Math.round(t); 22 frame = this.slow(1000).queryArc(t, t); 23 // } 24 ctx.fillStyle = clearColor; 25 ctx.fillRect(0, 0, ww, wh); 26 frame.forEach((f) => { 27 let { x, y, w, h, s, r, angle = 0, fill = 'darkseagreen' } = f.value; 28 w *= ww; 29 h *= wh; 30 if (r !== undefined && angle !== undefined) { 31 const radians = angle * 2 * Math.PI; 32 const [cx, cy] = [(ww - w) / 2, (wh - h) / 2]; 33 x = cx + Math.cos(radians) * r * cx; 34 y = cy + Math.sin(radians) * r * cy; 35 } else { 36 x *= ww - w; 37 y *= wh - h; 38 } 39 const val = { ...f.value, x, y, w, h }; 40 ctx.fillStyle = fill; 41 if (s === 'rect') { 42 ctx.fillRect(x, y, w, h); 43 } else if (s === 'ellipse') { 44 ctx.beginPath(); 45 ctx.ellipse(x + w / 2, y + h / 2, w / 2, h / 2, 0, 0, 2 * Math.PI); 46 ctx.fill(); 47 } 48 callback && callback(ctx, val, f); 49 }); 50 window.frame = requestAnimationFrame(render); 51 }; 52 window.frame = requestAnimationFrame(render); 53 return silence; 54}; 55 56export const { x, y, w, h, angle, r, fill, smear } = createParams('x', 'y', 'w', 'h', 'angle', 'r', 'fill', 'smear'); 57 58export const rescale = register('rescale', function (f, pat) { 59 return pat.mul(x(f).w(f).y(f).h(f)); 60}); 61 62export const moveXY = register('moveXY', function (dx, dy, pat) { 63 return pat.add(x(dx).y(dy)); 64}); 65 66export const zoomIn = register('zoomIn', function (f, pat) { 67 const d = pure(1).sub(f).div(2); 68 return pat.rescale(f).move(d, d); 69});