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