The previous understanding of SVG was very superficial, and the development was just simple copy and paste. Recently, after some torturing, I have a further understanding of SVG. Here I share my experience and I believe it will be helpful to you.

An introduction to

Canvas or SVG?

Canvas SVG
Graphics category Raster images Vector images
Rendering mode Immediate Mode Retained mode

Graphics categories are easier to understand, one is distorted and the other is not. Here we will focus on rendering modes. The instant mode can be understood as the playback of a film movie, with each modification updating the entire picture. The retained mode updates only the elements that need to be updated, that is, each HTML node that needs to be updated. In general, each has its own advantages and disadvantages. For massive data, Canvas is definitely the best choice.

How to choose Canvas/SVG?

Image from Microsoft Technical documentation – How to choose between Canvas and SVG for your website, and even mix scenarios, too high end.

Since the scene itself is scaled by all child elements controlled by external parent container nodes, and there are generally not too many SVG nodes, SVG is definitely the best choice.

Introduction to SVG

The basic elements Introduction to the
path Generic elements that define shapes.All the basic shapesCan be created using the path element.
circle Used to create circles based on a center and a radius.
ellipse Used to create an ellipse based on a central coordinate and their x and y radii.
rect Used to create a rectangle based on an angular position and its width and height. It can also be used to create rounded rectangles.
polyline Used to create a series of straight lines connecting points. A polyline is typically used to create an open shape where the last point is not connected to the first point.

Some of the common basic elements are listed here, and you can refer to the MDN documentation for more information. It is important to note that path can create all the basic shapes, which is an important prerequisite when implementing some common components.

Graphic transformation

SVG transformWith CSStransformThe similarities and differences

Notable differences are:

  • SVG Internal elementsthetransformNo units or percentages
  • SVG Internal elementsthetransformThe default is the upper left corner (0, 0) as the transform origin, while CSStransformThe transformation origin of is the center of the graph and can be passedtransform-origintransform-boxAdjust the transformation effect.

The basic transform

  • Translation/translate
  • Rotate/rotate
  • Oblique/skew
  • Zoom/scale
  • Matrix transformation/matrix

Composite transformations can be realized by combining multiple basic transformations. It is worth noting that the order in which the basic transformations are arranged may affect the final render. This is described in MDN as follows:

The transform functions are multiplied in order from left to right, meaning that composite transforms are effectively applied in order from right to left.

The transformation functions are multiplied from left to right, which means that the composition transformations are efficiently applied from right to left.

So the question is, what do you think of effective application from right to left? After painstaking search and understanding, I found the most reasonable explanation in the discussion of CSS3 Transform Order Matters: Rightmost Operation First:

It all depends whether you consider your coordinates attached to your element (left to right) or fixed to the page based on the initial element position (right to left).

An associated article Chaining Transforms also details this problem, which is highly recommended to read if you can. In a word, it can be understood that the difference in the frame of reference studied in physics leads to the difference in the observed behavior.

As shown in the figure above, the two animations in CSS, the first is the understanding of transform from left to right (the origin of transform moves with the graph), and the second is the understanding of transform from right to left (the origin of transform does not move with the graph). It can be seen that CSS takes the center of the graph as the origin of transform by default, so the final effect is consistent. But the process is different. The first transformation process is easier to understand. The second transformation readers must note that the transformation origin does not move with the graph.

For the SVG transform example, it can be seen that the final effect is different simply by changing the transform order. As for the forward and backward derivation of the transform process, readers can try their own. Note that the default SVG transform origin is (0, 0), and if you encounter any problems, please leave a comment.

Typically, it’s ok to interpret it left to right or right to left, but one special case was mentioned in the previous article Chaining transforms: Rotate (.5) rotate(45deg) scaleY(.5) rotate(45deg) scaleY(.5) rotate(45deg)

Matrix transformation/matrix

According to MDN we know that matrix(a, B, C, D, tx, TY) means matrix(scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY()). However, I found in practice that this meaning is not strictly corresponding. Skew cannot be directly migrated except for scale and translate. There is another important question: what about rotation?

When I found this problem, it haunted me all the time. Finally, after collecting information from various sources, 2D matrix: what demons and ghosts are these? For those of you who are interested in it, explore 😂 for those who are interested in it. From :з “Angle)_

The matrix is the operation of a point, and the two-dimensional transformation matrix only operates on X and y, so it can only represent scale and skew:

The translation operation of x and y can be expressed when the following 3d transformation matrix is used, which can be understood as the translation of the origin by a slice in the 3D coordinate system (as for the homogeneous transformation mentioned in the original text, I can only say it is familiar 😂) :

Finally, we care about the tangent and rotation matrices:

Therefore, skew-related values in matrix(scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY()) are actually tan(θ), Rotate is implemented with scale and skew. Did you learn that? (I just see the conclusion, theoretical derivation is also a face forced _ |  ̄ |”

In actual combat

General graphic drawing

The general graph here refers to the graph which can meet the business requirements by matrix transformation of the unit graph. For example, you can draw arbitrary size squares and rectangles through square matrix transformation, and draw ellipses through a circle… All of these operations are built on the basis of the unit graph is drawn by path, it is very convenient to achieve common tool functions to achieve various operations.

Note that the default matrix transformation is also applied to lines, which can be left untouched by vector-effect=” non-scale-stroke. At this point, everything is ready except the wind.

Here is the core processing logic, based on (svg.js and GSAP) :

onDrag() {
  // Set the unit graphic path while draggingpencilPath.plot(pathD); \// Get the drag destination
  const endCoord = { x: this.endX, y: this.endY };
  // Since the user can drag in any direction, the drag needs to be based on the current start and end point
  // Recalculate the starting coordinates of the SVG drawing
  const relocateStartCoord = calcRelocatedStartCoord(startCoord, endCoord);

  const width = Math.abs(endCoord.x - startCoord.x);
  const height = Math.abs(endCoord.y - startCoord.y);

  if (relocateStartCoord) {
    // svg.js defaults to the center of the graph.
    // ref: https://github.com/svgdotjs/svg.js/blob/2b028c35ab1a77c38a850c3c21082a5dacc18ac8/src/utils/utils.js#L81
    // pathCenter represents the center of the unit graph, usually (0, 0)
    pencilPath.transform({
      translateX: relocateStartCoord.x + width / 2 - pathCenter.x,
      translateY: relocateStartCoord.y + height / 2 - pathCenter.y,
      scaleX: width / pathSize.width,
      scaleY: height / pathSize.height,
    });
  }

  this.update();
}
Copy the code

Arrows to draw

Suppose the following arrows are drawn, starting point S, key point E, and key point data are marked as follows:

Since the user can drag and drop the graph arbitrarily, other key points need to be calculated in real time based on the starting point and ending point to draw the graph. Here are the main mathematical principles and methods used and their effects:

Principles and Methods role
Equation of a line (slope-intercept form) We get the equation L1 of the line at S and E
Similar triangle I get the coordinates of A and B
The product of the slopes of two vertically intersecting lines is -1 Obtain the slope of line L2 perpendicular to line L1, and then obtain the equation of line L2 according to point B
Pythagorean theorem (distance formula between two points) Establish functional relationship between point B and key points on both sides F (Circle equation)
Solve a quadratic equation of one variable F and L2 are solved simultaneously to obtain the coordinates of key points on both sides of point B

In addition, if the distance between two points S and E is too close, the coordinates of point E should be recalculated, that is, the shortest distance of the arrow. More boundary conditions need to be explored independently in practical operation 👻

conclusion

In terms of actual practice, I only share two examples of myself, focusing more on the introduction of SVG, and further on the understanding of basic transformation. Because I have been troubled by this problem for a long time, in order to get an acceptable answer, it is true that I took great pains. The most interesting thing is my understanding of the order of transform transformation. When I just read the description on MDN, I had a thought in my mind: “Why did I tell you both the pros and cons?” After figuring it out, it’s worth noting that “effectively applied from right to left” is true.