Canvas动态万花筒核心是构建几何对称系统:以中心扇形为基(如60°→6次反射),用rotate与scale(-1,1)模拟镜像,结合鼠标输入生成动态图元,通过offscreenCanvas优化性能并添加残影、柔光等视觉效果。

用 Canvas 实现动态万花筒效果,核心是利用几何对称(尤其是镜像反射)和实时坐标变换,配合 requestAnimationFrame 做平滑动画。关键不在“画图案”,而在“构造对称系统”——把一个基础图形(比如三角形、线段或小圆)通过多次反射、旋转,自动铺满整个画布,形成无限延伸的镜面分形感。
一、搭建对称反射系统:60°/90°/120°扇形是万花筒基础
真实万花筒靠三面相交的镜子形成等边三角形反射腔。网页中可简化为:在画布中心画一个夹角为 θ 的扇形(如 60°),然后将用户绘制的原始图形,在该扇形内做 n = 360°/θ 次镜像反射(或旋转变换),就能复现镜面叠加效果。
- 例如取 θ = 60° → 需生成 6 个对称副本;取 θ = 45° → 8 个;θ = 30° → 12 个
- 不用手动计算每条镜面线,而是用 canvas 的 save() → rotate() → scale(-1,1) → restore() 组合模拟单次反射
- 更稳定的做法:用 setTransform(1,0,0,1,0,0) 重置矩阵后,对每个副本单独应用 rotate(angle) + transform(reflectMatrix)
二、动态交互:鼠标/触控驱动图形演化
万花筒的“动感”来自实时变化的基础图形。不要预设固定形状,而是把鼠标位置、移动轨迹、按键状态作为输入源:
- 用 mousemove 获取 (x,y),将其映射到中心扇形内(减去 canvas 中心,再极坐标归一化)
- 以鼠标点为顶点,随机生成小三角形 / 贝塞尔曲线 / 粒子簇,作为“原始图元”
- 按帧更新时,给图元加轻微旋转偏移(rotation += 0.01)或缩放抖动(scale *= 0.995),制造漂浮感
- 支持键盘(如空格切换对称阶数,1–6键切换反射角度)或触摸多点识别(两点距离控制图元大小)
三、性能与视觉增强技巧
全量重绘 12 个反射副本易卡顿,需分层优化:
立即学习“前端免费学习笔记(深入)”;
- 用 offscreenCanvas(或内存 canvas)预先渲染基础图元,每次只 copyTransform 复制,避免重复路径绘制
- 添加透明度叠加:globalAlpha = 0.03 每帧清屏时不完全擦除,保留残影形成光迹效果
- 对高阶对称(如12镜),跳过部分副本的描边或填充,仅保留关键轮廓,降低 fill() 调用次数
- 用 createRadialGradient 给中心加柔光晕,模拟镜筒物理透光特性
四、封装可复用的 KaleidoRenderer 类
避免逻辑散落在事件监听里,建议封装成类:
- KaleidoRenderer(ctx, symmetry=6, radius=150):初始化画布上下文与对称参数
- .addShape(pathFn):注册一个函数,接收 (cx,cy,angle,step) 返回 Path2D 或 draw 操作
- .animate():内部调用 requestAnimationFrame,自动执行旋转+反射+绘制循环
- 暴露 .setCenter(x,y) 和 .setRotationSpeed(rps) 方便外部控制
这样只需几行代码就能启动一个可交互万花筒:
const k = new KaleidoRenderer(ctx, 8);
k.addShape((cx,cy,a) => { ctx.arc(cx,cy,10+Math.sin(a*3)*3,0,PI2); });
k.animate();



















