完整全部代码
1. app.json
{ "pages": [ "pages/index/index" ], "window": { "navigationBarTextStyle": "black", "navigationStyle": "custom" }, "style": "v2", "renderer": "skyline", "rendererOptions": { "skyline": { "defaultDisplayBlock": true, "defaultContentBox": true, "tagNameStyleIsolation": "legacy", "disableABTest": true, "sdkVersionBegin": "3.0.0", "sdkVersionEnd": "15.255.255" } }, "componentFramework": "glass‑easel", "sitemapLocation": "sitemap.json", "lazyCodeLoading": "requiredComponents" }2. pages/index/index.wxml
作业新增按钮:
绘制图片,绑定事件drawImageCanvas
<navigation-bar title="基本绘图" back="{{false}}" color="black" background="#FFF"></navigation-bar> <scroll-view class="scrollarea" scroll-y type="list"> <view class="box"> <view class="title">{{title}}</view> <canvas type="2d" id="my-canvas" /> <view class="btn-layout"> <button type="primary" size="mini" bind:tap="clear">清空画布</button> <button type="primary" size="mini" bind:tap="drawFillCircle">画实心圆</button> <button type="primary" size="mini" bind:tap="drawStrokeCircle">画轮廓圆</button> </view> <view class="btn-layout"> <button type="primary" size="mini" bind:tap="drawDashLine">绘制虚线</button> <button type="primary" size="mini" bind:tap="drawCapAndJoin">端点交点</button> <button type="primary" size="mini" bind:tap="drawFillText">绘制文字</button> </view> <view class="btn-layout"> <button type="primary" size="mini" bind:tap="drawRadialGrad">图形渐变</button> <button type="primary" size="mini" bind:tap="drawShadowRect">阴影矩形</button> <button type="primary" size="mini" bind:tap="drawTranslucent">半透明图</button> </view> <!--作业扩展:绘制图片按钮 --> <view class="btn-layout"> <button type="primary" size="mini" bind:tap="drawImageCanvas">绘制图片</button> </view> </view> </scroll-view>3. pages/index/index.wxss
page { height: 100vh; display: flex; flex-direction: column; } .scrollarea { flex: 1; overflow-y: hidden; } canvas { width: 100%; height: 680rpx; background-color: #e9ecf3; } .btn-layout { display: flex; flex-direction: row; margin: 20rpx; justify-content: space‑around; }4. app.wxss
.box { margin: 20rpx; padding: 20rpx; border: 2rpx solid purple; } .title { font-size: 40rpx; font-weight: bolder; text-align: center; color: #e43d33; margin-bottom: 30rpx; }5. pages/index/index.js(全部逻辑,含作业绘制图片)![]()
Page({ data: { title: '基本绘图' }, onReady() { const query = wx.createSelectorQuery() query.select('#my‑canvas') .fields({ node: true, size: true }) .exec(res => { console.log(res); const canvas = res[0].node const ctx = canvas.getContext('2d') const dpr = wx.getWindowInfo().pixelRatio canvas.width = res[0].width * dpr canvas.height = res[0].height * dpr ctx.scale(dpr, dpr) this.canvas = canvas this.ctx = ctx }) }, // 清空画布 clear() { let canvas = this.canvas let ctx = this.ctx ctx.save() ctx.beginPath() ctx.clearRect(0, 0, canvas.width, canvas.height) this.setData({ title: '清空画布' }) }, // 画实心圆 drawFillCircle() { this.clear() let ctx = this.ctx ctx.arc(175, 175, 120, 0, 2 * Math.PI) ctx.fillStyle = 'purple' ctx.fill() ctx.restore() this.setData({ title: '画实心圆' }) }, // 画轮廓圆 drawStrokeCircle() { this.clear() let ctx = this.ctx ctx.strokeStyle = 'purple' ctx.lineWidth = 6 ctx.arc(175, 175, 120, 0, 2 * Math.PI) ctx.stroke() ctx.restore() this.setData({ title: '画轮廓圆' }) }, // 绘制虚线三角形 drawDashLine() { this.clear() let ctx = this.ctx ctx.strokeStyle = 'purple' ctx.setLineDash([5, 15]) ctx.lineWidth = 10 ctx.moveTo(50, 100) ctx.lineTo(250, 100) ctx.lineTo(150, 300) ctx.lineTo(50, 100) ctx.stroke() ctx.restore() this.setData({ title: '绘制虚线' }) }, // 端点与交点样式 Z字形 drawCapAndJoin() { this.clear() let ctx = this.ctx ctx.strokeStyle = 'purple' ctx.lineWidth = 20 ctx.lineCap = 'round' ctx.lineJoin = 'miter' ctx.moveTo(50, 50) ctx.lineTo(250, 50) ctx.lineTo(50, 250) ctx.lineTo(250, 250) ctx.stroke() ctx.restore() this.setData({ title: '端点交点' }) }, // 绘制文字(包含旋转文字) drawFillText() { this.clear() let ctx = this.ctx ctx.font = 'bold 48px serif' ctx.fillStyle = 'red' ctx.textBaseline = 'bottom' ctx.fillText('东方学院', 40, 80) ctx.fillStyle = 'yellow' ctx.textBaseline = 'top' ctx.fillText('东方学院', 40, 120) ctx.fillStyle = 'blue' ctx.rotate(30 * Math.PI / 180) ctx.fillText('东方学院', 100, 80) ctx.restore() this.setData({ title: '绘制文字' }) }, // 径向圆形渐变 drawRadialGrad() { this.clear() let ctx = this.ctx let grad = ctx.createRadialGradient(175, 175, 25, 175, 175, 125) grad.addColorStop(0, 'yellow') grad.addColorStop(0.2, 'red') grad.addColorStop(0.4, 'pink') grad.addColorStop(0.6, 'green') grad.addColorStop(0.8, 'orange') grad.addColorStop(1, 'blue') ctx.fillStyle = grad ctx.fillRect(50, 50, 250, 250) ctx.restore() this.setData({ title: '图形渐变' }) }, // 阴影矩形 drawShadowRect() { this.clear() let ctx = this.ctx ctx.fillStyle = 'orange' ctx.shadowOffsetX = 20 ctx.shadowOffsetY = 30 ctx.shadowBlur = 50 ctx.shadowColor = 'yellow' ctx.fillRect(50, 50, 250, 250) ctx.restore() this.setData({ title: '阴影矩形' }) }, // 半透明图形 globalAlpha drawTranslucent() { this.clear() let ctx = this.ctx ctx.fillStyle = 'red' ctx.globalAlpha = 0.2 ctx.fillRect(50, 50, 250, 250) ctx.restore() this.setData({ title: '半透明图' }) }, // =========作业扩展:绘制图片============ drawImageCanvas() { this.clear() const ctx = this.ctx const canvas = this.canvas // 1. 使用canvas.createImage创建Image对象(小程序2dcanvas专用) const img = canvas.createImage() // 图片地址:可以放本地static资源,也可以网络图片,网络图片需要配置downloadFile域名 img.src = "/images/autumn.jpg" // 图片加载完成回调onload,再执行drawImage img.onload = () => { // drawImage(图片对象,x,y,宽度,高度) ctx.drawImage(img, 20, 20, 300, 360) } ctx.restore() this.setData({ title: '绘制图片' }) } })