Something went wrong. Try again.
Flat, round, designer-friendly pseudo-3D engine for canvas & SVG
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188/** * Vector */
( function( root, factory ) { // module definition if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( require('./boilerplate') ); } else { // browser global var Zdog = root.Zdog; Zdog.Vector = factory( Zdog ); }
}( this, function factory( utils ) {
function Vector( position ) { this.set( position );}
var TAU = utils.TAU;
// 'pos' = 'position'Vector.prototype.set = function( pos ) { this.x = pos && pos.x || 0; this.y = pos && pos.y || 0; this.z = pos && pos.z || 0; return this;};
// set coordinates without sanitizing// vec.write({ y: 2 }) only sets y coordVector.prototype.write = function( pos ) { if ( !pos ) { return this; } this.x = pos.x != undefined ? pos.x : this.x; this.y = pos.y != undefined ? pos.y : this.y; this.z = pos.z != undefined ? pos.z : this.z; return this;};
Vector.prototype.rotate = function( rotation ) { if ( !rotation ) { return; } this.rotateZ( rotation.z ); this.rotateY( rotation.y ); this.rotateX( rotation.x ); return this;};
Vector.prototype.rotateZ = function( angle ) { rotateProperty( this, angle, 'x', 'y' );};
Vector.prototype.rotateX = function( angle ) { rotateProperty( this, angle, 'y', 'z' );};
Vector.prototype.rotateY = function( angle ) { rotateProperty( this, angle, 'x', 'z' );};
function rotateProperty( vec, angle, propA, propB ) { if ( !angle || angle % TAU === 0 ) { return; } var cos = Math.cos( angle ); var sin = Math.sin( angle ); var a = vec[ propA ]; var b = vec[ propB ]; vec[ propA ] = a * cos - b * sin; vec[ propB ] = b * cos + a * sin;}
Vector.prototype.isSame = function( pos ) { if ( !pos ) { return false; } return this.x === pos.x && this.y === pos.y && this.z === pos.z;};
Vector.prototype.add = function( pos ) { if ( !pos ) { return this; } this.x += pos.x || 0; this.y += pos.y || 0; this.z += pos.z || 0; return this;};
Vector.prototype.subtract = function( pos ) { if ( !pos ) { return this; } this.x -= pos.x || 0; this.y -= pos.y || 0; this.z -= pos.z || 0; return this;};
Vector.prototype.multiply = function( pos ) { if ( pos == undefined ) { return this; } // multiple all values by same number if ( typeof pos == 'number' ) { this.x *= pos; this.y *= pos; this.z *= pos; } else { // multiply object this.x *= pos.x != undefined ? pos.x : 1; this.y *= pos.y != undefined ? pos.y : 1; this.z *= pos.z != undefined ? pos.z : 1; } return this;};
Vector.prototype.transform = function( translation, rotation, scale ) { this.multiply( scale ); this.rotate( rotation ); this.add( translation ); return this;};
Vector.prototype.lerp = function( pos, alpha ) { this.x = utils.lerp( this.x, pos.x || 0, alpha ); this.y = utils.lerp( this.y, pos.y || 0, alpha ); this.z = utils.lerp( this.z, pos.z || 0, alpha ); return this;};
Vector.prototype.magnitude = function() { var sum = this.x * this.x + this.y * this.y + this.z * this.z; return getMagnitudeSqrt( sum );};
function getMagnitudeSqrt( sum ) { // PERF: check if sum ~= 1 and skip sqrt if ( Math.abs( sum - 1 ) < 0.00000001 ) { return 1; } return Math.sqrt( sum );}
Vector.prototype.magnitude2d = function() { var sum = this.x * this.x + this.y * this.y; return getMagnitudeSqrt( sum );};
Vector.prototype.copy = function() { return new Vector( this );};
function round( num ) { return Math.round( num * 1000 ) / 1000;}
Vector.prototype.toJSON = function() { var x = this.x; var y = this.y; var z = this.z;
if ( x === y && y === z ) { return x !== 0 ? round( x ) : undefined; }
var obj = { x: x, y: y, z: z }; var result = {};
Object.keys( obj ).forEach( function( key ) { var value = obj[ key ]; if ( value !== 0 ) { result[ key ] = round( value ); } });
return Object.keys( result ).length ? result : undefined;};
return Vector;
} ) );