This is the 13th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Speaking of the simple creation of canvas, I have mentioned 😀😀😀 in the last video. Before I saw someone drawing a drawing board with canvas and changing the color and thickness of the brush, I had to mention dragging the elements on the drawing board.

Create a canvas

<canvas type="2d" id="myCanvas" style="height: 600px; width: 500px;"></canvas>
Copy the code

The data of data

// Mouse status
statusConfig : {
      idle: 0.// Normal status
      Drag_start: 1.// Drag begins
      Dragging: 2./ / drag
},
/ / canvas
canvasInfo : {
   // Circle state
   status: 0.// Place the mouse in the circle
   dragTarget: null.// The position of the circle when clicked
   lastEvtPos: {x: null.y: null}},Copy the code

Draw two circles on the canvas

onLoad: function (options) {
    // Set the canvas to get the context CTX of the canvas
    this.getCanvas();
},
getCanvas(){
    Wx.createselectorquery () is used instead of using document
    const query = wx.createSelectorQuery()
    query.select('#myCanvas')
      .fields({ node: true.size: true })
      .exec((res) = > {
        const canvas = res[0].node
        // Set the canvas scale
        canvas.width="500";
        canvas.height="600";
        const ctx = canvas.getContext('2d')
        // Draw two circles on the canvas and pass the CTX to draw
        this.drawCircle(ctx, 100.100.20);
        this.drawCircle(ctx, 200.200.10);
        // Save the information of our drawing, and then move it to empty the drawing board and draw again
        var circles = []
        circles.push({x: 100.y: 100.r: 20});
        circles.push({x: 200.y: 200.r: 10});
        // Don't forget to save
        this.setData({
         circles
        })
      })
   },
/ / draw circles
drawCircle(ctx, cx, cy, r){
    ctx.save()
    ctx.beginPath()
    ctx.strokeStyle = 'yellow'
    ctx.lineWidth = 3
    ctx.arc(cx, cy, r, 0.2 * Math.PI)
    ctx.stroke()
    ctx.closePath()
    ctx.restore()
},
Copy the code

Set 3 touch events for the canvas

<canvas type="2d" id="myCanvas" 
 bindtouchstart="handleCanvasStart"  bindtouchmove="handleCanvasMove"  bindtouchend="handleCanvasEnd"
 style="height: 600px; width: 500px;">
</canvas>
Copy the code
type The trigger condition
touchstart Finger touch begins
touchmove Fingers move after touch
touchcancel Finger touch action is interrupted, such as a reminder, popover
touchend End of finger touch action
tap Touch your finger and leave immediately

The touch action starts, and if the point is in the circle, changes the information in canvasInfo

handleCanvasStart(e){
    // Get the click position
    const canvasPosition = this.getCanvasPosition(e);
    // Check whether the click point is in the circle, if not return false, return information about the circle
    const circleRef = this.ifInCircle(canvasPosition);
    const {canvasInfo, statusConfig} = this.data;
    // In a circle, change the state of the circle
    if(circleRef){
      canvasInfo.dragTarget = circleRef;
      // Change the drag state idle -> Drag_start
      canvasInfo.status = statusConfig.Drag_start;
      canvasInfo.lastEvtPos = canvasPosition;
    }
    this.setData({
      canvasInfo
    })
  },
// Get the click position
getCanvasPosition(e){
    return{
      x: e.changedTouches[0].x,
      y: e.changedTouches[0].y
    }
},

// See if the click point is in the circle
ifInCircle(pos){
    const {circles} = this.data;
    for( let i = 0 ; i < circles.length; i++ ){
      // Determine if the point to the center of the circle is smaller than the radius
      if( this.getDistance(circles[i], pos) < circles[i].r ){
        return circles[i]
      }
    }
    return false
  },
// Get the distance between two points
getDistance(p1, p2){
    return Math.sqrt((p1.x-p2.x) ** 2 + (p1.y-p2.y) ** 2)}Copy the code

Finger touch and move to redraw the circle

handleCanvasMove(e){
    const canvasPosition = this.getCanvasPosition(e);
    const {canvasInfo, statusConfig, circles} = this.data;
    // Start drag state, slide size greater than 5 (shake)
    if( canvasInfo.status === statusConfig.Drag_start && 
      this.getDistance(canvasPosition, canvasInfo.lastEvtPos) > 5) {// Change the drag state Drag_start -> Dragging
        canvasInfo.status = statusConfig.Dragging;
    }else if( canvasInfo.status === statusConfig.Dragging ){
        canvasInfo.dragTarget.x = canvasPosition.x;
        canvasInfo.dragTarget.y = canvasPosition.y;
        // Redraw
        const query = wx.createSelectorQuery()
        query.select('#myCanvas')
          .fields({ node: true.size: true })
          .exec((res) = > {
            const canvas = res[0].node
            canvas.width="500";
            canvas.height="600";
            const ctx = canvas.getContext('2d')
            // Walk through the circles and redraw the circles
            circles.forEach(c= > this.drawCircle(ctx, c.x, c.y, c.r))
          })
    }

    this.setData({
      canvasInfo,
    })
  }
Copy the code

When the finger touch action ends, change the canvasInfo state back to idle

 handleCanvasEnd(e){
    const {canvasInfo, statusConfig} = this.data;
    if( canvasInfo.status === statusConfig.Dragging ){
    // Change Dragging state Dragging -> idle
      canvasInfo.status = statusConfig.idle;
      this.setData({
        canvasInfo
      })
    }
  }
Copy the code

Learn with the big guy of B station, but the gap between wechat apap and HTML canvas has made me depressed 😭, I hope more people can send notes of wechat apap to me to learn 😁😁😁, don’t let me fail to baidu fb fb