This is the seventh day of my participation in the More text Challenge. For details, see more text Challenge
preface
In canvas to achieve picture movement, rectangles to achieve movement, you may see a lot of. But why do I want to write such an article, because I have done 3 dimensional graphics under the movement. This includes moving a side line, a face, and a point of a polygon on a cube. I’ve been writing about Canvas recently, and as a review, after reading this article you’ll learn how to move a point, a line, and the entire surface of a rectangle. This article is from shallow to deep, I hope you read patiently.
The mobile
Imagine moving on canvas. The first step is to make sure to create the canvas and add a move event to the canvas, so that we can get the position of our mouse in real time, and then we just need to keep clearing the canvas and redraw the rectangle. OK, the initial implementation of the mobile. I’m going to write down here the movement of the dots is going to rewrite this, but let me do a quick and easy version of this.
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const width = 100;
const height = 100;
drawRect();
function drawRect(x = 10,y = 10, scale = 1) {
ctx.clearRect( 0.0.1800.800 );
const halfwidth = width * scale / 2;
const halfheight = height * scale / 2;
ctx.strokeRect(x - halfwidth, y - halfheight,width * scale, height * scale)
}
let isMove = true;
canvas.addEventListener('mousemove'.(e) = >{
if(! isMove) {return
}
const x = e.clientX;
const y = e.clientY;
drawRect(x,y)
})
canvas.addEventListener('click'.(e) = >{ isMove = ! isMove; });Copy the code
The isMove variable is a switch. We can’t keep moving. It’s too tiring. Why x-halfwidth, y-halfheight
Here’s an explanation: strokeRect starts at the top left corner of the rectangle, but I want the rectangle to be in the center of the mouse, so a subtraction of the width and height will work perfectly.
The movement of the point
First of all, the first question is? How do we know which point we’re picking? Well, I’m just doing a simple judgment here by comparing the position of the mouse click to the position of each point in the rectangle, and seeing which point is closer is the target point. Because when we move a point in 2D we’re just looking for the line segment that’s associated with that point, so we just have to regenerate the line segment that’s associated with that point, but there’s a tricky part here, right? You move a semicircle, right? If we move the break point of the semicircle, there is a change in the arc, which may become ellipsometry or expressed in terms of second or third order Bessel curves. And then moving one shape to other shapes on the canvas creates a cut, right? Do you want to cut algorithms as well? In fact, you can use Clipper to solve the intersection difference, and those who are interested in it can learn about it on their own, but these are not what this article wants to explain. All of the examples in this article (only lines are supported, i.e. LineSegment).
OK, so our first step is we’re going to have to reexpress the rectangle, because it’s not universal enough but the exact thing is to reexpress the quadrilateral, the rectangle and the square are just the columns. I’m going to give you the reason, right? Why? In a simple case, if you move a point on a quadrilateral, it might look like this:
Ok let’s create a new class Point2d to represent each point on the canvas as an instance.
class Point2d {
constructor(x,y) {
this.x = x || 0;
this.y = y || 0;
}
clone() {
return this.constructor(this.x, this.y);
}
add(v) {
this.x += v.x;
this.y += v.y
return this;
}
random() {
this.x = Math.random() *1800;
this.y = Math.random() * 800;
return this}}Copy the code
Next, we will draw a rectangle by adding the length and width of the rectangle at any mouse position on the canvas. The code is as follows:
function drawFourPolygon(x, y ,width = 50, height = 50) {
ctx.clearRect( 0.0.1800.800 );
ctx.beginPath();
ctx.moveTo(x- width /2, y - height/2)
ctx.lineTo(x+ width / 2, y -height/2 )
ctx.lineTo(x+ width / 2, y + height/2 )
ctx.lineTo(x - width / 2, y + height/2 )
ctx.closePath()
ctx.stroke()
}
Copy the code
In order to make the interaction more perfect, the first click of the mouse determines the start point of the movement, and then the mouse keeps moving is the end point of the movement, so that a vector is determined. Here I’ve added the dotted line function to make it more obvious when moving, and the code is as follows
function drawDashLine(start, end) {
if(! start || ! end) {return
}
ctx.strokeStyle = 'red';
ctx.setLineDash( [5.10]); ctx.beginPath(); ctx.moveTo( start.x, start.y ); ctx.lineTo( end.x, end.y ); ctx.closePath() ctx.stroke(); }Copy the code
This is what the CANVAS setLineDash API parameter means. The solid line has a distance of 5, and the blank line has a distance of 10. Start and end is the mouse click to determine the start point, and then the mouse kept moving is the end point. A little bit of a reminder here is that as I mouse over here I draw a dotted line and then I draw a rectangle so what? The rectangle is still solid. So we’ve changed the code for drawing rectangles here, and we’ve brought back the dotted lines.
The code is as follows:
ctx.setLineDash([]);
Copy the code
OK overall interaction out, I first to show you the effect:
Do you feel a little bit ha ha ha? This is still an overall movement, not a point movement. Since I used the point that the mouse clicked to draw the rectangle, my next article will show you the point movement of irregular polygons. In this article, I will assume that I moved the point in the upper right corner. OK, we can get a moving vector from the starting point and the ending point, so we just add the point that we’re going to move to this vector. So are we moving the points.
const moveVec = end.clone().sub(start);
const rightTop = new Point2d(x+ width / 2, y - height/2).clone().add(moveVec)
Copy the code
Here I changed the upper right corner of the dot, but the problem is that we click on the same function, so we need to add a switch to determine, mainly to determine whether the first click or move the code is as follows:
ctx.lineTo(isSelect ? rightTop.x : x+ width / 2, isSelect ? rightTop.y : y height/2)
// The click and move event switches are the isSelect variable
canvas.addEventListener('mousemove'.(e) = >{
if(! isMove) {return
}
const x = e.clientX;
const y = e.clientY;
clearRect();
end = new Point2d(x,y);
drawDashLine(start,end);
drawFourPolygon(start)
})
canvas.addEventListener('click'.(e) = > {
// This is a function that clears the canvas every timeclearRect() isMove = ! isMove;const x = e.clientX;
const y = e.clientY;
start = new Point2d(x,y);
drawFourPolygon(start)
isSelect = true;
});
Copy the code
The renderings are as follows:
Ha ha ha is not very silky and smooth, found canvas drawing performance is very good. But there’s still a problem with determining the result, and looking at the code above we know that the result is wrong. So I’m going to end up holding Alt to make sure that this is perfect, and I won’t show you the code here.
The movement of the line
With the point movement, the line movement is shown very simply. The movement of the line is actually the movement of the corresponding points. Let’s take the line on the right as an example:
function drawFourPolygon( point, width = 50, height = 50) {
if(! point) {return
}
ctx.strokeStyle = 'black'
ctx.setLineDash([]);
ctx.beginPath();
const { x, y } = point;
const moveVec = end.clone().sub(start);
// In fact, the upper right and the lower right move at the same time
const rightTop = new Point2d(x+ width / 2, y - height/2).clone().add(moveVec)
const rightBottom = new Point2d(x+ width / 2, y + height/2).clone().add(moveVec)
ctx.moveTo(x- width /2, y - height/2)
ctx.lineTo(isSelect ? rightTop.x : x+ width / 2, isSelect ? rightTop.y : y - height/2)
ctx.lineTo(isSelect ? rightBottom.x : x+ width / 2, isSelect ? rightBottom.y : y + height/2)
ctx.lineTo(x - width / 2, y + height/2 )
ctx.closePath()
ctx.stroke()
}
Copy the code
Let’s look at the renderings:
conclusion
This article mainly introduces the 2d graphics under the most basic change of movement, whether the movement of the line or the movement of the surface is ultimately the movement of the point. In fact, in addition to being represented by vectors, we can also represent movement in terms of matrices, or we can represent rotation, movement, scaling and so forth in terms of matrix changes. Finally, thank you for seeing the end, code word is not easy, if it is helpful to you, welcome to click 👍 and follow. Your support is the biggest motivation for me to keep updating good articles. All the code is on my Github. Welcome to Star.