Flat, round, designer-friendly pseudo-3D engine for canvas & SVG
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

๐Ÿ›  #26 refactor & recalc updateSortValue

+ Use Vector.lerp
+ Add Hemisphere apex

+40 -39
+5 -10
js/cone.js
··· 34 34 35 35 // vectors used for calculation 36 36 this.renderApex = new Vector(); 37 + this.renderCentroid = new Vector(); 37 38 this.tangentA = new Vector(); 38 39 this.tangentB = new Vector(); 39 40 ··· 45 46 }; 46 47 47 48 Cone.prototype.updateSortValue = function() { 48 - // call super 49 - Ellipse.prototype.updateSortValue.apply( this, arguments ); 50 - var apexNormal = new Vector(); 51 - apexNormal.set( this.renderOrigin ) 52 - .subtract( this.apex.renderOrigin ); 53 - var apexAngleZ = Math.atan2( apexNormal.z, apexNormal.y ); 54 - apexAngleZ = utils.modulo( apexAngleZ, TAU ); 55 - //center of cone is one third of its length. 56 - var apexZ = this.length/3 * Math.sin(apexAngleZ); 57 - this.sortValue -= apexZ; 49 + // center of cone is one third of its length 50 + this.renderCentroid.set( this.renderOrigin ) 51 + .lerp( this.apex.renderOrigin, 1/3 ); 52 + this.sortValue = this.renderCentroid.z; 58 53 }; 59 54 60 55 Cone.prototype.render = function( ctx, renderer ) {
+20 -10
js/hemisphere.js
··· 6 6 // module definition 7 7 if ( typeof module == 'object' && module.exports ) { 8 8 // CommonJS 9 - module.exports = factory( require('./boilerplate'), require('./ellipse') ); 9 + module.exports = factory( require('./boilerplate'), require('./vector'), 10 + require('./anchor'), require('./ellipse') ); 10 11 } else { 11 12 // browser global 12 13 var Zdog = root.Zdog; 13 - Zdog.Hemisphere = factory( Zdog, Zdog.Ellipse ); 14 + Zdog.Hemisphere = factory( Zdog, Zdog.Vector, Zdog.Anchor, Zdog.Ellipse ); 14 15 } 15 - }( this, function factory( utils, Ellipse ) { 16 + }( this, function factory( utils, Vector, Anchor, Ellipse ) { 16 17 17 18 var Hemisphere = Ellipse.subclass({ 18 19 fill: true, ··· 20 21 21 22 var TAU = utils.TAU; 22 23 23 - Hemisphere.prototype.updateSortValue = function() { 24 + Hemisphere.prototype.create = function(/* options */) { 24 25 // call super 25 - Ellipse.prototype.updateSortValue.apply( this, arguments ); 26 - var contourAngleZ = Math.atan2( this.renderNormal.z, this.renderNormal.y ); 27 - contourAngleZ = utils.modulo( contourAngleZ, TAU ); 28 - //center of dome is half the radius. 29 - var domeZ = this.diameter/2/2 * Math.sin(contourAngleZ); 30 - this.sortValue -= domeZ; 26 + Ellipse.prototype.create.apply( this, arguments ); 27 + // composite shape, create child shapes 28 + this.apex = new Anchor({ 29 + addTo: this, 30 + translate: { z: this.diameter/2 }, 31 + }); 32 + // vector used for calculation 33 + this.renderCentroid = new Vector(); 34 + }; 35 + 36 + Hemisphere.prototype.updateSortValue = function() { 37 + // centroid of hemisphere is 3/8 between origin and apex 38 + this.renderCentroid.set( this.renderOrigin ) 39 + .lerp( this.apex.renderOrigin, 3/8 ); 40 + this.sortValue = this.renderCentroid.z; 31 41 }; 32 42 33 43 Hemisphere.prototype.render = function( ctx, renderer ) {
+14 -16
js/shape.js
··· 108 108 }); 109 109 }; 110 110 111 - 112 111 Shape.prototype.updateSortValue = function() { 113 - // average sort all z points. 114 - // ignore the final point if it is a closed shape. 115 - var howManyPoints = this.pathCommands.length; 116 - var sortValueTotal = 0; 112 + // sort by average z of all points 113 + // def not geometrically correct, but works for me 114 + var pointCount = this.pathCommands.length; 117 115 var firstPoint = this.pathCommands[0].endRenderPoint; 118 - var lastPoint = this.pathCommands[this.pathCommands.length-1].endRenderPoint; 119 - if (howManyPoints > 2 && 120 - firstPoint.isSame(lastPoint)) { 121 - howManyPoints -= 1; // closed shape; ignore final point. 116 + var lastPoint = this.pathCommands[ pointCount - 1 ].endRenderPoint; 117 + // ignore the final point if self closing shape 118 + var isSelfClosing = pointCount > 2 && firstPoint.isSame( lastPoint ); 119 + if ( isSelfClosing ) { 120 + pointCount -= 1; 122 121 } 123 - 124 - for (var i = 0; i < howManyPoints; i++) { 125 - sortValueTotal += this.pathCommands[i].endRenderPoint.z; 126 - } 127 - // average sort value of all points 128 - // def not geometrically correct, but works for me 129 - this.sortValue = sortValueTotal / howManyPoints; 122 + 123 + var sortValueTotal = 0; 124 + for ( var i = 0; i < pointCount; i++ ) { 125 + sortValueTotal += this.pathCommands[i].endRenderPoint.z; 126 + } 127 + this.sortValue = sortValueTotal / pointCount; 130 128 }; 131 129 132 130 // ----- render ----- //
+1 -3
js/vector.js
··· 79 79 if ( !pos ) { 80 80 return false; 81 81 } 82 - return (this.x === pos.x && 83 - this.y === pos.y && 84 - this.z === pos.z); 82 + return this.x === pos.x && this.y === pos.y && this.z === pos.z; 85 83 }; 86 84 87 85 Vector.prototype.add = function( pos ) {