Build a Canvas vector graphics Renderer (4)-various vector elements (line, surface, pentagram)

Source: Internet
Author: User
Document directory
  • 2. geometric type: LinerRing)
  • 3. Extended geometric type: Star)
  • 2. Draw a line
  • 3. Draw a plane
  • 3. rendererPath

This essay continues with the previous content and adds more vector elements to our geometry class.

(The Directory is online. If you do not know much about this series, see the directory !)

In fact, with the designed architecture, we can easily extend the new ry type through the geometry base class.

There are not a lot of content in this essay. First, go to the demo.

 

Add point Add circle Add line Add a plane Tim Wuxing Zoom in Zoom out

1. Add various geometric objects. 1. geometric type: Line)

Line is also a class inherited from Geometry. In short, a line is actually a collection of arrays.

// CLASS: ry object line CLASS. Function Line (points) {Geometry. apply (this, arguments); this. points = points;} Line. prototype = new Geometry (); Line. prototype. geoType = "Line ";

Is it simple? The geometric type of a line is exactly like 4 or 5 lines of code ~

2. geometric type: LinerRing)

A plane can also be called a closed line. In this way, our plane inherits the line and makes some modifications to the line.

// CLASS: function LinerRing (points) {Line. apply (this, arguments); if (points) {this. points = points; var len = this. points. length; if (this. points [0]. x! = This. points [len-1]. x | this. points [0]. y! = This. points [len-1]. y) {this. points. push (this. points [0]. clone () ;}} LinerRing. prototype = new Line (); LinerRing. prototype. geoType = "LinerRing ";

Is it easy to determine whether the beginning and end of the line are connected (whether the x and y values of the last vertex are equal to the first vertex ). If not, clone the first vertex and add it to the end of the array.

3. Extended geometric type: Star)
// CLASS: ry Star function Star (center, r) {// center point this. center = center; // The long radius of the pentagram. this. r = r; var points = this. getPoints (center, r); LinerRing. call (this, points);} Star. prototype = new LinerRing (); Star. prototype. getPoints = function (center, r) {var point, points = []; var angle = 0; var degree = Math. PI/180; for (var I = 0; I <10; I ++) {var radius = (I % 2 = 0 )? R: r/2; point = new Point (center. x + Math. sin (angle * degree) * radius, center. y + Math. cos (angle * degree) * radius); points. push (point); angle + = 36;} return points;} Star. prototype. geoType = "LinerRing ";

Here we will not elaborate on the specific painting method of pentagram. Simply put, we will define a long radius r, which is set to r/2 here. Like the circle method, the vertex is drawn by using the long radius and short radius alternately, so that each vertex of the five-pointed star is drawn. In fact, pentagram is LinerRing, so here he also inherits from LinerRing.

After talking about these basic types, let's talk about how to parse these types of geometric types in the Renderer.

2. The Renderer parses the geometric type. 1. adds the rendering type.
// Draw every vector element. Here we will add more vector images in the future. Canvas. prototype. draw = function (geometry, style, id) {if (geometry. geoType = "Point") {this. drawPoint (geometry, style, id);} if (geometry. geoType = "Circle") {this. drawCircle (geometry, style, id);} if (geometry. geoType = "Line") {this. drawLine (geometry, style, id);} if (geometry. geoType = "LinerRing") {this. drawLinerRing (geometry, style, id) ;}// {todo} we can judge the plot of various vector elements here. }
2. Draw a line
Canvas.prototype.drawLine = function(geometry, style, id) {    this.setCanvasStyle("stroke", style);    this.rendererPath(geometry, {fill: false, stroke: true}, id);    this.setCanvasStyle("reset");}

Because the line only needs to call the stroke method, we only set the stroke style for it here.

RendererPath: This method will be discussed with the drawing area later.

3. Draw a plane
Canvas.prototype.drawLinerRing = function(geometry, style, id) {    if(style.stroke) {        this.setCanvasStyle("stroke", style);        this.rendererPath(geometry, {fill: false, stroke: true}, id);    }    if(style.fill) {        this.setCanvasStyle("fill", style);        this.rendererPath(geometry, {fill: true, stroke: true}, id);    }    this.setCanvasStyle("reset");}

When drawing the surface, we will call different style setting methods based on whether the style requires stroke and fill, and call the rendererPath method.

3. rendererPath
Canvas.prototype.rendererPath = function(geometry, rendererType, id) {    var points = geometry.points;    var len = points.length;    var context = this.context;    context.beginPath();    var start = this.getLocalXY(points[0]);    var x = start.x;    var y = start.y;    if (!isNaN(x) && !isNaN(y)) {        context.moveTo(x, y);        for (var i=1; i<len; ++i) {            var pt = this.getLocalXY(points[i]);            context.lineTo(pt.x, pt.y);        }        if (rendererType.fill) {            context.fill();        }         if (rendererType.stroke) {            context.stroke();        }     }}

In fact, both the line and the plane are rendered on a path. The difference is that one does not need to be filled or another needs.

Then, when calling this function, we pass in rendererType to identify whether to fill in.

The content in this section is here. So far, the general structure of a vector Renderer has been completed. The next step is to add points, surface, and line segments as supported by clicking the mouse. You can get more ry by extending geometry.

Try: After downloading the source code, you can extend the geometry type to add a rectangular graphics class to it.

Next notice: 1. Support for images will be added.

2. Preliminary performance optimization.

For all the source code + demo in this essay, please click to download.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.