After deleting games from your phone and playing them for a week, it’s time to reclaim your evenings and think about some questions.
Rectangle that can drag and drop transformations
This feature is common, like cropping photos on your phone, as shown here:As shown above: the mouse style becomes a resized style when the mouse is over the four corners of the image area or four edges up, down, left, and right. At this point, we can move the mouse to transform the area.
What you need to know before implementing a feature
clientX
.offsetX
.pageX
The difference between
ClientX: Returns the X coordinate of the contact relative to the left edge of the visual ViewPort. Does not include any roll offset. This value changes depending on how the user scales the viewable area.
OffsetX: The read-only property offsetX of the MouseEvent interface specifies the X offset of the event object from the target node’s padding edge.
PageX: The X coordinate of the contact relative to the left edge of the HTML document. Unlike the clientX attribute, this value is a coordinate relative to the entire HTML document, independent of where the user scrolls. So this value contains the offset of horizontal scrolling when there is one.
Get mouse position information
- Position of the mouse when the mouse is pressed
// Press the mouse button
down = (self, e) = > {
const { offsetX, offsetY, layerX, layerY } = e;
this.mouseX = offsetX || layerX;
this.mouseY = offsetY || layerY;
console.log('mouseX,mouseY'.this.mouseX, this.mouseY);
this.isMove = true;
};
Copy the code
- Position of the mouse when moving the mouse
// Move the mouse
move = (self, e) = > {
const { offsetX, offsetY, layerX, layerY } = e;
// console.log('e----current-mouse-pos---->', e)
console.log('posNo----'.this.posNo);
// console.log(' rectangle instance ----', this.rect)
let cur_x_point = offsetX || layerX;
let cur_y_point = offsetY || layerY;
// console.log(' current mouse position ', cur_x_point, cur_y_point). }Copy the code
- Mouse offset
deltaX,deltaY
let deltaX = cur_x_point - this.mouseX;
let deltaY = cur_y_point - this.mouseY;
Copy the code
Note: the offset is mainly used to calculate the position change and width change of the rectangle, which is very important.
Checks whether the current path contains check points
We need to save the path information of four corners and four sides, and detect whether the current mouse position is in the path, to display the corresponding mouse pointer style.
The detection method uses canvas’s isPointInPath() method.
Mouse pointer style
The mouse pointer style is familiar to many front ends because of the use of cursor:pointer. But there are actually five types of mouse pointer styles. Link state and choose | | drag | | reset size scale.
- Links and status
context-menu
There is a directory of available content under the pointer.help
Direct help.pointer
Suspended on a connection, usually by hand.progress
The background is busy and users can still interact (as opposed to Wait).wait
The application is busy and users cannot interact (as opposed to Progress). ICONS are usually hourglass or tables.
- choose
cell
Indicates that cells are available for selectioncrosshair
Cross pointer, usually indicating box selection in a bitmaptext
A pointer can be selectedvertical-text
Indicates that vertical text can be selected
- Drag and drop
alias
A copy or shortcut will be createdcopy
Indicating replicabilitymove
A suspended object can be movedno-drop
The current position cannot be droppednot-allowed
Cannot performgrab
Can grabgrabbing
Grab the
- Resize and scroll
all-scroll
Elements can scroll (pan) in any direction.col-resize
The element can be reset width. Usually rendered as left and right arrows separated by a vertical line in the middlerow-resize
Elements can be reset to height. It is usually rendered as the top and bottom arrows separated by a horizontal linen-resize
Some edge is going to be moved. For example, use se-resize when the southeast corner of the element box is movede-resize
Some edge is going to be moved. For example, use se-resize when the southeast corner of the element box is moveds-resize
Some edge is going to be moved. For example, use se-resize when the southeast corner of the element box is movedw-resize
Some edge is going to be moved. For example, use se-resize when the southeast corner of the element box is movedne-resize
Some edge is going to be moved. For example, use se-resize when the southeast corner of the element box is movednw-resize
Some edge is going to be moved. For example, use se-resize when the southeast corner of the element box is movedse-resize
Some edge is going to be moved. For example, use se-resize when the southeast corner of the element box is movedew-resize
Indicates resize in both directionsns-resize
Indicates resize in both directionsnesw-resize
Indicates resize in both directionsnwse-resize
Indicates resize in both directions
- The zoom
zoom-in
amplificationzoom-out
narrow
General logic of the transformation process
- Add a rectangle to the canvas.
- To the canvas to add
mousedown
.mousemove
.mouseup
.mouseout
Events. mousedown
Mouse down try to record the current mouse position,mousemove
The offset is calculated when the mouse is moved, which is also the offset of the rectangle.mousemove
Update the path information of the four corners and four sides of the rectangle when moving the mouse to set the corresponding pointer style when moving the mouse to the corresponding position.mousemove
Make various judgments as you move the mouse (is it the upper left corner? The top right corner? Top side? Bottom? And reset the position and width of the rectangle based on the offset.
Specific code roughly 200-300 lines, paste a core move() method out, interested can study.
move = (self, e) = > {
const { offsetX, offsetY, layerX, layerY } = e;
// console.log('e----current-mouse-pos---->', e)
console.log('posNo----'.this.posNo);
// console.log(' rectangle instance ----', this.rect)
let cur_x_point = offsetX || layerX;
let cur_y_point = offsetY || layerY;
// console.log(' current mouse position ', cur_x_point, cur_y_point)
let cur_ctrl_posNo = -1; // Current control area id
if (this.isMove) {
let deltaX = cur_x_point - this.mouseX;
let deltaY = cur_y_point - this.mouseY;
if (this.posNo == 0) {
/ / drag
console.log('move -- -- -- -- -- -);
console.log('deltaX,deltaY', deltaX, deltaY);
console.log('move -- -- -- -- -- -);
this.rect.rectInit(
deltaX,
deltaY,
this.options.canvas_w,
this.options.canvas_h,
this.options.rect_w,
this.options.rect_h
);
} else if (this.posNo == 1) {
/ / the top left corner
if (this.options.rect_w <= this.min && this.options.rect_h > this.min) {
cur_ctrl_posNo = 2;
} else if (
this.options.rect_h <= this.min &&
this.options.rect_w > this.min
) {
cur_ctrl_posNo = 3;
} else if (
this.options.rect_h <= this.min &&
this.options.rect_w <= this.min
) {
cur_ctrl_posNo = 4;
} else {
cur_ctrl_posNo = 1;
}
this.options.rect_w -= deltaX;
this.options.rect_h -= deltaY;
this.rect.rectInit(
deltaX,
deltaY,
this.options.canvas_w,
this.options.canvas_h,
this.options.rect_w,
this.options.rect_h
);
} else if (this.posNo == 4) {
/ / the bottom right hand corner
if (this.options.rect_w <= this.min && this.options.rect_h > this.min) {
cur_ctrl_posNo = 3;
} else if (
this.options.rect_h <= this.min &&
this.options.rect_w > this.min
) {
cur_ctrl_posNo = 2;
} else if (
this.options.rect_w <= this.min &&
this.options.rect_h > this.min
) {
cur_ctrl_posNo = 1;
} else {
cur_ctrl_posNo = 4;
}
this.options.rect_w += deltaX;
this.options.rect_h += deltaY;
this.rect.rectInit(
0.0.this.options.canvas_w,
this.options.canvas_h,
this.options.rect_w,
this.options.rect_h
);
} else if (this.posNo == 2) {
/ / the top left corner
if (this.options.rect_w <= this.min && this.rect_h > this.min) {
cur_ctrl_posNo = 1;
} else if (this.options.rect_h <= this.min && this.rect_w > this.min) {
cur_ctrl_posNo = 4;
} else if (this.options.rect_h <= this.min && this.rect_w <= this.min) {
cur_ctrl_posNo = 3;
} else {
cur_ctrl_posNo = 2;
}
this.options.rect_w += deltaX;
this.options.rect_h -= deltaY;
this.rect.rectInit(
0,
deltaY,
this.options.canvas_w,
this.options.canvas_h,
this.options.rect_w,
this.options.rect_h
);
} else if (this.posNo == 3) {
if (this.options.rect_w <= this.min && this.options.rect_h > this.min) {
cur_ctrl_posNo = 4;
} else if (
this.options.rect_h <= this.min &&
this.options.rect_w > this.min
) {
cur_ctrl_posNo = 1;
} else if (
this.options.rect_w <= this.min &&
this.options.rect_h <= this.min
) {
cur_ctrl_posNo = 2;
} else {
cur_ctrl_posNo = 3;
}
this.options.rect_w -= deltaX;
this.options.rect_h += deltaY;
this.rect.rectInit(
deltaX,
0.this.options.canvas_w,
this.options.canvas_h,
this.options.rect_w,
this.options.rect_h
);
} else if (this.posNo == 5) {
/ /
this.options.rect_h < 0 ? (cur_ctrl_posNo = 6) : (cur_ctrl_posNo = 5);
this.options.rect_h -= deltaY;
this.rect.rectInit(
0,
deltaY,
this.options.canvas_w,
this.options.canvas_h,
this.options.rect_w,
this.options.rect_h
);
} else if (this.posNo == 6) {
/ /
this.options.rect_h < 0 ? (cur_ctrl_posNo = 5) : (cur_ctrl_posNo = 6);
this.options.rect_h += deltaY;
this.rect.rectInit(
0.0.this.options.canvas_w,
this.options.canvas_h,
this.options.rect_w,
this.options.rect_h
);
} else if (this.posNo == 7) {
/ / left
this.options.rect_w < 0 ? (cur_ctrl_posNo = 8) : (cur_ctrl_posNo = 7);
this.options.rect_w -= deltaX;
this.rect.rectInit(
deltaX,
0.this.options.canvas_w,
this.options.canvas_h,
this.options.rect_w,
this.options.rect_h
);
} else if (this.posNo == 8) {
/ / right
this.options.rect_w < 0 ? (cur_ctrl_posNo = 7) : (cur_ctrl_posNo = 8);
this.options.rect_w += deltaX;
this.rect.rectInit(
0.0.this.options.canvas_w,
this.options.canvas_h,
this.options.rect_w,
this.options.rect_h
);
}
changeMouse(this.canvas, cur_ctrl_posNo);
this.mouseX = cur_x_point;
this.mouseY = cur_y_point;
this.rect.drawRect(
this.ctx,
this.options.canvas_w,
this.options.canvas_h
);
this.pathes = changePath(
this.rect.startX,
this.rect.startY,
this.rect.rect_w,
this.rect_h,
this.options.dis,
this.pathes
);
} else {
this.posNo = getPos(cur_x_point, cur_y_point, this.ctx, this.pathes); // When moving, you can no longer retrieve the position
console.log('this.posNo=------>'.this.posNo);
changeMouse(this.canvas, this.posNo); }};Copy the code
conclusion
Canvas APIS all look very simple, but it really takes a lot of effort to make a good thing. I hope I can stick to it and go through all its APIS.
One last word
- Move your rich little hands and “like it.”
- Move your rich little hands, “click here”
- All see here, might as well “add a follow”
- Might as well “forward”, good things to remember to share
Click to add a follow