news 2026/10/29 11:08:19

微信小程序实战:Canvas 2D 自由画板与画笔颜色切换功能实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微信小程序实战:Canvas 2D 自由画板与画笔颜色切换功能实现

前言

在微信小程序开发中,canvas组件常用于实现图表绘制、图片裁剪、签名板等功能。相比于旧版的 canvas 接口,小程序基础库 2.9.0 起开始支持的Canvas 2D 接口性能更好,且与 Web 标准更加接轨。

本文将带领大家从零开始,实现一个基于 Canvas 2D 的自由绘图画板,并在此基础上扩展一个实用功能:动态切换画笔颜色。

一、 核心知识点

  1. Canvas 2D 组件:使用<canvas type="2d">标签。

  2. 节点查询 (SelectQuery):通过wx.createSelectorQuery()获取 canvas 节点及上下文。

  3. 触摸事件:利用bindtouchstart和bindtouchmove获取手指坐标并绘制。

  4. 绘图 API:ctx.beginPath(),ctx.lineTo(),ctx.stroke(),ctx.clearRect()等。

二、 项目结构与布局设计

首先,在index.wxml中搭建页面结构。我们需要一个画布区域以及底部的操作按钮。

html

<!--index.wxml--> <view class="box"> <view class="title">自由绘图</view> <!-- Canvas 2D 组件,绑定触摸事件 --> <canvas type="2d" id="my-canvas" bindtouchstart="paintStart" bindtouchmove="paintMove" /> <view class="btn-layout"> <!-- 清空按钮 --> <button type="primary" size="mini" bindtap="clear">清空画布</button> <!-- 扩展功能:改变颜色按钮 --> <button type="warn" size="mini" bindtap="changeColor">改变画笔颜色</button> </view> </view>

接着,在app.wxss或index.wxss中添加一些基础的样式,让界面看起来更加美观:

css

/**app.wxss**/ .box { margin: 20rpx; padding: 20rpx; border: 2rpx solid purple; } .title { font-size: 40rpx; font-weight: bolder; text-align: center; margin-bottom: 30rpx; color: red; } /* 设置画布大小,必须指定具体像素 */ canvas { width: 100%; height: 600rpx; background-color: cornflowerblue; /* 初始画布背景色 */ } .btn-layout { display: flex; justify-content: space-around; margin-top: 20rpx; }

三、 核心逻辑实现 (index.js)

这是整个案例的核心部分。我们需要在页面加载完成后(onReady)初始化 Canvas,并在触摸事件中处理绘图逻辑。

1. 初始化 Canvas 与获取上下文

在小程序中,我们必须通过wx.createSelectorQuery来获取真实的 canvas 节点。

javascript

Page({ data: { currentColor: '#ff0000' // 默认画笔颜色:红色 }, onReady() { // 创建查询对象 const query = wx.createSelectorQuery() // 选择 id 为 my-canvas 的节点 query.select('#my-canvas') .fields({ node: true, size: true }) .exec((res) => { const canvas = res[0].node const ctx = canvas.getContext('2d') // 处理设备像素比,防止绘图模糊 const dpr = wx.getSystemInfoSync().pixelRatio canvas.width = res[0].width * dpr canvas.height = res[0].height * dpr ctx.scale(dpr, dpr) // 将 canvas 和 ctx 挂载到 this 上,方便其他函数调用 this.canvas = canvas this.ctx = ctx // 初始设置画笔样式 ctx.lineWidth = 4 ctx.lineCap = 'round' ctx.lineJoin = 'round' }) }, // ... 后续方法 })

2. 实现自由绘制 (TouchStart & TouchMove)

  • paintStart:手指按下时,记录起始点,并开启一个新路径。

  • paintMove:手指移动时,不断连接坐标点并绘制。

javascript

paintStart(e) { let ctx = this.ctx if (!ctx) return // 开启新路径 ctx.beginPath() // 获取触点坐标 (注意:小程序新版接口推荐使用 e.touches[0].x 或 clientX) let x = e.touches[0].x let y = e.touches[0].y // 将画笔移动到起始点 ctx.moveTo(x, y) }, paintMove(e) { let ctx = this.ctx if (!ctx) return let x = e.touches[0].x let y = e.touches[0].y // 动态应用当前的颜色 ctx.strokeStyle = this.data.currentColor // 画线到当前坐标 ctx.lineTo(x, y) // 执行绘制 ctx.stroke() }

3. 扩展功能:清空画布与切换颜色

  • clear:使用clearRect擦除整个画布区域。

  • changeColor:在红、绿、蓝三种颜色之间循环切换,并更新 data 中的状态。

javascript

clear() { let canvas = this.canvas let ctx = this.ctx if (!canvas || !ctx) return // 开启新路径(避免之前的路径影响) ctx.beginPath() // 清空整个画布矩形区域 ctx.clearRect(0, 0, canvas.width, canvas.height) }, // 扩展功能:改变画笔颜色 changeColor() { let color = this.data.currentColor let newColor = '' // 颜色轮换逻辑:红 -> 绿 -> 蓝 -> 红 if (color === '#ff0000') { newColor = '#00ff00' } else if (color === '#00ff00') { newColor = '#0000ff' } else { newColor = '#ff0000' } // 更新页面数据 this.setData({ currentColor: newColor }) }

四、 效果展示与总结

完成代码编写后,运行小程序,效果如下:

  1. 初始状态:画布为蓝色背景,默认画笔为红色,可以自由书写。

  2. 颜色切换:点击“改变画笔颜色”按钮后,画笔颜色变为绿色/蓝色,继续书写即可看到效果。

  3. 清空画布:点击“清空画布”按钮,画板恢复初始空白状态。

开发踩坑提示:

  1. 模糊问题:在手机上运行时,如果不乘以设备的pixelRatio进行缩放,画出来的线条会非常模糊(发虚)。代码中的ctx.scale(dpr, dpr)是解决此问题的关键。

  2. 坐标获取:部分旧版开发工具可能获取不到e.touches[0].x,此时可以尝试兼容写法(如e.touches[0].clientX)。但在最新基础库的 Canvas 2D 模式下,直接使用x和y属性即可。

  3. 样式设置顺序:ctx.strokeStyle等样式设置最好放在ctx.stroke()调用之前。

通过这个小案例,不仅掌握了小程序 Canvas 2D 的基本绘图流程,还学会了如何结合数据绑定(setData)来实现绘图属性的动态更新,希望能为你的小程序开发之路提供帮助!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/29 11:07:50

中项-数据工程

数据采集的方法&#xff1a;传感器采集、系统日志采集、网络采集和其他数据采集等。 数据预处理&#xff1a;数据分析&#xff0c;数据检测&#xff0c;数据修正 数据备份&#xff1a;备份结构&#xff0c;备份策略 数据容灾&#xff1a;远程镜像&#xff0c;快照技术 数据模型…

作者头像 李华
网站建设 2026/10/29 11:07:08

微信小程序 canvas 组件实战笔记

一、canvas&#xff1a;小程序里唯一能"自己画"的地方 前面几个案例练的都是现成组件&#xff1a;滚动视图、地图、按钮&#xff0c;都是微信提供什么就用什么。canvas 不一样&#xff0c;它是一块近乎空白的画布——组件本身只负责给你一块区域&#xff0c;画什么、…

作者头像 李华
网站建设 2026/10/29 11:06:31

《人月神话》读后感

前段时间我给高并发内存池做收尾工作时&#xff0c;跑了一轮多线程benchmark。4 线程的时候数据还不错&#xff0c;但当我加到8个时&#xff0c;结果吞吐量不升反降。我第一反应是代码有bug&#xff0c;查了半天&#xff0c;发现没有&#xff0c;问了AI才知道真正的原因是线程太…

作者头像 李华
网站建设 2026/10/29 11:05:42

MySQL 数据库全栈运维实战系列 — 合集索引(24 篇)

MySQL 数据库全栈运维实战系列 — 合集索引&#xff08;24 篇&#xff09; 系列定位&#xff1a;《MySQL 数据库全栈运维实战系列》7 大模块 22 篇 2 篇番外&#xff0c;与《Oracle 数据库全栈运维实战系列&#xff08;VMware 版&#xff09;》同构对标&#xff0c;方便跨数据…

作者头像 李华
网站建设 2026/10/29 11:04:50

谍赞把一个“发内容”的动作,做成一条能跑通的流水线

——记一次内容运营团队的 AI 工作台落地项目记录&#xff5c;谍赞智能 企业 AI 转型顾问 服务方式&#xff1a;需求诊断 方案设计 培训 陪跑 兜底 记录时间&#xff1a;2026 年 10 月先把项目说清楚客户是一家做内容运营的团队&#xff0c;人不多&#xff0c;活很杂。选题…

作者头像 李华
网站建设 2026/10/29 11:03:44

C++课程资源复习地图:从语法到并发项目实战

简介&#xff1a;面向C入门到进阶学习者的黑马程序员课程资料包&#xff0c;聚焦课堂教学与项目实战的衔接&#xff0c;适合希望系统梳理C语法、面向对象编程及STL应用的自学者与在校学生。压缩包约64.14MB&#xff0c;内含课程文档手册、实验项目及多本PDF电子书&#xff0c;文…

作者头像 李华