<!--pages/API/FreeDrawing/index.wxml-->
<view class='box'>
  <view class='title'>自由绘图</view>
  <!--画布区域-->
  <view>
    <canvas canvas-id='myCanvas' disable-scroll='true' bindtouchstart='touchStart' bindtouchmove='touchMove' bindtouchend='touchEnd'>
    </canvas>
  </view>
  <!--绘图工具区域-->
  <view class='toolStyle01'>
    <view class='toolStyle02'>
      <view class='toolStyle' hover-class='changeBc' bindtap='penSelect' data-param='5'>钢笔</view>
      <view class='toolStyle' hover-class='changeBc' bindtap='penSelect' data-param='15'>毛笔</view>
    </view>
    <view class='toolStyle02'>
      <view class='toolStyle' hover-class='changeBc' bindtap='colorSelect' data-param='red'>红色</view>
      <view class='toolStyle' hover-class='changeBc' bindtap='colorSelect' data-param='blue'>蓝色</view>
    </view>
    <view class='toolStyle02'>
      <view class='toolStyle' hover-class='changeBc' bindtap='clear'>擦除</view>
      <view class='toolStyle' hover-class='changeBc' bindtap='clearAll'>清屏</view>
    </view>
  </view>
</view>

通过data-param传递数据到js文件,把视图层数据传递到逻辑层

/* pages/API/FreeDrawing/index.wxss */

canvas {
  /* 画布样式 */
  width: 100%;
  height: 360px;
  border: 1px solid springgreen;
}

.toolStyle01 {
  /* 底部画图工具总体布局 */
  position: absolute; /* 绝对位置布局,生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。 */
  bottom: 10px; /* 整个,距离页面底部10px */
  display: flex;
  flex-direction: row;/* 三组元素采用行布局 */
}

.toolSyle02 {
  /* 底部画图工具分组布局 */
  display: flex;
  flex-direction: column;/* 列布局,弹性布局 */
}

.toolStyle {
  /* 底部画图工具样式 */
  width: 60px;
  height: 60px;
  border: 1px solid #ccc;
  border-radius: 50%; /* 边框半径 */
  text-align: center;
  line-height: 60px;
  background: green;
  color: #fff;
  margin: 10px 20px;
}

.changeBc {
  /* 底部画图工具被点击后的背景颜色 */
  background: #f00;
}
// pages/API/FreeDrawing/index.js
Page({
  isClear: false, //不启用擦除

  data: {
    pen: 5, //画笔粗细默认值
    color: '#000000' //画笔颜色默认值,黑色
  },

  onLoad: function() {
    this.ctx = wx.createCanvasContext('myCanvas', this); //创建画布绘图环境
  },

  touchStart: function(e) { //开始触摸屏幕
    this.x1 = e.changedTouches[0].x; //将开始触摸屏幕点x坐标赋值给x1
    this.y1 = e.changedTouches[0].y; //将开始触摸屏幕点x坐标赋值给x1    
    if (this.isClear) { //如果是擦除模式(点击了擦除按钮)
      this.ctx.setStrokeStyle('#FFFFFF'); //设置画布颜色为背景颜色(白色)
      this.ctx.setLineCap('round'); //设置线条端点样式
      this.ctx.setLineJoin('round'); //设置线条交点样式
      this.ctx.setLineWidth(20); //设置线条宽度
      this.ctx.beginPath(); //开始一个路径
    } else { //如果是绘图模式(默认模式,没有点击擦除按钮)
      this.ctx.setStrokeStyle(this.data.color);
      this.ctx.setLineWidth(this.data.pen);
      this.ctx.setLineCap('round');
      this.ctx.beginPath();
    }
  },

  touchMove: function(e) { //触摸屏幕后移动
    var x2 = e.changedTouches[0].x; //将当前点的x坐标赋值给x2
    var y2 = e.changedTouches[0].y; //将当前点的y坐标赋值给y2
    if (this.isClear) { //擦除模式
      this.ctx.moveTo(this.x1, this.y1); //将画笔移动到起点
      this.ctx.lineTo(x2, y2); //在起点与当前点之间画线
      this.ctx.stroke();
      this.x1 = x2; //将当前点x坐标赋值给起点x坐标
      this.y1 = y2; //将当前点y坐标赋值给起点y坐标
    } else { //画线模式
      this.ctx.moveTo(this.x1, this.y1);
      this.ctx.lineTo(x2, y2);
      this.ctx.stroke();
      this.x1 = x2;
      this.y1 = y2;
    }
    this.ctx.draw(true);
  },

  touchEnd: function() {},

  penSelect: function(e) {
    this.setData({
      pen: parseInt(e.currentTarget.dataset.param) //根据data-param设置pen值,从param传过来的值
    })
    this.isClear = false;
  },

  colorSelect: function(e) {
    this.setData({
      color: e.currentTarget.dataset.param  //根据data-param设置color值,从param传过来的值
    });
    this.isClear = false;
  },
  
  clear: function() { //擦除图形
    this.isClear = true;
  },

  clearAll: function() {
    this.setData({
      pen: 5, //恢复画笔粗细默认值
      color: '#000000' //恢复画笔颜色默认值
    })
    this.ctx.draw();
  }
})

isClear:False定义在page中,page函数的参数就是一个对象,isClear该对象当中的一个属性,使用:赋值,后面通过this.isClear使用,也可以放在data中定义,只不过在其他函数中访问的时候是通过this.data.isClear()访问,也可以放在onLoad中定义,写法this.isClear=False

 

canvas画布组件的使用方法其属性如下