├── .DS_Store ├── .babelrc ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── demo ├── VectorPlayground.js ├── addition │ ├── index.html │ ├── pub.js │ └── run.js ├── app │ ├── DrawingVector.js │ ├── VectorPlayground.js │ ├── calcUpdate.js │ ├── colours.js │ ├── dat.gui.min.js │ ├── drawer.js │ └── test.js ├── index.css ├── index.html ├── linear-transformations │ ├── index.html │ ├── pub.js │ └── run.js ├── matrix-multiplication │ ├── index.html │ ├── pub.js │ └── run.js ├── pub.js ├── run.js ├── snowflake.js ├── snowflake │ ├── index.html │ ├── pub.js │ └── run.js └── unit-vectors │ ├── index.html │ ├── pub.js │ └── run.js ├── dist ├── es5-bundle.js └── wtc-vector.js ├── docs ├── Vector.html ├── classes.list.html ├── demo ├── fonts │ ├── OpenSans-Bold-webfont.eot │ ├── OpenSans-Bold-webfont.svg │ ├── OpenSans-Bold-webfont.woff │ ├── OpenSans-BoldItalic-webfont.eot │ ├── OpenSans-BoldItalic-webfont.svg │ ├── OpenSans-BoldItalic-webfont.woff │ ├── OpenSans-Italic-webfont.eot │ ├── OpenSans-Italic-webfont.svg │ ├── OpenSans-Italic-webfont.woff │ ├── OpenSans-Light-webfont.eot │ ├── OpenSans-Light-webfont.svg │ ├── OpenSans-Light-webfont.woff │ ├── OpenSans-LightItalic-webfont.eot │ ├── OpenSans-LightItalic-webfont.svg │ ├── OpenSans-LightItalic-webfont.woff │ ├── OpenSans-Regular-webfont.eot │ ├── OpenSans-Regular-webfont.svg │ ├── OpenSans-Regular-webfont.woff │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── global.html ├── img │ ├── glyphicons-halflings-white.png │ └── glyphicons-halflings.png ├── index.html ├── quicksearch.html ├── scripts │ ├── docstrap.lib.js │ ├── fulltext-search-ui.js │ ├── fulltext-search.js │ ├── linenumber.js │ ├── lunr.min.js │ ├── prettify │ │ ├── Apache-License-2.0.txt │ │ ├── jquery.min.js │ │ ├── lang-css.js │ │ └── prettify.js │ ├── sunlight.js │ └── toc.js ├── styles │ ├── darkstrap.css │ ├── jsdoc-default.css │ ├── prettify-jsdoc.css │ ├── prettify-tomorrow.css │ ├── site.cerulean.css │ ├── site.cosmo.css │ ├── site.cyborg.css │ ├── site.darkly.css │ ├── site.darkstrap.css │ ├── site.dibs-bootstrap.css │ ├── site.flatly.css │ ├── site.journal.css │ ├── site.lumen.css │ ├── site.paper.css │ ├── site.readable.css │ ├── site.sandstone.css │ ├── site.simplex.css │ ├── site.slate.css │ ├── site.spacelab.css │ ├── site.superhero.css │ ├── site.united.css │ ├── site.yeti.css │ ├── sunlight.dark.css │ └── sunlight.default.css └── wtc-vector.js.html ├── gulpfile.js ├── jsdoc.json ├── package.json ├── src ├── .DS_Store └── wtc-vector.js └── yarn.lock /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/.DS_Store -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env" 4 | ] 5 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependency directories 2 | node_modules 3 | jspm_packages 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | docs/ 3 | demo/ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wtc-vector 2 | A basic 2d vector class. 3 | 4 | ## Usage 5 | ``` 6 | let vPosition = new Vector(10, 10); 7 | let vForce = new Vector(0, 1); 8 | vPosition.add(vForce); // [0, 11]; 9 | ``` 10 | 11 | ## Using the es5 bundle in browser 12 | ``` 13 | npm install --save wtc-vector 14 | ``` 15 | ### Using gulp 16 | Add the final module to your JS bundle. 17 | ``` 18 | ...JS bundle logic 19 | node_modules/wtc-vector/dist/es5-bundle.js 20 | ``` 21 | The module will then be exposed inside ```window``` as ```window.WTCVector.default``` 22 | #### Example 23 | ``` 24 | 27 | ``` 28 | ## Documentation 29 | Documentation can be found [here](https://wethegit.github.io/wtc-vector/docs/) 30 | 31 | ## Demos 32 | The following demos provide proofs and interactive examples of the Vector class: 33 | - [Basic demo](https://wethegit.github.io/wtc-vector/demo/) 34 | 35 | A basic Vector demonstration. 36 | - [Addition proof](https://wethegit.github.io/wtc-vector/demo/addition/) 37 | 38 | A basic proof of addition with vectors, with associated display. 39 | - [Unit vectors](https://wethegit.github.io/wtc-vector/demo/unit-vectors/) 40 | 41 | Shows the use of unit vectors and the reasoning behind their use in a vector's redering. 42 | - [Linear transformations](https://wethegit.github.io/wtc-vector/demo/linear-transformations/) 43 | 44 | This demo shows how to calculate linear transformations (specifically in the vector space's unit vectors). 45 | - [Snowflake](https://wethegit.github.io/wtc-vector/demo/snowflake/) 46 | 47 | This demonstrates the use of a rotating vector as a a method of calculating a sinewave and it's applicable use in the animation of a falling snowflake. 48 | -------------------------------------------------------------------------------- /demo/VectorPlayground.js: -------------------------------------------------------------------------------- 1 | import Vector from "../src/wtc-vector"; 2 | 3 | let colours = ['#c678dd', '#98c379', '#c34448', '#4e9c9e', '#d18549', '#abb2bf'] 4 | 5 | class DrawingVector { 6 | constructor(x, y, color) { 7 | this.v = new Vector(x, y); 8 | 9 | this.arrowheadV1 = new Vector(-10,-10); 10 | this.arrowheadV2 = new Vector(-10, 10); 11 | 12 | if( typeof color !== 'string' || !(/^#[0-9ABCDEFabcdef]*/.test(color)) ) { 13 | let color = '#' + ('0'+(Math.round(Math.random()*255)).toString(16)).substr(-2) + ('0'+(Math.round(Math.random()*255)).toString(16)).substr(-2) + ('0'+(Math.round(Math.random()*255)).toString(16)).substr(-2); 14 | } 15 | 16 | this.color = color; 17 | } 18 | 19 | draw(playground) { 20 | let offset = playground.offset; 21 | let x = offset.x; 22 | let y = offset.y; 23 | let ctx = playground.mainCtx; 24 | 25 | ctx.beginPath(); 26 | ctx.lineWidth = 1; 27 | ctx.strokeStyle = this.color; 28 | ctx.moveTo(x, y); 29 | x = this.v.x + offset.x; 30 | y = this.v.y + offset.y; 31 | ctx.lineTo(x, y); 32 | 33 | var av1 = this.arrowheadV1.rotateNew(this.v.angle); 34 | var av2 = this.arrowheadV2.rotateNew(this.v.angle); 35 | 36 | ctx.lineTo(av1.x + x, av1.y + y); 37 | ctx.moveTo(x, y); 38 | ctx.lineTo(av2.x + x, av2.y + y); 39 | 40 | ctx.stroke(); 41 | 42 | } 43 | 44 | get playground() { 45 | return this._pg; 46 | } 47 | set playground(pg) { 48 | this._pg = pg; 49 | } 50 | 51 | set color(color) { 52 | if( typeof color == 'string' && /^#[0-9ABCDEFabcdef]*/.test(color) ) { 53 | this._color = color; 54 | } 55 | } 56 | get color() { 57 | return this._color || '#FFFFFF'; 58 | } 59 | } 60 | 61 | class VectorPlayground { 62 | static init(drawing = true) { 63 | this.initialised = true; 64 | 65 | this.mainCanvas = document.createElement('canvas'); 66 | this.mainCtx = this.mainCanvas.getContext('2d'); 67 | this.secondaryCanvas = document.createElement('canvas'); 68 | this.secondarCtx = this.secondaryCanvas.getContext('2d'); 69 | 70 | document.body.appendChild(this.mainCanvas); 71 | document.body.appendChild(this.secondaryCanvas); 72 | 73 | window.addEventListener('resize', this.resizeListener); 74 | this.resizeListener(); 75 | 76 | this.vectors = []; 77 | 78 | this.gridDistance = 100; 79 | 80 | this.drawing = drawing; 81 | } 82 | 83 | static resizeListener(e) { 84 | this.dimensions = new Vector(window.innerWidth, window.innerHeight); 85 | this.offset = this.dimensions.divideScalarNew(2); 86 | 87 | this.mainCanvas.width = this.secondaryCanvas.width = window.innerWidth; 88 | this.mainCanvas.height = this.secondaryCanvas.height = window.innerHeight; 89 | } 90 | 91 | static addVector(drawingVector) { 92 | if( ! (drawingVector instanceof DrawingVector) ) { 93 | return; 94 | } 95 | 96 | this.vectors.push(drawingVector); 97 | 98 | return drawingVector; 99 | } 100 | 101 | static draw() { 102 | // Clear the canvases before drawing 103 | this.mainCtx.fillStyle = this.bgColor; 104 | this.mainCtx.beginPath(); 105 | this.mainCtx.rect(0,0, this.dimensions.width, this.dimensions.height); 106 | this.mainCtx.fill(); 107 | // this.secondarCtx.clearRect(0,0,this.mainCanvas.width, this.mainCanvas.height); 108 | 109 | this.drawGrid(); 110 | this.drawVectors(); 111 | 112 | if( this.drawing ) { 113 | window.requestAnimationFrame(this.draw.bind(this)); 114 | } 115 | } 116 | 117 | static drawVectors() { 118 | this.vectors.forEach(function(v) { 119 | v.draw(this); 120 | }.bind(this)); 121 | } 122 | 123 | static drawGrid() { 124 | // draw the main grid lines 125 | 126 | this.mainCtx.lineWidth = 1; 127 | this.mainCtx.strokeStyle = this.gridColor; 128 | this.mainCtx.beginPath(); 129 | 130 | let xPos = this.offset.x; 131 | while(xPos < this.dimensions.width) { 132 | xPos += this.gridDistance; 133 | this.mainCtx.moveTo(xPos, 0); 134 | this.mainCtx.lineTo(xPos, this.dimensions.height); 135 | } 136 | xPos = this.offset.x; 137 | while(xPos > 0) { 138 | xPos -= this.gridDistance; 139 | this.mainCtx.moveTo(xPos, 0); 140 | this.mainCtx.lineTo(xPos, this.dimensions.height); 141 | } 142 | let yPos = this.offset.y; 143 | while(yPos < this.dimensions.height) { 144 | yPos += this.gridDistance; 145 | this.mainCtx.moveTo(0, yPos); 146 | this.mainCtx.lineTo(this.dimensions.width, yPos); 147 | } 148 | yPos = this.offset.y; 149 | while(yPos > 0) { 150 | yPos -= this.gridDistance; 151 | this.mainCtx.moveTo(0, yPos); 152 | this.mainCtx.lineTo(this.dimensions.width, yPos); 153 | } 154 | this.mainCtx.stroke(); 155 | 156 | 157 | this.mainCtx.strokeStyle = this.originColor; 158 | this.mainCtx.beginPath(); 159 | 160 | this.mainCtx.moveTo(0, this.offset.y); 161 | this.mainCtx.lineTo(this.dimensions.width, this.offset.y); 162 | this.mainCtx.moveTo(this.offset.x, 0); 163 | this.mainCtx.lineTo(this.offset.x, this.dimensions.height); 164 | 165 | this.mainCtx.stroke(); 166 | 167 | } 168 | 169 | static set drawing(d) { 170 | this._drawing = d === true; 171 | 172 | if(this._drawing === true) { 173 | this.draw(); 174 | } 175 | } 176 | static get drawing() { 177 | return this._drawing === true; 178 | } 179 | 180 | static set bgColor(color) { 181 | if( typeof color == 'string' && /#[0-9ABCDEF]{6}/.test(color.toUpperCase())) { 182 | this._bgColor = color; 183 | } 184 | } 185 | static get bgColor() { 186 | return this._bgColor || '#282C34'; 187 | } 188 | 189 | static set originColor(color) { 190 | if( typeof color == 'string' && /#[0-9ABCDEF]{6}/.test(color.toUpperCase())) { 191 | this._originColor = color; 192 | } 193 | } 194 | static get originColor() { 195 | return this._originColor || '#FFFFFF'; 196 | } 197 | 198 | static set gridColor(color) { 199 | if( typeof color == 'string' && /#[0-9ABCDEF]{6}/.test(color.toUpperCase())) { 200 | this._gridColor = color; 201 | } 202 | } 203 | static get gridColor() { 204 | return this._gridColor || '#666666'; 205 | } 206 | 207 | static set unitVectorX(v) { 208 | if( v instanceof Vector ) { 209 | this._unitVectorX = v 210 | } 211 | } 212 | static get unitVectorX() { 213 | return this._unitVectorX || new Vector(1, 0); 214 | } 215 | 216 | static set unitVectorY(v) { 217 | if( v instanceof Vector ) { 218 | this._unitVectorY = v 219 | } 220 | } 221 | static get unitVectorY() { 222 | return this._unitVectorY || new Vector(0, 1); 223 | } 224 | 225 | static set dimensions(dims) { 226 | if(dims instanceof Vector) { 227 | this._dimensions = dims; 228 | } 229 | } 230 | static get dimensions() { 231 | return this._dimensions || new Vector(); 232 | } 233 | 234 | static set offset(dims) { 235 | if(dims instanceof Vector) { 236 | this._offset = dims; 237 | } 238 | } 239 | static get offset() { 240 | return this._offset || new Vector(); 241 | } 242 | 243 | 244 | 245 | } 246 | 247 | export {DrawingVector, VectorPlayground}; 248 | -------------------------------------------------------------------------------- /demo/addition/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vector - V addition proof 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 |
14 |

Vector Addition

15 |

This proof shows that Va + Vb = Vc

16 |

For this example, we're positioning Vb so that it originates from the end of Va to illustrate this relationship.

17 |

Click animating to see the affect that rotating the vector has on this procedure.

18 |
19 |
20 |
1
21 |
-2
22 |
23 | + 24 |
25 |
-3
26 |
1
27 |
28 | = 29 |
30 |
0 + 0
31 |
0 + 0
32 |
33 | = 34 |
35 |
1.5
36 |
-1.5
37 |
38 |
39 |
40 |
41 | 42 | 43 | -------------------------------------------------------------------------------- /demo/addition/run.js: -------------------------------------------------------------------------------- 1 | import Vector from "../../src/wtc-vector"; 2 | import DrawingVector from "../app/DrawingVector"; 3 | import VectorPlayground from "../app/VectorPlayground"; 4 | import {colours} from '../app/colours'; 5 | import dat from 'dat-gui'; 6 | import updateCalculation from '../app/calcUpdate'; 7 | 8 | window.Vector = Vector; 9 | 10 | let settings = { 11 | animating: false 12 | } 13 | 14 | function ready(fn) { 15 | if (document.readyState != 'loading'){ 16 | fn(); 17 | } else { 18 | document.addEventListener('DOMContentLoaded', fn); 19 | } 20 | } 21 | ready(function() { 22 | 23 | let va = new DrawingVector(1, -2, colours[0]); 24 | va.label = `[ 1, -2 ]`; 25 | let vb = new DrawingVector(-3, 1, colours[1]); 26 | vb.label = `[ -3, 1 ]`; 27 | settings._vector0 = va.v; 28 | settings._vector1 = vb.v; 29 | vb.offset = va.v; 30 | let vc = new DrawingVector(0, 0, '#CCCCCC'); 31 | vc.v = va.v.addNew(vb.v); 32 | settings._vector2 = vc.v; 33 | vc.label = `[ ${vc.v.x}, ${vc.v.y} ]`; 34 | let vd = new DrawingVector(0, 0, '#777777'); 35 | vd.v = va.v.subtractNew(vb.v); 36 | vd.label = `subtraction`; 37 | 38 | VectorPlayground.init(); 39 | VectorPlayground.addVector(vc); 40 | VectorPlayground.addVector(va); 41 | VectorPlayground.addVector(vb); 42 | VectorPlayground.addVector(vd); 43 | 44 | let update = function(animate = true) { 45 | 46 | if(settings.animating && animate === true) { 47 | 48 | // Update the angle of the vector 49 | va.v.angle += 0.01; 50 | 51 | requestAnimationFrame(function() { update(true); }); 52 | } 53 | 54 | // Update Vector C based on the addition of the two components 55 | vc.v = va.v.addNew(vb.v); 56 | 57 | // Update Vector D based on the addition of the two components 58 | vd.v = va.v.subtractNew(vb.v); 59 | 60 | // Update the settings variables 61 | settings._vector0 = va.v; 62 | settings._vector2 = vc.v; 63 | 64 | // update the labels 65 | va.label = `[ ${Math.round(va.v.x * 100) / 100}, ${Math.round(va.v.y * 100) / 100} ]`; 66 | vb.label = `[ ${Math.round(vb.v.x * 100) / 100}, ${Math.round(vb.v.y * 100) / 100} ]`; 67 | vc.label = `[ ${Math.round(vc.v.x * 100) / 100}, ${Math.round(vc.v.y * 100) / 100} ]`; 68 | vd.label = `subtraction [ ${Math.round(vd.v.x * 100) / 100}, ${Math.round(vd.v.y * 100) / 100} ]`; 69 | 70 | } 71 | 72 | update(); 73 | 74 | var gui = new dat.GUI(); 75 | var animationControl = gui.add(settings, 'animating'); 76 | animationControl.onChange(function(value) { 77 | if(value == true) { 78 | update(); 79 | } 80 | }); 81 | let t_V_onChange = function(val, item) { 82 | update(false); 83 | } 84 | let t_VA = gui.addFolder('Vector A'); 85 | let t_VA_x = t_VA.add(settings._vector0, 'x').listen(); 86 | let t_VA_y = t_VA.add(settings._vector0, 'y').listen(); 87 | let t_VB = gui.addFolder('Vector B'); 88 | let t_VB_x = t_VB.add(settings._vector1, 'x').listen(); 89 | let t_VB_y = t_VB.add(settings._vector1, 'y').listen(); 90 | let t_VC = gui.addFolder('Vector C'); 91 | let t_VC_x = t_VC.add(settings._vector2, 'x').listen(); 92 | let t_VC_y = t_VC.add(settings._vector2, 'y').listen(); 93 | t_VA_x.onChange(t_V_onChange); 94 | t_VA_y.onChange(t_V_onChange); 95 | t_VB_x.onChange(t_V_onChange); 96 | t_VB_y.onChange(t_V_onChange); 97 | t_VA_x.__precision = t_VA_y.__precision = t_VB_x.__precision = t_VB_y.__precision = 3; 98 | t_VA_x.__impliedStep = t_VA_y.__impliedStep = t_VB_x.__impliedStep = t_VB_y.__impliedStep = 0.05; 99 | 100 | updateCalculation(settings); 101 | 102 | }); 103 | -------------------------------------------------------------------------------- /demo/app/DrawingVector.js: -------------------------------------------------------------------------------- 1 | import Vector from "../../src/wtc-vector"; 2 | 3 | class DrawingVector { 4 | constructor(x, y, color, lineWidth = 1) { 5 | this.v = new Vector(x, y); 6 | 7 | this.arrowheadV1 = new Vector(-10,-10); 8 | this.arrowheadV2 = new Vector(-10, 10); 9 | 10 | if( typeof color !== 'string' || !(/^#[0-9ABCDEFabcdef]*/.test(color)) ) { 11 | color = '#' + ('0'+(Math.round(Math.random()*255)).toString(16)).substr(-2) + ('0'+(Math.round(Math.random()*255)).toString(16)).substr(-2) + ('0'+(Math.round(Math.random()*255)).toString(16)).substr(-2); 12 | } 13 | 14 | this.color = color; 15 | this.lineWidth = lineWidth; 16 | } 17 | 18 | draw(playground) { 19 | let isCartesian = playground.cartesian; 20 | let unitX = playground.scaledUnitVectorX; // iHat 21 | let unitY = playground.scaledUnitVectorY; // jHat 22 | let scale = playground.scale; 23 | let offset = new Vector(0, 0); 24 | // Gtting the offset of the vector and, if it has length, setting up the 25 | // translated offset 26 | if(this.offset instanceof Vector) { 27 | let _offset = this.offset.clone(); 28 | if(isCartesian) { 29 | _offset.y *= -1 30 | } 31 | offset.x = (_offset.x * unitX.x) + (_offset.y * unitY.x); 32 | offset.y = (_offset.x * unitX.y) + (_offset.y * unitY.y); 33 | } 34 | // Adding the playground's offset to it (origin point) 35 | let pgOffset = playground.offset; 36 | // if(isCartesian) pgOffset.y *= -1; // reversing the output Y if we're set to cartesian coords 37 | offset.add(pgOffset); 38 | let x = offset.x; 39 | let y = offset.y; 40 | let ctx = playground.mainCtx; 41 | 42 | if(this.outputVector instanceof Vector) { 43 | let unitX = playground.unitVectorX.clone(); // iHat 44 | let unitY = playground.unitVectorY.clone(); // jHat 45 | let V = this.v.clone(); 46 | 47 | if(isCartesian) { 48 | unitX.y *= -1; // reversing the output Y if we're set to cartesian coords 49 | unitY.y *= -1; 50 | V.y *= -1; 51 | } 52 | 53 | this.outputVector.x = (V.x * unitX.x) + (V.y * unitY.x); 54 | this.outputVector.y = (V.x * unitX.y) + (V.y * unitY.y); 55 | } 56 | 57 | // Translate the vector using linear transformation x(î) + y(j) 58 | // î = unix X 59 | // j = unit Y 60 | // _ _ _ _ 61 | // | x(î.x) | + | y(j.x) | 62 | // | x(i.y) | + | y(j.y) | 63 | // 64 | let V = this.v.clone(); 65 | if(isCartesian) { 66 | V.y *= -1; // Reverse the Y coord if this is a cartesian system 67 | } 68 | let translatedVector = new Vector(0, 0); 69 | translatedVector.x = (V.x * unitX.x) + (V.y * unitY.x); 70 | translatedVector.y = (V.x * unitX.y) + (V.y * unitY.y); 71 | 72 | ctx.beginPath(); 73 | ctx.lineWidth = this.lineWidth; 74 | ctx.strokeStyle = this.color; 75 | ctx.moveTo(x, y); 76 | x = translatedVector.x + offset.x; 77 | y = translatedVector.y + offset.y; 78 | ctx.lineTo(x, y); 79 | 80 | this.translatedVector = translatedVector; 81 | 82 | // Create the arrow head vectors. These are not dependent upon the unit vector 83 | var av1 = this.arrowheadV1.rotateNew(translatedVector.angle); 84 | var av2 = this.arrowheadV2.rotateNew(translatedVector.angle); 85 | 86 | // Draw the arrowhead 87 | ctx.lineTo(av1.x + x, av1.y + y); 88 | ctx.moveTo(x, y); 89 | ctx.lineTo(av2.x + x, av2.y + y); 90 | 91 | ctx.stroke(); 92 | 93 | let label = this.label; 94 | if(label) { 95 | let labelPoint = this.v.divideScalarNew(2); 96 | let textloc = new Vector(0, 0); 97 | if(isCartesian) { 98 | labelPoint.y *= -1; // Reverse the Y coord if this is a cartesian system 99 | } 100 | textloc.x = (labelPoint.x * unitX.x) + (labelPoint.y * unitY.x) + offset.x; 101 | textloc.y = (labelPoint.x * unitX.y) + (labelPoint.y * unitY.y) + offset.y; 102 | 103 | ctx.font = "10px Helvetica, Arial, sans-serif"; 104 | let textdims = ctx.measureText(label); 105 | let padding = 3; 106 | textdims.height = 10; 107 | ctx.fillStyle = 'rgba(0,0,0,0.7)'; 108 | ctx.fillRect(textloc.x - padding - textdims.width / 2, textloc.y - padding - textdims.height / 2, textdims.width + padding * 2, textdims.height + padding * 2); 109 | ctx.fillStyle = this.color; 110 | ctx.fillText(label,textloc.x - textdims.width / 2, textloc.y - textdims.height / 2 + textdims.height - textdims.height / 4); 111 | } 112 | 113 | } 114 | 115 | get playground() { 116 | return this._pg; 117 | } 118 | set playground(pg) { 119 | this._pg = pg; 120 | } 121 | 122 | set color(color) { 123 | if( typeof color == 'string' && /^#[0-9ABCDEFabcdef]*/.test(color) ) { 124 | this._color = color; 125 | } 126 | } 127 | get color() { 128 | return this._color || '#FFFFFF'; 129 | } 130 | 131 | set offset(v) { 132 | if( v instanceof Vector ) { 133 | this._offset = v; 134 | } 135 | } 136 | get offset() { 137 | // if( !(this._offset instanceof Vector) ) { 138 | // this._offset = new Vector(0,0); 139 | // } 140 | return this._offset || false; 141 | } 142 | 143 | set label(label) { 144 | if(label) { 145 | this._label = label; 146 | } else { 147 | this._label = null; 148 | } 149 | } 150 | get label() { 151 | return this._label || null; 152 | } 153 | } 154 | 155 | export default DrawingVector; 156 | -------------------------------------------------------------------------------- /demo/app/VectorPlayground.js: -------------------------------------------------------------------------------- 1 | import Vector from "../../src/wtc-vector"; 2 | import DrawingVector from "./DrawingVector"; 3 | import colours from './colours'; 4 | 5 | class VectorPlayground { 6 | static init(drawing = true, scale = 100, drawGrid = true) { 7 | this.initialised = true; 8 | 9 | this.mainCanvas = document.createElement('canvas'); 10 | this.mainCtx = this.mainCanvas.getContext('2d'); 11 | this.secondaryCanvas = document.createElement('canvas'); 12 | this.secondarCtx = this.secondaryCanvas.getContext('2d'); 13 | 14 | document.body.appendChild(this.mainCanvas); 15 | document.body.appendChild(this.secondaryCanvas); 16 | 17 | window.addEventListener('resize', this.resizeListener.bind(this)); 18 | this.resizeListener(); 19 | 20 | this.vectors = []; 21 | 22 | this.gridDistance = 1; 23 | 24 | this.doDrawGrid = drawGrid; 25 | this.scale = scale; 26 | this.drawing = drawing; 27 | } 28 | 29 | static resizeListener(e) { 30 | this.dimensions = new Vector(window.innerWidth, window.innerHeight); 31 | this.offset = this.dimensions.divideScalarNew(2); 32 | 33 | this.mainCanvas.width = this.secondaryCanvas.width = window.innerWidth; 34 | this.mainCanvas.height = this.secondaryCanvas.height = window.innerHeight; 35 | } 36 | 37 | static addVector(drawingVector) { 38 | if( ! (drawingVector instanceof DrawingVector) ) { 39 | return; 40 | } 41 | 42 | this.vectors.push(drawingVector); 43 | 44 | return drawingVector; 45 | } 46 | 47 | static draw() { 48 | // Clear the canvases before drawing 49 | this.mainCtx.fillStyle = this.bgColor; 50 | this.mainCtx.beginPath(); 51 | this.mainCtx.rect(0,0, this.dimensions.width, this.dimensions.height); 52 | this.mainCtx.fill(); 53 | // this.secondarCtx.clearRect(0,0,this.mainCanvas.width, this.mainCanvas.height); 54 | 55 | if(this.doDrawGrid) this.drawGrid(); 56 | this.drawVectors(); 57 | 58 | if( this.drawing ) { 59 | window.requestAnimationFrame(this.draw.bind(this)); 60 | } 61 | } 62 | 63 | static drawVectors() { 64 | this.vectors.forEach(function(v) { 65 | v.draw(this); 66 | }.bind(this)); 67 | } 68 | 69 | static drawGrid() { 70 | let scale = this.scale; 71 | let gridDistance = this.gridDistance * scale; 72 | 73 | // draw the main grid lines 74 | 75 | this.mainCtx.lineWidth = 1; 76 | this.mainCtx.strokeStyle = this.gridColor; 77 | this.mainCtx.beginPath(); 78 | 79 | let xPos = this.offset.x; 80 | while(xPos < this.dimensions.width) { 81 | xPos += gridDistance; 82 | this.mainCtx.moveTo(xPos, 0); 83 | this.mainCtx.lineTo(xPos, this.dimensions.height); 84 | } 85 | xPos = this.offset.x; 86 | while(xPos > 0) { 87 | xPos -= gridDistance; 88 | this.mainCtx.moveTo(xPos, 0); 89 | this.mainCtx.lineTo(xPos, this.dimensions.height); 90 | } 91 | let yPos = this.offset.y; 92 | while(yPos < this.dimensions.height) { 93 | yPos += gridDistance; 94 | this.mainCtx.moveTo(0, yPos); 95 | this.mainCtx.lineTo(this.dimensions.width, yPos); 96 | } 97 | yPos = this.offset.y; 98 | while(yPos > 0) { 99 | yPos -= gridDistance; 100 | this.mainCtx.moveTo(0, yPos); 101 | this.mainCtx.lineTo(this.dimensions.width, yPos); 102 | } 103 | this.mainCtx.stroke(); 104 | 105 | 106 | this.mainCtx.strokeStyle = this.originColor; 107 | this.mainCtx.beginPath(); 108 | 109 | this.mainCtx.moveTo(0, this.offset.y); 110 | this.mainCtx.lineTo(this.dimensions.width, this.offset.y); 111 | this.mainCtx.moveTo(this.offset.x, 0); 112 | this.mainCtx.lineTo(this.offset.x, this.dimensions.height); 113 | 114 | this.mainCtx.stroke(); 115 | 116 | } 117 | 118 | static set drawing(d) { 119 | this._drawing = d === true; 120 | 121 | if(this._drawing === true) { 122 | this.draw(); 123 | } 124 | } 125 | static get drawing() { 126 | return this._drawing === true; 127 | } 128 | 129 | static set bgColor(color) { 130 | if( typeof color == 'string' && /#[0-9ABCDEF]{6}/.test(color.toUpperCase())) { 131 | this._bgColor = color; 132 | } 133 | } 134 | static get bgColor() { 135 | return this._bgColor || '#282C34'; 136 | } 137 | 138 | static set originColor(color) { 139 | if( typeof color == 'string' && /#[0-9ABCDEF]{6}/.test(color.toUpperCase())) { 140 | this._originColor = color; 141 | } 142 | } 143 | static get originColor() { 144 | return this._originColor || '#FFFFFF'; 145 | } 146 | 147 | static set gridColor(color) { 148 | if( typeof color == 'string' && /#[0-9ABCDEF]{6}/.test(color.toUpperCase())) { 149 | this._gridColor = color; 150 | } 151 | } 152 | static get gridColor() { 153 | return this._gridColor || '#666666'; 154 | } 155 | 156 | static set unitVectorX(v) { 157 | if( v instanceof Vector ) { 158 | this._unitVectorX = v 159 | } 160 | } 161 | static get unitVectorX() { 162 | return this._unitVectorX || new Vector(1, 0); 163 | } 164 | static get scaledUnitVectorX() { 165 | let scale = this.scale; 166 | let uv = this.unitVectorX.clone(); 167 | if(scale !== 1) uv.multiplyScalar(scale); 168 | return uv; 169 | } 170 | 171 | static set unitVectorY(v) { 172 | if( v instanceof Vector ) { 173 | this._unitVectorY = v 174 | } 175 | } 176 | static get unitVectorY() { 177 | return this._unitVectorY || new Vector(0, 1); 178 | } 179 | static get scaledUnitVectorY() { 180 | let scale = this.scale; 181 | let uv = this.unitVectorY.clone(); 182 | if(scale !== 1) uv.multiplyScalar(scale); 183 | return uv; 184 | } 185 | 186 | static set dimensions(dims) { 187 | if(dims instanceof Vector) { 188 | this._dimensions = dims; 189 | } 190 | } 191 | static get dimensions() { 192 | return this._dimensions || new Vector(); 193 | } 194 | 195 | static set offset(dims) { 196 | if(dims instanceof Vector) { 197 | this._offset = dims; 198 | } 199 | } 200 | static get offset() { 201 | let offset = this._offset || new Vector(); 202 | return offset; 203 | } 204 | 205 | static set scale(scale) { 206 | if(typeof scale === 'number') { 207 | this._scale = scale; 208 | } 209 | } 210 | static get scale() { 211 | return this._scale || 1; 212 | } 213 | 214 | static set doDrawGrid(drawGrid) { 215 | this._drawGrid = drawGrid === true; 216 | } 217 | static get doDrawGrid() { 218 | return this._drawGrid || false; 219 | } 220 | 221 | static set cartesian(isCartesian) { 222 | this.isCartesian = isCartesian === true; 223 | } 224 | static get cartesian() { 225 | return this.isCartesian || false; 226 | } 227 | 228 | 229 | } 230 | 231 | export default VectorPlayground; 232 | -------------------------------------------------------------------------------- /demo/app/calcUpdate.js: -------------------------------------------------------------------------------- 1 | 2 | let updateCalculation = function(settings) { 3 | 4 | let els = document.querySelectorAll('[data-value]'); 5 | 6 | function animate() { 7 | els.forEach(function(el) { 8 | let address = el.getAttribute('data-value').split('.'); 9 | let value = settings; 10 | address.forEach(function(address){ 11 | try { 12 | if(value[address] !== 'undefined') value = value[address]; 13 | } catch (e) { 14 | 15 | } 16 | }); 17 | if(typeof value == 'number') value = Math.round(value * 100) / 100; 18 | el.innerText = value; 19 | }); 20 | requestAnimationFrame(animate); 21 | 22 | } 23 | animate(); 24 | 25 | } 26 | 27 | export default updateCalculation; 28 | -------------------------------------------------------------------------------- /demo/app/colours.js: -------------------------------------------------------------------------------- 1 | 2 | let colours = ['#c678dd', '#98c379', '#c34448', '#4e9c9e', '#d18549', '#abb2bf']; 3 | let namedColours = { 4 | silver: '#CCCCCC' 5 | }; 6 | export { colours, namedColours } 7 | -------------------------------------------------------------------------------- /demo/app/drawer.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/demo/app/drawer.js -------------------------------------------------------------------------------- /demo/app/test.js: -------------------------------------------------------------------------------- 1 | import colours from 'demo/app/colours'; 2 | -------------------------------------------------------------------------------- /demo/index.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 4 | 5 | margin: 0px; 6 | padding: 0px; 7 | } 8 | 9 | canvas { 10 | left: 0px; 11 | position: absolute; 12 | top: 0px; 13 | 14 | } 15 | 16 | #canvas2 17 | { 18 | z-index: 1; 19 | } 20 | 21 | h1, h2, h3, h4, h5 { 22 | margin-bottom: 0.3em; 23 | } 24 | h1 { 25 | font-size: 1.3em; 26 | } 27 | h1:first-child { 28 | margin-top: 0; 29 | } 30 | h1 ~ p { 31 | margin-top: 0px; 32 | } 33 | p { 34 | margin: 0.3em 0; 35 | } 36 | 37 | .drawer-container { 38 | color: #FFF; 39 | font-family: helvetica, arial, sans-serif; 40 | position: fixed; 41 | bottom: 0px; 42 | width: 100%; 43 | z-index: 1000; 44 | } 45 | 46 | .drawer-container .drawer { 47 | background: RGBA(0,0,0,0.5); 48 | box-shadow: inset 0 -50px 100px #000; 49 | display: none; 50 | padding: 20px; 51 | } 52 | .drawer-container label { 53 | background: RGBA(0,0,0,0.5); 54 | display: block; 55 | margin: 0px auto; 56 | padding: 10px; 57 | width: 100px; 58 | } 59 | .drawer-container input { 60 | display: none; 61 | } 62 | .drawer-container input:checked ~ .drawer { 63 | display: block; 64 | } 65 | 66 | .calculation { 67 | align-items: center; 68 | display: flex; 69 | } 70 | .calculation > * { 71 | margin: 5px; 72 | } 73 | .matrix, 74 | .vector { 75 | border-left: 2px solid #FFF; 76 | border-right: 2px solid #FFF; 77 | display: inline-flex; 78 | padding: 5px; 79 | position: relative; 80 | } 81 | .vector::before, 82 | .vector::after, 83 | .matrix::before, 84 | .matrix::after { 85 | border-top: 2px solid #FFF; 86 | border-bottom: 2px solid #FFF; 87 | content: ''; 88 | height: calc(100% - 4px); 89 | left: 0px; 90 | top: 0px; 91 | position: absolute; 92 | width: 5px; 93 | } 94 | .vector::after, 95 | .matrix::after { 96 | left: auto; 97 | right: 0px; 98 | } 99 | .matrix--2x2 { 100 | 101 | } 102 | .vector { 103 | /*display: inline-block;*/ 104 | flex-direction: column; 105 | text-align: center; 106 | padding: 10px; 107 | } 108 | .matrix .vector { 109 | border: none; 110 | flex: 1 1 auto; 111 | padding: 5px; 112 | } 113 | .matrix .vector::before, 114 | .matrix .vector::after { 115 | display: none; 116 | } 117 | 118 | .color-0, 119 | .color-0::before, 120 | .color-0::after { 121 | border-color: #c678dd; 122 | color: #c678dd; 123 | } 124 | .color-1, 125 | .color-1::before, 126 | .color-1::after { 127 | border-color: #98c379; 128 | color: #98c379; 129 | } 130 | .color-2, 131 | .color-2::before, 132 | .color-2::after { 133 | border-color: #c34448; 134 | color: #c34448; 135 | } 136 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vector test 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demo/linear-transformations/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vector - Unit vectors 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 |
14 |

Linear Transformation of Unit Vectors

15 |

This example shows the linear transformation of unit vectors Vi (the x unit vector) and Vj (the y unit vector)

16 |

Two main things to note here:

17 |
    18 |
  1. How changing the unit vectors warps the vector space; and
  2. 19 |
  3. that the value of Vc doesn't actually change.
  4. 20 |
21 |
22 |
23 |
24 |
0
25 |
1
26 |
27 |
28 |
-1
29 |
0
30 |
31 |
32 |
33 |
1.5
34 |
-1.5
35 |
36 | = 37 |
38 |
39 |
0 × 0   +  
40 |
0 × 0   +  
41 |
42 |
43 |
0 × 0
44 |
0 × 0
45 |
46 |
47 | = 48 |
49 |
1.5
50 |
-1.5
51 |
52 |
53 |
54 |
55 | 56 | 57 | -------------------------------------------------------------------------------- /demo/linear-transformations/run.js: -------------------------------------------------------------------------------- 1 | import Vector from "../../src/wtc-vector"; 2 | import _DrawingVector from "../app/DrawingVector"; 3 | import _VectorPlayground from "../app/VectorPlayground"; 4 | import {colours} from '../app/colours'; 5 | import dat from 'dat-gui'; 6 | import updateCalculation from '../app/calcUpdate'; 7 | 8 | window.Vector = Vector; 9 | 10 | let settings = { 11 | animating: false, 12 | time: 0, 13 | increments: 1000, 14 | scale: 100 15 | } 16 | 17 | class Gridline { 18 | constructor(x, y, v) { 19 | // The V indicates the directiont he dridline is pointing as well as its length 20 | this.v = v; 21 | // This class expects the gridline to be centered 22 | this.position = new Vector(x, y); 23 | this.startPosition = this.position.clone().subtract(this.v.divideScalarNew(2)); 24 | this.endPosition = this.position.clone().add(this.v.divideScalarNew(2)); 25 | 26 | this.lineWidth = 1; 27 | this.color = '#01a7f9'; 28 | 29 | if(x == 0 && y == 0) { 30 | this.trace = true; 31 | } 32 | 33 | } 34 | draw(playground) { 35 | let unitX = playground.scaledUnitVectorX; // iHat 36 | let unitY = playground.scaledUnitVectorY; // jHat 37 | let unitVector = unitX.addNew(unitY); 38 | let scale = playground.scale; 39 | let offset = playground.offset; // creating the offset 40 | let ctx = playground.mainCtx; 41 | 42 | ctx.beginPath(); 43 | ctx.lineWidth = this.lineWidth; 44 | ctx.strokeStyle = this.color; 45 | 46 | let translatedVectorA = this.startPosition.clone(); 47 | translatedVectorA.x = offset.x + (this.startPosition.x * unitX.x) + (this.startPosition.y * unitY.x); 48 | translatedVectorA.y = offset.y + (this.startPosition.x * unitX.y) + (this.startPosition.y * unitY.y); 49 | let translatedVectorB = this.endPosition.clone(); 50 | translatedVectorB.x = offset.x + (this.endPosition.x * unitX.x) + (this.endPosition.y * unitY.x); 51 | translatedVectorB.y = offset.y + (this.endPosition.x * unitX.y) + (this.endPosition.y * unitY.y); 52 | 53 | ctx.moveTo(translatedVectorA.x, translatedVectorA.y); 54 | ctx.lineTo(translatedVectorB.x, translatedVectorB.y); 55 | 56 | ctx.stroke(); 57 | } 58 | } 59 | 60 | class VectorPlayground extends _VectorPlayground { 61 | static init() { 62 | super.init(...arguments); 63 | 64 | this.setupGridlines(); 65 | } 66 | 67 | static setupGridlines() { 68 | this.gridlines = []; 69 | 70 | let xGridSize = 20; 71 | let yGridSize = 20; 72 | 73 | let xPos = 0; 74 | while(xPos < xGridSize / 2) { 75 | this.gridlines.push(new Gridline(xPos, 0, new Vector(0, yGridSize-2))); 76 | xPos++; 77 | } 78 | xPos = -1; 79 | while(xPos > -(xGridSize / 2)) { 80 | this.gridlines.push(new Gridline(xPos, 0, new Vector(0, yGridSize-2))); 81 | xPos--; 82 | } 83 | 84 | let yPos = 0; 85 | while(yPos < yGridSize / 2) { 86 | this.gridlines.push(new Gridline(0, yPos, new Vector(xGridSize-2, 0))); 87 | yPos++; 88 | } 89 | yPos = -1; 90 | while(yPos > -(yGridSize / 2)) { 91 | this.gridlines.push(new Gridline(0, yPos, new Vector(xGridSize-2, 0))); 92 | yPos--; 93 | } 94 | 95 | } 96 | 97 | static drawGrid() { 98 | super.drawGrid(); 99 | 100 | this.gridlines.forEach(function(gridline) { 101 | gridline.draw(this); 102 | }.bind(this)); 103 | } 104 | 105 | static set scale(scale) { 106 | if(typeof scale === 'number') { 107 | this._scale = scale; 108 | this.setupGridlines(); 109 | } 110 | } 111 | static get scale() { 112 | return this._scale || 1; 113 | } 114 | } 115 | 116 | class DrawingVector extends _DrawingVector { 117 | 118 | constructor() { 119 | super(...arguments); 120 | 121 | this._v = this.v; 122 | } 123 | 124 | draw(playground) { 125 | let textLabel = ''; 126 | if(this.textLabel) textLabel = `${this.textLabel} : `; 127 | this.label = `${textLabel}[ ${Math.round(this._v.x * 100) / 100}, ${Math.round(this._v.y * 100) / 100} ]`; 128 | super.draw(playground); 129 | } 130 | 131 | set textLabel(label) { 132 | this._textLabel = label; 133 | } 134 | get textLabel() { 135 | return this._textLabel || ''; 136 | } 137 | } 138 | 139 | window.VectorPlayground = VectorPlayground; 140 | 141 | function ready(fn) { 142 | if (document.readyState != 'loading'){ 143 | fn(); 144 | } else { 145 | document.addEventListener('DOMContentLoaded', fn); 146 | } 147 | } 148 | ready(function() { 149 | 150 | // Setting up our basic vectors 151 | // Notice that they are so much smaller than previously. This is because 152 | // we're going to rely on the "world's" unit vector to translate these into 153 | // visibly large values for rendering 154 | let va = new DrawingVector(2, -2, colours[0]); // The vector on the vector space 155 | let vb = new DrawingVector(1, 0, colours[1]); // A graphical representation of the X unit vector 156 | let vc = new DrawingVector(0, 1, colours[2]); // A graphical representation of the Y unit vector 157 | va.textLabel = 'Vc'; 158 | vb.textLabel = 'i'; 159 | vc.textLabel = 'j'; 160 | 161 | // Initiallising the world 162 | VectorPlayground.init(); 163 | // Adding the initial unit vectors 164 | // VectorPlayground.unitVectorX = new Vector(100, 0); 165 | // VectorPlayground.unitVectorY = new Vector(0, 100); 166 | settings._unitVectorX = VectorPlayground.unitVectorX; 167 | settings._unitVectorY = VectorPlayground.unitVectorY; 168 | settings._vector0 = va.v; 169 | settings._vector0translate = va.v.clone(); 170 | va.outputVector = settings._vector0translate; 171 | settings.startUVX = VectorPlayground.unitVectorX.clone(); 172 | settings.startUVY = VectorPlayground.unitVectorY.clone(); 173 | settings.endUVX = new Vector(0, 1); 174 | settings.endUVY = new Vector(-1, 0); 175 | settings.vector = va.v; 176 | 177 | // Add the vectors to stage 178 | VectorPlayground.addVector(va); 179 | VectorPlayground.addVector(vb); 180 | VectorPlayground.addVector(vc); 181 | 182 | // Animation 183 | let update = function() { 184 | 185 | if(settings.animating) { 186 | 187 | // Update the angle of the vector 188 | va.v.angle += 0.01; 189 | 190 | requestAnimationFrame(update); 191 | } 192 | 193 | } 194 | 195 | update(); 196 | 197 | // Set up the dat gui 198 | var gui = new dat.GUI(); 199 | var animationControl = gui.add(settings, 'animating'); 200 | animationControl.onChange(function(value) { 201 | if(value == true) { 202 | update(); 203 | } 204 | }); 205 | let prec = []; 206 | let f_unitX = gui.addFolder('End Unit X'); 207 | prec.push(f_unitX.add(settings.endUVX, 'x')); 208 | prec.push(f_unitX.add(settings.endUVX, 'y')); 209 | let f_unitY = gui.addFolder('End Unit Y'); 210 | prec.push(f_unitY.add(settings.endUVY, 'x')); 211 | prec.push(f_unitY.add(settings.endUVY, 'y')); 212 | let time = gui.add(settings, 'time', 0, settings.increments); 213 | time.onChange(function(value) { 214 | let diffX = settings.endUVX.subtractNew(settings.startUVX); 215 | let diffY = settings.endUVY.subtractNew(settings.startUVY); 216 | let incrementX = diffX.divideScalarNew(settings.increments); 217 | let incrementY = diffY.divideScalarNew(settings.increments); 218 | VectorPlayground.unitVectorX = settings.startUVX.addNew(incrementX.multiplyScalar(value)); 219 | VectorPlayground.unitVectorY = settings.startUVY.addNew(incrementY.multiplyScalar(value)); 220 | 221 | settings._unitVectorX.x = VectorPlayground.unitVectorX.x; 222 | settings._unitVectorX.y = VectorPlayground.unitVectorX.y; 223 | settings._unitVectorY.x = VectorPlayground.unitVectorY.x; 224 | settings._unitVectorY.y = VectorPlayground.unitVectorY.y; 225 | settings.vector.x = va.v.x; 226 | settings.vector.y = va.v.y; 227 | 228 | vb._v = settings._unitVectorX; 229 | vc._v = settings._unitVectorY; 230 | }); 231 | // let t_unitX = gui.addFolder('Translated Unit X'); 232 | // prec.push(t_unitX.add(settings._unitVectorX, 'x').listen()); 233 | // prec.push(t_unitX.add(settings._unitVectorX, 'y').listen()); 234 | // let t_unitY = gui.addFolder('Translated Unit Y'); 235 | // prec.push(t_unitY.add(settings._unitVectorY, 'x').listen()); 236 | // prec.push(t_unitY.add(settings._unitVectorY, 'y').listen()); 237 | // t_unitY.open(); 238 | // t_unitX.open(); 239 | let t_V = gui.addFolder('Vector'); 240 | prec.push(t_V.add(settings.vector, 'x').listen()); 241 | prec.push(t_V.add(settings.vector, 'y').listen()); 242 | var scaleControl = gui.add(settings, 'scale'); 243 | scaleControl.onChange(function(value) { 244 | VectorPlayground.scale = value; 245 | }); 246 | prec.forEach(function(control) { 247 | control.__precision = 3; 248 | control.__impliedStep = 0.1; 249 | }); 250 | 251 | updateCalculation(settings); 252 | }); 253 | -------------------------------------------------------------------------------- /demo/matrix-multiplication/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vector - Unit vectors 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 |
14 |

Linear Transformation of Unit Vectors

15 |

This example shows the linear transformation of unit vectors Vi (the x unit vector) and Vj (the y unit vector)

16 |

Two main things to note here:

17 |
    18 |
  1. How changing the unit vectors warps the vector space; and
  2. 19 |
  3. that the value of Vc doesn't actually change.
  4. 20 |
21 |
22 |
23 |
24 |
0
25 |
1
26 |
27 |
28 |
-1
29 |
0
30 |
31 |
32 |
33 |
1.5
34 |
-1.5
35 |
36 | = 37 |
38 |
39 |
0 × 0   +  
40 |
0 × 0   +  
41 |
42 |
43 |
0 × 0
44 |
0 × 0
45 |
46 |
47 | = 48 |
49 |
1.5
50 |
-1.5
51 |
52 |
53 |
54 |
55 | 56 | 57 | -------------------------------------------------------------------------------- /demo/matrix-multiplication/run.js: -------------------------------------------------------------------------------- 1 | import Vector from "../../src/wtc-vector"; 2 | import _DrawingVector from "../app/DrawingVector"; 3 | import _VectorPlayground from "../app/VectorPlayground"; 4 | import {colours} from '../app/colours'; 5 | import dat from 'dat-gui'; 6 | import updateCalculation from '../app/calcUpdate'; 7 | 8 | window.Vector = Vector; 9 | 10 | let settings = { 11 | animating: false, 12 | time: 0, 13 | increments: 1000, 14 | scale: 100 15 | } 16 | function ready(fn) { 17 | if (document.readyState != 'loading'){ 18 | fn(); 19 | } else { 20 | document.addEventListener('DOMContentLoaded', fn); 21 | } 22 | } 23 | ready(function() { 24 | 25 | // Setting up our basic vectors 26 | // Notice that they are so much smaller than previously. This is because 27 | // we're going to rely on the "world's" unit vector to translate these into 28 | // visibly large values for rendering 29 | let va = new DrawingVector(2, -2, colours[0]); // The vector on the vector space 30 | let vb = new DrawingVector(1, 0, colours[1]); // A graphical representation of the X unit vector 31 | let vc = new DrawingVector(0, 1, colours[2]); // A graphical representation of the Y unit vector 32 | va.textLabel = 'Vc'; 33 | vb.textLabel = 'i'; 34 | vc.textLabel = 'j'; 35 | 36 | // Initiallising the world 37 | VectorPlayground.init(); 38 | // Adding the initial unit vectors 39 | // VectorPlayground.unitVectorX = new Vector(100, 0); 40 | // VectorPlayground.unitVectorY = new Vector(0, 100); 41 | settings._unitVectorX = VectorPlayground.unitVectorX; 42 | settings._unitVectorY = VectorPlayground.unitVectorY; 43 | settings._vector0 = va.v; 44 | settings._vector0translate = va.v.clone(); 45 | va.outputVector = settings._vector0translate; 46 | settings.startUVX = VectorPlayground.unitVectorX.clone(); 47 | settings.startUVY = VectorPlayground.unitVectorY.clone(); 48 | settings.endUVX = new Vector(0, 1); 49 | settings.endUVY = new Vector(-1, 0); 50 | settings.vector = va.v; 51 | 52 | // Add the vectors to stage 53 | VectorPlayground.addVector(va); 54 | VectorPlayground.addVector(vb); 55 | VectorPlayground.addVector(vc); 56 | 57 | // Animation 58 | let update = function() { 59 | 60 | if(settings.animating) { 61 | 62 | // Update the angle of the vector 63 | va.v.angle += 0.01; 64 | 65 | requestAnimationFrame(update); 66 | } 67 | 68 | } 69 | 70 | update(); 71 | 72 | // Set up the dat gui 73 | var gui = new dat.GUI(); 74 | var animationControl = gui.add(settings, 'animating'); 75 | animationControl.onChange(function(value) { 76 | if(value == true) { 77 | update(); 78 | } 79 | }); 80 | var catesianControl = gui.add(VectorPlayground, 'cartesian'); 81 | let prec = []; 82 | let f_unitX = gui.addFolder('End Unit X'); 83 | prec.push(f_unitX.add(settings.endUVX, 'x')); 84 | prec.push(f_unitX.add(settings.endUVX, 'y')); 85 | let f_unitY = gui.addFolder('End Unit Y'); 86 | prec.push(f_unitY.add(settings.endUVY, 'x')); 87 | prec.push(f_unitY.add(settings.endUVY, 'y')); 88 | let time = gui.add(settings, 'time', 0, settings.increments); 89 | time.onChange(function(value) { 90 | let diffX = settings.endUVX.subtractNew(settings.startUVX); 91 | let diffY = settings.endUVY.subtractNew(settings.startUVY); 92 | let incrementX = diffX.divideScalarNew(settings.increments); 93 | let incrementY = diffY.divideScalarNew(settings.increments); 94 | VectorPlayground.unitVectorX = settings.startUVX.addNew(incrementX.multiplyScalar(value)); 95 | VectorPlayground.unitVectorY = settings.startUVY.addNew(incrementY.multiplyScalar(value)); 96 | 97 | settings._unitVectorX.x = VectorPlayground.unitVectorX.x; 98 | settings._unitVectorX.y = VectorPlayground.unitVectorX.y; 99 | settings._unitVectorY.x = VectorPlayground.unitVectorY.x; 100 | settings._unitVectorY.y = VectorPlayground.unitVectorY.y; 101 | settings.vector.x = va.v.x; 102 | settings.vector.y = va.v.y; 103 | 104 | vb._v = settings._unitVectorX; 105 | vc._v = settings._unitVectorY; 106 | }); 107 | // let t_unitX = gui.addFolder('Translated Unit X'); 108 | // prec.push(t_unitX.add(settings._unitVectorX, 'x').listen()); 109 | // prec.push(t_unitX.add(settings._unitVectorX, 'y').listen()); 110 | // let t_unitY = gui.addFolder('Translated Unit Y'); 111 | // prec.push(t_unitY.add(settings._unitVectorY, 'x').listen()); 112 | // prec.push(t_unitY.add(settings._unitVectorY, 'y').listen()); 113 | // t_unitY.open(); 114 | // t_unitX.open(); 115 | let t_V = gui.addFolder('Vector'); 116 | prec.push(t_V.add(settings.vector, 'x').listen()); 117 | prec.push(t_V.add(settings.vector, 'y').listen()); 118 | var scaleControl = gui.add(settings, 'scale'); 119 | scaleControl.onChange(function(value) { 120 | VectorPlayground.scale = value; 121 | }); 122 | prec.forEach(function(control) { 123 | control.__precision = 3; 124 | control.__impliedStep = 0.1; 125 | }); 126 | gui.add('Rotate90'); 127 | 128 | updateCalculation(settings); 129 | }); 130 | 131 | 132 | 133 | 134 | 135 | class Gridline { 136 | constructor(x, y, v) { 137 | // The V indicates the directiont he dridline is pointing as well as its length 138 | this.v = v; 139 | // This class expects the gridline to be centered 140 | this.position = new Vector(x, y); 141 | this.startPosition = this.position.clone().subtract(this.v.divideScalarNew(2)); 142 | this.endPosition = this.position.clone().add(this.v.divideScalarNew(2)); 143 | 144 | this.lineWidth = 1; 145 | this.color = '#01a7f9'; 146 | 147 | if(x == 0 && y == 0) { 148 | this.trace = true; 149 | } 150 | 151 | } 152 | draw(playground) { 153 | let unitX = playground.scaledUnitVectorX; // iHat 154 | let unitY = playground.scaledUnitVectorY; // jHat 155 | let unitVector = unitX.addNew(unitY); 156 | let scale = playground.scale; 157 | let offset = playground.offset; // creating the offset 158 | let ctx = playground.mainCtx; 159 | 160 | ctx.beginPath(); 161 | ctx.lineWidth = this.lineWidth; 162 | ctx.strokeStyle = this.color; 163 | 164 | let translatedVectorA = this.startPosition.clone(); 165 | translatedVectorA.x = offset.x + (this.startPosition.x * unitX.x) + (this.startPosition.y * unitY.x); 166 | translatedVectorA.y = offset.y + (this.startPosition.x * unitX.y) + (this.startPosition.y * unitY.y); 167 | let translatedVectorB = this.endPosition.clone(); 168 | translatedVectorB.x = offset.x + (this.endPosition.x * unitX.x) + (this.endPosition.y * unitY.x); 169 | translatedVectorB.y = offset.y + (this.endPosition.x * unitX.y) + (this.endPosition.y * unitY.y); 170 | 171 | ctx.moveTo(translatedVectorA.x, translatedVectorA.y); 172 | ctx.lineTo(translatedVectorB.x, translatedVectorB.y); 173 | 174 | ctx.stroke(); 175 | } 176 | } 177 | 178 | class VectorPlayground extends _VectorPlayground { 179 | static init() { 180 | super.init(...arguments); 181 | 182 | this.setupGridlines(); 183 | } 184 | 185 | static setupGridlines() { 186 | this.gridlines = []; 187 | 188 | let xGridSize = 20; 189 | let yGridSize = 20; 190 | 191 | let xPos = 0; 192 | while(xPos < xGridSize / 2) { 193 | this.gridlines.push(new Gridline(xPos, 0, new Vector(0, yGridSize-2))); 194 | xPos++; 195 | } 196 | xPos = -1; 197 | while(xPos > -(xGridSize / 2)) { 198 | this.gridlines.push(new Gridline(xPos, 0, new Vector(0, yGridSize-2))); 199 | xPos--; 200 | } 201 | 202 | let yPos = 0; 203 | while(yPos < yGridSize / 2) { 204 | this.gridlines.push(new Gridline(0, yPos, new Vector(xGridSize-2, 0))); 205 | yPos++; 206 | } 207 | yPos = -1; 208 | while(yPos > -(yGridSize / 2)) { 209 | this.gridlines.push(new Gridline(0, yPos, new Vector(xGridSize-2, 0))); 210 | yPos--; 211 | } 212 | 213 | } 214 | 215 | static drawGrid() { 216 | super.drawGrid(); 217 | 218 | this.gridlines.forEach(function(gridline) { 219 | gridline.draw(this); 220 | }.bind(this)); 221 | } 222 | 223 | static set scale(scale) { 224 | if(typeof scale === 'number') { 225 | this._scale = scale; 226 | this.setupGridlines(); 227 | } 228 | } 229 | static get scale() { 230 | return this._scale || 1; 231 | } 232 | } 233 | 234 | class DrawingVector extends _DrawingVector { 235 | 236 | constructor() { 237 | super(...arguments); 238 | 239 | this._v = this.v; 240 | } 241 | 242 | draw(playground) { 243 | let textLabel = ''; 244 | if(this.textLabel) textLabel = `${this.textLabel} : `; 245 | this.label = `${textLabel}[ ${Math.round(this._v.x * 100) / 100}, ${Math.round(this._v.y * 100) / 100} ]`; 246 | super.draw(playground); 247 | } 248 | 249 | set textLabel(label) { 250 | this._textLabel = label; 251 | } 252 | get textLabel() { 253 | return this._textLabel || ''; 254 | } 255 | } 256 | 257 | window.VectorPlayground = VectorPlayground; 258 | -------------------------------------------------------------------------------- /demo/run.js: -------------------------------------------------------------------------------- 1 | import Vector from "../src/wtc-vector"; 2 | import DrawingVector from "./app/DrawingVector"; 3 | import VectorPlayground from "./app/VectorPlayground"; 4 | import {colours} from './app/colours'; 5 | 6 | window.Vector = Vector; 7 | 8 | let settings = { 9 | animating: false 10 | } 11 | window.settings = settings; 12 | 13 | function ready(fn) { 14 | if (document.readyState != 'loading'){ 15 | fn(); 16 | } else { 17 | document.addEventListener('DOMContentLoaded', fn); 18 | } 19 | } 20 | 21 | ready(function() { 22 | 23 | let va = new DrawingVector(-2, -2, colours[0]); 24 | let vb = new DrawingVector(1, 1, colours[1]); 25 | settings.va = va.v; 26 | settings.vb = vb.v; 27 | 28 | // Initiallising the world 29 | VectorPlayground.init(); 30 | 31 | // Add the vectors to stage 32 | VectorPlayground.addVector(va); 33 | VectorPlayground.addVector(vb); 34 | 35 | // Animation 36 | let update = function() { 37 | 38 | if(settings.animating) { 39 | 40 | // Update the angle of the vector 41 | va.v.angle += 0.01; 42 | 43 | requestAnimationFrame(update); 44 | } 45 | 46 | } 47 | 48 | update(); 49 | 50 | // Set up the dat gui 51 | var gui = new dat.GUI(); 52 | var animationControl = gui.add(settings, 'animating'); 53 | animationControl.onChange(function(value) { 54 | if(value == true) { 55 | update(); 56 | } 57 | }); 58 | let _va = gui.addFolder('Vector A'); 59 | let unitX_x = _va.add(settings.va, '_x').listen(); 60 | let unitX_y = _va.add(settings.va, '_y').listen(); 61 | let _vb = gui.addFolder('Vector B'); 62 | let unitY_x = _vb.add(settings.vb, 'x').listen(); 63 | let unitY_y = _vb.add(settings.vb, 'y').listen(); 64 | _va.open(); 65 | _vb.open(); 66 | }); 67 | -------------------------------------------------------------------------------- /demo/snowflake/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vector - Snowflake 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 |
14 |

Vector Snowflake

15 |

This example illustrates a how vector rotation relates to a sinewave and the motion of a snowflake falling through space.

16 |

Click around to add snowflakes to the stage.

17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /demo/snowflake/run.js: -------------------------------------------------------------------------------- 1 | import Vector from "../../src/wtc-vector"; 2 | import DrawingVector from "../app/DrawingVector"; 3 | import VectorPlayground from "../app/VectorPlayground"; 4 | import {colours} from '../app/colours'; 5 | import dat from 'dat-gui'; 6 | import updateCalculation from '../app/calcUpdate'; 7 | 8 | window.Vector = Vector; 9 | 10 | function ready(fn) { 11 | if (document.readyState != 'loading'){ 12 | fn(); 13 | } else { 14 | document.addEventListener('DOMContentLoaded', fn); 15 | } 16 | } 17 | 18 | 19 | let settings = { 20 | speed: 0.01, 21 | } 22 | 23 | ready(function() { 24 | 25 | 26 | let draw = function() { 27 | 28 | drawSnowflakes(); 29 | 30 | requestAnimationFrame(draw); 31 | } 32 | 33 | // These are the vectors that affect the snowflake's movement 34 | let factor = 2; 35 | let gravity = new DrawingVector(0, 1); 36 | let float = new DrawingVector(0.5, 0.5); 37 | 38 | settings.gravityV = gravity.v; 39 | settings.floatV = float.v; 40 | 41 | // Initiallising the world 42 | VectorPlayground.init(); 43 | 44 | let snowflakes = []; 45 | 46 | let addSnowklake = function(x, y) { 47 | let snowflake = { 48 | radius: 2 + Math.random() * 10, 49 | opacity: 20 + Math.random() * 60, 50 | pos: new Vector(x, y) 51 | } 52 | 53 | snowflakes.push(snowflake); 54 | } 55 | 56 | // Add the vectors to stage 57 | VectorPlayground.addVector(gravity); 58 | VectorPlayground.addVector(float); 59 | 60 | let ctx = VectorPlayground.mainCtx; 61 | let ctx2 = VectorPlayground.secondarCtx; 62 | 63 | let drawSnowflakes = function() { 64 | float.v.rotate(settings.speed); 65 | 66 | let dims = VectorPlayground.dimensions; 67 | let waveData = ctx2.getImageData(0,0,dims.width, dims.height); 68 | ctx2.clearRect(0,0,dims.width, dims.height0,0,dims.width, dims.height); 69 | ctx2.putImageData(waveData, 1, 0); 70 | ctx2.fillStyle = '#FFFFFF'; 71 | let pointV = new Vector(VectorPlayground.offset.width + float.v.length * VectorPlayground.scale, VectorPlayground.offset.height + float.v.y * VectorPlayground.scale); 72 | ctx2.fillRect(pointV.x, pointV.y, 1, 1); 73 | 74 | ctx.strokeStyle = '#FFFFFF'; 75 | let floatV = new Vector(VectorPlayground.offset.width + float.v.x * VectorPlayground.scale, VectorPlayground.offset.height + float.v.y * VectorPlayground.scale); 76 | ctx.moveTo(floatV.x, floatV.y+1); 77 | ctx.lineTo(pointV.x, pointV.y+1); 78 | ctx.stroke(); 79 | 80 | snowflakes.forEach(function(flake, index) { 81 | // Apply our forces 82 | let forces = new Vector(0,0); 83 | forces.add(gravity.v.divideScalarNew(factor)); 84 | forces.add(float.v.divideScalarNew(factor).multiply(new Vector(1, 0))); 85 | // Add our forces to the position 86 | flake.pos.add(forces); 87 | 88 | // draw the flake 89 | ctx.beginPath(); 90 | ctx.fillStyle = "rgba(255,255,255," + flake.opacity / 100 + ")"; 91 | ctx.arc(flake.pos.x, flake.pos.y, flake.radius, 0, 2 * Math.PI, false); 92 | ctx.fill(); 93 | 94 | if(flake.pos.y > window.innerHeight) { 95 | snowflakes.splice(index, 1); 96 | } 97 | 98 | 99 | }); 100 | } 101 | 102 | 103 | document.body.addEventListener('click', function(e) { 104 | addSnowklake(e.clientX, e.clientY); 105 | }); 106 | 107 | 108 | 109 | 110 | 111 | draw(); 112 | 113 | // Set up the dat gui 114 | let prec = []; 115 | var gui = new dat.GUI(); 116 | var speedControl = gui.add(settings, 'speed'); 117 | let t_gravV = gui.addFolder('Gravity Vector'); 118 | prec.push(t_gravV.add(settings.gravityV, 'length').listen()); 119 | let t_sinV = gui.addFolder('Sinewave Vector'); 120 | prec.push(t_sinV.add(settings.floatV, 'length').listen()); 121 | t_sinV.open(); 122 | prec.forEach(function(control) { 123 | control.__precision = 3; 124 | control.__impliedStep = 0.01; 125 | }); 126 | }); 127 | -------------------------------------------------------------------------------- /demo/unit-vectors/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vector - Unit vectors 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 |
14 |

Unit Vectors

15 |

This example shows what happens to different vectors when the unit vectors are changed.

16 |

Finding the new location of a vector is simply a matter of creating a matrix from the unit X and unit Y, and processing the vector using that function.

17 | 18 |
19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /demo/unit-vectors/run.js: -------------------------------------------------------------------------------- 1 | import Vector from "../../src/wtc-vector"; 2 | import _DrawingVector from "../app/DrawingVector"; 3 | import VectorPlayground from "../app/VectorPlayground"; 4 | import {colours, namedColours} from '../app/colours'; 5 | import dat from 'dat-gui'; 6 | 7 | window.Vector = Vector; 8 | 9 | let settings = { 10 | animating: false, 11 | unitX: 100, 12 | unitY: 100 13 | } 14 | 15 | class DrawingVector extends _DrawingVector { 16 | constructor(x, y, color, lineWidth = 2, secondary = false, basis, offset) { 17 | 18 | super(x, y, color, lineWidth); 19 | 20 | this.secondary = secondary; 21 | this.basis = basis; 22 | if(offset instanceof Vector) this.offset = offset; 23 | 24 | if(this.secondary) { 25 | this.label = ` ${basis === 'j' ? y : x}${basis} `; 26 | } else { 27 | this.label = `[ ${x}, ${y} ]`; 28 | } 29 | 30 | } 31 | 32 | } 33 | 34 | function ready(fn) { 35 | if (document.readyState != 'loading'){ 36 | fn(); 37 | } else { 38 | document.addEventListener('DOMContentLoaded', fn); 39 | } 40 | } 41 | ready(function() { 42 | 43 | // Setting up our basic vectors 44 | // Notice that they are so much smaller than previously. This is because 45 | // we're going to rely on the "world's" unit vector and scale to translate 46 | // these into visibly large values for rendering 47 | let vectors = []; 48 | vectors.push(new DrawingVector(1, -2, colours[0])); 49 | vectors.push(new DrawingVector(1, 0, namedColours.silver, 1, true, 'i')); 50 | vectors.push(new DrawingVector(0, -2, namedColours.silver, 1, true, 'j', new Vector(1, 0))); 51 | vectors.push(new DrawingVector(-3, 1, colours[1])); 52 | vectors.push(new DrawingVector(-3, 0, namedColours.silver, 1, true, 'i')); 53 | vectors.push(new DrawingVector(0, 1, namedColours.silver, 1, true, 'j', new Vector(-3, 0))); 54 | vectors.push(new DrawingVector(-0.5, -3, colours[2])); 55 | vectors.push(new DrawingVector(-0.5, 0, namedColours.silver, 1, true, 'i')); 56 | vectors.push(new DrawingVector(0, -3, namedColours.silver, 1, true, 'j', new Vector(-0.5, 0))); 57 | 58 | // Initiallising the world 59 | VectorPlayground.init(); 60 | 61 | VectorPlayground.unitVectorX = new Vector(1, 0); 62 | VectorPlayground.unitVectorY = new Vector(0, 1); 63 | 64 | // Add the vectors to stage 65 | vectors.forEach(function(vector) { 66 | VectorPlayground.addVector(vector); 67 | }); 68 | 69 | // Animation 70 | let update = function() { 71 | 72 | if(settings.animating) { 73 | 74 | // Update the angle of the vector 75 | vectors[0].v.angle += 0.01; 76 | 77 | requestAnimationFrame(update); 78 | } 79 | 80 | } 81 | 82 | update(); 83 | 84 | // Set up the dat gui 85 | dat.utils.requestAnimationFrame = window.requestAnimationFrame; 86 | let prec = []; 87 | var gui = new dat.GUI(); 88 | var animationControl = gui.add(settings, 'animating'); 89 | animationControl.onChange(function(value) { 90 | if(value == true) { 91 | update(); 92 | } 93 | }); 94 | var catesianControl = gui.add(VectorPlayground, 'cartesian'); 95 | let f_unitX = gui.addFolder('Unit X (i)'); 96 | prec.push(f_unitX.add(VectorPlayground.unitVectorX, '_x').listen()); 97 | prec.push(f_unitX.add(VectorPlayground.unitVectorX, '_y').listen()); 98 | prec.push(f_unitX.add(VectorPlayground.unitVectorX, 'length').listen()); 99 | let f_unitY = gui.addFolder('Unit Y (j)'); 100 | prec.push(f_unitY.add(VectorPlayground.unitVectorY, '_x').listen()); 101 | prec.push(f_unitY.add(VectorPlayground.unitVectorY, '_y').listen()); 102 | prec.push(f_unitY.add(VectorPlayground.unitVectorY, 'length').listen()); 103 | prec.forEach(function(control) { 104 | control.__precision = 3; 105 | control.__impliedStep = 0.05; 106 | }); 107 | window.prec = prec; 108 | }); 109 | -------------------------------------------------------------------------------- /docs/classes.list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Documentation Classes 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 57 | 58 | 59 |
60 |
61 | 62 | 63 |
64 | 65 |
66 | 67 | 68 |

Classes

69 |
70 | 71 |
72 | 73 |

74 | 75 |

76 | 77 | 78 |
79 | 80 | 81 |
82 |
83 | 84 | 85 | 86 | 87 |
88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
124 | 125 | 126 | 127 | 128 |
129 | 130 | 131 | 132 | 133 | 134 | 135 |

Classes

136 | 137 |
138 |
Vector
139 |
140 | 141 |
Vector
142 |
143 |
144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 |
158 | 159 |
160 | 161 | 162 | 163 | 164 |
165 |
166 | 167 |
168 | 169 | 170 |
171 | 172 |
173 | 174 | 175 |
176 |
177 | 178 | 179 | 193 | 194 | 195 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 289 | 290 | 291 | 292 | -------------------------------------------------------------------------------- /docs/demo: -------------------------------------------------------------------------------- 1 | ../demo/ -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-BoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-BoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-Italic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-Italic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-LightItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-LightItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-Regular-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /docs/global.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Documentation Global 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 64 | 65 | 66 |
67 |
68 | 69 | 70 |
71 | 72 |
73 | 74 | 75 |

Global

76 |
77 | 78 |
79 | 80 |

81 | 82 |

83 | 84 | 85 |
86 | 87 | 88 |
89 |
90 | 91 | 92 | 93 | 94 |
95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 |
131 | 132 | 133 | 134 | 135 |
136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 |

Members

149 | 150 |
151 | 152 |
153 |
154 |

multiplyScalar

155 | 156 | 157 |
158 |
159 | 160 |
161 |

Multiplies the vector by a scalar.

162 |
163 | 164 | 165 | 166 | 167 | 168 |
169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 |
205 | 206 | 207 | 208 |
209 | 210 | 211 | 212 |
213 |
214 |

multiplyScalarNew

215 | 216 | 217 |
218 |
219 | 220 |
221 |

Clones the vector and multiplies it by the provided scalar.

222 |
223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 |
265 | 266 | 267 | 268 |
269 | 270 |
271 | 272 | 273 | 274 |

Methods

275 | 276 |
277 | 278 |
279 |
280 |

multiplyScalar()

281 | 282 | 283 |
284 |
285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 |
297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 |
333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 |
349 | 350 | 351 | 352 |
353 |
354 |

multiplyScalarNew()

355 | 356 | 357 |
358 |
359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 |
371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 |
407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 |
423 | 424 | 425 | 426 |
427 |
428 |

rotate()

429 | 430 | 431 |
432 |
433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 |
445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 |
481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 |
497 | 498 | 499 | 500 |
501 |
502 |

rotateNew()

503 | 504 | 505 |
506 |
507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 |
519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 |
555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 |
571 | 572 | 573 | 574 |
575 |
576 |

rotateDeg()

577 | 578 | 579 |
580 |
581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 |
593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 |
629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 |
645 | 646 | 647 | 648 |
649 |
650 |

rotateDegNew()

651 | 652 | 653 |
654 |
655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 |
667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 |
703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 |
719 | 720 |
721 | 722 | 723 | 724 | 725 | 726 |
727 | 728 |
729 | 730 | 731 | 732 | 733 |
734 |
735 | 736 |
737 | 738 | 739 |
740 | 741 |
742 | 743 | 744 |
745 |
746 | 747 | 748 | 762 | 763 | 764 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 858 | 859 | 860 | 861 | -------------------------------------------------------------------------------- /docs/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /docs/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/docs/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Home 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Home

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |

30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 55 | 56 |
57 | 58 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /docs/quicksearch.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/scripts/fulltext-search-ui.js: -------------------------------------------------------------------------------- 1 | window.SearcherDisplay = (function($) { 2 | /** 3 | * This class provides support for displaying quick search text results to users. 4 | */ 5 | function SearcherDisplay() { } 6 | 7 | SearcherDisplay.prototype.init = function() { 8 | this._displayQuickSearch(); 9 | }; 10 | 11 | /** 12 | * This method creates the quick text search entry in navigation menu and wires all required events. 13 | */ 14 | SearcherDisplay.prototype._displayQuickSearch = function() { 15 | var quickSearch = $(document.createElement("iframe")), 16 | body = $("body"), 17 | self = this; 18 | 19 | quickSearch.attr("src", "quicksearch.html"); 20 | quickSearch.css("width", "0px"); 21 | quickSearch.css("height", "0px"); 22 | 23 | body.append(quickSearch); 24 | 25 | $(window).on("message", function(msg) { 26 | var msgData = msg.originalEvent.data; 27 | 28 | if (msgData.msgid != "docstrap.quicksearch.done") { 29 | return; 30 | } 31 | 32 | var results = msgData.results || []; 33 | 34 | self._displaySearchResults(results); 35 | }); 36 | 37 | function startSearch() { 38 | var searchTerms = $('#search-input').prop("value"); 39 | if (searchTerms) { 40 | quickSearch[0].contentWindow.postMessage({ 41 | "searchTerms": searchTerms, 42 | "msgid": "docstrap.quicksearch.start" 43 | }, "*"); 44 | } 45 | } 46 | 47 | $('#search-input').on('keyup', function(evt) { 48 | if (evt.keyCode != 13) { 49 | return; 50 | } 51 | startSearch(); 52 | return false; 53 | }); 54 | $('#search-submit').on('click', function() { 55 | startSearch(); 56 | return false; 57 | }); 58 | }; 59 | 60 | /** 61 | * This method displays the quick text search results in a modal dialog. 62 | */ 63 | SearcherDisplay.prototype._displaySearchResults = function(results) { 64 | var resultsHolder = $($("#searchResults").find(".modal-body")), 65 | fragment = document.createDocumentFragment(), 66 | resultsList = document.createElement("ul"); 67 | 68 | resultsHolder.empty(); 69 | 70 | for (var idx = 0; idx < results.length; idx++) { 71 | var result = results[idx], 72 | item = document.createElement("li"), 73 | link = document.createElement("a"); 74 | 75 | link.href = result.id; 76 | link.innerHTML = result.title; 77 | 78 | item.appendChild(link) 79 | resultsList.appendChild(item); 80 | } 81 | 82 | fragment.appendChild(resultsList); 83 | resultsHolder.append(fragment); 84 | 85 | $("#searchResults").modal({"show": true}); 86 | }; 87 | 88 | return new SearcherDisplay(); 89 | })($); 90 | -------------------------------------------------------------------------------- /docs/scripts/fulltext-search.js: -------------------------------------------------------------------------------- 1 | window.Searcher = (function() { 2 | function Searcher() { 3 | this._index = lunr(function () { 4 | this.field('title', {boost: 10}) 5 | this.field('body') 6 | this.ref('id') 7 | }) ; 8 | 9 | this._indexContent = undefined; 10 | } 11 | 12 | Searcher.prototype.init = function() { 13 | var self = this; 14 | 15 | $("script[type='text/x-docstrap-searchdb']").each(function(idx, item) { 16 | self._indexContent = JSON.parse(item.innerHTML); 17 | 18 | for (var entryId in self._indexContent) { 19 | self._index.add(self._indexContent[entryId]); 20 | } 21 | }); 22 | }; 23 | 24 | Searcher.prototype.search = function(searchTerm) { 25 | var results = [], 26 | searchResults = this._index.search(searchTerm); 27 | 28 | for (var idx = 0; idx < searchResults.length; idx++) { 29 | results.push(this._indexContent[searchResults[idx].ref]) 30 | } 31 | 32 | return results; 33 | }; 34 | 35 | return new Searcher(); 36 | })(); -------------------------------------------------------------------------------- /docs/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | /*global document */ 2 | (function() { 3 | var source = document.getElementsByClassName('prettyprint source linenums'); 4 | var i = 0; 5 | var lineNumber = 0; 6 | var lineId; 7 | var lines; 8 | var totalLines; 9 | var anchorHash; 10 | 11 | if (source && source[0]) { 12 | anchorHash = document.location.hash.substring(1); 13 | lines = source[0].getElementsByTagName('li'); 14 | totalLines = lines.length; 15 | 16 | for (; i < totalLines; i++) { 17 | lineNumber++; 18 | lineId = 'line' + lineNumber; 19 | lines[i].id = lineId; 20 | if (lineId === anchorHash) { 21 | lines[i].className += ' selected'; 22 | } 23 | } 24 | } 25 | })(); 26 | -------------------------------------------------------------------------------- /docs/scripts/lunr.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.7.1 3 | * Copyright (C) 2016 Oliver Nightingale 4 | * @license MIT 5 | */ 6 | !function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.7.1",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.utils.asString=function(t){return void 0===t||null===t?"":t.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(e){return arguments.length&&null!=e&&void 0!=e?Array.isArray(e)?e.map(function(e){return t.utils.asString(e).toLowerCase()}):e.toString().trim().toLowerCase().split(t.tokenizer.seperator):[]},t.tokenizer.seperator=/[\s\-]+/,t.tokenizer.load=function(t){var e=this.registeredFunctions[t];if(!e)throw new Error("Cannot load un-registered function: "+t);return e},t.tokenizer.label="default",t.tokenizer.registeredFunctions={"default":t.tokenizer},t.tokenizer.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing tokenizer: "+n),e.label=n,this.registeredFunctions[n]=e},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,r=0;n>r;r++){for(var o=t[r],s=0;i>s&&(o=this._stack[s](o,r,t),void 0!==o&&""!==o);s++);void 0!==o&&""!==o&&e.push(o)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(o===t)return r;t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r]}return o===t?r:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,r=e+Math.floor(i/2),o=this.elements[r];i>1;)t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r];return o>t?r:t>o?r+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,r=0,o=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>o-1||r>s-1)break;a[i]!==h[r]?a[i]h[r]&&r++:(n.add(a[i]),i++,r++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone();for(var r=0,o=n.toArray();rp;p++)c[p]===a&&d++;h+=d/f*l.boost}}this.tokenStore.add(a,{ref:o,tf:h})}n&&this.eventEmitter.emit("add",e,this)},t.Index.prototype.remove=function(t,e){var n=t[this._ref],e=void 0===e?!0:e;if(this.documentStore.has(n)){var i=this.documentStore.get(n);this.documentStore.remove(n),i.forEach(function(t){this.tokenStore.remove(t,n)},this),e&&this.eventEmitter.emit("remove",t,this)}},t.Index.prototype.update=function(t,e){var e=void 0===e?!0:e;this.remove(t,!1),this.add(t,!1),e&&this.eventEmitter.emit("update",t,this)},t.Index.prototype.idf=function(t){var e="@"+t;if(Object.prototype.hasOwnProperty.call(this._idfCache,e))return this._idfCache[e];var n=this.tokenStore.count(t),i=1;return n>0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(this.tokenizerFn(e)),i=new t.Vector,r=[],o=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*o,h=this,u=this.tokenStore.expand(e).reduce(function(n,r){var o=h.corpusTokens.indexOf(r),s=h.idf(r),u=1,l=new t.SortedSet;if(r!==e){var c=Math.max(3,r.length-e.length);u=1/Math.log(c)}o>-1&&i.insert(o,a*s*u);for(var f=h.tokenStore.get(r),d=Object.keys(f),p=d.length,v=0;p>v;v++)l.add(f[d[v]].ref);return n.union(l)},new t.SortedSet);r.push(u)},this);var a=r.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,r=new t.Vector,o=0;i>o;o++){var s=n.elements[o],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);r.insert(this.corpusTokens.indexOf(s),a*h)}return r},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,tokenizer:this.tokenizerFn.label,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",r=n+"[^aeiouy]*",o=i+"[aeiou]*",s="^("+r+")?"+o+r,a="^("+r+")?"+o+r+"("+o+")?$",h="^("+r+")?"+o+r+o+r,u="^("+r+")?"+i,l=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(u),p=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,g=/^(.+?)eed$/,m=/^(.+?)(ed|ing)$/,y=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),k=new RegExp("^"+r+i+"[^aeiouwxy]$"),x=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,F=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,_=/^(.+?)(s|t)(ion)$/,z=/^(.+?)e$/,O=/ll$/,P=new RegExp("^"+r+i+"[^aeiouwxy]$"),T=function(n){var i,r,o,s,a,h,u;if(n.length<3)return n;if(o=n.substr(0,1),"y"==o&&(n=o.toUpperCase()+n.substr(1)),s=p,a=v,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=g,a=m,s.test(n)){var T=s.exec(n);s=l,s.test(T[1])&&(s=y,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,u=k,a.test(n)?n+="e":h.test(n)?(s=y,n=n.replace(s,"")):u.test(n)&&(n+="e"))}if(s=x,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+t[r])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+e[r])}if(s=F,a=_,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=z,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=P,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=O,a=c,s.test(n)&&a.test(n)&&(s=y,n=n.replace(s,"")),"y"==o&&(n=o.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.generateStopWordFilter=function(t){var e=t.reduce(function(t,e){return t[e]=e,t},{});return function(t){return t&&e[t]!==t?t:void 0}},t.stopWordFilter=t.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){return t.replace(/^\W+/,"").replace(/\W+$/,"")},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t.charAt(0),r=t.slice(1);return i in n||(n[i]={docs:{}}),0===r.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(r,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /docs/scripts/prettify/prettify.js: -------------------------------------------------------------------------------- 1 | var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; 2 | (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= 3 | [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), 9 | l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, 10 | q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, 11 | q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, 12 | "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), 13 | a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} 14 | for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], 18 | "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], 19 | H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], 20 | J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ 21 | I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), 22 | ["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", 23 | /^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), 24 | ["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", 25 | hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= 26 | !k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p 0 ? top : 0); 102 | }); 103 | } 104 | 105 | //highlight on scroll 106 | var timeout; 107 | var highlightOnScroll = function(e) { 108 | if (!tocs.length) { 109 | return; 110 | } 111 | if (timeout) { 112 | clearTimeout(timeout); 113 | } 114 | timeout = setTimeout(function() { 115 | var top = $(window).scrollTop(), 116 | highlighted; 117 | for (var i = headingOffsets.length - 1; i >= 0; i--) { 118 | var isActive = tocs[i].hasClass(activeClassName); 119 | // at the end of the page, allow any shown header 120 | if (isActive && headingOffsets[i] >= maxScrollTo && top >= maxScrollTo) { 121 | return; 122 | } 123 | // if we have got to the first heading or the heading is the first one visible 124 | if (i === 0 || (headingOffsets[i] + headerHeight >= top && (headingOffsets[i - 1] + headerHeight <= top))) { 125 | // in the case that a heading takes up more than the visible height e.g. we are showing 126 | // only the one above, highlight the one above 127 | if (i > 0 && headingOffsets[i] - visibleHeight >= top) { 128 | i--; 129 | } 130 | $('a', self).removeClass(activeClassName); 131 | if (i >= 0) { 132 | highlighted = tocs[i].addClass(activeClassName); 133 | opts.onHighlight(highlighted); 134 | } 135 | break; 136 | } 137 | } 138 | }, 50); 139 | }; 140 | if (opts.highlightOnScroll) { 141 | $(window).bind('scroll', highlightOnScroll); 142 | $(window).bind('load resize', function() { 143 | calcHadingOffsets(); 144 | highlightOnScroll(); 145 | }); 146 | } 147 | 148 | return this.each(function() { 149 | //build TOC 150 | var el = $(this); 151 | var ul = $('
'); 152 | 153 | headings.each(function(i, heading) { 154 | var $h = $(heading); 155 | 156 | var anchor = $('').attr('id', opts.anchorName(i, heading, opts.prefix) + ANCHOR_PREFIX).insertBefore($h); 157 | 158 | var span = $('') 159 | .text(opts.headerText(i, heading, $h)); 160 | 161 | //build TOC item 162 | var a = $('') 163 | .append(span) 164 | .attr('href', '#' + opts.anchorName(i, heading, opts.prefix)) 165 | .bind('click', function(e) { 166 | scrollTo(e); 167 | el.trigger('selected', $(this).attr('href')); 168 | }); 169 | 170 | span.addClass(opts.itemClass(i, heading, $h, opts.prefix)); 171 | 172 | tocs.push(a); 173 | 174 | ul.append(a); 175 | }); 176 | el.html(ul); 177 | 178 | calcHadingOffsets(); 179 | }); 180 | }; 181 | 182 | 183 | jQuery.fn.toc.defaults = { 184 | container: 'body', 185 | selectors: 'h1,h2,h3', 186 | smoothScrolling: true, 187 | prefix: 'toc', 188 | onHighlight: function() {}, 189 | highlightOnScroll: true, 190 | navbarOffset: 0, 191 | anchorName: function(i, heading, prefix) { 192 | return prefix+i; 193 | }, 194 | headerText: function(i, heading, $heading) { 195 | return $heading.text(); 196 | }, 197 | itemClass: function(i, heading, $heading, prefix) { 198 | return prefix + '-' + $heading[0].tagName.toLowerCase(); 199 | } 200 | 201 | }; 202 | 203 | })(jQuery); 204 | -------------------------------------------------------------------------------- /docs/styles/jsdoc-default.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Open Sans'; 3 | font-weight: normal; 4 | font-style: normal; 5 | src: url('../fonts/OpenSans-Regular-webfont.eot'); 6 | src: 7 | local('Open Sans'), 8 | local('OpenSans'), 9 | url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), 10 | url('../fonts/OpenSans-Regular-webfont.woff') format('woff'), 11 | url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg'); 12 | } 13 | 14 | @font-face { 15 | font-family: 'Open Sans Light'; 16 | font-weight: normal; 17 | font-style: normal; 18 | src: url('../fonts/OpenSans-Light-webfont.eot'); 19 | src: 20 | local('Open Sans Light'), 21 | local('OpenSans Light'), 22 | url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'), 23 | url('../fonts/OpenSans-Light-webfont.woff') format('woff'), 24 | url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg'); 25 | } 26 | 27 | html 28 | { 29 | overflow: auto; 30 | background-color: #fff; 31 | font-size: 14px; 32 | } 33 | 34 | body 35 | { 36 | font-family: 'Open Sans', sans-serif; 37 | line-height: 1.5; 38 | color: #4d4e53; 39 | background-color: white; 40 | } 41 | 42 | a, a:visited, a:active { 43 | color: #0095dd; 44 | text-decoration: none; 45 | } 46 | 47 | a:hover { 48 | text-decoration: underline; 49 | } 50 | 51 | header 52 | { 53 | display: block; 54 | padding: 0px 4px; 55 | } 56 | 57 | tt, code, kbd, samp { 58 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 59 | } 60 | 61 | .class-description { 62 | font-size: 130%; 63 | line-height: 140%; 64 | margin-bottom: 1em; 65 | margin-top: 1em; 66 | } 67 | 68 | .class-description:empty { 69 | margin: 0; 70 | } 71 | 72 | #main { 73 | float: left; 74 | width: 70%; 75 | } 76 | 77 | article dl { 78 | margin-bottom: 40px; 79 | } 80 | 81 | article img { 82 | max-width: 100%; 83 | } 84 | 85 | section 86 | { 87 | display: block; 88 | background-color: #fff; 89 | padding: 12px 24px; 90 | border-bottom: 1px solid #ccc; 91 | margin-right: 30px; 92 | } 93 | 94 | .variation { 95 | display: none; 96 | } 97 | 98 | .signature-attributes { 99 | font-size: 60%; 100 | color: #aaa; 101 | font-style: italic; 102 | font-weight: lighter; 103 | } 104 | 105 | nav 106 | { 107 | display: block; 108 | float: right; 109 | margin-top: 28px; 110 | width: 30%; 111 | box-sizing: border-box; 112 | border-left: 1px solid #ccc; 113 | padding-left: 16px; 114 | } 115 | 116 | nav ul { 117 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif; 118 | font-size: 100%; 119 | line-height: 17px; 120 | padding: 0; 121 | margin: 0; 122 | list-style-type: none; 123 | } 124 | 125 | nav ul a, nav ul a:visited, nav ul a:active { 126 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 127 | line-height: 18px; 128 | color: #4D4E53; 129 | } 130 | 131 | nav h3 { 132 | margin-top: 12px; 133 | } 134 | 135 | nav li { 136 | margin-top: 6px; 137 | } 138 | 139 | footer { 140 | display: block; 141 | padding: 6px; 142 | margin-top: 12px; 143 | font-style: italic; 144 | font-size: 90%; 145 | } 146 | 147 | h1, h2, h3, h4 { 148 | font-weight: 200; 149 | margin: 0; 150 | } 151 | 152 | h1 153 | { 154 | font-family: 'Open Sans Light', sans-serif; 155 | font-size: 48px; 156 | letter-spacing: -2px; 157 | margin: 12px 24px 20px; 158 | } 159 | 160 | h2, h3.subsection-title 161 | { 162 | font-size: 30px; 163 | font-weight: 700; 164 | letter-spacing: -1px; 165 | margin-bottom: 12px; 166 | } 167 | 168 | h3 169 | { 170 | font-size: 24px; 171 | letter-spacing: -0.5px; 172 | margin-bottom: 12px; 173 | } 174 | 175 | h4 176 | { 177 | font-size: 18px; 178 | letter-spacing: -0.33px; 179 | margin-bottom: 12px; 180 | color: #4d4e53; 181 | } 182 | 183 | h5, .container-overview .subsection-title 184 | { 185 | font-size: 120%; 186 | font-weight: bold; 187 | letter-spacing: -0.01em; 188 | margin: 8px 0 3px 0; 189 | } 190 | 191 | h6 192 | { 193 | font-size: 100%; 194 | letter-spacing: -0.01em; 195 | margin: 6px 0 3px 0; 196 | font-style: italic; 197 | } 198 | 199 | table 200 | { 201 | border-spacing: 0; 202 | border: 0; 203 | border-collapse: collapse; 204 | } 205 | 206 | td, th 207 | { 208 | border: 1px solid #ddd; 209 | margin: 0px; 210 | text-align: left; 211 | vertical-align: top; 212 | padding: 4px 6px; 213 | display: table-cell; 214 | } 215 | 216 | thead tr 217 | { 218 | background-color: #ddd; 219 | font-weight: bold; 220 | } 221 | 222 | th { border-right: 1px solid #aaa; } 223 | tr > th:last-child { border-right: 1px solid #ddd; } 224 | 225 | .ancestors, .attribs { color: #999; } 226 | .ancestors a, .attribs a 227 | { 228 | color: #999 !important; 229 | text-decoration: none; 230 | } 231 | 232 | .clear 233 | { 234 | clear: both; 235 | } 236 | 237 | .important 238 | { 239 | font-weight: bold; 240 | color: #950B02; 241 | } 242 | 243 | .yes-def { 244 | text-indent: -1000px; 245 | } 246 | 247 | .type-signature { 248 | color: #aaa; 249 | } 250 | 251 | .name, .signature { 252 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 253 | } 254 | 255 | .details { margin-top: 14px; border-left: 2px solid #DDD; } 256 | .details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } 257 | .details dd { margin-left: 70px; } 258 | .details ul { margin: 0; } 259 | .details ul { list-style-type: none; } 260 | .details li { margin-left: 30px; padding-top: 6px; } 261 | .details pre.prettyprint { margin: 0 } 262 | .details .object-value { padding-top: 0; } 263 | 264 | .description { 265 | margin-bottom: 1em; 266 | margin-top: 1em; 267 | } 268 | 269 | .code-caption 270 | { 271 | font-style: italic; 272 | font-size: 107%; 273 | margin: 0; 274 | } 275 | 276 | .prettyprint 277 | { 278 | border: 1px solid #ddd; 279 | width: 80%; 280 | overflow: auto; 281 | } 282 | 283 | .prettyprint.source { 284 | width: inherit; 285 | } 286 | 287 | .prettyprint code 288 | { 289 | font-size: 100%; 290 | line-height: 18px; 291 | display: block; 292 | padding: 4px 12px; 293 | margin: 0; 294 | background-color: #fff; 295 | color: #4D4E53; 296 | } 297 | 298 | .prettyprint code span.line 299 | { 300 | display: inline-block; 301 | } 302 | 303 | .prettyprint.linenums 304 | { 305 | padding-left: 70px; 306 | -webkit-user-select: none; 307 | -moz-user-select: none; 308 | -ms-user-select: none; 309 | user-select: none; 310 | } 311 | 312 | .prettyprint.linenums ol 313 | { 314 | padding-left: 0; 315 | } 316 | 317 | .prettyprint.linenums li 318 | { 319 | border-left: 3px #ddd solid; 320 | } 321 | 322 | .prettyprint.linenums li.selected, 323 | .prettyprint.linenums li.selected * 324 | { 325 | background-color: lightyellow; 326 | } 327 | 328 | .prettyprint.linenums li * 329 | { 330 | -webkit-user-select: text; 331 | -moz-user-select: text; 332 | -ms-user-select: text; 333 | user-select: text; 334 | } 335 | 336 | .params .name, .props .name, .name code { 337 | color: #4D4E53; 338 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 339 | font-size: 100%; 340 | } 341 | 342 | .params td.description > p:first-child, 343 | .props td.description > p:first-child 344 | { 345 | margin-top: 0; 346 | padding-top: 0; 347 | } 348 | 349 | .params td.description > p:last-child, 350 | .props td.description > p:last-child 351 | { 352 | margin-bottom: 0; 353 | padding-bottom: 0; 354 | } 355 | 356 | .disabled { 357 | color: #454545; 358 | } 359 | -------------------------------------------------------------------------------- /docs/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: #006400; 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /docs/styles/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: #718c00; } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: #8959a8; } 17 | 18 | /* a comment */ 19 | .com { 20 | color: #8e908c; } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: #4271ae; } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: #f5871f; } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #4d4d4c; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #4d4d4c; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #4d4d4c; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /docs/styles/sunlight.dark.css: -------------------------------------------------------------------------------- 1 | /* global styles */ 2 | .sunlight-container { 3 | clear: both !important; 4 | position: relative !important; 5 | margin: 10px 0 !important; 6 | } 7 | .sunlight-code-container { 8 | clear: both !important; 9 | position: relative !important; 10 | border: none; 11 | border-color: #626262 !important; 12 | background-color: #262626 !important; 13 | } 14 | .sunlight-highlighted, .sunlight-container, .sunlight-container textarea { 15 | font-family: Consolas, Inconsolata, Monaco, "Courier New" !important; 16 | font-size: 12px !important; 17 | line-height: 15px !important; 18 | } 19 | .sunlight-highlighted, .sunlight-container textarea { 20 | color: #FFFFFF !important; 21 | margin: 0 !important; 22 | } 23 | .sunlight-container textarea { 24 | padding-left: 0 !important; 25 | margin-left: 0 !important; 26 | margin-right: 0 !important; 27 | padding-right: 0 !important; 28 | } 29 | .sunlight-code-container > .sunlight-highlighted { 30 | white-space: pre; 31 | overflow-x: auto; 32 | overflow-y: hidden; /* ie requires this wtf? */ 33 | } 34 | .sunlight-highlighted { 35 | z-index: 1; 36 | position: relative; 37 | } 38 | .sunlight-highlighted * { 39 | background: transparent; 40 | } 41 | .sunlight-line-number-margin { 42 | float: left !important; 43 | margin-right: 5px !important; 44 | margin-top: 0 !important; 45 | margin-bottom: 0 !important; 46 | padding: 0 !important; 47 | padding-right: 4px !important; 48 | padding-left: 4px !important; 49 | border-right: 1px solid #9A9A9A !important; 50 | background-color: #3E3E3E !important; 51 | color: #9A9A9A !important; 52 | text-align: right !important; 53 | position: relative; 54 | z-index: 3; 55 | } 56 | .sunlight-highlighted a, .sunlight-line-number-margin a { 57 | border: none !important; 58 | text-decoration: none !important; 59 | font-style: normal !important; 60 | padding: 0 !important; 61 | } 62 | .sunlight-line-number-margin a { 63 | color: inherit !important; 64 | } 65 | .sunlight-line-highlight-overlay { 66 | position: absolute; 67 | top: 0; 68 | left: 0; 69 | width: 100%; 70 | z-index: 0; 71 | } 72 | .sunlight-line-highlight-overlay div { 73 | height: 15px; 74 | width: 100%; 75 | } 76 | .sunlight-line-highlight-overlay .sunlight-line-highlight-active { 77 | background-color: #4B4B4B; 78 | } 79 | 80 | /* menu */ 81 | .sunlight-menu { 82 | background-color: #FFFFCC; 83 | color: #000000; 84 | } 85 | .sunlight-menu ul { 86 | margin: 0 !important; 87 | padding: 0 !important; 88 | list-style-type: none !important; 89 | } 90 | .sunlight-menu li { 91 | float: right !important; 92 | margin-left: 5px !important; 93 | } 94 | .sunlight-menu a, .sunlight-menu img { 95 | color: #000099 !important; 96 | text-decoration: none !important; 97 | border: none !important; 98 | } 99 | 100 | 101 | 102 | 103 | .sunlight-string, 104 | .sunlight-char, 105 | .sunlight-heredoc, 106 | .sunlight-heredocDeclaration, 107 | .sunlight-nowdoc, 108 | .sunlight-longString, 109 | .sunlight-rawString, 110 | .sunlight-binaryString, 111 | .sunlight-verbatimString, 112 | .sunlight-rawLongString, 113 | .sunlight-binaryLongString, 114 | .sunlight-diff .sunlight-added { 115 | color: #55EB54 !important; 116 | } 117 | .sunlight-operator, 118 | .sunlight-punctuation, 119 | .sunlight-delimiter { 120 | color: #B1EDEC !important; 121 | } 122 | .sunlight-ident, 123 | .sunlight-diff .sunlight-unchanged { 124 | color: #E0E0E0 !important; 125 | font-weight: bold !important; 126 | } 127 | .sunlight-comment, 128 | .sunlight-xmlDocCommentContent, 129 | .sunlight-nginx .sunlight-ssiCommand, 130 | .sunlight-sln .sunlight-formatDeclaration, 131 | .sunlight-diff .sunlight-mergeHeader, 132 | .sunlight-diff .sunlight-noNewLine { 133 | color: #787D31 !important; 134 | } 135 | .sunlight-number, 136 | .sunlight-cdata, 137 | .sunlight-guid, 138 | .sunlight-diff .sunlight-modified { 139 | color: #F7BA7E !important; 140 | font-weight: bold !important; 141 | } 142 | .sunlight-named-ident, 143 | .sunlight-xml .sunlight-attribute, 144 | .sunlight-constant, 145 | .sunlight-javascript .sunlight-globalVariable, 146 | .sunlight-globalObject, 147 | .sunlight-css .sunlight-id, 148 | .sunlight-python .sunlight-attribute, 149 | .sunlight-nginx .sunlight-context, 150 | .sunlight-httpd .sunlight-context, 151 | .sunlight-lisp .sunlight-declarationSpecifier, 152 | .sunlight-erlang .sunlight-userDefinedFunction, 153 | .sunlight-diff .sunlight-removed { 154 | color: #FBBDEE !important; 155 | font-weight: bold !important; 156 | } 157 | .sunlight-keyword, 158 | .sunlight-languageConstruct, 159 | .sunlight-specialOperator, 160 | .sunlight-xml .sunlight-tagName, 161 | .sunlight-xml .sunlight-operator, 162 | .sunlight-bash .sunlight-command, 163 | .sunlight-erlang .sunlight-moduleAttribute { 164 | color: #A3CCF7 !important; 165 | font-weight: bold !important; 166 | } 167 | .sunlight-shortOpenTag, 168 | .sunlight-openTag, 169 | .sunlight-closeTag, 170 | .sunlight-xmlOpenTag, 171 | .sunlight-xmlCloseTag, 172 | .sunlight-aspOpenTag, 173 | .sunlight-aspCloseTag, 174 | .sunlight-label, 175 | .sunlight-css .sunlight-importantFlag { 176 | background-color: #7373C1 !important; 177 | } 178 | .sunlight-content { 179 | color: #FFFFFF !important; 180 | font-weight: bold !important; 181 | } 182 | .sunlight-function, 183 | .sunlight-globalFunction, 184 | .sunlight-objective-c .sunlight-messageDestination, 185 | .sunlight-ruby .sunlight-specialFunction, 186 | .sunlight-6502asm .sunlight-illegalOpcode, 187 | .sunlight-powershell .sunlight-switch, 188 | .sunlight-lisp .sunlight-macro, 189 | .sunlight-lisp .sunlight-specialForm, 190 | .sunlight-lisp .sunlight-type, 191 | .sunlight-sln .sunlight-sectionName, 192 | .sunlight-diff .sunlight-header { 193 | color: #C8BBF1 !important; 194 | font-weight: bold !important; 195 | } 196 | .sunlight-variable, 197 | .sunlight-environmentVariable, 198 | .sunlight-specialVariable, 199 | .sunlight-objective-c .sunlight-messageArgumentName, 200 | .sunlight-lisp .sunlight-globalVariable, 201 | .sunlight-ruby .sunlight-globalVariable, 202 | .sunlight-ruby .sunlight-instanceVariable { 203 | color: #F5E5B0 !important; 204 | font-weight: bold !important; 205 | } 206 | .sunlight-regexLiteral, 207 | .sunlight-lisp .sunlight-operator, 208 | .sunlight-6502asm .sunlight-pseudoOp, 209 | .sunlight-erlang .sunlight-macro, 210 | .sunlight-diff .sunlight-rangeInfo { 211 | color: #E0F16A !important; 212 | } 213 | .sunlight-specialVariable { 214 | font-style: italic !important; 215 | font-weight: bold !important; 216 | } 217 | .sunlight-csharp .sunlight-pragma, 218 | .sunlight-preprocessorDirective, 219 | .sunlight-vb .sunlight-compilerDirective { 220 | color: #666363 !important; 221 | font-style: italic !important; 222 | } 223 | .sunlight-xmlDocCommentMeta, 224 | .sunlight-java .sunlight-annotation, 225 | .sunlight-scala .sunlight-annotation, 226 | .sunlight-docComment { 227 | color: #666363 !important; 228 | } 229 | .sunlight-quotedIdent, 230 | .sunlight-ruby .sunlight-subshellCommand, 231 | .sunlight-lisp .sunlight-keywordArgument, 232 | .sunlight-haskell .sunlight-infixOperator, 233 | .sunlight-erlang .sunlight-quotedAtom { 234 | color: #F8CA16 !important; 235 | } 236 | 237 | 238 | 239 | 240 | /* html/xml */ 241 | .sunlight-xml .sunlight-tagName, 242 | .sunlight-xml .sunlight-operator, 243 | .sunlight-xml .sunlight-attribute { 244 | font-weight: normal !important; 245 | } 246 | .sunlight-doctype { 247 | color: #DEB9B2 !important; 248 | font-style: italic !important; 249 | } 250 | .sunlight-xml .sunlight-entity { 251 | background-color: #E6E585 !important; 252 | color: #000000 !important; 253 | } 254 | 255 | /* javascript */ 256 | .sunlight-javascript .sunlight-reservedWord { 257 | font-style: italic !important; 258 | } 259 | 260 | /* css */ 261 | .sunlight-css .sunlight-element { 262 | color: #E9EE97 !important; 263 | } 264 | .sunlight-css .sunlight-microsoftFilterPrefix { 265 | color: #C9FF9F !important; 266 | } 267 | .sunlight-css .sunlight-rule { 268 | color: #0099FF !important; 269 | } 270 | .sunlight-css .sunlight-class { 271 | color: #E78282 !important; 272 | } 273 | .sunlight-css .sunlight-pseudoClass, .sunlight-css .sunlight-pseudoElement { 274 | color: #73D693 !important; 275 | } 276 | 277 | /* bash */ 278 | .sunlight-bash .sunlight-hashBang { 279 | color: #FFFF00 !important; 280 | } 281 | 282 | .sunlight-bash .sunlight-verbatimCommand { 283 | color: #BBA4EE !important; 284 | } 285 | .sunlight-bash .sunlight-variable, 286 | .sunlight-bash .sunlight-specialVariable { 287 | color: #ED8585 !important; 288 | } 289 | 290 | /* python */ 291 | .sunlight-python .sunlight-specialMethod { 292 | font-weight: bold !important; 293 | color: #B0A3C2; 294 | } 295 | 296 | /* ruby */ 297 | .sunlight-ruby .sunlight-symbol { 298 | font-weight: bold !important; 299 | color: #90EEA2 !important; 300 | } 301 | 302 | /* brainfuck */ 303 | .sunlight-brainfuck { 304 | font-weight: bold !important; 305 | color: #000000 !important; 306 | } 307 | .sunlight-brainfuck .sunlight-increment { 308 | background-color: #FF9900 !important; 309 | } 310 | .sunlight-brainfuck .sunlight-decrement { 311 | background-color: #FF99FF !important; 312 | } 313 | .sunlight-brainfuck .sunlight-incrementPointer { 314 | background-color: #FFFF99 !important; 315 | } 316 | .sunlight-brainfuck .sunlight-decrementPointer { 317 | background-color: #66CCFF !important; 318 | } 319 | .sunlight-brainfuck .sunlight-read { 320 | background-color: #FFFFFF !important; 321 | } 322 | .sunlight-brainfuck .sunlight-write { 323 | background-color: #99FF99 !important; 324 | } 325 | .sunlight-brainfuck .sunlight-openLoop, .sunlight-brainfuck .sunlight-closeLoop { 326 | background-color: #FFFFFF !important; 327 | } 328 | 329 | /* 6502 asm */ 330 | .sunlight-6502asm .sunlight-label { 331 | background: none !important; 332 | color: #FFFFFF !important; 333 | text-decoration: underline !important; 334 | } 335 | 336 | /* lisp */ 337 | .sunlight-lisp .sunlight-macro { 338 | font-style: italic !important; 339 | } 340 | 341 | /* erlang */ 342 | .sunlight-erlang .sunlight-atom { 343 | color: #FFFFFF !important; 344 | font-weight: bold !important; 345 | } -------------------------------------------------------------------------------- /docs/styles/sunlight.default.css: -------------------------------------------------------------------------------- 1 | /* global styles */ 2 | .sunlight-container { 3 | clear: both !important; 4 | position: relative !important; 5 | margin: 10px 0 !important; 6 | } 7 | .sunlight-code-container { 8 | clear: both !important; 9 | position: relative !important; 10 | border: none; 11 | border-color: #969696 !important; 12 | background-color: #FFFFFF !important; 13 | } 14 | .sunlight-highlighted, .sunlight-container, .sunlight-container textarea { 15 | font-family: Consolas, Inconsolata, Monaco, "Courier New" !important; 16 | font-size: 12px !important; 17 | line-height: 15px !important; 18 | } 19 | .sunlight-highlighted, .sunlight-container textarea { 20 | color: #000000 !important; 21 | margin: 0 !important; 22 | } 23 | .sunlight-container textarea { 24 | padding-left: 0 !important; 25 | margin-left: 0 !important; 26 | margin-right: 0 !important; 27 | padding-right: 0 !important; 28 | } 29 | .sunlight-code-container > .sunlight-highlighted { 30 | white-space: pre; 31 | overflow-x: auto; 32 | overflow-y: hidden; /* ie requires this wtf? */ 33 | } 34 | .sunlight-highlighted { 35 | z-index: 1; 36 | position: relative; 37 | } 38 | .sunlight-highlighted * { 39 | background: transparent; 40 | } 41 | .sunlight-line-number-margin { 42 | float: left !important; 43 | margin-right: 5px !important; 44 | margin-top: 0 !important; 45 | margin-bottom: 0 !important; 46 | padding: 0 !important; 47 | padding-right: 4px !important; 48 | padding-left: 4px !important; 49 | border-right: 1px solid #CCCCCC !important; 50 | background-color: #EEEEEE !important; 51 | color: #848484 !important; 52 | text-align: right !important; 53 | position: relative; 54 | z-index: 3; 55 | } 56 | .sunlight-highlighted a, .sunlight-line-number-margin a { 57 | border: none !important; 58 | text-decoration: none !important; 59 | font-weight: normal !important; 60 | font-style: normal !important; 61 | padding: 0 !important; 62 | } 63 | .sunlight-line-number-margin a { 64 | color: inherit !important; 65 | } 66 | .sunlight-line-highlight-overlay { 67 | position: absolute; 68 | top: 0; 69 | left: 0; 70 | width: 100%; 71 | z-index: 0; 72 | } 73 | .sunlight-line-highlight-overlay div { 74 | height: 15px; 75 | width: 100%; 76 | } 77 | .sunlight-line-highlight-overlay .sunlight-line-highlight-active { 78 | background-color: #E7FCFA; 79 | } 80 | 81 | /* menu */ 82 | .sunlight-menu { 83 | background-color: #FFFFCC; 84 | color: #000000; 85 | } 86 | .sunlight-menu ul { 87 | margin: 0 !important; 88 | padding: 0 !important; 89 | list-style-type: none !important; 90 | } 91 | .sunlight-menu li { 92 | float: right !important; 93 | margin-left: 5px !important; 94 | } 95 | .sunlight-menu a, .sunlight-menu img { 96 | color: #000099 !important; 97 | text-decoration: none !important; 98 | border: none !important; 99 | } 100 | 101 | 102 | 103 | 104 | .sunlight-string, 105 | .sunlight-char, 106 | .sunlight-heredoc, 107 | .sunlight-heredocDeclaration, 108 | .sunlight-nowdoc, 109 | .sunlight-longString, 110 | .sunlight-rawString, 111 | .sunlight-binaryString, 112 | .sunlight-rawLongString, 113 | .sunlight-binaryLongString, 114 | .sunlight-verbatimString, 115 | .sunlight-diff .sunlight-removed { 116 | color: #990000 !important; 117 | } 118 | 119 | .sunlight-ident, 120 | .sunlight-operator, 121 | .sunlight-punctuation, 122 | .sunlight-delimiter, 123 | .sunlight-diff .sunlight-unchanged { 124 | color: #000000 !important; 125 | } 126 | 127 | .sunlight-comment, 128 | .sunlight-xmlDocCommentContent, 129 | .sunlight-nginx .sunlight-ssiCommand, 130 | .sunlight-sln .sunlight-formatDeclaration, 131 | .sunlight-diff .sunlight-added { 132 | color: #009900 !important; 133 | } 134 | .sunlight-number, 135 | .sunlight-guid, 136 | .sunlight-cdata { 137 | color: #CC6600 !important; 138 | } 139 | 140 | .sunlight-named-ident, 141 | .sunlight-constant, 142 | .sunlight-javascript .sunlight-globalVariable, 143 | .sunlight-globalObject, 144 | .sunlight-python .sunlight-attribute, 145 | .sunlight-nginx .sunlight-context, 146 | .sunlight-httpd .sunlight-context, 147 | .sunlight-haskell .sunlight-class, 148 | .sunlight-haskell .sunlight-type, 149 | .sunlight-lisp .sunlight-declarationSpecifier, 150 | .sunlight-erlang .sunlight-userDefinedFunction, 151 | .sunlight-diff .sunlight-header { 152 | color: #2B91AF !important; 153 | } 154 | .sunlight-keyword, 155 | .sunlight-languageConstruct, 156 | .sunlight-css 157 | .sunlight-element, 158 | .sunlight-bash .sunlight-command, 159 | .sunlight-specialOperator, 160 | .sunlight-erlang .sunlight-moduleAttribute, 161 | .sunlight-xml .sunlight-tagName, 162 | .sunlight-xml .sunlight-operator, 163 | .sunlight-diff .sunlight-modified { 164 | color: #0000FF !important; 165 | } 166 | .sunlight-shortOpenTag, 167 | .sunlight-openTag, 168 | .sunlight-closeTag, 169 | .sunlight-xmlOpenTag, 170 | .sunlight-xmlCloseTag, 171 | .sunlight-aspOpenTag, 172 | .sunlight-aspCloseTag, 173 | .sunlight-label, 174 | .sunlight-css .sunlight-importantFlag { 175 | background-color: #FFFF99 !important; 176 | color: #000000 !important; 177 | } 178 | .sunlight-function, 179 | .sunlight-globalFunction, 180 | .sunlight-ruby .sunlight-specialFunction, 181 | .sunlight-objective-c .sunlight-messageDestination, 182 | .sunlight-6502asm .sunlight-illegalOpcode, 183 | .sunlight-powershell .sunlight-switch, 184 | .sunlight-lisp .sunlight-macro, 185 | .sunlight-lisp .sunlight-specialForm, 186 | .sunlight-lisp .sunlight-type, 187 | .sunlight-sln .sunlight-sectionName, 188 | .sunlight-diff .sunlight-rangeInfo { 189 | color: #B069AF !important; 190 | } 191 | 192 | .sunlight-variable, 193 | .sunlight-specialVariable, 194 | .sunlight-environmentVariable, 195 | .sunlight-objective-c .sunlight-messageArgumentName, 196 | .sunlight-lisp .sunlight-globalVariable, 197 | .sunlight-ruby .sunlight-globalVariable, 198 | .sunlight-ruby .sunlight-instanceVariable, 199 | .sunlight-sln .sunlight-operator { 200 | color: #325484 !important; 201 | } 202 | .sunlight-regexLiteral, 203 | .sunlight-lisp .sunlight-operator, 204 | .sunlight-6502asm .sunlight-pseudoOp, 205 | .sunlight-erlang .sunlight-macro { 206 | color: #FF00B2 !important; 207 | } 208 | .sunlight-specialVariable { 209 | font-style: italic !important; 210 | font-weight: bold !important; 211 | } 212 | .sunlight-csharp .sunlight-pragma, 213 | .sunlight-preprocessorDirective, 214 | .sunlight-vb .sunlight-compilerDirective, 215 | .sunlight-diff .sunlight-mergeHeader, 216 | .sunlight-diff .sunlight-noNewLine { 217 | color: #999999 !important; 218 | font-style: italic !important; 219 | } 220 | .sunlight-xmlDocCommentMeta, 221 | .sunlight-java .sunlight-annotation, 222 | .sunlight-scala .sunlight-annotation, 223 | .sunlight-docComment { 224 | color: #808080 !important; 225 | } 226 | .sunlight-quotedIdent, 227 | .sunlight-ruby .sunlight-subshellCommand, 228 | .sunlight-lisp .sunlight-keywordArgument, 229 | .sunlight-haskell .sunlight-infixOperator, 230 | .sunlight-erlang .sunlight-quotedAtom { 231 | color: #999900 !important; 232 | } 233 | 234 | 235 | 236 | /* xml */ 237 | .sunlight-xml .sunlight-string { 238 | color: #990099 !important; 239 | } 240 | .sunlight-xml .sunlight-attribute { 241 | color: #FF0000 !important; 242 | } 243 | .sunlight-xml .sunlight-entity { 244 | background-color: #EEEEEE !important; 245 | color: #000000 !important; 246 | border: 1px solid #000000 !important; 247 | } 248 | .sunlight-xml .sunlight-doctype { 249 | color: #2B91AF !important; 250 | } 251 | 252 | /* javascript */ 253 | .sunlight-javascript .sunlight-reservedWord { 254 | font-style: italic !important; 255 | } 256 | 257 | /* css */ 258 | .sunlight-css .sunlight-microsoftFilterPrefix { 259 | color: #FF00FF !important; 260 | } 261 | .sunlight-css .sunlight-rule { 262 | color: #0099FF !important; 263 | } 264 | .sunlight-css .sunlight-keyword { 265 | color: #4E65B8 !important; 266 | } 267 | .sunlight-css .sunlight-class { 268 | color: #FF0000 !important; 269 | } 270 | .sunlight-css .sunlight-id { 271 | color: #8A8E13 !important; 272 | } 273 | .sunlight-css .sunlight-pseudoClass, 274 | .sunlight-css .sunlight-pseudoElement { 275 | color: #368B87 !important; 276 | } 277 | 278 | /* bash */ 279 | .sunlight-bash .sunlight-hashBang { 280 | color: #3D97F5 !important; 281 | } 282 | .sunlight-bash .sunlight-verbatimCommand { 283 | color: #999900 !important; 284 | } 285 | .sunlight-bash .sunlight-variable, 286 | .sunlight-bash .sunlight-specialVariable { 287 | color: #FF0000 !important; 288 | } 289 | 290 | /* python */ 291 | .sunlight-python .sunlight-specialMethod { 292 | font-weight: bold !important; 293 | color: #A07DD3; 294 | } 295 | 296 | /* ruby */ 297 | .sunlight-ruby .sunlight-symbol { 298 | font-weight: bold !important; 299 | color: #ED7272 !important; 300 | } 301 | 302 | /* brainfuck */ 303 | .sunlight-brainfuck { 304 | font-weight: bold !important; 305 | color: #000000 !important; 306 | } 307 | .sunlight-brainfuck .sunlight-increment { 308 | background-color: #FF9900 !important; 309 | } 310 | .sunlight-brainfuck .sunlight-decrement { 311 | background-color: #FF99FF !important; 312 | } 313 | .sunlight-brainfuck .sunlight-incrementPointer { 314 | background-color: #FFFF99 !important; 315 | } 316 | .sunlight-brainfuck .sunlight-decrementPointer { 317 | background-color: #66CCFF !important; 318 | } 319 | .sunlight-brainfuck .sunlight-read { 320 | background-color: #FFFFFF !important; 321 | } 322 | .sunlight-brainfuck .sunlight-write { 323 | background-color: #99FF99 !important; 324 | } 325 | .sunlight-brainfuck .sunlight-openLoop, .sunlight-brainfuck .sunlight-closeLoop { 326 | background-color: #FFFFFF !important; 327 | } 328 | 329 | /* 6502 asm */ 330 | .sunlight-6502asm .sunlight-label { 331 | font-weight: bold !important; 332 | color: #000000 !important; 333 | background: none !important; 334 | } 335 | 336 | /* lisp */ 337 | .sunlight-lisp .sunlight-macro { 338 | font-style: italic !important; 339 | } 340 | 341 | /* erlang */ 342 | .sunlight-erlang .sunlight-atom { 343 | font-weight: bold !important; 344 | } -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | YAY GULP! 3 | ======================================= 4 | - *Author* liamegan 5 | - *email* liam@wethecollective.com 6 | - *Created* 2015-08-24 13:39:12 7 | - *namespace* . 8 | - *Requirements* . 9 | - *Description* . 10 | - *Edited by* Liam Egan 11 | - *Edited* 2016-06-21 12:39:20 12 | - *Version* 0.1 13 | */ 14 | var gulp = require('gulp'), 15 | babel = require('gulp-babel'), 16 | babelify = require('babelify'), 17 | browserify = require('browserify'), 18 | buffer = require('vinyl-buffer'), 19 | notify = require('gulp-notify'), 20 | source = require('vinyl-source-stream'), 21 | jsdoc = require("gulp-jsdoc3"), 22 | webserver = require('gulp-webserver'); 23 | 24 | var files = { 25 | es6 : [{ 26 | entries: './demo/run.js', 27 | output: './demo' 28 | }, { 29 | entries: './demo/addition/run.js', 30 | output: './demo/addition' 31 | }, { 32 | entries: './demo/unit-vectors/run.js', 33 | output: './demo/unit-vectors' 34 | }, { 35 | entries: './demo/linear-transformations/run.js', 36 | output: './demo/linear-transformations' 37 | }, { 38 | entries: './demo/matrix-multiplication/run.js', 39 | output: './demo/matrix-multiplication' 40 | }, { 41 | entries: './demo/snowflake/run.js', 42 | output: './demo/snowflake' 43 | }], 44 | jsdoc : { 45 | src: './src/*.js', 46 | opt: './doc' 47 | }, 48 | watch : [ 49 | 'src/wtc-vector.js', 50 | 'demo/app/VectorPlayground.js', 51 | 'demo/app/DrawingVector.js' 52 | ] 53 | } 54 | 55 | gulp.task('build', function() { 56 | 57 | files.es6.forEach(function(entry) { 58 | var b = browserify({ 59 | entries: entry.entries, 60 | debug: true 61 | }); 62 | 63 | b.transform("babelify", {presets: ["env"]}); 64 | return b.bundle() 65 | .pipe(source('pub.js')) 66 | .pipe(buffer()) 67 | .pipe(gulp.dest(entry.output)) 68 | .pipe(notify('✓ <%= file.relative %> ready.')); 69 | }); 70 | 71 | }); 72 | 73 | 74 | /* 75 | Watch 76 | */ 77 | gulp.task('watch', () => { 78 | 79 | files.es6.forEach(function(entry) { 80 | 81 | let entries = [entry.entries].concat(files.watch); 82 | gulp.watch(entries, function() { 83 | 84 | var b = browserify({ 85 | entries: entry.entries, 86 | debug: true 87 | }); 88 | 89 | 90 | b.transform("babelify", {presets: ["es2015"]}); 91 | return b.bundle() 92 | .on('error', function(e) { 93 | // If you want details of the error in the console 94 | console.log(e.toString()) 95 | 96 | this.emit('end') 97 | }) 98 | .pipe(source('pub.js')) 99 | .pipe(buffer()) 100 | .pipe(gulp.dest(entry.output)) 101 | .pipe(notify('✓ <%= file.relative %> ready.')); 102 | }) 103 | }); 104 | 105 | gulp.src('demo') 106 | .pipe(webserver({ 107 | fallback: 'index.html', 108 | host: '0.0.0.0', 109 | port: 1337, 110 | livereload: true, 111 | open: 'http://0.0.0.0:1337/' 112 | })); 113 | }); 114 | 115 | gulp.task('document', function(cb) { 116 | 117 | var config = require('./jsdoc.json'); 118 | gulp.src(['README.md', './src/**/*.js'], {read: false}) 119 | .pipe(jsdoc(config, cb)); 120 | }) 121 | -------------------------------------------------------------------------------- /jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": true 4 | }, 5 | "opts": { 6 | "destination": "./docs", 7 | "private": true 8 | }, 9 | "plugins": [ 10 | "plugins/markdown" 11 | ], 12 | "templates": { 13 | "cleverLinks": false, 14 | "monospaceLinks": false, 15 | "default": { 16 | "outputSourceFiles": true 17 | }, 18 | "sort": false, 19 | "theme": "slate", 20 | "navType": "inline", 21 | "linenums": true, 22 | "dateFormat": "MMMM Do YYYY, h:mm:ss a" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wtc-vector", 3 | "version": "0.1.10", 4 | "description": "ES6 2D Vector Class", 5 | "main": "dist/wtc-vector.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "npx babel src/ --presets @babel/env --out-dir dist", 9 | "build-es5": "browserify ./src/wtc-vector.js --standalone WTCVector > ./dist/es5-bundle.js", 10 | "prepublish": "npm run build && npm run build-es5" 11 | }, 12 | "devDependencies": { 13 | "@babel/cli": "^7.5.5", 14 | "@babel/core": "^7.5.5", 15 | "@babel/preset-env": "^7.5.5", 16 | "babelify": "^10.0.0", 17 | "browserify": "^16.3.0", 18 | "dat-gui": "^0.5.0", 19 | "dat.gui": "^0.7.6", 20 | "gulp": "^4.0.2", 21 | "gulp-babel": "^8.0.0", 22 | "gulp-jsdoc3": "^2.0.0", 23 | "gulp-notify": "^3.2.0", 24 | "gulp-uglify": "^3.0.2", 25 | "gulp-webserver": "^0.9.1", 26 | "jaguarjs-jsdoc": "^1.1.0", 27 | "vinyl-buffer": "^1.0.1", 28 | "vinyl-source-stream": "^2.0.0", 29 | "watchify": "^3.11.1" 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "git+https://github.com/wethegit/wtc-vector.git" 34 | }, 35 | "keywords": [ 36 | "wtc", 37 | "math", 38 | "vector", 39 | "vector2d" 40 | ], 41 | "homepage": "https://github.com/wethegit/wtc-vector#readme", 42 | "author": "Liam Egan (http://wethecollective.com)", 43 | "license": "ISC", 44 | "browserify": { 45 | "transform": [ 46 | "babelify" 47 | ] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wethegit/wtc-vector/da67a0371ff47caf3aafc49a074b4ffe939fa619/src/.DS_Store -------------------------------------------------------------------------------- /src/wtc-vector.js: -------------------------------------------------------------------------------- 1 | const conversionFactor = 180 / Math.PI; 2 | 3 | var radianToDegrees = function(radian) { 4 | return radian * conversionFactor; 5 | } 6 | 7 | var degreesToRadian = function(degrees) { 8 | return degrees / conversionFactor; 9 | } 10 | 11 | /** 12 | * A basic 2D Vector class that provides simple algebraic functionality in the form 13 | * of 2D Vectors. 14 | * 15 | * We use Getters/setters for both principle properties (x & y) as well as virtual 16 | * properties (rotation, length etc.). 17 | * 18 | * @class Vector 19 | * @author Liam Egan 20 | * @version 0.1.1 21 | * @created Dec 19, 2016 22 | */ 23 | class Vector { 24 | 25 | /** 26 | * The Vector Class constructor 27 | * 28 | * @constructor 29 | * @param {number} x The x coord 30 | * @param {number} y The y coord 31 | */ 32 | constructor(x, y){ 33 | this.x = x; 34 | this.y = y; 35 | } 36 | 37 | /** 38 | * Resets the vector coordinates 39 | * 40 | * @public 41 | * @param {number} x The x coord 42 | * @param {number} y The y coord 43 | */ 44 | reset(x, y) { 45 | this.x = x; 46 | this.y = y; 47 | } 48 | 49 | /** 50 | * Resets the vector coordinates to another vector object 51 | * 52 | * @public 53 | * @param {Vector} v The vector object to use to reset the coordinates 54 | */ 55 | resetToVector(v) { 56 | if(v instanceof Vector) { 57 | this.x = v.x; 58 | this.y = v.y; 59 | } 60 | } 61 | 62 | /** 63 | * Clones the vector 64 | * 65 | * @public 66 | * @return {Vector} The cloned vector 67 | */ 68 | clone() { 69 | return new Vector(this.x, this.y); 70 | } 71 | 72 | /** 73 | * Adds one vector to another. 74 | * 75 | * @public 76 | * @chainable 77 | * @param {Vector} vector The vector to add to this one 78 | * @return {Vector} Returns itself, modified 79 | */ 80 | add(vector) { 81 | this.x += vector.x; 82 | this.y += vector.y; 83 | return this; 84 | } 85 | /** 86 | * Clones the vector and adds the vector to it instead 87 | * 88 | * @public 89 | * @chainable 90 | * @param {Vector} vector The vector to add to this one 91 | * @return {Vector} Returns the clone of itself, modified 92 | */ 93 | addNew(vector) { 94 | let v = this.clone(); 95 | return v.add(vector); 96 | } 97 | 98 | /** 99 | * Adds a scalar to the vector, modifying both the x and y 100 | * 101 | * @public 102 | * @chainable 103 | * @param {number} scalar The scalar to add to the vector 104 | * @return {Vector} Returns itself, modified 105 | */ 106 | addScalar(scalar) { 107 | return this.add(new Vector(scalar, scalar)); 108 | } 109 | /** 110 | * Clones the vector and adds the scalar to it instead 111 | * 112 | * @public 113 | * @chainable 114 | * @param {number} scalar The scalar to add to the vector 115 | * @return {Vector} Returns the clone of itself, modified 116 | */ 117 | addScalarNew(scalar) { 118 | let v = this.clone(); 119 | return v.addScalar(scalar); 120 | } 121 | 122 | /** 123 | * Subtracts one vector from another. 124 | * 125 | * @public 126 | * @chainable 127 | * @param {Vector} vector The vector to subtract from this one 128 | * @return {Vector} Returns itself, modified 129 | */ 130 | subtract(vector) { 131 | this.x -= vector.x; 132 | this.y -= vector.y; 133 | return this; 134 | } 135 | /** 136 | * Clones the vector and subtracts the vector from it instead 137 | * 138 | * @public 139 | * @chainable 140 | * @param {Vector} vector The vector to subtract from this one 141 | * @return {Vector} Returns the clone of itself, modified 142 | */ 143 | subtractNew(vector) { 144 | let v = this.clone(); 145 | return v.subtract(vector); 146 | } 147 | 148 | /** 149 | * Subtracts a scalar from the vector, modifying both the x and y 150 | * 151 | * @public 152 | * @chainable 153 | * @param {number} scalar The scalar to subtract from the vector 154 | * @return {Vector} Returns itself, modified 155 | */ 156 | subtractScalar(scalar) { 157 | return this.subtract(new Vector(scalar, scalar)); 158 | } 159 | /** 160 | * Clones the vector and subtracts the scalar from it instead 161 | * 162 | * @public 163 | * @chainable 164 | * @param {number} scalar The scalar to add to the vector 165 | * @return {Vector} Returns the clone of itself, modified 166 | */ 167 | subtractScalarNew(scalar) { 168 | let v = this.clone(); 169 | return v.subtractScalar(scalar); 170 | } 171 | 172 | /** 173 | * Divides one vector by another. 174 | * 175 | * @public 176 | * @chainable 177 | * @param {Vector} vector The vector to divide this by 178 | * @return {Vector} Returns itself, modified 179 | */ 180 | divide(vector) { 181 | if(vector.x !== 0) { 182 | this.x /= vector.x 183 | } else { 184 | this.x = 0; 185 | } 186 | if(vector.y !== 0) { 187 | this.y /= vector.y 188 | } else { 189 | this.y = 0; 190 | } 191 | return this; 192 | } 193 | /** 194 | * Clones the vector and divides it by the vector instead 195 | * 196 | * @public 197 | * @chainable 198 | * @param {Vector} vector The vector to divide the clone by 199 | * @return {Vector} Returns the clone of itself, modified 200 | */ 201 | divideNew(vector) { 202 | let v = this.clone(); 203 | return v.divide(vector); 204 | } 205 | 206 | /** 207 | * Divides the vector by a scalar. 208 | * 209 | * @public 210 | * @chainable 211 | * @param {number} scalar The scalar to divide both x and y by 212 | * @return {Vector} Returns itself, modified 213 | */ 214 | divideScalar(scalar) { 215 | var v = new Vector(scalar, scalar); 216 | return this.divide(v); 217 | } 218 | /** 219 | * Clones the vector and divides it by the provided scalar. 220 | * 221 | * @public 222 | * @chainable 223 | * @param {number} scalar The scalar to divide both x and y by 224 | * @return {Vector} Returns the clone of itself, modified 225 | */ 226 | divideScalarNew(scalar) { 227 | let v = this.clone(); 228 | return v.divideScalar(scalar); 229 | } 230 | 231 | /** 232 | * Multiplies one vector by another. 233 | * 234 | * @public 235 | * @chainable 236 | * @param {Vector} vector The vector to multiply this by 237 | * @return {Vector} Returns itself, modified 238 | */ 239 | multiply(vector) { 240 | this.x *= vector.x; 241 | this.y *= vector.y; 242 | return this; 243 | } 244 | /** 245 | * Clones the vector and multiplies it by the vector instead 246 | * 247 | * @public 248 | * @chainable 249 | * @param {Vector} vector The vector to multiply the clone by 250 | * @return {Vector} Returns the clone of itself, modified 251 | */ 252 | multiplyNew(vector) { 253 | let v = this.clone(); 254 | return v.multiply(vector); 255 | } 256 | 257 | /** 258 | * Multiplies the vector by a scalar. 259 | * 260 | * @public 261 | * @chainable 262 | * @param {number} scalar The scalar to multiply both x and y by 263 | * @return {Vector} Returns itself, modified 264 | */ 265 | multiplyScalar(scalar) { 266 | var v = new Vector(scalar, scalar); 267 | return this.multiply(v); 268 | } 269 | /** 270 | * Clones the vector and multiplies it by the provided scalar. 271 | * 272 | * @public 273 | * @chainable 274 | * @param {number} scalar The scalar to multiply both x and y by 275 | * @return {Vector} Returns the clone of itself, modified 276 | */ 277 | multiplyScalarNew(scalar) { 278 | let v = this.clone(); 279 | return v.multiplyScalar(scalar); 280 | } 281 | 282 | /** 283 | * Alias of {@link Vector#multiplyScalar__anchor multiplyScalar} 284 | */ 285 | scale(scalar) { 286 | return this.multiplyScalar(scalar); 287 | } 288 | /** 289 | * Alias of {@link Vector#multiplyScalarNew__anchor multiplyScalarNew} 290 | */ 291 | scaleNew(scalar) { 292 | return this.multiplyScalarNew(scalar); 293 | } 294 | 295 | /** 296 | * Rotates a vecor by a given amount, provided in radians. 297 | * 298 | * @public 299 | * @chainable 300 | * @param {number} radian The angle, in radians, to rotate the vector by 301 | * @return {Vector} Returns itself, modified 302 | */ 303 | rotate(radian) { 304 | var x = (this.x * Math.cos(radian)) - (this.y * Math.sin(radian)); 305 | var y = (this.x * Math.sin(radian)) + (this.y * Math.cos(radian)); 306 | 307 | this.x = x; 308 | this.y = y; 309 | 310 | return this; 311 | } 312 | /** 313 | * Clones the vector and rotates it by the supplied radian value 314 | * 315 | * @public 316 | * @chainable 317 | * @param {number} radian The angle, in radians, to rotate the vector by 318 | * @return {Vector} Returns the clone of itself, modified 319 | */ 320 | rotateNew(radian) { 321 | let v = this.clone(); 322 | return v.rotate(radian); 323 | } 324 | 325 | /** 326 | * Rotates a vecor by a given amount, provided in degrees. Converts the degree 327 | * value to radians and runs the rotaet method. 328 | * 329 | * @public 330 | * @chainable 331 | * @param {number} degrees The angle, in degrees, to rotate the vector by 332 | * @return {Vector} Returns itself, modified 333 | */ 334 | rotateDeg(degrees) { 335 | return this.rotate(degreesToRadian(degrees)); 336 | } 337 | /** 338 | * Clones the vector and rotates it by the supplied degree value 339 | * 340 | * @public 341 | * @chainable 342 | * @param {number} degrees The angle, in degrees, to rotate the vector by 343 | * @return {Vector} Returns the clone of itself, modified 344 | */ 345 | rotateDegNew(degrees) { 346 | return this.rotateNew(degreesToRadian(degrees)); 347 | } 348 | 349 | /** 350 | * Alias of {@link Vector#rotate__anchor rotate} 351 | */ 352 | rotateBy(radian) { 353 | return this.rotate(radian); 354 | } 355 | /** 356 | * Alias of {@link Vector#rotateNew__anchor rotateNew} 357 | */ 358 | rotateByNew(radian) { 359 | return this.rotateNew(radian); 360 | } 361 | 362 | /** 363 | * Alias of {@link Vector#rotateDeg__anchor rotateDeg} 364 | */ 365 | rotateDegBy(degrees) { 366 | return this.rotateDeg(degrees); 367 | } 368 | /** 369 | * Alias of {@link Vector#rotateDegNew__anchor rotateDegNew} 370 | */ 371 | rotateDegByNew(radian) { 372 | return tjos.rotateDegNew(radian); 373 | } 374 | 375 | /** 376 | * Rotates a vector to a specific angle 377 | * 378 | * @public 379 | * @chainable 380 | * @param {number} radian The angle, in radians, to rotate the vector to 381 | * @return {Vector} Returns itself, modified 382 | */ 383 | rotateTo(radian) { 384 | return this.rotate(radian-this.angle); 385 | }; 386 | /** 387 | * Clones the vector and rotates it to the supplied radian value 388 | * 389 | * @public 390 | * @chainable 391 | * @param {number} radian The angle, in radians, to rotate the vector to 392 | * @return {Vector} Returns the clone of itself, modified 393 | */ 394 | rotateToNew(radian) { 395 | let v = this.clone(); 396 | return v.rotateTo(radian); 397 | }; 398 | 399 | /** 400 | * Rotates a vecor to a given amount, provided in degrees. Converts the degree 401 | * value to radians and runs the rotateTo method. 402 | * 403 | * @public 404 | * @chainable 405 | * @param {number} degrees The angle, in degrees, to rotate the vector to 406 | * @return {Vector} Returns itself, modified 407 | */ 408 | rotateToDeg(degrees) { 409 | return this.rotateTo(degreesToRadian(degrees)); 410 | } 411 | /** 412 | * Clones the vector and rotates it to the supplied degree value 413 | * 414 | * @public 415 | * @chainable 416 | * @param {number} degrees The angle, in degrees, to rotate the vector to 417 | * @return {Vector} Returns the clone of itself, modified 418 | */ 419 | rotateToDegNew(degrees) { 420 | return this.rotateToNew(degreesToRadian(degrees)); 421 | } 422 | 423 | /** 424 | * Normalises the vector down to a length of 1 unit 425 | * 426 | * @public 427 | * @chainable 428 | * @return {Vector} Returns itself, modified 429 | */ 430 | normalise() { 431 | return this.divideScalar(this.length); 432 | } 433 | /** 434 | * Clones the vector and normalises it 435 | * 436 | * @public 437 | * @chainable 438 | * @return {Vector} Returns a clone of itself, modified 439 | */ 440 | normaliseNew() { 441 | return this.divideScalarNew(this.length); 442 | } 443 | 444 | /** 445 | * Calculates the distance between this and the supplied vector 446 | * 447 | * @param {Vector} vector The vector to calculate the distance from 448 | * @return {number} The distance between this and the supplied vector 449 | */ 450 | distance(vector) { 451 | return this.subtractNew(vector).length; 452 | } 453 | 454 | /** 455 | * Calculates the distance on the X axis between this and the supplied vector 456 | * 457 | * @param {Vector} vector The vector to calculate the distance from 458 | * @return {number} The distance, along the x axis, between this and the supplied vector 459 | */ 460 | distanceX(vector) { 461 | return this.x - vector.x; 462 | } 463 | 464 | /** 465 | * Calculated the distance on the Y axis between this and the supplied vector 466 | * 467 | * @param {Vector} vector The vector to calculate the distance from 468 | * @return {number} The distance, along the y axis, between this and the supplied vector 469 | */ 470 | distanceY(vector) { 471 | return this.y - vector.y; 472 | } 473 | 474 | 475 | /** 476 | * Calculates the dot product between this and a supplied vector 477 | * 478 | * @example 479 | * // returns -14 480 | * new Vector(2, -3).dot(new Vector(-4, 2)) 481 | * new Vector(-4, 2).dot(new Vector(2, -3)) 482 | * new Vector(2, -4).dot(new Vector(-3, 2)) 483 | * 484 | * @param {Vector} vector The vector object against which to calculate the dot product 485 | * @return {number} The dot product of the two vectors 486 | */ 487 | dot(vector) { 488 | return (this.x * vector.x) + (this.y * vector.y); 489 | } 490 | 491 | /** 492 | * Calculates the cross product between this and the supplied vector. 493 | * 494 | * @example 495 | * // returns -2 496 | * new Vector(2, -3).cross(new Vector(-4, 2)) 497 | * new Vector(-4, 2).cross(new Vector(2, -3)) 498 | * // returns 2 499 | * new Vector(2, -4).cross(new Vector(-3, 2)) 500 | * 501 | * @param {Vector} vector The vector object against which to calculate the cross product 502 | * @return {number} The cross product of the two vectors 503 | */ 504 | cross(vector) { 505 | return (this.x * vector.x) - (this.y * vector.y); 506 | } 507 | 508 | 509 | /** 510 | * Getters and setters 511 | */ 512 | 513 | /** 514 | * (getter/setter) The x value of the vector. 515 | * 516 | * @type {number} 517 | * @default 0 518 | */ 519 | set x(x) { 520 | if(typeof x == 'number') { 521 | this._x = x; 522 | } else { 523 | throw new TypeError('X should be a number'); 524 | } 525 | } 526 | get x() { 527 | return this._x || 0; 528 | } 529 | 530 | /** 531 | * (getter/setter) The y value of the vector. 532 | * 533 | * @type {number} 534 | * @default 0 535 | */ 536 | set y(y) { 537 | if(typeof y == 'number') { 538 | this._y = y; 539 | } else { 540 | throw new TypeError('Y should be a number'); 541 | } 542 | } 543 | get y() { 544 | return this._y || 0; 545 | } 546 | 547 | /** 548 | * (getter/setter) The length of the vector presented as a square. If you're using 549 | * length for comparison, this is quicker. 550 | * 551 | * @type {number} 552 | * @default 0 553 | */ 554 | set lengthSquared(length) { 555 | var factor; 556 | if(typeof length == 'number') { 557 | factor = length / this.lengthSquared; 558 | this.multiplyScalar(factor); 559 | } else { 560 | throw new TypeError('length should be a number'); 561 | } 562 | } 563 | get lengthSquared() { 564 | return (this.x * this.x) + (this.y * this.y); 565 | } 566 | 567 | /** 568 | * (getter/setter) The length of the vector 569 | * 570 | * @type {number} 571 | * @default 0 572 | */ 573 | set length(length) { 574 | var factor; 575 | if(typeof length == 'number') { 576 | factor = length / this.length; 577 | this.multiplyScalar(factor); 578 | } else { 579 | throw new TypeError('length should be a number'); 580 | } 581 | } 582 | get length() { 583 | return Math.sqrt(this.lengthSquared); 584 | } 585 | 586 | /** 587 | * (getter/setter) The angle of the vector, in radians 588 | * 589 | * @type {number} 590 | * @default 0 591 | */ 592 | set angle(radian) { 593 | if(typeof radian == 'number') { 594 | this.rotateTo(radian); 595 | } else { 596 | throw new TypeError('angle should be a number'); 597 | } 598 | } 599 | get angle() { 600 | return Math.atan2(this.y, this.x); 601 | } 602 | 603 | /** 604 | * (getter/setter) The angle of the vector, in radians 605 | * 606 | * @type {number} 607 | * @default 0 608 | */ 609 | set angleInDegrees(degrees) { 610 | if(typeof degrees == 'number') { 611 | this.rotateToDeg(degrees); 612 | } else { 613 | throw new TypeError('angle should be a number'); 614 | } 615 | } 616 | get angleInDegrees() { 617 | return radianToDegrees(Math.atan2(this.y, this.x)); 618 | } 619 | 620 | /** 621 | * (getter/setter) Vector width. 622 | * Alias of {@link Vector#x x} 623 | * 624 | * @type {number} 625 | */ 626 | set width(w) { 627 | this.x = w; 628 | } 629 | get width() { 630 | return this.x; 631 | } 632 | 633 | /** 634 | * (getter/setter) Vector height. 635 | * Alias of {@link Vector#x x} 636 | * 637 | * @type {number} 638 | */ 639 | set height(h) { 640 | this.y = h; 641 | } 642 | get height() { 643 | return this.y; 644 | } 645 | 646 | /** 647 | * (getter/setter) Vector area. 648 | * @readonly 649 | * 650 | * @type {number} 651 | */ 652 | get area() { 653 | return this.x * this.y; 654 | } 655 | 656 | /** 657 | * (getter/setter) Vector slope. 658 | * 659 | * @type {number} 660 | */ 661 | set slope(value) { 662 | if(!isNaN(value)) { 663 | let angle = Math.atan(value); 664 | this.angle = angle; 665 | } 666 | } 667 | get slope() { 668 | return this.y / this.x; 669 | } 670 | 671 | } 672 | 673 | export default Vector; 674 | --------------------------------------------------------------------------------