在上一篇canvas绘图的基础上做了延伸,做了一个绘图小程序。
下面附上draw文件夹下各文件的源码:
html文件 ----- draw.html:
<view class="container"> <canvas canvas-id="canvas" disable-scroll='true' bindtouchstart="beginStroke" bindtouchmove="moveStroke" bindtouchend="endStroke" style="{{canvasWidth}}rpx;height:{{canvasHeight}}rpx" ></canvas> </view> <view class="controller"> <view class="colorContr"> <block wx:for="{{colors}}"> <button bindtap="selectColor" class="colorBtn {{curColor == item ? 'selected' : ''}}" data-value="{{item}}" style="background-color:{{item}}"></button> </block> </view> <slider bindchange='changeBold' min="1" max="20" value="5" block-size="18"/> <button bindtap="clearCanvas" class="clearBtn"><image src="../imgs/reset.png" mode="aspectFit"></image></button> <button bindtap="eraser" class="clearBtn {{isEraser ? 'selected' : ''}}"><image src="../imgs/eraser-v3.png" mode="aspectFit"></image></button> </view> <button class="saveImg" bindtap='saveImg'>保存</button> <text class="sucTip" hidden="{{isSuc}}">保存成功</text>
css文件 ----- draw.css:
/* pages/draw/draw.wxss */ .container{ 604rpx; height:604rpx; overflow: hidden; margin:40rpx auto; border: 1px solid #91d487; padding:1rpx; } .controller{ 600rpx; margin:30rpx auto; } .controller slider{ 360rpx; float:left; margin:10rpx 0; } .controller .colorContr{ overflow: hidden; margin-bottom:40rpx; } .controller .colorBtn{ 29px; height:29px; margin:3px; float:left; padding:0; border:3px solid #fff; } .controller .selected{ border:1px solid #666; } .clearBtn{ 80rpx; height:60rpx; float:right; padding:0; margin:0 10rpx; line-height:60rpx; font-size:30rpx; background:none; } .clearBtn::after{ border:none; } .clearBtn image{ 100%; height:100%; } .saveImg{ position:fixed; bottom:8rpx; left:50%; margin-left:-80rpx; 132rpx; height:132rpx; line-height:132rpx; font-size:34rpx; font-weight: bold; letter-spacing: 5rpx; background:#91d487; color:#ffffff; border-radius: 50%; border:0; box-shadow: 3px 3px 3px #aaa; text-align:center; } .saveImg.button-hover{ background:#82c078; color:#efefef; } .sucTip{ /* display:block; */ position:fixed; bottom:35%; left:50%; transform: translateX(-50%); color:#fff; padding:10rpx 20rpx; border-radius: 5px; background:#91d487; }
js文件 ----- draw.js:
Page({ /** * 页面的初始数据 */ data: { canvasWidth:'600', canvasHeight: 0, boldVal:5, colors: ['black', 'pink', 'red', 'skyblue', 'greenyellow', '#00FF00', '#0000FF', '#FF00FF','#00FFFF', '#FFFF00', '#70DB93', '#5C3317 ', '#9F5F9F', '#B5A642', '#FF7F00','#42426F'], curColor:'#000000', isEraser:false, isSuc:true, isTap:true, }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.context = wx.createCanvasContext('canvas'); this.setData({ canvasHeight: this.data.canvasWidth}) this.isMouseDown=false this.lastLoc={ x: 0, y: 0 } this.lastTimestamp = 0; this.lastLineWidth = -1; this.drawBgColor(); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { // this.setData({context: }); }, drawBgColor(){ this.context.save(); this.context.setFillStyle('#ffffff'); this.context.fillRect(0, 0, this.data.canvasWidth, this.data.canvasHeight) this.context.restore(); this.context.draw({ reserve: true }) }, changeBold:function(e){ this.setData({boldVal: e.detail.value}) }, selectColor:function(e){ this.setData({ curColor: e.currentTarget.dataset.value }) this.setData({ isEraser: false }) }, beginStroke(event) { this.isMouseDown = true this.lastLoc = { x: event.touches[0].x, y: event.touches[0].y } this.lastTimestamp = event.timeStamp; this.setData({ isTap: true }) // //draw this.context.arc(this.lastLoc.x, this.lastLoc.y, this.data.boldVal / 2, 0, 2 * Math.PI) this.context.setFillStyle(this.data.curColor); this.context.fill(); wx.drawCanvas({ canvasId: 'canvas', reserve: true, actions: this.context.getActions() // 获取绘图动作数组 }) // if (event.touches.length>1){ // var xMove = event.touches[1].x - event.touches[0].x; // var yMove = event.touches[1].y - event.touches[0].y; // this.lastDistance = Math.sqrt(xMove * xMove + yMove * yMove); // } }, endStroke(event) { // console.log(this.data.isTap) // if (this.data.isTap){ // this.lastLoc = { x: event.changedTouches[0].x, y: event.changedTouches[0].y } // this.lastTimestamp = event.timeStamp; // //draw // this.context.arc(this.lastLoc.x, this.lastLoc.y, this.data.boldVal / 2, 0, 2 * Math.PI) // this.context.setFillStyle(this.data.curColor); // this.context.fill(); // wx.drawCanvas({ // canvasId: 'canvas', // reserve: true, // actions: this.context.getActions() // 获取绘图动作数组 // }) // } this.isMouseDown= false }, moveStroke(event) { if (this.isMouseDown && event.touches.length == 1) { var touch = event.touches[0]; var context = this.context; var curLoc = { x: touch.x, y: touch.y }; var curTimestamp = event.timeStamp; var s = this.calcDistance(curLoc, this.lastLoc) var t = curTimestamp - this.lastTimestamp; var lineWidth = this.calcLineWidth(t, s) //draw context.setStrokeStyle(this.data.curColor); context.setLineWidth(lineWidth); context.beginPath() context.moveTo(this.lastLoc.x, this.lastLoc.y) context.lineTo(curLoc.x, curLoc.y) // locHistory.push({ x: curLoc.x, y: curLoc.y, with: lineWidth, t: t }) context.setLineCap("round") context.setLineJoin("round") context.stroke(); this.lastLoc=curLoc; // this.setData({ lastTimestamp: curTimestamp }) // this.setData({ lastLineWidth: lineWidth }) wx.drawCanvas({ canvasId: 'canvas', reserve: true, actions: this.context.getActions() // 获取绘图动作数组 }) } else if (event.touches.length > 1){ this.setData({isTap:false}) var xMove = event.touches[1].x - event.touches[0].x; var yMove = event.touches[1].y - event.touches[0].y; var newdistance = Math.sqrt(xMove*xMove + yMove*yMove); // if (newdistance - this.lastDistance>0){ // this.setData({ canvasWidth: this.data.canvasWidth * 1.2 }) // this.setData({ canvasHeight: this.data.canvasHeight * 1.2 }) // }else{ // this.setData({ canvasWidth: this.data.canvasWidth * 0.8 }) // this.setData({ canvasHeight: this.data.canvasHeight * 0.8}) // } } }, calcLineWidth(t, s){ var v = s / t; var resultLineWidth = this.data.boldVal; if(v <= 0.1) { resultLineWidth = resultLineWidth * 1.2; }else if(v >= 10) { resultLineWidth = resultLineWidth/1.2 }else{ resultLineWidth = resultLineWidth - (v - 0.1) / (10 - 0.1) * (resultLineWidth * 1.2 - resultLineWidth / 1.2) } return resultLineWidth }, calcDistance(loc1, loc2) { return Math.sqrt((loc1.x - loc2.x) * (loc1.x - loc2.x) + (loc1.y - loc2.y) * (loc1.y - loc2.y)) }, clearCanvas:function(){ this.drawBgColor() this.setData({ isEraser:false}) }, eraser:function () { this.setData({ isEraser: !this.data.isEraser}) this.setData({ curColor:'#ffffff'}) // this.context.clearActions(); // this.context.draw() }, saveImg:function(){ var that = this; var keys = wx.getStorageSync('myImg') || []; console.log(that.data.keyLength) wx.canvasToTempFilePath({ canvasId: 'canvas', success: function (response) { keys.unshift(response.tempFilePath) wx.setStorage({ key: 'myImg', data: keys, }) that.setData({ isSuc: false }) setTimeout(function () { that.setData({ isSuc: true }) wx.navigateTo({ url: '../index/index', }) }, 1000) } }) } })
小程序中canvas的具体用法和属性请参考小程序文档。