Flat, round, designer-friendly pseudo-3D engine for canvas & SVG
1/**
2 * PathCommand
3 */
4
5( function( root, factory ) {
6 // module definition
7 if ( typeof module == 'object' && module.exports ) {
8 // CommonJS
9 module.exports = factory( require('./vector') );
10 } else {
11 // browser global
12 var Zdog = root.Zdog;
13 Zdog.PathCommand = factory( Zdog.Vector );
14 }
15}( this, function factory( Vector ) {
16
17function PathCommand( method, points, previousPoint ) {
18 this.method = method;
19 this.points = points.map( mapVectorPoint );
20 this.renderPoints = points.map( mapNewVector );
21 this.previousPoint = previousPoint;
22 this.endRenderPoint = this.renderPoints[ this.renderPoints.length - 1 ];
23 // arc actions come with previous point & corner point
24 // but require bezier control points
25 if ( method == 'arc' ) {
26 this.controlPoints = [ new Vector(), new Vector() ];
27 }
28}
29
30function mapVectorPoint( point ) {
31 if ( point instanceof Vector ) {
32 return point;
33 } else {
34 return new Vector( point );
35 }
36}
37
38function mapNewVector( point ) {
39 return new Vector( point );
40}
41
42PathCommand.prototype.reset = function() {
43 // reset renderPoints back to orignal points position
44 var points = this.points;
45 this.renderPoints.forEach( function( renderPoint, i ) {
46 var point = points[i];
47 renderPoint.set( point );
48 } );
49};
50
51PathCommand.prototype.transform = function( translation, rotation, scale ) {
52 this.renderPoints.forEach( function( renderPoint ) {
53 renderPoint.transform( translation, rotation, scale );
54 } );
55};
56
57PathCommand.prototype.render = function( ctx, elem, renderer ) {
58 return this[ this.method ]( ctx, elem, renderer );
59};
60
61PathCommand.prototype.move = function( ctx, elem, renderer ) {
62 return renderer.move( ctx, elem, this.renderPoints[0] );
63};
64
65PathCommand.prototype.line = function( ctx, elem, renderer ) {
66 return renderer.line( ctx, elem, this.renderPoints[0] );
67};
68
69PathCommand.prototype.bezier = function( ctx, elem, renderer ) {
70 var cp0 = this.renderPoints[0];
71 var cp1 = this.renderPoints[1];
72 var end = this.renderPoints[2];
73 return renderer.bezier( ctx, elem, cp0, cp1, end );
74};
75
76var arcHandleLength = 9/16;
77
78PathCommand.prototype.arc = function( ctx, elem, renderer ) {
79 var prev = this.previousPoint;
80 var corner = this.renderPoints[0];
81 var end = this.renderPoints[1];
82 var cp0 = this.controlPoints[0];
83 var cp1 = this.controlPoints[1];
84 cp0.set( prev ).lerp( corner, arcHandleLength );
85 cp1.set( end ).lerp( corner, arcHandleLength );
86 return renderer.bezier( ctx, elem, cp0, cp1, end );
87};
88
89return PathCommand;
90
91} ) );