欢迎光临
我们一直在努力

春节整活:我用React + Canvas写了一个“剪纸+写春联”生成器(附源码)

本文分享一个完全由前端技术(React + TypeScript + Canvas)实现的春节主题开源项目——《在线剪纸+写春联》。 项目核心包含两个图形学模块:基于坐标映射的 径向对称剪纸系统 和基于速度/压力的 物理流体笔刷系统。 代码已开源,欢迎 Star 🌟。

1. 项目背景

春节期间,为了寻找“赛博年味”,我尝试用代码还原传统的“剪窗花”和“写春联”体验。 主要挑战在于:

  • 剪纸:如何实时计算并渲染复杂的 N 折(2/4/8/12)对称图形?
  • 书法:如何摆脱 Canvas lineTo 的生硬感,模拟出毛笔的笔锋和墨水扩散效果?

2. 技术栈

  • 框架:React 18 (Hooks 状态管理)
  • 语言:TypeScript (类型安全)
  • 渲染:HTML5 Canvas API (2D Context)
  • 样式:TailwindCSS
  • 构建:Vite

3. 核心技术解析

3.1 径向对称算法(剪纸模式)

剪窗花的本质是极坐标系下的旋转对称。我们在 Canvas 上只需要绘制“原本”,然后通过矩阵变换生成“镜像本”。

实现思路:

  • 定义一个“主扇区”(例如 8 折剪纸,主扇区角度为 45°)。
  • 监听鼠标在主扇区的操作 (x, y)。
  • 将 (x, y) 转换为极坐标 (r, θ)。
  • 根据对称阶数 n,生成 n 个旋转角度 θ_i = θ + 2π/n * i。
  • 将所有点转换回直角坐标并绘制。
  • AI 辅助点:我在开发中让 AI 推导了通用的坐标映射公式,解决了 12 折对称中的边界裁切问题。

    3.2 物理流体笔刷(写春联模式)

    如果直接用 ctx.lineWidth 固定值画线,效果会像记号笔一样死板。毛笔的精髓在于“提按顿挫”。

    物理模型设计:

    • 速度 v:计算鼠标移动的两点距离 / 时间。
    • 压力 p:模拟物理规则,速度越快压力越小(线条越细),速度越慢压力越大(线条越粗)。
    • 公式:width = baseWidth * (1 / (1 + v * factor))

    代码片段(简化版):

    typescript

    // 计算当前点的宽度

    const distance = Math.hypot(x2 – x1, y2 – y1);

    const velocity = distance / timeDelta;

    // 速度权重平滑处理

    const targetWidth = MAX_WIDTH * (1 – Math.min(velocity / MAX_VELOCITY, 0.8));

    // 使用插值平滑宽度变化

    currentWidth += (targetWidth – currentWidth) * 0.2;

    此外,为了模拟 墨水晕染,我在笔触边缘增加了随机的高斯模糊粒子,并让它们随时间做一个微小的扩散动画(RequestAnimationFrame)。

    3.3 离屏渲染性能优化

    由于笔刷的粒子效果非常消耗性能,我采用了 双缓冲技术 (Double Buffering)。

    • PaperCanvas:负责实时绘制当前的笔迹。
    • MainCanvas:负责保存已经画好的内容。 当一笔画完(MouseUp)时,将 PaperCanvas 的内容 drawImage 到 MainCanvas 上,清空临时层。这样可以支持无限次数的 Undo/Redo 而不掉帧。

    4. 效果展示

    我用 React + Canvas写了一个剪纸+写春联网站

    • 剪窗花:支持 2/4/8/12 折对称,实时预览。
    • 写春联:万年红金粉纸纹理,流体笔触。
    • 保存:支持导出为透明 PNG,可以用作设计素材。

    5. 源码与体验

    这是一个纯粹的开源项目,无任何商业引流。 希望能给正在学习 Canvas 交互的同学提供一点参考。

    获取:

    关注公众号:FlameAI

    (提前祝大家新春快乐!)

    赞(0)
    未经允许不得转载:171主机测评 » 春节整活:我用React + Canvas写了一个“剪纸+写春联”生成器(附源码)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址