Component address

Github.com/jasondu/wx-…

Implementation effect

How to implement

  1. The use of canvas
  2. Use movable-view tags

Since movable-View cannot rotate, canvas was chosen

Problems that need to be solved

  • How to render multiple elements to canvas
  • How do you know if your finger is on an element or which element is on top if multiple elements overlap
  • How do you implement drag elements
  • How to scale, rotate, and delete elements

It looks very simple, the above several problems solved, you can achieve the function; So let’s take care of each one.

How to render multiple elements to canvas

Define a DragGraph class that passes in various attributes of the element (coordinates, dimensions…) Instantiate it and push it into a render array, then loop through the array to call the render method in the instance to render multiple elements to the canvas.

How do you know if your finger is on an element or which element is on top if multiple elements overlap

In the DragGraph class, a method is defined to determine the click position. We bind the TouchStart event to the canvas and pass the coordinate of the finger into the method above, so we can know whether the finger is clicking on the element itself, deleting the icon or changing the size of the icon. How to determine this method will be explained later.

Loop through the array to determine which element to click on. If multiple elements are clicked, the first element will be the topmost element.

### How to implement drag elements

When the TouchStart event is triggered, we record the current finger coordinates. When the TouchMove event is triggered, we also know the coordinates at that time. If we take the difference of the two coordinates, we can figure out how far the element has moved. To implement drag and drop, reroute the render array.

How to scale, rotate, and delete elements

This step is a little bit more difficult, and I’ll show you through a diagram.

Let’s start with scaling and rotation

Through TouchStart and TouchMove, we can obtain the coordinates before rotation and after rotation. Line A in the figure is the line between the midpoint of the element and the pre-rotation point. Line B is the line between the element midpoint and the rotated point. We just need to find the Angle between lines A and B to know the rotation of the element. The scale size is the difference between the lengths of lines A and B.

The code for calculating the rotation Angle is as follows:

const centerX = (this.x + this.w) / 2;  // Midpoint coordinates
const centerY = (this.y + this.h) / 2;  // Midpoint coordinates

const diffXBefore = px - centerX;   // Rotate the front coordinate
const diffYBefore = py - centerY;   // Rotate the front coordinate
const diffXAfter = x - centerX;     // Rotate the coordinates
const diffYAfter = y - centerY;     // Rotate the coordinates

const angleBefore = Math.atan2(diffYBefore, diffXBefore) / Math.PI * 180;
const angleAfter = Math.atan2(diffYAfter, diffXAfter) / Math.PI * 180;

// The rotation Angle
this.rotate = currentGraph.rotate + angleAfter - angleBefore;
Copy the code

The code for calculating the scale size is as follows:

// Zoom in or out
this.x = currentGraph.x - (x - px);
this.y = currentGraph.y - (x - px);
Copy the code