The feed

We often use SVG when writing business visualization components, and we also use SVG for animation. SVG. Js is an open source project that gives you a more elegant and convenient way to write SVG. We can also take a look at how to write a visual library by analyzing svG.js.




SVG. Js goal: To make SVG easier to write. Here’s a look at the source code and the design behind it.

SVG. Introduction of js

Svg.js is a lightweight library for manipulating SVG and performing SVG animations. A good class library, extensibility is also essential, svG.js extensibility is also good; SVG. Js has no dependencies, is small (compared to snap.svg and Raphael, common class libraries in the same class), and provides a near-complete SVG specification.

SVG. Js usage

<div id="drawing">
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300">
    <rect width="100" height="100" fill="#f06"></rect> </ SVG ></ div>'drawing').size(300, 300)
var rect = draw.rect(100, 100).attr({ fill: '#f06' })
Copy the code

SVG. Js all SVG graphics to help us encapsulate, can let us better use JS with chain writing, object-oriented writing better draw their own business components; Get back to simplicity; SVG. Js wraps basic shapes, including circle, Ellipse, Line, Polygon, Polyline, Rect, etc.

In addition to object-oriented wrapping and chain writing, it also has more fun syntax candy, take a look

//'M', 0, 0, 'L', 100, 100, 'z'] // svg.js [['M', 0, 0], ['L', 100, 100], ['z']]Copy the code

This way it’s easier to read

From the Demo, we can see that the API defined by svg.js is easy to use,

Design ideas

SVG. The design idea of js also pretty simple, can also be seen from the official website of the Overview, divide the whole according to the function into several categories, this a few kinds of definition, all classes and its associated specific components or can be in accordance with the function of specific scenarios and use in where, can know how to arrange entity relationship structure, You can then develop and implement functionality for each component.

  • 【Parents】 SVG container related. All containers inherit from svG.parent, providing many basic methods
  • 【Elements】 SVG displays element correlation. The basic prototype for all rendered elements is svG.Element, which provides many basic methods
  • Taking SVG, the correlation of elements is made. It’s a bunch of ways to get containers
  • [Manipulating] SVG operation related. Including properties, location, size, style, data, etc.
  • [Boxes] Bounding Boxes, SVG Bounding Boxes
  • Animating SVG animation. Includes several animation components and utility classes from which all animation is implemented and extended;
  • 【Events】 SVG event correlation. Includes several animation components and utility classes from which all animation is implemented and extended;
  • Classes Utility Classes that are not related to SVG itself.
  • 【Extending】 is related to an SVG extension. You can rewrite or extend components, or extend plug-ins;

To give you an overview:

Design patterns are used more or less inadvertently in every design. Let’s take a look at the design patterns used in svG.js:

Factory mode, create

Whatever element is created goes through the create method in the svG.js module; Unified creation;

Policy mode, FX

There are many kinds of SVG. Js animation, and these different kinds can be individually encapsulated into a policy for the upper layer to call uniformly;

extends

Here you can use svG.extend to wrap the methods of an element class, add method extensions, and so on.

API design

The overall API for SVG.js is minimalist, complete, semantically clear, intuitive, and easy to remember, with the same name as the native SVG and specification.

Abstract Methods

Overall abstract thinking (ER entity Relationship diagram)

The overall ER model (E-R Entity Relationship Diagram) is well designed, but lacks a bit of object-oriented abstract design; For example, poly in the following code uses the extension method of SVG. Js extends to allow classes of the same class to have the same method. This place can be abstracted into poly classes, so that each subclass contains or integrates its parent class, so that each subclass can easily see which methods it owns and which classes it inherits.

// poly.js 
SVG.extend(SVG.Polyline, SVG.Polygon, {
  // Get array
  array: function() {... } // Plot new path , plot:function(p) { ... }... })Copy the code

With SVG. Js, it’s a bit of a struggle to read the integration of a class, like what Element methods are, and what they look like in the code (which can of course be seen in the prototype chain at runtime), so that we can see what extensions have been made and what methods have been added. This is a design nitpick.

Svg.invent implements parsing

The svG.invent method is the basic method for creating new elements, and most classes in SVG.js are created through this basic method.

// Invent new element svg.invent =function(config) {// Create element initializer = typeof config.create =='function' ?
    config.create :
    function() {this.constructor. Call (this, svg.create (config.create))} // Sets the inheritance stereotype chainif(config.inherit) Initializer. Prototype = new config.inherit //if(config.extend) svg.extend (initializer, config.extend) // Append the method from the constructor to the parent Container (note Container, because parent is not set, So most construct methods augment containers.if (config.construct)
    SVG.extend(config.parent || SVG.Container, config.construct)

  return initializer
}
Copy the code

Svg.invent is a base class method for adding invents to a new element, which contains several configuration items:

create

Is a setting that creates an element initializer. It can be a string, with the name of the string used to create the Dom element, which is passed in as an argument when instantiated. It can also be a function. If the new element is to be rendered, then the constructor. Call method will be implemented inside the function to pass in the element and add other processing. If the new element is not used for rendering such as svg. Set, svG. Array, svG. Transformation, etc., then you do not need to call this.constructive. call

inherit

Set the prototype chain method, inheritance method use; You can set which parent the new element class inherits from

extend

Extension methods, new methods for new elements are all here

construct

Each new element will have methods in construct that extend into the parent container. If the parent container is not set, It extends to svG. Container, which is why elements retrieved after new Doc have all the methods you want; SVG.Doc (as shown in ER) corresponds to the prototype chain Doc → Container → Parent -> Element.

All works

Let’s take a look at how a simple polygon in SVG.

var draw = SVG('drawing').size(300, 130) var polygon = draw.polygon([ [50, 0], [60, 40], [100, 50], [60, 60], [50, 100], [40, 60], [0, 50], [40, 40]])Copy the code

SVG(‘ drawing ‘), draw.polygon(…) ;

Step1: SVG(‘ drawing ‘) process

SVG(‘ drawing ‘) basically generates an SVG Dom Element (Element) on the Dom Element whose ID is Drawing and returns an svG.doc object. This returned object (Element) can be used to generate any SVG Element you want such as Polygon, Rect, etc. As mentioned earlier, the corresponding prototype chain for SVG.doc is Doc → Container → Parent -> Element, so the svG.doc object has all the manipulable methods that svG.js is supposed to provide.

Step2: the draw polygon (…). process

The draw polygon (…). Polygon elements are created in 2.1 and 2.2 and placed in the parent container. 2.3 New waypoints will be drawn; 2.4, 2.5 will redraw the path through the re-attr method; Such a process can be drawn corresponding to the Polygon graph;

Plug-in extension

The top NEFE-> Dolphin Gradient (Morph) image was created using the SVG. Js plugin Pathmorph, which is very simple

// create path
 var path = draw.path(nefe)
 // animate path
 setTimeout(function() {
   path.animate(1000).plot(dolphin);
 }, 2000); 
Copy the code

However, this plugin is not very powerful, and we sometimes need to set certain points where SVG starts and corresponding points where SVG ends; With these, the whole process of gradual change looks more harmonious; Otherwise the gradients are a little stiff. Interfaces that reveal which elements are tweaked to each other, such as:

// API recommendations can be designed as animate. To ("#E"."#tail"// Animate ({time:1000, [{from:'#E',to:'#tail'}]
 }).plot(dolphin);
Copy the code

If such an API is provided, most animation effects can be satisfied, and complex animation effects can be set freely;

Summary.

SVG. Js wraps the writing of SVG files that are purely XML into JS, transforming the experience of writing HTML or XML into scripts, which makes the whole development experience smoother. The object-oriented chain-writing API provided by svg.js lets developers not worry about how native SVG renders to the Dom and how to write a bunch of code Settings to achieve the desired effect. SVG. Js animations also make the development of many special effects more possible, which can help developers think more about animation and make the SVG world a better place.

We will continue to analyze and experiment with visual tools and libraries that we will apply to large screens and data products in various data media. Come on! We work together, conquer together, build together, share together, we are waiting for you here [email protected].