// 015 - Moiré Interference (geometry)
// 1:1 Original algorithm engine source
function createMoireInterference() {
return {
setup() {
},
render(context, timeState, params) {
const { ctx, width, height } = context;
const t = timeState.time * Number(params.speed || 0.5);
const ringCount = Number(params.ringCount || 75);
const separation = Number(params.separation || 40) + Math.sin(t * 0.8) * 30;
ctx.fillStyle = "#08090d";
ctx.fillRect(0, 0, width, height);
const cx = width * 0.5;
const cy = height * 0.5;
const c1x = cx - separation;
const c1y = cy;
const c2x = cx + separation * Math.cos(t * 0.5);
const c2y = cy + separation * Math.sin(t * 0.5);
const maxR = Math.max(width, height) * 0.75;
const step = maxR / ringCount;
ctx.lineWidth = 1.3;
for (let r = 5; r < maxR; r += step) {
ctx.beginPath();
ctx.arc(c1x, c1y, r, 0, Math.PI * 2);
ctx.strokeStyle = hsla((180 + r / maxR * 60) % 360, 85, 60, 0.6);
ctx.stroke();
}
for (let r = 5; r < maxR; r += step) {
ctx.beginPath();
ctx.arc(c2x, c2y, r, 0, Math.PI * 2);
ctx.strokeStyle = hsla((280 + r / maxR * 60) % 360, 85, 65, 0.6);
ctx.stroke();
}
}
};
}
// Default parameters from content metadata
const defaultParams = [
{
"key": "ringCount",
"label": "Ring Density",
"type": "range",
"min": 30,
"max": 120,
"step": 5,
"defaultValue": 75,
"description": "Concentric circle count"
},
{
"key": "speed",
"label": "Orbital Shift Speed",
"type": "range",
"min": 0.1,
"max": 2,
"step": 0.1,
"defaultValue": 0.5,
"description": "Phase drift speed"
}
];
if (!window.__art_instances) window.__art_instances = {};
if (!window.__art_instances['moire-interference']) {
const inst = typeof createMoireInterference === 'function' ? createMoireInterference() : null;
if (inst && inst.setup) {
inst.setup({ ctx, width, height, dpr: 1, aspectRatio: width / height }, defaultParams);
}
window.__art_instances['moire-interference'] = inst;
}
const instance = window.__art_instances['moire-interference'];
if (instance && instance.render) {
instance.render(
{ ctx, width, height, dpr: 1, aspectRatio: width / height },
{ time, deltaTime: dt, frameCount: Math.floor(time * 60), fps: 60 },
defaultParams
);
}