diff --git a/README.md b/README.md index ec40cf0..ddfed6f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -# p5.teach.js +# p5.teach.js + +astrik-logo + +> A beginner friendly math animation library for p5.js p5.teach.js provides tools for teaching through p5.js, such as functions to animate text, TeX, and shapes. @@ -6,7 +10,8 @@ p5.teach.js provides tools for teaching through p5.js, such as functions to anim ## Documentation -- [API Reference](api_reference.md) +- [TypeDoc Documentation](https://two-ticks.github.io/p5.teach.js/docs/index.html) +- [API Reference](https://two-ticks.github.io/p5.teach.js/api_reference.md) - [Example Sketches](https://editor.p5js.org/radium.scientist/collections/-xxYz8cof) ## Setting up the development environment @@ -17,6 +22,11 @@ p5.teach.js provides tools for teaching through p5.js, such as functions to anim 4. As the code is updated, the final js file is updated in `dist/p5.teach.js` dynamically 5. The sketch in the `index.html` file is reflected with the changes +## Generating documentation + +1. We use `TypeDoc` +2. Run `yarn typedoc src` for generating docs + ## Tests 1. We use `jest` for testing diff --git a/api_reference.md b/api_reference.md index 3cb3942..2f87228 100644 --- a/api_reference.md +++ b/api_reference.md @@ -2,9 +2,25 @@ ## Index +- MObject - [`createText(text, x, y, font-size)`](#createtexttext-x-y-font-size) - - [`createTeX(tex, x, y, width, height)`](#createtextex-x-y-width-height) - - + - [`createTeX(tex, x, y, font-size)`](#createtextex-x-y-font-size) +- GObject + - [`create2DGraph(equation, x, y, width, height)`](#create2dgraphequation-x-y-width-height) + - [`create2DPolarGraph(equation, theta-range, x, y, width, height)`](#create2dpolargraphequation-theta-range-x-y-width-height) + - [`create2DParametricGraph(x, y, [range])`](#create2dparametricgraphx-y-range) + - [`.axes()`]() + - [`.configure()`]() +- Scene + - [`Scene()`](#scene) + - [`createControls()`](#createcontrols) + - [`clock()`](#clock) + - [`addDuration(timeDuration)`](#adddurationtimeduration) + - [`.add()`](#add) + - [`.remove()`](#remove) + - [`.play()`](#playanimationtype) + - [`transform()`](#transformobject1-object2) + - [`group()`](#groupobjects) ## `createText(text, x, y, font-size)` @@ -38,6 +54,9 @@ let myText = createText('Cat and Dogs'); [🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/LVPT38ig-) +
+ Code + ```js function setup() { createCanvas(400, 400); @@ -60,6 +79,8 @@ function reel() { } ``` +
+ | **Animations** | Description | | :------------- | :------------------------------------------------------------ | | `write` | Writes the text with a blurry effect at each new character | @@ -71,17 +92,16 @@ function reel() { | `dissolve` | Dissolves the text and make it disappear from the screen | | `spinOut` | Spins the text and make it disappear from the screen | -## `createTeX(tex, x, y, width, height)` +## `createTeX(tex, x, y, font-size)` **Parameters** -| Parameter | Type | Description | -| :-------- | :---------- | :------------------- | -| tex | `string` | escaped TeX sequence | -| [x] | `number` | x-coordinate of tex | -| [y] | `number` | y-coordinate of tex | -| [width] | `number` px | width of SVG | -| [height] | `number` px | height of SVG | +| Parameter | Type | Description | +| :---------- | :---------- | :------------------- | +| tex | `string` | escaped TeX sequence | +| [x] | `number` | x-coordinate of tex | +| [y] | `number` | y-coordinate of tex | +| [font-size] | `number` px | font-size of text | [ ] : optional arguments @@ -115,6 +135,9 @@ let tex = createTeX('\\overrightarrow{F}_{12} = k_e \\frac{q_1 q_2}{r^2}'); [🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/1YDfYFeF9) +
+ Code + ```js function setup() { createCanvas(400, 400); @@ -137,3 +160,803 @@ async function reel() { play(tex, 'all-at-once'); } ``` + +
+ +## `create2DGraph(equation, x, y, width, height)` + +**Parameters** + +| Parameter | Type | Description | +| :-------- | :---------- | :--------------------- | +| equation | `function` | function to be plotted | +| [x] | `number` | x-coordinate of graph | +| [y] | `number` | y-coordinate of graph | +| [width] | `number` px | width of SVG | +| [height] | `number` px | height of SVG | + +[ ] : optional arguments + +```js +let curve = create2DGraph((t) => 400 + 1500 * cos(2 * t)); +``` + +| Method | Description | +| :------------------------- | :------------------------------------ | +| object.plot() | plots the graph | +| object.position(x, y) | sets position of graph object | +| object.size(width, height) | sets width and height of graph object | +| object.stroke(strokeColor) | sets stroke color of graph object | +| object.play() | play animation of creation | +| object1.transform(object2) | transforms object1 into object2 | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/Nl55ATBHk) + +
+ Code + +```js +function setup() { + createCanvas(400, 400); + background(220); + scene = new Scene(); + reel(); +} + +function draw() { + background(220); +} + +function reel() { + let graph1 = create2DGraph( + (t) => + 800 * cos(2 * t) + 1000 * sin(4 * t) + 800 * sin(6 * t) + ); + graph1.plot(); + graph1.position(10, 200); + graph1.play(); + + let graph2 = create2DGraph((t) => 800 * cos(2 * t)); + graph2.plot(); + graph2.position(10, 0); + graph2.play(); + + let graph3 = create2DGraph((t) => 1000 * sin(4 * t)); + graph3.plot(); + graph3.position(10, 50); + graph3.play(); + + let graph4 = create2DGraph((t) => 800 * sin(6 * t)); + graph4.plot(); + graph4.position(10, 100); + graph4.play(); +} +``` + +
+ +## `create2DPolarGraph(equation, theta-range, x, y, width, height)` + +**Parameters** + +| Parameter | Type | Description | +| :---------- | :------------- | :--------------------- | +| equation | `function` | function to be plotted | +| theta-range | `number array` | range of theta | +| [x] | `number` | x-coordinate of graph | +| [y] | `number` | y-coordinate of graph | +| [width] | `number` px | width of SVG | +| [height] | `number` px | height of SVG | + +[ ] : optional arguments + +```js +let curve = create2DPolarGraph( + (t) => + 15 * + (pow(Math.E, cos(t)) - + 2 * cos(4 * t) - + pow(sin(t / 12), 5)), + [0, 12 * PI] +); +``` + +| Method | Description | +| :------------------------- | :------------------------------------ | +| object.plot() | plots the graph | +| object.position(x, y) | sets position of graph object | +| object.size(width, height) | sets width and height of graph object | +| object.stroke(strokeColor) | sets stroke color of graph object | +| object.play() | play animation of creation | +| object1.transform(object2) | transforms object1 into object2 | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/am40f47oTj) + +
+ Code + +```js +function setup() { + createCanvas(400, 400); + background(220); + scene = new Scene(); + reel(); +} + +function draw() { + background(220); +} + +function reel() { + let graph = create2DPolarGraph( + (t) => + 15 * + (pow(Math.E, cos(t)) - + 2 * cos(4 * t) - + pow(sin(t / 12), 5)), + [0, 12 * PI] + ); + graph.plot(); + graph.size(400, 400); + graph.position(50, 50); + graph.play(); +} +``` + +
+ +## `create2DParametricGraph(x, y, [range])` + +**Parameters** + +| Parameter | Type | Description | +| :----------- | :------------- | :----------------- | +| x expression | `function` | x expression | +| y expression | `function` | y expression | +| [range] | `number array` | range of parameter | + +[ ] : optional arguments + +```js +let curve = create2DParametricGraph( + (t) => 40 * sin(4 * t + QUARTER_PI), + (t) => 40 * cos(5 * t) +); +``` + +| Method | Description | +| :------------------------- | :------------------------------------ | +| object.plot() | plots the graph | +| object.position(x, y) | sets position of graph object | +| object.size(width, height) | sets width and height of graph object | +| object.stroke(strokeColor) | sets stroke color of graph object | +| object.play() | play animation of creation | +| object1.transform(object2) | transforms object1 into object2 | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/_CHFblWtj) + +
+ Code + +```js +let button; +let A = 40; +let B = 40; +let a = 3; +let b = 2; +let d = Math.PI / 4; + +function setup() { + createCanvas(400, 400); + background(0); + scene = new Scene(); + createControls(); + reel(); +} + +function reel() { + let curve1 = create2DParametricGraph( + (t) => A * sin(a * t + d), + (t) => B * cos(b * t) + ); + + curve1.plot(); + curve1.stroke('blue'); + curve1.position(50, 50); + a = 5; + b = 4; + d = PI / 8; + + let curve2 = create2DParametricGraph( + (t) => A * sin(a * t + d), + (t) => B * cos(b * t) + ); + curve2.stroke('blue'); + // curve2.plot(); + curve2.size(400, 400); + curve2.position(50, 150); + curve1.transform(curve2, 0, 10); +} + +``` + +
+ +## `createControls()` + +**Parameters** + +| Parameter | Type | Description | +| :-------- | :--- | :---------- | +| | | | + +[ ] : optional arguments + +```js +createControls(); +``` + +| Method | Description | +| :----- | :---------- | +| | | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/PpfDceZsi) + +
+ Code + +```js +let t = 0; +let i = 0; +let MAGENTA50 = '#dc267f'; + +function setup() { + createCanvas(400, 400); + scene = new Scene(); + createControls(); + reel(); +} + +function draw() { + background(220); + t = clock(); // sets t = time of animation timeline + + if (t < 1000) i = t; + + fill(255, 0, 0); + + rect(30 + 0.25 * i, 20, 75, 10); +} + +function reel() { + let title = createText('Lorentz Transformation', 30, 75, 35); + title.fill('red'); + title.play('growFromCenter', 1, 4); + let equation = createTeX( + '\\gamma = \\dfrac{1}{\\sqrt{1 - \\frac{v^2}{c^2}}}' + ); + equation.position(45, 175); + equation.size(50); + equation.stroke(MAGENTA50); + equation.strokeWidth(20); + equation.fill(MAGENTA50); + equation.play('createFill', 1, 6); +} +``` + +
+ +## `Scene()` + +**Description** +A class to describe a `Scene`. A scene contains all of the objects (such as MObjects and GObjects) created by p5.teach. All the objects exist inside a div element of the `sceneContainer` class. + +**Parameters** + +| Parameter | Type | Description | +| :-------- | :--- | :---------- | +| | | | + +[ ] : optional arguments + +```js +scene = new Scene(); +``` + +| Method | Description | +| :------------------ | :------------------------------------------------- | +| remove() | removes `sceneContainer` | +| delay(timeDuration) | provide async delay of `timeDuration` milliseconds | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/PpfDceZsi) + +
+ Code + +```js +function setup() { + createCanvas(400, 400); + scene = new Scene(); +} +``` + +
+ +## `clock()` + +**Description** +`clock()` returns the current time of the p5.teach animation timeline(anime.js). It is used to synchronise p5.js elements with p5.teach animation timeline. + +**Parameters** + +| Parameter | Type | Description | +| :-------- | :--- | :---------- | +| | | | + +[ ] : optional arguments + +```js +clock(); +``` + +| Method | Description | +| :----- | :---------- | +| | | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/PpfDceZsi) + +
+ Code + +```js +let t = 0; +let i = 0; +let MAGENTA50 = '#dc267f'; + +function setup() { + createCanvas(400, 400); + scene = new Scene(); + createControls(); + reel(); +} + +function draw() { + background(220); + t = clock(); // sets t = time of animation timeline + + if (t < 1000) i = t; + + fill(255, 0, 0); + + rect(30 + 0.25 * i, 20, 75, 10); +} + +function reel() { + let title = createText('Lorentz Transformation', 30, 75, 35); + title.fill('red'); + title.play('growFromCenter', 1, 4); + let equation = createTeX( + '\\gamma = \\dfrac{1}{\\sqrt{1 - \\frac{v^2}{c^2}}}' + ); + equation.position(45, 175); + equation.size(50); + equation.stroke(MAGENTA50); + equation.strokeWidth(20); + equation.fill(MAGENTA50); + equation.play('createFill', 1, 6); +} +``` + +
+ +## `addDuration(timeDuration)` + +**Description** +`addDuration(timeDuration)` adds `timeDuration` to the animation timeline. + +**Parameters** + +| Parameter | Type | Description | +| :-------- | :--- | :---------- | +| | | | + +[ ] : optional arguments + +```js +addDuration(timeDuration); +``` + +| Method | Description | +| :----- | :---------- | +| | | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/PpfDceZsi) + +
+ Code + +```js +let t = 0; +let i = 0; +let MAGENTA50 = '#dc267f'; + +function setup() { + createCanvas(400, 400); + scene = new Scene(); + createControls(); + reel(); +} + +function draw() { + background(220); + t = clock(); // sets t = time of animation timeline + + if (t < 1000) i = t; + + fill(255, 0, 0); + + rect(30 + 0.25 \* i, 20, 75, 10); +} + +function reel() { + let title = createText('Lorentz Transformation', 30, 75, 35); + title.fill('red'); + title.play('growFromCenter', 1, 4); + let equation = createTeX( + '\\gamma = \\dfrac{1}{\\sqrt{1 - \\frac{v^2}{c^2}}}' + ); + equation.position(45, 175); + equation.size(50); + equation.stroke(MAGENTA50); + equation.strokeWidth(20); + equation.fill(MAGENTA50); + equation.play('createFill', 1, 6); +} +``` + +
+ +## `.add()` + +**Parameters** + +| Parameter | Type | Description | +| :-------- | :--- | :---------- | +| | | | + +[ ] : optional arguments + +```js +add(); +``` + +| Method | Description | +| :----- | :---------- | +| | | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/PpfDceZsi) + +
+ Code + +```js +let t = 0; +let i = 0; +let MAGENTA50 = '#dc267f'; + +function setup() { + createCanvas(400, 400); + scene = new Scene(); + createControls(); + reel(); +} + +function draw() { + background(220); + t = clock(); // sets t = time of animation timeline + + if (t < 1000) i = t; + + fill(255, 0, 0); + + rect(30 + 0.25 \* i, 20, 75, 10); +} + +function reel() { + let title = createText('Lorentz Transformation', 30, 75, 35); + title.fill('red'); + title.play('growFromCenter', 1, 4); + let equation = createTeX( + '\\gamma = \\dfrac{1}{\\sqrt{1 - \\frac{v^2}{c^2}}}' + ); + equation.position(45, 175); + equation.size(50); + equation.stroke(MAGENTA50); + equation.strokeWidth(20); + equation.fill(MAGENTA50); + equation.play('createFill', 1, 6); +} +``` + +
+ +## `.remove()` + +**Parameters** + +| Parameter | Type | Description | +| :-------- | :--- | :---------- | +| | | | + +[ ] : optional arguments + +```js +remove(); +``` + +| Method | Description | +| :----- | :---------- | +| | | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/PpfDceZsi) + +
+ Code + +```js +let t = 0; +let i = 0; +let MAGENTA50 = '#dc267f'; + +function setup() { + createCanvas(400, 400); + scene = new Scene(); + createControls(); + reel(); +} + + +function draw() { + background(220); + t = clock(); // sets t = time of animation timeline + + if (t < 1000) i = t; + + fill(255, 0, 0); + + rect(30 + 0.25 \* i, 20, 75, 10); +} + +function reel() { + let title = createText('Lorentz Transformation', 30, 75, 35); + title.fill('red'); + title.play('growFromCenter', 1, 4); + let equation = createTeX( + '\\gamma = \\dfrac{1}{\\sqrt{1 - \\frac{v^2}{c^2}}}' + ); + equation.position(45, 175); + equation.size(50); + equation.stroke(MAGENTA50); + equation.strokeWidth(20); + equation.fill(MAGENTA50); + equation.play('createFill', 1, 6); +} +``` + +
+ +## `.play(animationType)` + +**Parameters** + +| Parameter | Type | Description | +| :-------- | :--- | :---------- | +| | | | + +[ ] : optional arguments + +```js +.play(animationType) +``` + +| Method | Description | +| :----- | :---------- | +| | | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/PpfDceZsi) + +
+ Code + +```js +let t = 0; +let i = 0; +let MAGENTA50 = '#dc267f'; + +function setup() { + createCanvas(400, 400); + scene = new Scene(); + createControls(); + reel(); +} + +function draw() { + background(220); + t = clock(); //sets t = time of animation timeline + + if (t < 1000) i = t; + + fill(255, 0, 0); + + rect(30 + 0.25 \* i, 20, 75, 10); +} + +function reel() { + let title = createText('Lorentz Transformation', 30, 75, 35); + title.fill('red'); + title.play('growFromCenter', 1, 4); + let equation = createTeX( + '\\gamma = \\dfrac{1}{\\sqrt{1 - \\frac{v^2}{c^2}}}' + ); + equation.position(45, 175); + equation.size(50); + equation.stroke(MAGENTA50); + equation.strokeWidth(20); + equation.fill(MAGENTA50); + equation.play('createFill', 1, 6); +} +``` + +
+ +## `transform(object1, object2)` + +**Parameters** + +| Parameter | Type | Description | +| :-------- | :--- | :---------- | +| | | | + +[ ] : optional arguments + +```js +transform(object1, object2); +``` + +| Method | Description | +| :----- | :---------- | +| | | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/PpfDceZsi) + +
+ Code + +```js +let t = 0; +let i = 0; +let MAGENTA50 = '#dc267f'; + +function setup() { + createCanvas(400, 400); + scene = new Scene(); + createControls(); + reel(); +} + +function draw() { + background(220); + t = clock(); //sets t = time of animation timeline + + if (t < 1000) i = t; + + fill(255, 0, 0); + + rect(30 + 0.25 \* i, 20, 75, 10); +} + +function reel() { + let title = createText('Lorentz Transformation', 30, 75, 35); + title.fill('red'); + title.play('growFromCenter', 1, 4); + let equation = createTeX( + '\\gamma = \\dfrac{1}{\\sqrt{1 - \\frac{v^2}{c^2}}}' + ); + equation.position(45, 175); + equation.size(50); + equation.stroke(MAGENTA50); + equation.strokeWidth(20); + equation.fill(MAGENTA50); + equation.play('createFill', 1, 6); +} +``` + +
+ +## `group([objects])` + +**Parameters** + +| Parameter | Type | Description | +| :-------- | :--- | :---------- | +| | | | + +[ ] : optional arguments + +```js +group([objects]); +``` + +| Method | Description | +| :----- | :---------- | +| | | + +**Example** + +[🔗example sketch](https://editor.p5js.org/radium.scientist/sketches/PpfDceZsi) + +
+ Code + +```js +let t = 0; +let i = 0; +let MAGENTA50 = '#dc267f'; + +function setup() { + createCanvas(400, 400); + scene = new Scene(); + createControls(); + reel(); +} + +function draw() { + background(220); + t = clock(); //sets t = time of animation timeline + + if (t < 1000) i = t; + + fill(255, 0, 0); + + rect(30 + 0.25 \* i, 20, 75, 10); +} + +function reel() { + let title = createText('Lorentz Transformation', 30, 75, 35); + title.fill('red'); + title.play('growFromCenter', 1, 4); + let equation = createTeX( + '\\gamma = \\dfrac{1}{\\sqrt{1 - \\frac{v^2}{c^2}}}' + ); + equation.position(45, 175); + equation.size(50); + equation.stroke(MAGENTA50); + equation.strokeWidth(20); + equation.fill(MAGENTA50); + equation.play('createFill', 1, 6); +} +``` + +
diff --git a/assets/examples/TeX.html b/assets/examples/TeX.html new file mode 100644 index 0000000..ffe384e --- /dev/null +++ b/assets/examples/TeX.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/assets/p5-astrik-teach.png b/assets/p5-astrik-teach.png new file mode 100644 index 0000000..18f9afa Binary files /dev/null and b/assets/p5-astrik-teach.png differ diff --git a/assets/p5-teach-logo.png b/assets/p5-teach-logo.png new file mode 100644 index 0000000..76fff28 Binary files /dev/null and b/assets/p5-teach-logo.png differ diff --git a/dist/index.html b/dist/index.html index 8314824..01985f2 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1,9 +1,13 @@ - + + + - + + + - - \ No newline at end of file + + diff --git a/dist/p5.teach.js b/dist/p5.teach.js index 7e658c4..e7f60d1 100644 --- a/dist/p5.teach.js +++ b/dist/p5.teach.js @@ -1,605 +1,47471 @@ -parcelRequire=function(e,r,t,n){var i,o="function"==typeof parcelRequire&&parcelRequire,u="function"==typeof require&&require;function f(t,n){if(!r[t]){if(!e[t]){var i="function"==typeof parcelRequire&&parcelRequire;if(!n&&i)return i(t,!0);if(o)return o(t,!0);if(u&&"string"==typeof t)return u(t);var c=new Error("Cannot find module '"+t+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[t][1][r]||r},p.cache={};var l=r[t]=new f.Module(t);e[t][0].call(l.exports,p,l,l.exports,this)}return r[t].exports;function p(e){return f(p.resolve(e))}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.exports={}},f.modules=e,f.cache=r,f.parent=o,f.register=function(r,t){e[r]=[function(e,r){r.exports=t},{}]};for(var c=0;ci.length}}}},t.prototype.add=function(i,e){void 0===e&&(e=t.DEFAULTPRIORITY);var r=this.items.length;do{r--}while(r>=0&&e=0&&this.items[i].item!==t);i>=0&&this.items.splice(i,1)},t.DEFAULTPRIORITY=5,t}();exports.PrioritizedList=t; -},{}],"GAK3":[function(require,module,exports) { -"use strict";var t=this&&this.__extends||function(){var t=function(r,e){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,r){t.__proto__=r}||function(t,r){for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])})(r,e)};return function(r,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function n(){this.constructor=r}t(r,e),r.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}}(),r=this&&this.__values||function(t){var r="function"==typeof Symbol&&Symbol.iterator,e=r&&t[r],n=0;if(e)return e.call(t);if(t&&"number"==typeof t.length)return{next:function(){return t&&n>=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw new TypeError(r?"Object is not iterable.":"Symbol.iterator is not defined.")};Object.defineProperty(exports,"__esModule",{value:!0}),exports.HandlerList=void 0;var e=require("../util/PrioritizedList.js"),n=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return t(n,e),n.prototype.register=function(t){return this.add(t,t.priority)},n.prototype.unregister=function(t){this.remove(t)},n.prototype.handlesDocument=function(t){var e,n;try{for(var o=r(this),i=o.next();!i.done;i=o.next()){var u=i.value.item;if(u.handlesDocument(t))return u}}catch(l){e={error:l}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(e)throw e.error}}throw new Error("Can't find handler for document")},n.prototype.document=function(t,r){return void 0===r&&(r=null),this.handlesDocument(t).create(t,r)},n}(e.PrioritizedList);exports.HandlerList=n; -},{"../util/PrioritizedList.js":"oqxq"}],"L9Lo":[function(require,module,exports) { -"use strict";function r(r){return new Promise(function t(e,n){try{e(r())}catch(o){o.retry&&o.retry instanceof Promise?o.retry.then(function(){return t(e,n)}).catch(function(r){return n(r)}):o.restart&&o.restart.isCallback?MathJax.Callback.After(function(){return t(e,n)},o.restart):n(o)}})}function t(r){var t=new Error("MathJax retry");throw t.retry=r,t}Object.defineProperty(exports,"__esModule",{value:!0}),exports.retryAfter=exports.handleRetriesFor=void 0,exports.handleRetriesFor=r,exports.retryAfter=t; -},{}],"aZeM":[function(require,module,exports) { -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.mathjax=void 0;var e=require("./core/HandlerList.js"),r=require("./util/Retries.js");exports.mathjax={version:"3.2.0",handlers:new e.HandlerList,document:function(e,r){return exports.mathjax.handlers.document(e,r)},handleRetriesFor:r.handleRetriesFor,retryAfter:r.retryAfter,asyncLoad:null}; -},{"./core/HandlerList.js":"GAK3","./util/Retries.js":"L9Lo"}],"K1GY":[function(require,module,exports) { -"use strict";var r=this&&this.__values||function(r){var t="function"==typeof Symbol&&Symbol.iterator,e=t&&r[t],o=0;if(e)return e.call(r);if(r&&"number"==typeof r.length)return{next:function(){return r&&o>=r.length&&(r=void 0),{value:r&&r[o++],done:!r}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")},t=this&&this.__read||function(r,t){var e="function"==typeof Symbol&&r[Symbol.iterator];if(!e)return r;var o,n,a=e.call(r),i=[];try{for(;(void 0===t||t-- >0)&&!(o=a.next()).done;)i.push(o.value)}catch(s){n={error:s}}finally{try{o&&!o.done&&(e=a.return)&&e.call(a)}finally{if(n)throw n.error}}return i},e=this&&this.__spreadArray||function(r,t){for(var e=0,o=t.length,n=r.length;e=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw new TypeError(r?"Object is not iterable.":"Symbol.iterator is not defined.")},e=this&&this.__read||function(t,r){var e="function"==typeof Symbol&&t[Symbol.iterator];if(!e)return t;var n,o,i=e.call(t),u=[];try{for(;(void 0===r||r-- >0)&&!(n=i.next()).done;)u.push(n.value)}catch(a){o={error:a}}finally{try{n&&!n.done&&(e=i.return)&&e.call(i)}finally{if(o)throw o.error}}return u},n=this&&this.__spreadArray||function(t,r){for(var e=0,n=r.length,o=t.length;e0)&&!(n=i.next()).done;)s.push(n.value)}catch(u){o={error:u}}finally{try{n&&!n.done&&(e=i.return)&&e.call(i)}finally{if(o)throw o.error}}return s},r=this&&this.__spreadArray||function(t,r){for(var e=0,n=r.length,o=t.length;e=e&&this.state(e-1),t.renderActions.renderMath(this,t,e)},t.prototype.convert=function(t,e){void 0===e&&(e=exports.STATE.LAST),t.renderActions.renderConvert(this,t,e)},t.prototype.compile=function(t){this.state()=exports.STATE.INSERTED&&this.removeFromDocument(e),t=exports.STATE.TYPESET&&(this.outputData={}),t=exports.STATE.COMPILED&&(this.inputData={}),this._state=t),this._state},t.prototype.reset=function(t){void 0===t&&(t=!1),this.state(exports.STATE.UNPROCESSED,t)},t}();function o(t,e){if(t in exports.STATE)throw Error("State "+t+" already exists");exports.STATE[t]=e}exports.AbstractMathItem=e,exports.STATE={UNPROCESSED:0,FINDMATH:10,COMPILED:20,CONVERT:100,METRICS:110,RERENDER:125,TYPESET:150,INSERTED:200,LAST:1e4},exports.newState=o; -},{}],"xr3O":[function(require,module,exports) { -"use strict";var t=this&&this.__extends||function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])})(e,n)};return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),e=this&&this.__read||function(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,s,i=n.call(t),o=[];try{for(;(void 0===e||e-- >0)&&!(r=i.next()).done;)o.push(r.value)}catch(a){s={error:a}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(s)throw s.error}}return o};Object.defineProperty(exports,"__esModule",{value:!0}),exports.FindTeX=void 0;var n=require("../../core/FindMath.js"),r=require("../../util/string.js"),s=require("../../core/MathItem.js"),i=function(n){function i(t){var e=n.call(this,t)||this;return e.getPatterns(),e}return t(i,n),i.prototype.getPatterns=function(){var t=this,e=this.options,n=[],s=[],i=[];this.end={},this.env=this.sub=0;var o=1;e.inlineMath.forEach(function(e){return t.addPattern(n,e,!1)}),e.displayMath.forEach(function(e){return t.addPattern(n,e,!0)}),n.length&&s.push(n.sort(r.sortLength).join("|")),e.processEnvironments&&(s.push("\\\\begin\\s*\\{([^}]*)\\}"),this.env=o,o++),e.processEscapes&&i.push("\\\\([\\\\$])"),e.processRefs&&i.push("(\\\\(?:eq)?ref\\s*\\{[^}]*\\})"),i.length&&(s.push("("+i.join("|")+")"),this.sub=o),this.start=new RegExp(s.join("|"),"g"),this.hasPatterns=s.length>0},i.prototype.addPattern=function(t,n,s){var i=e(n,2),o=i[0],a=i[1];t.push(r.quotePattern(o)),this.end[o]=[a,s,this.endPattern(a)]},i.prototype.endPattern=function(t,e){return new RegExp((e||r.quotePattern(t))+"|\\\\(?:[a-zA-Z]|.)|[{}]","g")},i.prototype.findEnd=function(t,n,r,i){for(var o,a=e(i,3),h=a[0],u=a[1],p=a[2],c=p.lastIndex=r.index+r[0].length,d=0;o=p.exec(t);){if((o[1]||o[0])===h&&0===d)return s.protoItem(r[0],t.substr(c,o.index-c),o[0],n,r.index,o.index+o[0].length,u);"{"===o[0]?d++:"}"===o[0]&&d&&d--}return null},i.prototype.findMathInString=function(t,e,n){var i,o;for(this.start.lastIndex=0;i=this.start.exec(n);){if(void 0!==i[this.env]&&this.env){var a="\\\\end\\s*(\\{"+r.quotePattern(i[this.env])+"\\})";(o=this.findEnd(n,e,i,["{"+i[this.env]+"}",!0,this.endPattern(null,a)]))&&(o.math=o.open+o.math+o.close,o.open=o.close="")}else if(void 0!==i[this.sub]&&this.sub){var h=i[this.sub];a=i.index+i[this.sub].length;o=2===h.length?s.protoItem("",h.substr(1),"",e,i.index,a):s.protoItem("",h,"",e,i.index,a,!1)}else o=this.findEnd(n,e,i,this.end[i[0]]);o&&(t.push(o),this.start.lastIndex=o.end.n)}},i.prototype.findMath=function(t){var e=[];if(this.hasPatterns)for(var n=0,r=t.length;n numeric require +// +// anything defined in a previous bundle is accessed via the +// orig method which is the require for previous bundles +parcelRequire = (function (modules, cache, entry, globalName) { + // Save the require from previous bundle to this closure if any + var previousRequire = typeof parcelRequire === 'function' && parcelRequire; + var nodeRequire = typeof require === 'function' && require; + + function newRequire(name, jumped) { + if (!cache[name]) { + if (!modules[name]) { + // if we cannot find the module within our internal map or + // cache jump to the current global require ie. the last bundle + // that was added to the page. + var currentRequire = typeof parcelRequire === 'function' && parcelRequire; + if (!jumped && currentRequire) { + return currentRequire(name, true); + } + + // If there are other bundles on this page the require from the + // previous one is saved to 'previousRequire'. Repeat this as + // many times as there are bundles until the module is found or + // we exhaust the require chain. + if (previousRequire) { + return previousRequire(name, true); + } + + // Try the node require function if it exists. + if (nodeRequire && typeof name === 'string') { + return nodeRequire(name); + } + + var err = new Error('Cannot find module \'' + name + '\''); + err.code = 'MODULE_NOT_FOUND'; + throw err; + } + + localRequire.resolve = resolve; + localRequire.cache = {}; + + var module = cache[name] = new newRequire.Module(name); + + modules[name][0].call(module.exports, localRequire, module, module.exports, this); + } + + return cache[name].exports; + + function localRequire(x){ + return newRequire(localRequire.resolve(x)); + } + + function resolve(x){ + return modules[name][1][x] || x; + } + } + + function Module(moduleName) { + this.id = moduleName; + this.bundle = newRequire; + this.exports = {}; + } + + newRequire.isParcelRequire = true; + newRequire.Module = Module; + newRequire.modules = modules; + newRequire.cache = cache; + newRequire.parent = previousRequire; + newRequire.register = function (id, exports) { + modules[id] = [function (require, module) { + module.exports = exports; + }, {}]; + }; + + var error; + for (var i = 0; i < entry.length; i++) { + try { + newRequire(entry[i]); + } catch (e) { + // Save first error but execute all entries + if (!error) { + error = e; + } + } + } + + if (entry.length) { + // Expose entry point to Node, AMD or browser globals + // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js + var mainExports = newRequire(entry[entry.length - 1]); + + // CommonJS + if (typeof exports === "object" && typeof module !== "undefined") { + module.exports = mainExports; + + // RequireJS + } else if (typeof define === "function" && define.amd) { + define(function () { + return mainExports; + }); + + // + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class GObject

+
+
+
+
+
+
+
+

Hierarchy

+ +
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+
    +
  • new GObject(x?: number, y?: number, svgWidth?: number, svgHeight?: number): GObject
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    • +
      svgWidth: number = 300
      +
    • +
    • +
      svgHeight: number = 300
      +
    • +
    +

    Returns GObject

    +
  • +
+
+
+
+

Properties

+
+ +

graphContainer

+
graphContainer: Element
+ +
+
+ +

graphObject

+
graphObject: SVGSVGElement
+ +
+
+ +

linePath

+
linePath: SVGPathElement
+ +
+
+ +

pathData

+
pathData: string
+ +
+
+ +

svgHeight

+
svgHeight: number
+ +
+
+ +

svgWidth

+
svgWidth: number
+ +
+
+ +

x

+
x: number
+ +
+
+ +

y

+
y: number
+ +
+
+
+

Methods

+
+ +

moveTo

+
    +
  • moveTo(newX: any, newY: any, startTime: any, endTime: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      newX: any
      +
    • +
    • +
      newY: any
      +
    • +
    • +
      startTime: any
      +
    • +
    • +
      endTime: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Class
  • +
  • Constructor
  • +
  • Property
  • +
  • Method
  • +
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/classes/lib_Geometry_Shape.Graph.html b/docs/classes/lib_Geometry_Shape.Graph.html new file mode 100644 index 0000000..7c9a1a7 --- /dev/null +++ b/docs/classes/lib_Geometry_Shape.Graph.html @@ -0,0 +1,542 @@ + + + + + + Graph | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class Graph

+
+
+
+
+
+
+
+

Hierarchy

+ +
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+
    +
  • new Graph(x?: number, y?: number, svgWidth?: number, svgHeight?: number): Graph
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    • +
      svgWidth: number = 300
      +
    • +
    • +
      svgHeight: number = 300
      +
    • +
    +

    Returns Graph

    +
  • +
+
+
+
+

Properties

+
+ +

config

+
config: { arrowFollowerColor: any; arrowSize: any; axisColor: any; graphColor: any; graphStrokeWidth: any; gridColor: any; maxX: any; maxY: any; minX: any; minY: any; originX: any; originY: any; scaleX: any; scaleY: any; smallGridColor: any; stepX: any; stepY: any; tickColor: any; tickMarginX: any; tickMarginY: any; tickX: any; tickY: any; xAxis: any; yAxis: any }
+ +
+

Type declaration

+
    +
  • +
    arrowFollowerColor: any
    +
  • +
  • +
    arrowSize: any
    +
  • +
  • +
    axisColor: any
    +
  • +
  • +
    graphColor: any
    +
  • +
  • +
    graphStrokeWidth: any
    +
  • +
  • +
    gridColor: any
    +
  • +
  • +
    maxX: any
    +
  • +
  • +
    maxY: any
    +
  • +
  • +
    minX: any
    +
  • +
  • +
    minY: any
    +
  • +
  • +
    originX: any
    +
  • +
  • +
    originY: any
    +
  • +
  • +
    scaleX: any
    +
  • +
  • +
    scaleY: any
    +
  • +
  • +
    smallGridColor: any
    +
  • +
  • +
    stepX: any
    +
  • +
  • +
    stepY: any
    +
  • +
  • +
    tickColor: any
    +
  • +
  • +
    tickMarginX: any
    +
  • +
  • +
    tickMarginY: any
    +
  • +
  • +
    tickX: any
    +
  • +
  • +
    tickY: any
    +
  • +
  • +
    xAxis: any
    +
  • +
  • +
    yAxis: any
    +
  • +
+
+
+
+ +

coordinate

+
coordinate: SVGGElement
+ +
+
+ +

graphContainer

+
graphContainer: Element
+ +
+
+ +

graphObject

+
graphObject: SVGSVGElement
+ +
+
+ +

linePath

+
linePath: SVGPathElement
+ +
+
+ +

pathData

+
pathData: string
+ +
+
+ +

plotting

+
plotting: SVGGElement
+ +
+
+ +

svgHeight

+
svgHeight: number
+ +
+
+ +

svgWidth

+
svgWidth: number
+ +
+
+ +

x

+
x: number
+ +
+
+ +

y

+
y: number
+ +
+
+
+

Methods

+
+ +

moveTo

+
    +
  • moveTo(newX: any, newY: any, startTime: any, endTime: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      newX: any
      +
    • +
    • +
      newY: any
      +
    • +
    • +
      startTime: any
      +
    • +
    • +
      endTime: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Class
  • +
  • Constructor
  • +
  • Property
  • +
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Inherited property
  • +
  • Inherited method
  • +
+
    +
  • Interface
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/classes/lib_Geometry_graph.Graph2D.html b/docs/classes/lib_Geometry_graph.Graph2D.html new file mode 100644 index 0000000..f2e1fce --- /dev/null +++ b/docs/classes/lib_Geometry_graph.Graph2D.html @@ -0,0 +1,893 @@ + + + + + + Graph2D | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class Graph2D

+
+
+
+
+
+
+
+
+
+

class representing a 2-D Cartesian Graph

+
+
+
+
+

Hierarchy

+
    +
  • + GObject +
      +
    • + Graph2D +
    • +
    +
  • +
+
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+
    +
  • new Graph2D(eqn: Function, x?: number, y?: number, svgWidth?: number, svgHeight?: number): Graph2D
  • +
+
    +
  • + +
    +
    +

    creates a graph object

    +
    +
    +

    Parameters

    +
      +
    • +
      eqn: Function
      +
      +
      +

      function to plot

      +
      +
      +
    • +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    • +
      svgWidth: number = 300
      +
    • +
    • +
      svgHeight: number = 300
      +
    • +
    +

    Returns Graph2D

    +
  • +
+
+
+
+

Properties

+
+ +

config

+
config: { arrowSize: any; axisColor: any; graphBox: any; graphColor: any; graphStrokeWidth: any; grid: any; gridColor: any; maxX: any; maxY: any; minX: any; minY: any; originX: any; originY: any; pathElements: any; scaleX: any; scaleY: any; smallGridColor: any; stepX: any; stepY: any; tickColor: any; tickMarginX: any; tickMarginY: any; tickX: any; tickY: any; xAxis: any; yAxis: any }
+ +
+

Type declaration

+
    +
  • +
    arrowSize: any
    +
  • +
  • +
    axisColor: any
    +
  • +
  • +
    graphBox: any
    +
  • +
  • +
    graphColor: any
    +
  • +
  • +
    graphStrokeWidth: any
    +
  • +
  • +
    grid: any
    +
  • +
  • +
    gridColor: any
    +
  • +
  • +
    maxX: any
    +
  • +
  • +
    maxY: any
    +
  • +
  • +
    minX: any
    +
  • +
  • +
    minY: any
    +
  • +
  • +
    originX: any
    +
  • +
  • +
    originY: any
    +
  • +
  • +
    pathElements: any
    +
  • +
  • +
    scaleX: any
    +
  • +
  • +
    scaleY: any
    +
  • +
  • +
    smallGridColor: any
    +
  • +
  • +
    stepX: any
    +
  • +
  • +
    stepY: any
    +
  • +
  • +
    tickColor: any
    +
  • +
  • +
    tickMarginX: any
    +
  • +
  • +
    tickMarginY: any
    +
  • +
  • +
    tickX: any
    +
  • +
  • +
    tickY: any
    +
  • +
  • +
    xAxis: any
    +
  • +
  • +
    yAxis: any
    +
  • +
+
+
+
+ +

coordinate

+
coordinate: SVGGElement
+ +
+
+ +

eqn

+
eqn: Function
+ +
+
+ +

graphContainer

+
graphContainer: Element
+ +
+
+ +

graphObject

+
graphObject: SVGSVGElement
+ +
+
+ +

linePath

+
linePath: SVGPathElement
+ +
+
+ +

pathData

+
pathData: string
+ +
+
+ +

plotting

+
plotting: SVGGElement
+ +
+
+ +

svgHeight

+
svgHeight: number
+ +
+
+ +

svgWidth

+
svgWidth: number
+ +
+
+ +

x

+
x: number
+ +
+
+ +

y

+
y: number
+ +
+
+
+

Methods

+
+ +

axis

+
    +
  • axis(): void
  • +
+ +
+
+ +

configure

+
    +
  • configure(config: any): void
  • +
+ +
+
+ +

loop

+
    +
  • loop(finlEqn: any, timeDuration?: number, startTime?: number): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      finlEqn: any
      +
    • +
    • +
      timeDuration: number = 2
      +
    • +
    • +
      startTime: number = 0
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

moveTo

+
    +
  • moveTo(newX: any, newY: any, startTime: any, endTime: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      newX: any
      +
    • +
    • +
      newY: any
      +
    • +
    • +
      startTime: any
      +
    • +
    • +
      endTime: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

play

+
    +
  • play(timeDuration?: number, startTime?: number): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      timeDuration: number = 5
      +
    • +
    • +
      startTime: number = 0
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

plot

+
    +
  • plot(): void
  • +
+ +
+
+ +

position

+
    +
  • position(x: number, y?: number): void
  • +
+
    +
  • + +
    +
    +

    sets position of text

    +
    +
    +

    Parameters

    +
      +
    • +
      x: number
      +
    • +
    • +
      y: number = 10
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

scale

+
    +
  • scale(scaleFactor: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      scaleFactor: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

size

+
    +
  • size(width: any, height: any): undefined | number[]
  • +
+
    +
  • + +
    +
    +

    sets font-size of text

    +
    +
    +

    Parameters

    +
      +
    • +
      width: any
      +
    • +
    • +
      height: any
      +
    • +
    +

    Returns undefined | number[]

    +
  • +
+
+
+ +

stroke

+
    +
  • stroke(_stroke: any): void
  • +
+ +
+
+ +

transform

+
    +
  • transform(object_finl: any, startTime?: number, endTime?: number): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      object_finl: any
      +
    • +
    • +
      startTime: number = 0
      +
    • +
    • +
      endTime: number = 2
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

update

+
    +
  • update(eqn: any): void
  • +
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Class
  • +
  • Constructor
  • +
  • Property
  • +
  • Method
  • +
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Inherited property
  • +
  • Inherited method
  • +
+
    +
  • Interface
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/classes/lib_Geometry_parametric.GraphParametric2D.html b/docs/classes/lib_Geometry_parametric.GraphParametric2D.html new file mode 100644 index 0000000..20b087c --- /dev/null +++ b/docs/classes/lib_Geometry_parametric.GraphParametric2D.html @@ -0,0 +1,888 @@ + + + + + + GraphParametric2D | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class GraphParametric2D

+
+
+
+
+
+
+
+

Hierarchy

+
    +
  • + GObject +
      +
    • + GraphParametric2D +
    • +
    +
  • +
+
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+
    +
  • new GraphParametric2D(xeqn: any, yeqn: any, parameterRange?: number[], x?: number, y?: number, svgWidth?: number, svgHeight?: number): GraphParametric2D
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      xeqn: any
      +
    • +
    • +
      yeqn: any
      +
    • +
    • +
      parameterRange: number[] = ...
      +
    • +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    • +
      svgWidth: number = 300
      +
    • +
    • +
      svgHeight: number = 300
      +
    • +
    +

    Returns GraphParametric2D

    +
  • +
+
+
+
+

Properties

+
+ +

config

+
config: { arrowFollowerColor: any; arrowSize: any; axisColor: any; graphColor: any; graphStrokeWidth: any; gridColor: any; maxX: any; maxY: any; minX: any; minY: any; originX: any; originY: any; scaleX: any; scaleY: any; smallGridColor: any; stepX: any; stepY: any; tickColor: any; tickMarginX: any; tickMarginY: any; tickX: any; tickY: any; xAxis: any; yAxis: any }
+ +
+

Type declaration

+
    +
  • +
    arrowFollowerColor: any
    +
  • +
  • +
    arrowSize: any
    +
  • +
  • +
    axisColor: any
    +
  • +
  • +
    graphColor: any
    +
  • +
  • +
    graphStrokeWidth: any
    +
  • +
  • +
    gridColor: any
    +
  • +
  • +
    maxX: any
    +
  • +
  • +
    maxY: any
    +
  • +
  • +
    minX: any
    +
  • +
  • +
    minY: any
    +
  • +
  • +
    originX: any
    +
  • +
  • +
    originY: any
    +
  • +
  • +
    scaleX: any
    +
  • +
  • +
    scaleY: any
    +
  • +
  • +
    smallGridColor: any
    +
  • +
  • +
    stepX: any
    +
  • +
  • +
    stepY: any
    +
  • +
  • +
    tickColor: any
    +
  • +
  • +
    tickMarginX: any
    +
  • +
  • +
    tickMarginY: any
    +
  • +
  • +
    tickX: any
    +
  • +
  • +
    tickY: any
    +
  • +
  • +
    xAxis: any
    +
  • +
  • +
    yAxis: any
    +
  • +
+
+
+
+ +

coordinate

+
coordinate: SVGGElement
+ +
+
+ +

graphContainer

+
graphContainer: Element
+ +
+
+ +

graphObject

+
graphObject: SVGSVGElement
+ +
+
+ +

linePath

+
linePath: SVGPathElement
+ +
+
+ +

parameterRange

+
parameterRange: number[]
+ +
+
+ +

pathData

+
pathData: string
+ +
+
+ +

plotting

+
plotting: SVGGElement
+ +
+
+ +

svgHeight

+
svgHeight: number
+ +
+
+ +

svgWidth

+
svgWidth: number
+ +
+
+ +

x

+
x: number
+ +
+
+ +

xeqn

+
xeqn: Function
+ +
+
+ +

y

+
y: number
+ +
+
+ +

yeqn

+
yeqn: Function
+ +
+
+
+

Methods

+
+ +

arrow

+
    +
  • arrow(eqn: any): void
  • +
+ +
+
+ +

axis

+
    +
  • axis(): void
  • +
+ +
+
+ +

configure

+
    +
  • configure(config: any): void
  • +
+ +
+
+ +

moveTo

+
    +
  • moveTo(newX: any, newY: any, startTime: any, endTime: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      newX: any
      +
    • +
    • +
      newY: any
      +
    • +
    • +
      startTime: any
      +
    • +
    • +
      endTime: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

play

+
    +
  • play(timeDuration: any, delayDuration?: number, element?: string): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      timeDuration: any
      +
    • +
    • +
      delayDuration: number = 0
      +
    • +
    • +
      element: string = 'coordinateSystem'
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

plot

+
    +
  • plot(): void
  • +
+ +
+
+ +

position

+
    +
  • position(x: number, y?: number): void
  • +
+ +
+
+ +

remove

+
    +
  • remove(): void
  • +
+ +
+
+ +

size

+
    +
  • size(width: any, height: any): undefined | number[]
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      width: any
      +
    • +
    • +
      height: any
      +
    • +
    +

    Returns undefined | number[]

    +
  • +
+
+
+ +

stroke

+
    +
  • stroke(_stroke: any): void
  • +
+ +
+
+ +

transform

+
    +
  • transform(object_finl: any, startTime?: number, endTime?: number): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      object_finl: any
      +
    • +
    • +
      startTime: number = 0
      +
    • +
    • +
      endTime: number = 2
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

update

+
    +
  • update(xeqn: any, yeqn: any): void
  • +
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Class
  • +
  • Constructor
  • +
  • Property
  • +
  • Method
  • +
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Inherited property
  • +
  • Inherited method
  • +
+
    +
  • Interface
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/classes/lib_Geometry_polar.GraphPolar2D.html b/docs/classes/lib_Geometry_polar.GraphPolar2D.html new file mode 100644 index 0000000..bda99b1 --- /dev/null +++ b/docs/classes/lib_Geometry_polar.GraphPolar2D.html @@ -0,0 +1,859 @@ + + + + + + GraphPolar2D | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class GraphPolar2D

+
+
+
+
+
+
+
+

Hierarchy

+
    +
  • + GObject +
      +
    • + GraphPolar2D +
    • +
    +
  • +
+
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+
    +
  • new GraphPolar2D(eqn: Function, thetaRange?: number[], x?: number, y?: number, svgWidth?: number, svgHeight?: number): GraphPolar2D
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      eqn: Function
      +
    • +
    • +
      thetaRange: number[] = ...
      +
    • +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    • +
      svgWidth: number = 300
      +
    • +
    • +
      svgHeight: number = 300
      +
    • +
    +

    Returns GraphPolar2D

    +
  • +
+
+
+
+

Properties

+
+ +

config

+
config: { arrowFollowerColor: any; arrowSize: any; axisColor: any; graphColor: any; graphStrokeWidth: any; gridColor: any; maxX: any; maxY: any; minX: any; minY: any; originX: any; originY: any; scaleX: any; scaleY: any; smallGridColor: any; stepX: any; stepY: any; tickColor: any; tickMarginX: any; tickMarginY: any; tickX: any; tickY: any; xAxis: any; yAxis: any }
+ +
+

Type declaration

+
    +
  • +
    arrowFollowerColor: any
    +
  • +
  • +
    arrowSize: any
    +
  • +
  • +
    axisColor: any
    +
  • +
  • +
    graphColor: any
    +
  • +
  • +
    graphStrokeWidth: any
    +
  • +
  • +
    gridColor: any
    +
  • +
  • +
    maxX: any
    +
  • +
  • +
    maxY: any
    +
  • +
  • +
    minX: any
    +
  • +
  • +
    minY: any
    +
  • +
  • +
    originX: any
    +
  • +
  • +
    originY: any
    +
  • +
  • +
    scaleX: any
    +
  • +
  • +
    scaleY: any
    +
  • +
  • +
    smallGridColor: any
    +
  • +
  • +
    stepX: any
    +
  • +
  • +
    stepY: any
    +
  • +
  • +
    tickColor: any
    +
  • +
  • +
    tickMarginX: any
    +
  • +
  • +
    tickMarginY: any
    +
  • +
  • +
    tickX: any
    +
  • +
  • +
    tickY: any
    +
  • +
  • +
    xAxis: any
    +
  • +
  • +
    yAxis: any
    +
  • +
+
+
+
+ +

coordinate

+
coordinate: SVGGElement
+ +
+
+ +

eqn

+
eqn: Function
+ +
+
+ +

graphContainer

+
graphContainer: Element
+ +
+
+ +

graphObject

+
graphObject: SVGSVGElement
+ +
+
+ +

linePath

+
linePath: SVGPathElement
+ +
+
+ +

pathData

+
pathData: string
+ +
+
+ +

plotting

+
plotting: SVGGElement
+ +
+
+ +

svgHeight

+
svgHeight: number
+ +
+
+ +

svgWidth

+
svgWidth: number
+ +
+
+ +

thetaRange

+
thetaRange: number[]
+ +
+
+ +

x

+
x: number
+ +
+
+ +

y

+
y: number
+ +
+
+
+

Methods

+
+ +

arrow

+
    +
  • arrow(timeDuration: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      timeDuration: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

axis

+
    +
  • axis(): void
  • +
+ +
+
+ +

configure

+
    +
  • configure(config: any): void
  • +
+ +
+
+ +

moveTo

+
    +
  • moveTo(newX: any, newY: any, startTime: any, endTime: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      newX: any
      +
    • +
    • +
      newY: any
      +
    • +
    • +
      startTime: any
      +
    • +
    • +
      endTime: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

play

+
    +
  • play(): void
  • +
+ +
+
+ +

plot

+
    +
  • plot(): void
  • +
+ +
+
+ +

position

+
    +
  • position(x: number, y?: number): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      x: number
      +
    • +
    • +
      y: number = 10
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

remove

+
    +
  • remove(): void
  • +
+ +
+
+ +

size

+
    +
  • size(width: any, height: any): undefined | number[]
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      width: any
      +
    • +
    • +
      height: any
      +
    • +
    +

    Returns undefined | number[]

    +
  • +
+
+
+ +

stroke

+
    +
  • stroke(_stroke: any): void
  • +
+ +
+
+ +

transform

+
    +
  • transform(object_finl: any, startTime?: number, endTime?: number): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      object_finl: any
      +
    • +
    • +
      startTime: number = 0
      +
    • +
    • +
      endTime: number = 2
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

update

+
    +
  • update(eqn: any, thetaRange?: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      eqn: any
      +
    • +
    • +
      Optional thetaRange: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Class
  • +
  • Constructor
  • +
  • Property
  • +
  • Method
  • +
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Inherited property
  • +
  • Inherited method
  • +
+
    +
  • Interface
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/classes/lib_MObject_MObject.MObject.html b/docs/classes/lib_MObject_MObject.MObject.html new file mode 100644 index 0000000..ec8d282 --- /dev/null +++ b/docs/classes/lib_MObject_MObject.MObject.html @@ -0,0 +1,406 @@ + + + + + + MObject | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class MObject

+
+
+
+
+
+
+
+

Hierarchy

+
    +
  • + MObject + +
  • +
+
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+
    +
  • new MObject(sentence: string, x: number, y: number, _size: number): MObject
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      sentence: string
      +
    • +
    • +
      x: number
      +
    • +
    • +
      y: number
      +
    • +
    • +
      _size: number
      +
    • +
    +

    Returns MObject

    +
  • +
+
+
+
+

Properties

+
+ +

_size

+
_size: number
+ +
+
+ +

fillColor

+
fillColor: Color
+ +
+
+ +

sentence

+
sentence: string
+ +
+
+ +

writeElement

+
writeElement: Element
+ +
+
+ +

x

+
x: number = 10
+ +
+
+ +

y

+
y: number = 10
+ +
+
+
+

Methods

+
+ +

moveTo

+
    +
  • moveTo(newX: any, newY: any, startTime: any, endTime: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      newX: any
      +
    • +
    • +
      newY: any
      +
    • +
    • +
      startTime: any
      +
    • +
    • +
      endTime: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

resizeTo

+
    +
  • resizeTo(newSize: any, startTime: any, endTime: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      newSize: any
      +
    • +
    • +
      startTime: any
      +
    • +
    • +
      endTime: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Class
  • +
  • Constructor
  • +
  • Property
  • +
  • Method
  • +
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/classes/lib_MObject_TeX.TeX.html b/docs/classes/lib_MObject_TeX.TeX.html new file mode 100644 index 0000000..5a2edc9 --- /dev/null +++ b/docs/classes/lib_MObject_TeX.TeX.html @@ -0,0 +1,805 @@ + + + + + + TeX | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class TeX

+
+
+
+
+
+
+
+
+
+

class representing a tex

+
+
+
+
+

Hierarchy

+ +
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+ +
    +
  • + +
    +
    +

    creates a tex object

    +
    + +
    +
    example
    +

    example for creating TeX object:

    +
    let tex = new TeX(
    + '\\ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-}', 200, 300, 28);
    +
    +
    +
    +
    +

    Parameters

    + +

    Returns TeX

    +
  • +
+
+
+
+

Properties

+
+ +

_size

+
_size: number
+ +
+
+ +

_strokeWidth

+
_strokeWidth: number
+ +
+
+ +

fillColor

+
fillColor: Color
+ +
+
+ +

sentence

+
sentence: string
+ +
+
+ +

strokeColor

+
strokeColor: Color
+ +
+
+ +

svgEquation

+
svgEquation: string
+ +
+
+ +

writeElement

+
writeElement: Element
+ +
+
+ +

x

+
x: number = 10
+ +
+
+ +

y

+
y: number = 10
+ +
+
+
+

Methods

+
+ +

add

+
    +
  • add(): void
  • +
+ +
+
+ +

fill

+
    +
  • fill(fillColor?: any): undefined | Color
  • +
+
    +
  • + +
    +
    +

    sets fill-color of text

    +
    +
    +

    Parameters

    +
      +
    • +
      fillColor: any = 'black'
      +
    • +
    +

    Returns undefined | Color

    +
  • +
+
+
+ +

moveTo

+
    +
  • moveTo(newX: any, newY: any, startTime: any, endTime: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      newX: any
      +
    • +
    • +
      newY: any
      +
    • +
    • +
      startTime: any
      +
    • +
    • +
      endTime: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

play

+
    +
  • play(animationType?: string, startTime?: number, endTime?: number): void
  • +
+
    +
  • + +
    +
    +

    play text animation

    +
    +
    +

    Parameters

    +
      +
    • +
      animationType: string = 'write'
      +
      +

      type of animation to be played

      +
      +
    • +
    • +
      startTime: number = 0
      +
    • +
    • +
      endTime: number = 0
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

position

+
    +
  • position(x?: number, y?: number): undefined | number[]
  • +
+
    +
  • + +
    +
    +

    sets position of tex

    +
    +
    +

    Parameters

    +
      +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    +

    Returns undefined | number[]

    +
  • +
+
+
+ +

remove

+
    +
  • remove(): void
  • +
+
    +
  • + +
    +
    +

    removes text object

    +
    +
    +

    Returns void

    +
  • +
+
+
+ +

resizeTo

+
    +
  • resizeTo(newSize: any, startTime: any, endTime: any): void
  • +
+ +
+
+ +

size

+
    +
  • size(_size?: number): undefined | number
  • +
+
    +
  • + +
    +
    +

    sets font-size of tex

    +
    +
    +

    Parameters

    +
      +
    • +
      _size: number = 28
      +
    • +
    +

    Returns undefined | number

    +
  • +
+
+
+ +

stroke

+
    +
  • stroke(strokeColor?: any): undefined | Color
  • +
+
    +
  • + +
    +
    +

    sets stroke-color of tex

    +
    +
    +

    Parameters

    +
      +
    • +
      strokeColor: any = 'black'
      +
    • +
    +

    Returns undefined | Color

    +
  • +
+
+
+ +

strokeWidth

+
    +
  • strokeWidth(_strokeWidth?: number): undefined | number
  • +
+
    +
  • + +
    +
    +

    sets stroke-width of tex

    +
    +
    +

    Parameters

    +
      +
    • +
      _strokeWidth: number = 8
      +
    • +
    +

    Returns undefined | number

    +
  • +
+
+
+ +

style

+
    +
  • style(property: any, value: any): void
  • +
+
    +
  • + +
    +
    +

    Sets the given style (css) property (1st arg) of the element with the + given value (2nd arg). If the single argument + is given in css syntax ('text-align:center'), .style() sets the css + appropriately.

    +
    +
    +

    Parameters

    +
      +
    • +
      property: any
      +
      +

      property to be set

      +
      +
    • +
    • +
      value: any
      +
      +

      value

      +
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

update

+
    +
  • update(_tex: any): void
  • +
+
    +
  • + +
    +
    +

    updates the tex

    +
    +
    +

    Parameters

    +
      +
    • +
      _tex: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Class
  • +
  • Constructor
  • +
  • Property
  • +
  • Method
  • +
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Inherited property
  • +
  • Inherited method
  • +
+
    +
  • Interface
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/classes/lib_MObject_Text.Text.html b/docs/classes/lib_MObject_Text.Text.html new file mode 100644 index 0000000..c9bec77 --- /dev/null +++ b/docs/classes/lib_MObject_Text.Text.html @@ -0,0 +1,670 @@ + + + + + + Text | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class Text

+
+
+
+
+
+
+
+
+
+

class representing a text

+
+
+
+
+

Hierarchy

+ +
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+ +
    +
  • + +
    +
    +

    creates a text object

    +
    +
    +
    example
    +

    example for creating text object:

    +
    let text = new Text('Hi!', width/2, height/2, 28)
    +
    +
    +
    +
    +

    Parameters

    + +

    Returns Text

    +
  • +
+
+
+
+

Properties

+
+ +

_size

+
_size: number
+ +
+
+ +

fillColor

+
fillColor: Color
+ +
+
+ +

sentence

+
sentence: string
+ +
+
+ +

writeElement

+
writeElement: Element
+ +
+
+ +

x

+
x: number = 10
+ +
+
+ +

y

+
y: number = 10
+ +
+
+
+

Methods

+
+ +

add

+
    +
  • add(): void
  • +
+ +
+
+ +

fill

+
    +
  • fill(fillColor?: any): undefined | Color
  • +
+
    +
  • + +
    +
    +

    sets fill-color of text

    +
    +
    +

    Parameters

    +
      +
    • +
      fillColor: any = ...
      +
    • +
    +

    Returns undefined | Color

    +
  • +
+
+
+ +

moveTo

+
    +
  • moveTo(newX: any, newY: any, startTime: any, endTime: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      newX: any
      +
    • +
    • +
      newY: any
      +
    • +
    • +
      startTime: any
      +
    • +
    • +
      endTime: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

play

+
    +
  • play(animationType?: string, timeDuration?: number, delayDuration?: number): void
  • +
+
    +
  • + +
    +
    +

    play text animation

    +
    +
    +

    Parameters

    +
      +
    • +
      animationType: string = 'write'
      +
      +

      type of animation to be played

      +
      +
    • +
    • +
      timeDuration: number = 0
      +
      +

      duration of animation

      +
      +
    • +
    • +
      delayDuration: number = 0
      +
      +

      delay

      +
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

position

+
    +
  • position(x?: number, y?: number): undefined | number[]
  • +
+
    +
  • + +
    +
    +

    sets position of text

    +
    +
    +

    Parameters

    +
      +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    +

    Returns undefined | number[]

    +
  • +
+
+
+ +

remove

+
    +
  • remove(): void
  • +
+ +
+
+ +

resizeTo

+
    +
  • resizeTo(newSize: any, startTime: any, endTime: any): void
  • +
+ +
+
+ +

size

+
    +
  • size(_size?: number): undefined | number
  • +
+
    +
  • + +
    +
    +

    sets font-size of text

    +
    +
    +

    Parameters

    +
      +
    • +
      _size: number = 28
      +
    • +
    +

    Returns undefined | number

    +
  • +
+
+
+ +

style

+
    +
  • style(property: any, value: any): void
  • +
+
    +
  • + +
    +
    +

    Sets the given style (css) property (1st arg) of the element with the + given value (2nd arg). If the single argument + is given in css syntax ('text-align:center'), .style() sets the css + appropriately.

    +
    +
    +

    Parameters

    +
      +
    • +
      property: any
      +
      +

      property to be set

      +
      +
    • +
    • +
      value: any
      +
      +

      value

      +
      +
    • +
    +

    Returns void

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Class
  • +
  • Constructor
  • +
  • Method
  • +
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Inherited property
  • +
  • Inherited method
  • +
+
    +
  • Interface
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/classes/lib_Scene_group.Group.html b/docs/classes/lib_Scene_group.Group.html new file mode 100644 index 0000000..77c31ba --- /dev/null +++ b/docs/classes/lib_Scene_group.Group.html @@ -0,0 +1,301 @@ + + + + + + Group | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class Group

+
+
+
+
+
+
+
+

Hierarchy

+
    +
  • + Group +
  • +
+
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+
    +
  • new Group(...args: any[]): Group
  • +
+ +
+
+
+

Properties

+
+ +

group

+
group: any
+ +
+
+
+

Methods

+
+ +

remove

+
    +
  • remove(): void
  • +
+ +
+
+ +

scale

+
    +
  • scale(scaleFactor: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      scaleFactor: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Class
  • +
  • Constructor
  • +
  • Property
  • +
  • Method
  • +
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/classes/lib_Scene_scene.Scene.html b/docs/classes/lib_Scene_scene.Scene.html new file mode 100644 index 0000000..29217f8 --- /dev/null +++ b/docs/classes/lib_Scene_scene.Scene.html @@ -0,0 +1,278 @@ + + + + + + Scene | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class Scene

+
+
+
+
+
+
+
+

Hierarchy

+
    +
  • + Scene +
  • +
+
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+ + +
+
+
+

Methods

+
+ +

delay

+
    +
  • delay(sec: number): Promise<unknown>
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      sec: number
      +
    • +
    +

    Returns Promise<unknown>

    +
  • +
+
+
+ +

remove

+
    +
  • remove(): void
  • +
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Class
  • +
  • Constructor
  • +
  • Method
  • +
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..2a14503 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,206 @@ + + + + + + p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+

p5.teach.js

+
+
+
+
+
+
+
+ +

p5.teach.js

+
+ astrik-logo +
+

A beginner friendly math animation library for p5.js

+
+

p5.teach.js provides tools for teaching through p5.js, such as functions to animate text, TeX, and shapes.

+ +

Get Started

+
+ +

Documentation

+
+ + +

Setting up the development environment

+
+
    +
  1. Yarn should be preinstalled
  2. +
  3. Run yarn install for installing the dependencies
  4. +
  5. Run yarn dev for running the dev environment
  6. +
  7. As the code is updated, the final js file is updated in dist/p5.teach.js dynamically
  8. +
  9. The sketch in the index.html file is reflected with the changes
  10. +
+ +

Generating documentation

+
+
    +
  1. We use TypeDoc
  2. +
  3. Run yarn typedoc src for generating docs
  4. +
+ +

Tests

+
+
    +
  1. We use jest for testing
  2. +
  3. Run yarn test for running tests
  4. +
  5. Tests are in src/test
  6. +
+ +

Formatting the code

+
+
    +
  1. Before submitting PR, run yarn prettier to format the code
  2. +
+ +

Build

+
+
    +
  1. Run yarn build to export the final js file
  2. +
  3. Final js file is exported as dist/p5.teach.js
  4. +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/interfaces/lib_interfaces.TexObject.html b/docs/interfaces/lib_interfaces.TexObject.html new file mode 100644 index 0000000..6962d25 --- /dev/null +++ b/docs/interfaces/lib_interfaces.TexObject.html @@ -0,0 +1,250 @@ + + + + + + TexObject | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface TexObject

+
+
+
+
+
+
+
+

Hierarchy

+
    +
  • + TexObject +
  • +
+
+
+

Index

+
+
+
+

Properties

+ +
+
+
+
+
+

Properties

+
+ +

Optional _size

+
_size: number
+ +
+
+ +

_tex

+
_tex: string
+ +
+
+ +

Optional x

+
x: number
+ +
+
+ +

Optional y

+
y: number
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
  • Property
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/interfaces/lib_interfaces.TextObject.html b/docs/interfaces/lib_interfaces.TextObject.html new file mode 100644 index 0000000..676bc2f --- /dev/null +++ b/docs/interfaces/lib_interfaces.TextObject.html @@ -0,0 +1,250 @@ + + + + + + TextObject | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface TextObject

+
+
+
+
+
+
+
+

Hierarchy

+
    +
  • + TextObject +
  • +
+
+
+

Index

+
+
+
+

Properties

+ +
+
+
+
+
+

Properties

+
+ +

Optional _size

+
_size: number
+ +
+
+ +

_text

+
_text: string
+ +
+
+ +

Optional x

+
x: number
+ +
+
+ +

Optional y

+
y: number
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
  • Property
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules.html b/docs/modules.html new file mode 100644 index 0000000..b2e8e17 --- /dev/null +++ b/docs/modules.html @@ -0,0 +1,175 @@ + + + + + + p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+

p5.teach.js

+
+
+
+ +
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Geometry_GObject.html b/docs/modules/lib_Geometry_GObject.html new file mode 100644 index 0000000..a69748c --- /dev/null +++ b/docs/modules/lib_Geometry_GObject.html @@ -0,0 +1,171 @@ + + + + + + lib/Geometry/GObject | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Geometry/GObject

+
+
+
+
+ +
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Geometry_Shape.html b/docs/modules/lib_Geometry_Shape.html new file mode 100644 index 0000000..6aa7de5 --- /dev/null +++ b/docs/modules/lib_Geometry_Shape.html @@ -0,0 +1,290 @@ + + + + + + lib/Geometry/Shape | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Geometry/Shape

+
+
+
+
+
+
+
+

Index

+
+
+
+

Classes

+ +
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

SVGControlPointPosition

+
    +
  • SVGControlPointPosition(event: any): void
  • +
+ +
+
+ +

beginGraph

+
    +
  • beginGraph(x?: number, y?: number, svgWidth?: number, svgHeight?: number): Graph
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    • +
      svgWidth: number = ...
      +
    • +
    • +
      svgHeight: number = ...
      +
    • +
    +

    Returns Graph

    +
  • +
+
+
+ +

controlPoint

+
    +
  • controlPoint(...args: any[]): undefined | SVGControlPoint
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      Rest ...args: any[]
      +
    • +
    +

    Returns undefined | SVGControlPoint

    +
  • +
+
+
+ +

endGraph

+
    +
  • endGraph(): void
  • +
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Geometry_arrow.html b/docs/modules/lib_Geometry_arrow.html new file mode 100644 index 0000000..535adca --- /dev/null +++ b/docs/modules/lib_Geometry_arrow.html @@ -0,0 +1,197 @@ + + + + + + lib/Geometry/arrow | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Geometry/arrow

+
+
+
+
+
+
+
+

Index

+
+
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

arrow

+
    +
  • arrow(...args: any[]): undefined | SVGArrow
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      Rest ...args: any[]
      +
    • +
    +

    Returns undefined | SVGArrow

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Geometry_graph.html b/docs/modules/lib_Geometry_graph.html new file mode 100644 index 0000000..efb19c4 --- /dev/null +++ b/docs/modules/lib_Geometry_graph.html @@ -0,0 +1,266 @@ + + + + + + lib/Geometry/graph | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Geometry/graph

+
+
+
+
+
+
+
+

Index

+
+
+
+

Classes

+ +
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

create2DGraph

+
    +
  • create2DGraph(eqn: Function, x?: number, y?: number, svgWidth?: number, svgHeight?: number): Graph2D
  • +
+
    +
  • + +
    +
    +

    create2DGraph function creates a graph object and return graph object

    +
    +
    +

    Parameters

    +
      +
    • +
      eqn: Function
      +
      +

      function to plot

      +
      +
    • +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    • +
      svgWidth: number = 300
      +
    • +
    • +
      svgHeight: number = 300
      +
    • +
    +

    Returns Graph2D

    +

    2D Graph object

    +
  • +
+
+
+ +

createSVGPath

+
    +
  • createSVGPath(eqn: Function, config: any): string
  • +
+
    +
  • + +
    +
    +

    createSVGPath function creates a graph object and returns graph object

    +
    +
    +

    Parameters

    +
      +
    • +
      eqn: Function
      +
      +

      function to plot

      +
      +
    • +
    • +
      config: any
      +
    • +
    +

    Returns string

    +

    2D Graph object

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Geometry_parametric.html b/docs/modules/lib_Geometry_parametric.html new file mode 100644 index 0000000..1e53e8a --- /dev/null +++ b/docs/modules/lib_Geometry_parametric.html @@ -0,0 +1,260 @@ + + + + + + lib/Geometry/parametric | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Geometry/parametric

+
+
+
+
+
+
+
+

Index

+
+
+
+

Classes

+ +
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

create2DParametricGraph

+
    +
  • create2DParametricGraph(xeqn: any, yeqn: any, parameterRange?: number[], x?: number, y?: number, svgWidth?: number, svgHeight?: number): GraphParametric2D
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      xeqn: any
      +
    • +
    • +
      yeqn: any
      +
    • +
    • +
      parameterRange: number[] = ...
      +
    • +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    • +
      svgWidth: number = 300
      +
    • +
    • +
      svgHeight: number = 300
      +
    • +
    +

    Returns GraphParametric2D

    +
  • +
+
+
+ +

createParametricSVGPath

+
    +
  • createParametricSVGPath(xeqn: any, yeqn: any, parameterRange?: number[], config: any): string
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      xeqn: any
      +
    • +
    • +
      yeqn: any
      +
    • +
    • +
      parameterRange: number[] = ...
      +
    • +
    • +
      config: any
      +
    • +
    +

    Returns string

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Geometry_polar.html b/docs/modules/lib_Geometry_polar.html new file mode 100644 index 0000000..7dd47c4 --- /dev/null +++ b/docs/modules/lib_Geometry_polar.html @@ -0,0 +1,254 @@ + + + + + + lib/Geometry/polar | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Geometry/polar

+
+
+
+
+
+
+
+

Index

+
+
+
+

Classes

+ +
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

create2DPolarGraph

+
    +
  • create2DPolarGraph(eqn: Function, thetaRange?: number[], x?: number, y?: number, svgWidth?: number, svgHeight?: number): GraphPolar2D
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      eqn: Function
      +
    • +
    • +
      thetaRange: number[] = ...
      +
    • +
    • +
      x: number = 10
      +
    • +
    • +
      y: number = 10
      +
    • +
    • +
      svgWidth: number = 300
      +
    • +
    • +
      svgHeight: number = 300
      +
    • +
    +

    Returns GraphPolar2D

    +
  • +
+
+
+ +

createPolarSVGPath

+
    +
  • createPolarSVGPath(eqn: any, thetaRange?: number[], config: any): string
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      eqn: any
      +
    • +
    • +
      thetaRange: number[] = ...
      +
    • +
    • +
      config: any
      +
    • +
    +

    Returns string

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_MObject_MObject.html b/docs/modules/lib_MObject_MObject.html new file mode 100644 index 0000000..90c2135 --- /dev/null +++ b/docs/modules/lib_MObject_MObject.html @@ -0,0 +1,171 @@ + + + + + + lib/MObject/MObject | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/MObject/MObject

+
+
+
+
+ +
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_MObject_TeX.html b/docs/modules/lib_MObject_TeX.html new file mode 100644 index 0000000..a48f995 --- /dev/null +++ b/docs/modules/lib_MObject_TeX.html @@ -0,0 +1,222 @@ + + + + + + lib/MObject/TeX | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/MObject/TeX

+
+
+
+
+
+
+
+

Index

+
+
+
+

Classes

+ +
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

createTeX

+
    +
  • createTeX(...args: any[]): TeX
  • +
+
    +
  • + +
    +
    +

    createTeX

    +
    +
    +

    Parameters

    +
      +
    • +
      Rest ...args: any[]
      +
      +
      let tex = createTeX(
      + '\\ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-}\\overrightarrow{F}_{12} = k_e \\frac{q_1 q_2}{r^2}',
      +  200,
      +  300,
      +  20,
      +);
      +
      +
      + +
      +
    • +
    +

    Returns TeX

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_MObject_Text.html b/docs/modules/lib_MObject_Text.html new file mode 100644 index 0000000..4918665 --- /dev/null +++ b/docs/modules/lib_MObject_Text.html @@ -0,0 +1,212 @@ + + + + + + lib/MObject/Text | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/MObject/Text

+
+
+
+
+
+
+
+

Index

+
+
+
+

Classes

+ +
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

createText

+
    +
  • createText(...args: any[]): Text
  • +
+
    +
  • + +
    +
    +

    createText function creates a text object and return text object

    +
    +
    +

    Parameters

    +
      +
    • +
      Rest ...args: any[]
      +
    • +
    +

    Returns Text

    +

    MObject of type Text

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Scene_add.html b/docs/modules/lib_Scene_add.html new file mode 100644 index 0000000..e83147a --- /dev/null +++ b/docs/modules/lib_Scene_add.html @@ -0,0 +1,197 @@ + + + + + + lib/Scene/add | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Scene/add

+
+
+
+
+
+
+
+

Index

+
+
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

add

+
    +
  • add(object: Text | TeX): void
  • +
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Scene_controls.html b/docs/modules/lib_Scene_controls.html new file mode 100644 index 0000000..331cbf1 --- /dev/null +++ b/docs/modules/lib_Scene_controls.html @@ -0,0 +1,291 @@ + + + + + + lib/Scene/controls | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Scene/controls

+
+
+
+
+
+
+
+

Index

+
+
+
+

Variables

+ +
+
+

Functions

+ +
+
+
+
+
+

Variables

+
+ +

Let animationTimeline

+
animationTimeline: AnimeTimelineInstance = ...
+ +
+
+
+

Functions

+
+ +

addDuration

+
    +
  • addDuration(timeDuration: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      timeDuration: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

callAt

+
    +
  • callAt(startTime: any, func: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      startTime: any
      +
    • +
    • +
      func: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

clock

+
    +
  • clock(): number
  • +
+ +
+
+ +

createControls

+
    +
  • createControls(): void
  • +
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Scene_group.html b/docs/modules/lib_Scene_group.html new file mode 100644 index 0000000..897e9eb --- /dev/null +++ b/docs/modules/lib_Scene_group.html @@ -0,0 +1,206 @@ + + + + + + lib/Scene/group | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Scene/group

+
+
+
+
+
+
+
+

Index

+
+
+
+

Classes

+ +
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

createGroup

+
    +
  • createGroup(...args: any[]): Group
  • +
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Scene_play.html b/docs/modules/lib_Scene_play.html new file mode 100644 index 0000000..910485d --- /dev/null +++ b/docs/modules/lib_Scene_play.html @@ -0,0 +1,220 @@ + + + + + + lib/Scene/play | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Scene/play

+
+
+
+
+
+
+
+

Index

+
+
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

play

+
    +
  • play(object: any, animationType?: string, startTime?: number, endTime?: number): void
  • +
+
    +
  • + +
    +
    +

    Animation functions

    +
    +
    +
    example
    +

    example for playing animation of type 'appear' for TeX object:

    +
    play(tex_1, 'appear', 2000);
    +
    +
    +
    experimental
    +
    +
    +
    +

    Parameters

    +
      +
    • +
      object: any
      +
    • +
    • +
      animationType: string = 'write'
      +
    • +
    • +
      startTime: number = 0
      +
    • +
    • +
      endTime: number = 0
      +
    • +
    +

    Returns void

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Scene_scene.html b/docs/modules/lib_Scene_scene.html new file mode 100644 index 0000000..9fd4060 --- /dev/null +++ b/docs/modules/lib_Scene_scene.html @@ -0,0 +1,242 @@ + + + + + + lib/Scene/scene | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Scene/scene

+
+
+
+
+
+
+
+

Index

+
+
+
+

Classes

+ +
+
+

Variables

+ +
+
+

Functions

+ +
+
+
+
+
+

Variables

+
+ +

Let sceneContainer

+
sceneContainer: HTMLDivElement
+ +
+
+ +

Let sceneVariables

+
sceneVariables: ISceneVariables = ...
+ +
+
+
+

Functions

+
+ +

overflow

+
    +
  • overflow(value: any): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      value: any
      +
    • +
    +

    Returns void

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_Scene_transform.html b/docs/modules/lib_Scene_transform.html new file mode 100644 index 0000000..864dc84 --- /dev/null +++ b/docs/modules/lib_Scene_transform.html @@ -0,0 +1,206 @@ + + + + + + lib/Scene/transform | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/Scene/transform

+
+
+
+
+
+
+
+

Index

+
+
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

transform

+
    +
  • transform(objectInit: any, objectFinl: any, startTime?: number, endTime?: number): void
  • +
+
    +
  • + +

    Parameters

    +
      +
    • +
      objectInit: any
      +
    • +
    • +
      objectFinl: any
      +
    • +
    • +
      startTime: number = 0
      +
    • +
    • +
      endTime: number = 2
      +
    • +
    +

    Returns void

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/lib_interfaces.html b/docs/modules/lib_interfaces.html new file mode 100644 index 0000000..6962766 --- /dev/null +++ b/docs/modules/lib_interfaces.html @@ -0,0 +1,175 @@ + + + + + + lib/interfaces | p5.teach.js + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + +
+
+ Menu +
+
+
+
+
+
+ +

Module lib/interfaces

+
+
+
+ +
+
+

Legend

+
+
    +
  • Variable
  • +
  • Function
  • +
+
    +
  • Interface
  • +
+
    +
  • Class
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/gsoc/project_wrapup.md b/gsoc/project_wrapup.md new file mode 100644 index 0000000..b7dc353 --- /dev/null +++ b/gsoc/project_wrapup.md @@ -0,0 +1,36 @@ +# Addon Library Development - [p5.teach.js](https://github.com/two-ticks/p5.teach.js/) + +#### By Aditya Siddheshwar ([@two-ticks](https://github.com/two-ticks)) | GSoC 2021 + +## Overview +During the Google Summer of Code '21, I worked on p5.teach, under the mentorship of **Jithin KS** and **Nick McIntyre**. The goal of this project was to build an addon library for teaching maths through animations and simulations. It will provide users friendly API for creating text, TeX, and shape animations. +The major goals of this project were: +1. Development of animation methods and controls +2. Support for TeX + +## Tasks Completed +* Created TeX elements with help of tex-to-svg library (using MathJax) +* Created TeX and text animations using MathJax and anime.js by manipulating p5.js DOM elements and SVG elements +* Wrote play function for animations like write, waveIn, waveOut, fadeIn, fadeOut, createFill, etc. for TeX and text +* Added controls like play, pause and restart buttons for timeline +* Wrote test cases using Jest +* Included style, add, play, remove, update, fill, stroke, strokeWeight, position, and size methods for MObjects +* Included SVG plotting methods and animations +* Developed demo sketches and posted on Instagram, Processing Forum, and Twitter + +## Challenges +* TDD is important and is one of the most preferred best practices; however, it was quite challenging to develop test cases considering the lack of documentation involving Jest with p5.js and keep progressing under GSoC time constraints. +* Adding animations to TeX with help of SVGs required a lot of effort and research. I learned a lot about SVGs and TypeScript from articles and tutorials while solving this problem. +* GObjects (Geometry Objects) required a lot of digging and discussion to figure out API and apply configurations to the plots. + +## PRs +* https://github.com/two-ticks/p5.teach.js/pull/13 +* https://github.com/two-ticks/p5.teach.js/pull/6 +* https://github.com/two-ticks/p5.teach.js/pull/20 + +## Contribution & Next Steps +p5.teach is having text, TeX, and Shapes, I will refactor and fix bugs in animation. Before hosting it on the cloud, I will coordinate with mentors to ensure the library meets the coding standards and includes sufficient documentation. I will further improve the library by adding new features and adding more to the existing features. + +## Conclusion and Acknowledgements +I really had a lot of fun working on this project and learned a lot of things this summer working with my mentors and Processing Community. +I would like to thank my mentors **Jithin KS** and **Nick McIntyre** for their invaluable help and guidance throughout this summer of code. Their love for teaching, code, and STEM inspired me to do more work on the library. Nick pushed me in the right direction for API, and Jithin always emphasized best practices and standards. I am extremely grateful to the Processing community for having me in the team (family). \ No newline at end of file diff --git a/gsoc/proposal.pdf b/gsoc/proposal.pdf new file mode 100644 index 0000000..a805b45 Binary files /dev/null and b/gsoc/proposal.pdf differ diff --git a/package.json b/package.json index a468749..77ab64e 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,12 @@ "dependencies": { "animejs": "^3.2.1", "p5": "^1.2.0", - "tex-to-svg": "^0.2.0" + "tex-to-svg": "^0.2.0", + "typedoc": "^0.21.5" }, "devDependencies": { - "@types/jest": "^26.0.23", "@types/animejs": "^3.1.3", + "@types/jest": "^26.0.23", "@types/p5": "^0.9.1", "jest": "^26.6.3", "parcel-bundler": "^1.12.4", diff --git a/src/index.ts b/src/index.ts index 0b3ccc9..c8779bb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,5 +16,78 @@ global.add = add; import { play } from './lib/Scene/play'; global.play = play; -import { Scene } from './lib/Scene/scene'; -global.Scene = Scene; +import { Scene, overflow } from './lib/Scene/scene'; +// global.Scene = Scene; +global.overflow = overflow; + +global.p5.prototype.registerMethod('init', () => new Scene()); + +import { + //sceneTime, + createControls, + clock, + callAt, + addDuration + // pauseScene, + // playScene, + // restartScene +} from './lib/Scene/controls'; +//global.sceneTime = sceneTime; +global.createControls = createControls; +global.clock = clock; +global.callAt = callAt; +global.addDuration = addDuration; + +// global.pauseScene = pauseScene; +// global.playScene = playScene; +// global.restartScene = restartScene; + +import { + beginGraph, + controlPoint, + endGraph, + SVGControlPointPosition, + polyline +} from './lib/Geometry/Shape'; + +global.beginGraph = beginGraph; +global.polyline = polyline; +global.controlPoint = controlPoint; +global.SVGControlPointPosition = SVGControlPointPosition; +global.endGraph = endGraph; + +import { transform } from './lib/Scene/transform'; + +global.transform = transform; + +import { Graph2D, create2DGraph, plot2D, axis } from './lib/Geometry/graph'; + +global.Graph2D = Graph2D; +global.plot2D = plot2D; +global.axis = axis; +global.create2DGraph = create2DGraph; + +import { + GraphPolar2D, + create2DPolarGraph, + polar2D +} from './lib/Geometry/polar'; + +global.GraphPolar2D = GraphPolar2D; +global.polar2D = polar2D; + +global.create2DPolarGraph = create2DPolarGraph; + +import { + GraphParametric2D, + create2DParametricGraph, + parametric2D +} from './lib/Geometry/parametric'; + +global.GraphParametric2D = GraphParametric2D; +global.parametric2D = parametric2D; + +global.create2DParametricGraph = create2DParametricGraph; + +import { arrow } from './lib/Geometry/arrow'; +global.arrow = arrow; diff --git a/src/lib/Geometry/GObject.ts b/src/lib/Geometry/GObject.ts new file mode 100644 index 0000000..8bf6837 --- /dev/null +++ b/src/lib/Geometry/GObject.ts @@ -0,0 +1,54 @@ +import p5 from 'p5'; +import { animationTimeline } from '../Scene/controls'; + +export class GObject { + pathData!: string; + graphObject!: SVGSVGElement; + graphContainer!: p5.Element; + linePath!: SVGPathElement; + x: number; + y: number; + svgWidth: number; + svgHeight: number; + + constructor( + x: number = 10, + y: number = 10, + svgWidth: number = 300, + svgHeight: number = 300 + ) { + this.x = x; + this.y = y; + this.svgWidth = svgWidth; + this.svgHeight = svgHeight; + } + + moveTo(newX, newY, startTime, endTime) { + const object = this.graphContainer; + const timeDuration = (endTime - startTime) * 1000; + const delayDuration = startTime * 1000; + const currCoord = { + currX: this.x, + currY: this.y + }; + animationTimeline.add( + { + targets: currCoord, //[this.x, this.y], + currX: newX, + currY: newY, + + //translateZ: 0, + easing: 'easeInOutCubic', + duration: timeDuration, + update: function (anim) { + this.x = currCoord.currX; + this.y = currCoord.currY; + object.position(this.x, this.y); + } + //delay: anime.stagger(CONFIG.PLAY.DISSOLVE_STAGGERING_DELAY) + //delay: anime.stagger(180, { start: timeDuration }) //time duration must be replaced with delay + }, + delayDuration + ); + } +} diff --git a/src/lib/Geometry/Shape.ts b/src/lib/Geometry/Shape.ts new file mode 100644 index 0000000..f387eef --- /dev/null +++ b/src/lib/Geometry/Shape.ts @@ -0,0 +1,812 @@ +import anime from 'animejs'; +// import p5 from 'p5'; +import { animationTimeline } from '../Scene/controls'; +import { sceneContainer, sceneVariables } from '../Scene/scene'; +import { transform } from '../Scene/transform'; +import { GObject } from './GObject'; + +const global: any = globalThis; +const ULTRAMARINE40 = '#648fff'; +const MAGENTA50 = '#dc267f'; +const GOLD20 = '#ffb000'; +const INDIGO50 = '#785ef0'; +const ORANGE40 = '#fe6100'; + +export class Graph extends GObject { + plotting!: SVGGElement; + coordinate!: SVGGElement; + config: { + //configuration for graph + scaleX: any; + maxX: any; + minX: any; + scaleY: any; + maxY: any; + minY: any; + graphColor: any; + graphStrokeWidth: any; + arrowSize: any; + xAxis: any; + yAxis: any; + axisColor: any; + grid: any; + smallGridColor: any; + gridColor: any; + stepX: any; + stepY: any; + originX: any; + originY: any; + tickX: any; + tickY: any; + tickColor: any; + tickMarginX: any; + tickMarginY: any; + pathElements: any; + graphBox: any; + }; + // pathData: any; + // graphObject: any; + // graphContainer: any; + // x: number; + // y: number; + // svgWidth: number; + // svgHeight: number; + // linePath: SVGPathElement; + + constructor( + x: number = 0, + y: number = 0, + svgWidth: number = 300, + svgHeight: number = 300 + ) { + sceneVariables.isGraph = 'true'; + //window.isGraph = 'true'; + super(x, y, svgWidth, svgHeight); + this.config = { + graphColor: GOLD20, + graphStrokeWidth: 1, + arrowSize: 3, + xAxis: 'true', + yAxis: 'true', + minX: -12, + maxX: 10, + minY: -10, + maxY: 10, + scaleX: 1, + scaleY: 1, + axisColor: INDIGO50, + grid: 'true', + smallGridColor: MAGENTA50, + gridColor: ORANGE40, + stepX: 1, + stepY: 1, + originX: 0, + originY: 0, + tickX: 'false', + tickY: 'false', + tickColor: ULTRAMARINE40, + tickMarginX: -0.5, + tickMarginY: -0.5, + pathElements: 1000, + graphBox: 'true' + }; + + this.config.scaleX = abs( + this.svgWidth / (this.config.maxX - this.config.minX) + ); + this.config.scaleY = abs( + this.svgHeight / (this.config.maxY - this.config.minY) + ); + // this.x = x; + // this.y = y; + // this.svgWidth = svgWidth; + // this.svgHeight = svgHeight; + //this.pathData = createParametricSVGPath(this.xeqn, this.yeqn, this.parameterRange, this.config); + this.graphContainer = createElement('div'); + this.graphContainer.parent(sceneContainer); + this.linePath = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'path' + ); + this.linePath.setAttribute('fill', 'none'); + this.linePath.setAttribute('stroke', 'black'); + this.linePath.setAttribute( + 'stroke-width', + `${this.config.graphStrokeWidth}` + ); + this.graphContainer.position(this.x, this.y); + this.graphObject = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'svg' + ); + //this.graphObject.setAttribute('onload', 'SVGControlPointPosition(evt)'); + this.graphObject.setAttribute('width', `${this.svgWidth}`); + this.graphObject.setAttribute('height', `${this.svgHeight}`); + this.graphObject.setAttribute( + 'viewBox', + `${-this.svgWidth / 2} ${-this.svgHeight / 2} ${this.svgWidth} ${ + this.svgHeight + }` + ); + this.graphObject.setAttribute('preserveAspectRatio', 'xMidYMid meet'); + this.graphContainer.elt.appendChild(this.graphObject); + + return this; + } + + configure(config) { + this.config = { + graphColor: config.graphColor + ? config.graphColor + : this.config.graphColor, + graphStrokeWidth: config.graphStrokeWidth + ? config.graphStrokeWidth + : this.config.graphStrokeWidth, + arrowSize: config.arrowSize ? config.arrowSize : this.config.arrowSize, + xAxis: config.xAxis ? config.xAxis : this.config.xAxis, + yAxis: config.yAxis ? config.yAxis : this.config.yAxis, + minX: config.minX ? config.minX : this.config.minX, + maxX: config.maxX ? config.maxX : this.config.maxX, + minY: config.minY ? config.minY : this.config.minY, + maxY: config.maxY ? config.maxY : this.config.maxY, + scaleX: config.scaleX ? config.scaleX : this.config.scaleX, + scaleY: config.scaleY ? config.scaleY : this.config.scaleY, + axisColor: config.axisColor ? config.axisColor : this.config.axisColor, + smallGridColor: config.smallGridColor + ? config.smallGridColor + : this.config.smallGridColor, + gridColor: config.gridColor ? config.gridColor : this.config.gridColor, + stepX: config.stepX ? config.stepX : this.config.stepX, + stepY: config.stepY ? config.stepY : this.config.stepY, + originX: config.originX ? config.originX : this.config.originX, + originY: config.originY ? config.originY : this.config.originY, + grid: config.grid ? config.grid : this.config.grid, + tickX: config.tickX ? config.tickX : this.config.tickX, + tickY: config.tickY ? config.tickY : this.config.tickY, + tickColor: config.tickColor ? config.tickColor : this.config.tickColor, + tickMarginX: config.tickMarginX + ? config.tickMarginX + : this.config.tickMarginX, + tickMarginY: config.tickMarginY + ? config.tickMarginY + : this.config.tickMarginY, + pathElements: config.pathElements + ? config.pathElements + : this.config.pathElements, + graphBox: config.graphBox ? config.graphBox : this.config.graphBox + }; + //console.log(this.config); + } +} + +export function beginGraph( + x: number = 0, + y: number = 0, + svgWidth: number = width, + svgHeight: number = height +) { + const graphTemperoryObject = new Graph(x, y, svgWidth, svgHeight); + sceneVariables.graph = graphTemperoryObject; + sceneVariables.currentSVG = graphTemperoryObject.graphObject; + return graphTemperoryObject; +} + +export function endGraph() { + sceneVariables.isGraph = 'false'; +} + +global.p5.prototype._rect = global.p5.prototype.rect; +global.p5.prototype.rect = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + console.log('Canvas rect() called'); + return this._rect(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + console.log('SVG rect() called'); + return new Rectangle(...Array.from(arguments)); + } +}; + +class Rectangle { + x: number; + y: number; + shape: SVGRectElement; + w: number; + h: number; + shapeAngle: number; + //rectangle: SVGRectElement; + constructor(...args: any[]) { + // super(arguments[0], arguments[1]); + this.shape = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + this.x = arguments[0]; + this.y = arguments[1]; + this.w = arguments[2]; + this.h = arguments[3]; + this.shapeAngle = 0; + this.shape.setAttribute('x', `${this.x}`); + this.shape.setAttribute('y', `${this.y}`); + this.shape.setAttribute('width', `${this.w}`); + this.shape.setAttribute('height', `${this.h}`); + this.shape.setAttribute( + 'fill', + `${sceneVariables.currFillColor.toString()}` + ); + this.shape.setAttribute( + 'stroke', + `${sceneVariables.currStrokeColor.toString()}` + ); + this.shape.setAttribute( + 'stroke-width', + `${sceneVariables.currStrokeWidth}` + ); + this.shape.setAttribute( + 'style', + `transform : rotate(${sceneVariables.currAngle.toString()}deg);` + ); + //this.shape.style.transform = `rotate(${sceneVariables.currAngle.toString()})deg;` //rotation + sceneVariables.currentSVG.appendChild(this.shape); + return this; + } + position(x: any, y: any) { + this.x = x; + this.y = y; + this.shape.setAttribute('x', `${this.x}`); + this.shape.setAttribute('y', `${this.y}`); + } + remove() { + sceneVariables.currentSVG.removeChild(this.shape); + } + rotate(angle: number, mode: string = 'relative') { + if (angle) { + if (mode === 'relative') { + this.shapeAngle += angle; + } else if (mode === 'absolute') { + this.shapeAngle = angle; + } + } + this.shape.setAttribute( + 'style', + `transform : rotate(${sceneVariables.currAngle + this.shapeAngle}deg);` + ); + } +} + +global.p5.prototype._ellipse = global.p5.prototype.ellipse; +global.p5.prototype.ellipse = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + console.log('Canvas ellipse() called'); + return this._ellipse(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + console.log('SVG ellipse() called'); + return new SVGEllipse(...Array.from(arguments)); + } +}; + +class SVGEllipse { + cx: number; + cy: number; + rx: number; + ry: number; + shape: SVGEllipseElement | SVGCircleElement; + //rectangle: SVGRectElement; + constructor(...args: any[]) { + this.shape = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'ellipse' + ); + this.cx = arguments[0]; + this.cy = arguments[1]; + this.rx = arguments[2]; + this.ry = arguments[3]; + this.shape.setAttribute('cx', `${this.cx}`); + this.shape.setAttribute('cy', `${this.cy}`); + this.shape.setAttribute('rx', `${this.rx}`); + this.shape.setAttribute('ry', `${this.ry}`); + this.shape.setAttribute( + 'fill', + `${sceneVariables.currFillColor.toString()}` + ); + this.shape.setAttribute( + 'stroke', + `${sceneVariables.currStrokeColor.toString()}` + ); + this.shape.setAttribute( + 'stroke-width', + `${sceneVariables.currStrokeWidth}` + ); + this.shape.setAttribute( + 'style', + `transform : rotate(${sceneVariables.currAngle.toString()}deg);` + ); + sceneVariables.currentSVG.appendChild(this.shape); + return this; + } + position(cx: any, cy: any) { + this.cx = cx; + this.cy = cy; + this.shape.setAttribute('cx', `${this.cx}`); + this.shape.setAttribute('cy', `${this.cy}`); + } + remove() { + sceneVariables.currentSVG.removeChild(this.shape); + } +} + +global.p5.prototype._circle = global.p5.prototype.circle; +global.p5.prototype.circle = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + console.log('Canvas circle() called'); + return this._circle(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + console.log('SVG circle() called'); + return new SVGCircle(...Array.from(arguments)); + } +}; + +class SVGCircle extends SVGEllipse { + //rectangle: SVGRectElement; + constructor(...args: any[]) { + super(arguments[0], arguments[1], arguments[2], arguments[2]); + if (this.shape) { + sceneVariables.currentSVG.removeChild(this.shape); //removes ellipse if formed by super + } + this.shape = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'circle' + ); + this.cx = arguments[0]; + this.cy = arguments[1]; + this.rx = arguments[2]; + this.shape.setAttribute('cx', `${this.cx}`); + this.shape.setAttribute('cy', `${this.cy}`); + this.shape.setAttribute('r', `${this.rx}`); + this.shape.setAttribute( + 'fill', + `${sceneVariables.currFillColor.toString()}` + ); + this.shape.setAttribute( + 'stroke', + `${sceneVariables.currStrokeColor.toString()}` + ); + this.shape.setAttribute( + 'stroke-width', + `${sceneVariables.currStrokeWidth}` + ); + sceneVariables.currentSVG.appendChild(this.shape); + return this; + } + // position(cx: any, cy: any) { + // this.cx = cx; + // this.cy = cy; + // this.shape.setAttribute('cx', `${this.cx}`); + // this.shape.setAttribute('cy', `${this.cy}`); + // } + // remove() { + // sceneVariables.currentSVG.removeChild(this.shape); + // } +} + +global.p5.prototype._point = global.p5.prototype.point; +global.p5.prototype.point = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + console.log('Canvas point() called'); + return this._point(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + console.log('SVG point() called'); + + return new SVGPoint(...Array.from(arguments)); + } +}; + +class SVGPoint extends SVGEllipse { + //rectangle: SVGRectElement; + constructor(...args: any[]) { + super( + arguments[0], + arguments[1], + sceneVariables.currStrokeWidth, + sceneVariables.currStrokeWidth + ); + + if (this.shape) { + sceneVariables.currentSVG.removeChild(this.shape); //removes ellipse if formed by super + } + this.shape = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'circle' + ); + this.cx = arguments[0]; + this.cy = arguments[1]; + this.rx = float(sceneVariables.currStrokeWidth); + this.shape.setAttribute('cx', `${this.cx}`); + this.shape.setAttribute('cy', `${this.cy}`); + this.shape.setAttribute('r', `${this.rx / 2}`); + this.shape.setAttribute( + 'fill', + `${sceneVariables.currStrokeColor.toString()}` + ); + this.shape.setAttribute( + 'stroke', + `${sceneVariables.currStrokeColor.toString()}` + ); + this.shape.setAttribute('stroke-width', `${0}`); + sceneVariables.currentSVG.appendChild(this.shape); + return this; + } + // position(cx: any, cy: any) { + // this.cx = cx; + // this.cy = cy; + // this.shape.setAttribute('cx', `${this.cx}`); + // this.shape.setAttribute('cy', `${this.cy}`); + // } + // remove() { + // sceneVariables.currentSVG.removeChild(this.shape); + // } +} + +export function controlPoint(...args) { + if (sceneVariables.isGraph === 'true') { + return new SVGControlPoint(...args); + } +} +class SVGControlPoint extends SVGPoint { + x; + y; + constructor(...args: any[]) { + super(arguments[0], arguments[1]); + // this.xco = 0; + // this.yco = 0; + + this.shape.setAttribute('onmousedown', 'SVGControlPointPosition(evt)'); + + this.shape.setAttribute('class', 'controlPoint'); + this.shape.setAttribute('posX', `${this.cx}`); + this.shape.setAttribute('posY', `${this.cy}`); + + return this; + } + + position() { + this.x = this.shape.getAttributeNS(null, 'posX'); + this.y = this.shape.getAttributeNS(null, 'posY'); + return [this.x, this.y]; + } + // setX(x) { + // this.xco = x; + // // this.x = this.shape.getScreenCTM().e/ this.shape.getScreenCTM().a; + // // this.y = this.shape.getScreenCTM().f/ this.shape.getScreenCTM().d; + // console.log(this.xco); + // } +} + +export function SVGControlPointPosition(event) { + let svg = sceneVariables.currentSVG; + svg.addEventListener('mousedown', startDrag); + svg.addEventListener('mousemove', drag); + svg.addEventListener('mouseup', endDrag); + svg.addEventListener('mouseleave', endDrag); + let offset, transform; + function getMousePosition(event) { + let CTM: any = svg.getScreenCTM(); + return { + x: (event.clientX - CTM.e) / CTM.a, + y: (event.clientY - CTM.f) / CTM.d + }; + } + function startDrag(event) { + if (event.target.classList.contains('controlPoint')) { + sceneVariables.selectedPoint = event.target; + //console.log(sceneVariables.selectedPoint.x); + + offset = getMousePosition(event); + // Get all the transforms currently on this element + var transforms = sceneVariables.selectedPoint.transform.baseVal; + // Ensure the first transform is a translate transform + if ( + transforms.length === 0 || + transforms.getItem(0).type !== SVGTransform.SVG_TRANSFORM_TRANSLATE + ) { + // Create an transform that translates by (0, 0) + var translate = svg.createSVGTransform(); + translate.setTranslate(0, 0); + // Add the translation to the front of the transforms list + sceneVariables.selectedPoint.transform.baseVal.insertItemBefore( + translate, + 0 + ); + } + // Get initial translation amount + transform = transforms.getItem(0); + offset.x -= transform.matrix.e; + offset.y -= transform.matrix.f; + } + } + + function drag(event) { + if (sceneVariables.selectedPoint) { + event.preventDefault(); + var coord = getMousePosition(event); + transform.setTranslate(coord.x - offset.x, coord.y - offset.y); + sceneVariables.selectedPoint.setAttribute('posX', `${coord.x}`); + sceneVariables.selectedPoint.setAttribute('posY', `${coord.y}`); + } + } + function endDrag(event) { + sceneVariables.selectedPoint = null; + } +} +global.p5.prototype._line = global.p5.prototype.line; +global.p5.prototype.line = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + return this._line(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + return new SVGLine(...Array.from(arguments)); + } +}; + +class SVGLine { + svgLine: SVGLineElement; + x1: number; + x2: number; + y1: number; + y2: number; + constructor(...args: any[]) { + this.svgLine = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + this.x1 = arguments[0]; + this.y1 = arguments[1]; + this.x2 = arguments[2]; + this.y2 = arguments[3]; + this.svgLine.setAttribute('x1', `${this.x1}`); + this.svgLine.setAttribute('y1', `${this.y1}`); + this.svgLine.setAttribute('x2', `${this.x2}`); + this.svgLine.setAttribute('y2', `${-this.y2}`); + this.svgLine.setAttribute( + 'fill', + `${sceneVariables.currFillColor.toString()}` + ); + this.svgLine.setAttribute( + 'stroke', + `${sceneVariables.currStrokeColor.toString()}` + ); + this.svgLine.setAttribute( + 'stroke-width', + `${sceneVariables.currStrokeWidth}` + ); + this.svgLine.setAttribute( + 'style', + `transform : rotate(${sceneVariables.currAngle.toString()}deg);` + ); + sceneVariables.currentSVG.appendChild(this.svgLine); + } + + remove() { + sceneVariables.currentSVG.removeChild(this.svgLine); + } +} + +global.p5.prototype._fill = global.p5.prototype.fill; +global.p5.prototype.fill = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + sceneVariables.currFillColor = arguments[0].toString(); + this._fill(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + sceneVariables.currFillColor = arguments[0].toString(); + } +}; + +global.p5.prototype._stroke = global.p5.prototype.stroke; +global.p5.prototype.stroke = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + sceneVariables.currStrokeColor = arguments[0].toString(); + this._stroke(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + sceneVariables.currStrokeColor = arguments[0].toString(); + } +}; + +global.p5.prototype._strokeWeight = global.p5.prototype.strokeWeight; +global.p5.prototype.strokeWeight = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + sceneVariables.currStrokeWidth = arguments[0]; + this._strokeWeight(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + sceneVariables.currStrokeWidth = arguments[0]; + } +}; + +global.p5.prototype._rotate = global.p5.prototype.rotate; +global.p5.prototype.rotate = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + sceneVariables.currAngle += arguments[0]; + this._rotate(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + sceneVariables.currAngle += arguments[0]; + //console.log(sceneVariables.currAngle); + //TODO : rotate currently takes only angles in degree + } +}; + +/** + * beginShape + */ + +global.p5.prototype._beginShape = global.p5.prototype.beginShape; +global.p5.prototype.beginShape = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + console.log('Canvas beginShape() called'); + return this._beginShape(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + console.log('SVG beginShape() called'); + return new SVGPolygon(...Array.from(arguments)); + } +}; + +class SVGPolygon { + vertices; + shape: SVGPolygonElement; + //rectangle: SVGRectElement; + constructor(...args: any[]) { + this.vertices = []; + this.shape = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'polygon' + ); + sceneVariables.currentPolygon = this; + this.shape.setAttribute( + 'fill', + `${sceneVariables.currFillColor.toString()}` + ); + this.shape.setAttribute( + 'stroke', + `${sceneVariables.currStrokeColor.toString()}` + ); + this.shape.setAttribute( + 'stroke-width', + `${sceneVariables.currStrokeWidth}` + ); + this.shape.setAttribute( + 'style', + `transform : rotate(${sceneVariables.currAngle.toString()}deg);` + ); + sceneVariables.currentSVG.appendChild(this.shape); + return this; + } + // position(cx: any, cy: any) { + // this.cx = cx; + // this.cy = cy; + // this.shape.setAttribute('cx', `${this.cx}`); + // this.shape.setAttribute('cy', `${this.cy}`); + // } + remove() { + sceneVariables.currentSVG.removeChild(this.shape); + } +} + +global.p5.prototype._vertex = global.p5.prototype.vertex; +global.p5.prototype.vertex = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + console.log('Canvas beginShape() called'); + return this._vertex(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + console.log('SVG beginShape() called'); + return new SVGVertex(...Array.from(arguments)); + } +}; + +class SVGVertex { + //vertices; + //rectangle: SVGRectElement; + constructor(...args: any[]) { + if (sceneVariables.currentPolygon != null) { + sceneVariables.currentPolygon.vertices.push( + args[0] * + sceneVariables.graph.config.stepX * + sceneVariables.graph.config.scaleX + ); + sceneVariables.currentPolygon.vertices.push( + -args[1] * + sceneVariables.graph.config.stepY * + sceneVariables.graph.config.scaleY + ); + } + return this; + } + // position(cx: any, cy: any) { + // this.cx = cx; + // this.cy = cy; + // this.shape.setAttribute('cx', `${this.cx}`); + // this.shape.setAttribute('cy', `${this.cy}`); + // } + // remove() { + // sceneVariables.currentSVG.removeChild(this.shape); + // } +} + +global.p5.prototype._endShape = global.p5.prototype.endShape; +global.p5.prototype.endShape = function () { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + console.log('Canvas beginShape() called'); + return this._endShape(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + console.log('SVG beginShape() called'); + return SVGEndShape(...Array.from(arguments)); + } +}; + +function SVGEndShape(...args) { + sceneVariables.currentPolygon.shape.setAttribute( + 'points', + sceneVariables.currentPolygon.vertices.toString() + ); + sceneVariables.currentPolygon = null; +} + +export function polyline(...args) { + let vertices = args; + let shape = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'polyline' + ); + shape.setAttribute('fill', `${sceneVariables.currFillColor.toString()}`); + shape.setAttribute('stroke', `${sceneVariables.currStrokeColor.toString()}`); + shape.setAttribute('stroke-width', `${sceneVariables.currStrokeWidth}`); + shape.setAttribute( + 'style', + `transform : rotate(${sceneVariables.currAngle.toString()}deg);` + ); + let scaledVertices = vertices.map((elt, i) => { + if (i % 2 === 0) { + return elt * + sceneVariables.graph.config.stepX * + sceneVariables.graph.config.scaleX; + } + else if (i%2 === 1){ + return -elt * + sceneVariables.graph.config.stepY * + sceneVariables.graph.config.scaleY + } + }); + + + shape.setAttribute('points', scaledVertices.toString()); + sceneVariables.currentSVG.appendChild(shape); + return vertices; +} diff --git a/src/lib/Geometry/arrow.ts b/src/lib/Geometry/arrow.ts new file mode 100644 index 0000000..e5dd2f6 --- /dev/null +++ b/src/lib/Geometry/arrow.ts @@ -0,0 +1,137 @@ +import { sceneVariables } from "../Scene/scene"; + +export function arrow(...args) { + if ( + typeof sceneVariables.isGraph === 'undefined' || + sceneVariables.isGraph === 'false' + ) { + //return this._line(...Array.from(arguments)); + } else if (sceneVariables.isGraph === 'true') { + return new SVGArrow(...Array.from(arguments)); + } + } + + class SVGArrow { + svgLine: SVGLineElement; + x1: number; + x2: number; + y1: number; + y2: number; + arrowConfig: { + arrowHeadColor; + arrowHeadHeight; + arrowSize; + }; + //arrowSize; + arrow; + + defs: SVGDefsElement; + constructor(...args: any[]) { + this.arrowConfig = { + arrowHeadColor: sceneVariables.currStrokeColor, + arrowHeadHeight: float(sceneVariables.currStrokeWidth), + arrowSize: float(sceneVariables.currStrokeWidth) + }; + // this.arrowSize = + // this.arrowHeadColor = ; + this.arrow = document.createElementNS('http://www.w3.org/2000/svg', 'g'); + this.svgLine = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + this.x1 = arguments[0]; + this.y1 = arguments[1]; + this.x2 = arguments[2]; + this.y2 = arguments[3]; + const angle = Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)); + this.svgLine.setAttribute('x1', `${this.x1}`); + this.svgLine.setAttribute('y1', `${-this.y1}`); + this.svgLine.setAttribute( + 'x2', + `${this.x2 - 1.5 * this.arrowConfig.arrowSize * Math.cos(angle)}` + ); + this.svgLine.setAttribute( + 'y2', + `${-(this.y2 - 6 * this.arrowConfig.arrowSize * Math.sin(angle))}` + ); + this.svgLine.setAttribute( + 'fill', + `${sceneVariables.currFillColor.toString()}` + ); + this.svgLine.setAttribute( + 'stroke', + `${sceneVariables.currStrokeColor.toString()}` + ); + this.svgLine.setAttribute( + 'stroke-width', + `${sceneVariables.currStrokeWidth}` + ); + this.defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'); + this.defs.innerHTML = ``; + //this.svgLine.setAttribute('marker-start', 'url(#marker-arrow)'); + this.svgLine.setAttribute('marker-end', 'url(#marker-arrow)'); + + this.arrow.appendChild(this.defs); + this.arrow.appendChild(this.svgLine); + sceneVariables.currentSVG.appendChild(this.arrow); + } + + configure(arrowConfig) { + this.arrowConfig = { + arrowHeadColor: arrowConfig.arrowHeadColor + ? arrowConfig.arrowHeadColor + : this.arrowConfig.arrowHeadColor, + arrowHeadHeight: arrowConfig.arrowHeadHeight + ? arrowConfig.arrowHeadHeight + : this.arrowConfig.arrowHeadHeight, + arrowSize: arrowConfig.arrowSize + ? arrowConfig.arrowSize + : this.arrowConfig.arrowSize + }; + this.defs.innerHTML = ``; + //this.svgLine.setAttribute('marker-start', 'url(#marker-arrow)'); + this.svgLine.setAttribute('marker-end', 'url(#marker-arrow)'); + } + + remove() { + sceneVariables.currentSVG.removeChild(this.arrow); + } + + arrowHead(x, y) { + this.x2 = x; + this.y2 = y; + const angle = Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)); + + this.svgLine.setAttribute( + 'x2', + `${this.x2 - 1.5 * this.arrowConfig.arrowSize * Math.cos(angle)}` + ); + this.svgLine.setAttribute( + 'y2', + `${-(this.y2 - 6 * this.arrowConfig.arrowSize * Math.sin(angle))}` + ); + } + + arrowTail(x, y) { + this.x1 = x; + this.y1 = y; + this.svgLine.setAttribute('x1', `${this.x1}`); + this.svgLine.setAttribute('y1', `${-this.y1}`); + } + } \ No newline at end of file diff --git a/src/lib/Geometry/graph.ts b/src/lib/Geometry/graph.ts new file mode 100644 index 0000000..9299938 --- /dev/null +++ b/src/lib/Geometry/graph.ts @@ -0,0 +1,883 @@ +import anime from 'animejs'; +import { animationTimeline } from '../Scene/controls'; +import { sceneContainer, sceneVariables } from '../Scene/scene'; +import { transform } from '../Scene/transform'; +import { GObject } from './GObject'; + +// color blind safe palette +const ULTRAMARINE40 = '#648fff'; +const MAGENTA50 = '#dc267f'; +const GOLD20 = '#ffb000'; +const INDIGO50 = '#785ef0'; +const ORANGE40 = '#fe6100'; + +/** + * class representing a 2-D Cartesian Graph + */ + +export class Graph2D extends GObject { + eqn: Function; + plotting!: SVGGElement; + coordinate!: SVGGElement; + config: { + //configuration for graph + scaleX: any; + maxX: any; + minX: any; + scaleY: any; + maxY: any; + minY: any; + graphColor: any; + graphStrokeWidth: any; + arrowSize: any; + xAxis: any; + yAxis: any; + axisColor: any; + grid: any; + smallGridColor: any; + gridColor: any; + stepX: any; + stepY: any; + originX: any; + originY: any; + tickX: any; + tickY: any; + tickColor: any; + tickMarginX: any; + tickMarginY: any; + pathElements: any; + graphBox: any; + }; + + /** + * creates a graph object + * @param {Function} eqn function to plot + * @param {number} [x] x-coordinate of graph + * @param {number} [y] y-coordinate of graph + * @param {Number} [svgWidth] width of the graph + * @param {Number} [svgHeight] height of the graph + */ + + constructor( + eqn: Function, + x: number = 10, + y: number = 10, + svgWidth: number = 300, + svgHeight: number = 300 + ) { + super(x, y, svgWidth, svgHeight); + + this.config = { + graphColor: GOLD20, + graphStrokeWidth: 1, + arrowSize: 3, + xAxis: 'true', + yAxis: 'true', + minX: -5, + maxX: 5, + minY: -5, + maxY: 5, + scaleX: 1, + scaleY: 1, + axisColor: INDIGO50, + grid: 'true', + smallGridColor: MAGENTA50, + gridColor: ORANGE40, + stepX: 1, + stepY: 1, + originX: 0, + originY: 0, + tickX: 'true', + tickY: 'true', + tickColor: ULTRAMARINE40, + tickMarginX: -0.5, + tickMarginY: -0.5, + pathElements: 1000, + graphBox: 'true' + }; + + this.eqn = eqn; + // this.x = x; + // this.y = y; + + //this.config.minX = -this.svgWidth / 2; + //this.config.maxX = this.svgWidth / 2; + this.config.scaleX = abs( + this.svgWidth / (this.config.maxX - this.config.minX) + ); + this.config.scaleY = abs( + this.svgHeight / (this.config.maxY - this.config.minY) + ); + + //console.log(this.config.maxX - this.config.minX); + + // this.pathData = createSVGPath(eqn, this.config); + this.graphContainer = createElement('div'); //attaching it to sceneContainer + this.graphContainer.parent(sceneContainer); + this.linePath = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'path' + ); + this.linePath.setAttribute('fill', 'none'); + this.linePath.setAttribute('stroke', 'black'); + this.linePath.setAttribute('stroke-width', '1'); + this.graphContainer.position(this.x, this.y); + + this.graphObject = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'svg' + ); + this.graphObject.setAttribute('width', `${this.svgWidth}`); + this.graphObject.setAttribute('height', `${this.svgHeight}`); + this.graphObject.setAttribute( + 'viewBox', + `${-this.svgWidth / 2} ${-this.svgHeight / 2} ${this.svgWidth} ${ + this.svgHeight + }` + ); + this.graphObject.setAttribute('preserveAspectRatio', 'xMidYMid meet'); + } + + /** + * sets position of text + * @param {number} x-coordinate x-coordinate of text + * @param {number} y-coordinate y-coordinate of text + */ + + position(x: number, y: number = 10) { + this.x = x; + this.y = y; + this.graphContainer.position(this.x, this.y); + } + + configure(config) { + this.config = { + graphColor: config.graphColor + ? config.graphColor + : this.config.graphColor, + graphStrokeWidth: config.graphStrokeWidth + ? config.graphStrokeWidth + : this.config.graphStrokeWidth, + arrowSize: config.arrowSize ? config.arrowSize : this.config.arrowSize, + xAxis: config.xAxis ? config.xAxis : this.config.xAxis, + yAxis: config.yAxis ? config.yAxis : this.config.yAxis, + minX: config.minX ? config.minX : this.config.minX, + maxX: config.maxX ? config.maxX : this.config.maxX, + minY: config.minY ? config.minY : this.config.minY, + maxY: config.maxY ? config.maxY : this.config.maxY, + scaleX: config.scaleX ? config.scaleX : this.config.scaleX, + scaleY: config.scaleY ? config.scaleY : this.config.scaleY, + axisColor: config.axisColor ? config.axisColor : this.config.axisColor, + smallGridColor: config.smallGridColor + ? config.smallGridColor + : this.config.smallGridColor, + gridColor: config.gridColor ? config.gridColor : this.config.gridColor, + stepX: config.stepX ? config.stepX : this.config.stepX, + stepY: config.stepY ? config.stepY : this.config.stepY, + originX: config.originX ? config.originX : this.config.originX, + originY: config.originY ? config.originY : this.config.originY, + grid: config.grid ? config.grid : this.config.grid, + tickX: config.tickX ? config.tickX : this.config.tickX, + tickY: config.tickY ? config.tickY : this.config.tickY, + tickColor: config.tickColor ? config.tickColor : this.config.tickColor, + tickMarginX: config.tickMarginX + ? config.tickMarginX + : this.config.tickMarginX, + tickMarginY: config.tickMarginY + ? config.tickMarginY + : this.config.tickMarginY, + pathElements: config.pathElements + ? config.pathElements + : this.config.pathElements, + graphBox: config.graphBox ? config.graphBox : this.config.graphBox + }; + //console.log(this.config); + } + + /** + * sets font-size of text + * @param {number} font-size font-size of the text + */ + + size(width, height) { + if (arguments.length === 0) { + return [this.svgWidth, this.svgHeight]; + } else { + this.svgWidth = width; + this.svgHeight = height; + this.graphObject.setAttribute('width', `${this.svgWidth}`); + this.graphObject.setAttribute('height', `${this.svgHeight}`); + this.graphObject.setAttribute( + 'viewBox', + `${-this.svgWidth / 2} ${-this.svgHeight / 2} ${this.svgWidth} ${ + this.svgHeight + }` + ); + } + } + + scale(scaleFactor) { + this.graphContainer.style('transform', `scale(${scaleFactor})`); + } + + transform(object_finl: any, startTime: number = 0, endTime: number = 2) { + transform(this, object_finl, startTime, endTime); + } + + loop(finlEqn, timeDuration: number = 2, startTime: number = 0) { + timeDuration = timeDuration * 1000; + startTime = startTime * 1000; //s to ms + anime({ + loop: true, + targets: this.graphContainer.elt.querySelectorAll('path')[0], + d: [ + //{value: shapes[0].d}, + { value: `${createSVGPath(finlEqn, this.config)}` } + ], + duration: timeDuration, + direction: 'alternate', + autoplay: true, + easing: 'easeInOutCubic', + + delay: startTime + // complete: function(anim) { + // looper.restart; + // } + //elasticity: 1 + }); + } + + stroke(_stroke: any) { + this.config.graphColor = _stroke; + this.linePath.setAttribute('stroke', `${_stroke}`); + } + + plot() { + this.pathData = createSVGPath(this.eqn, this.config); + this.plotting = document.createElementNS('http://www.w3.org/2000/svg', 'g'); + this.plotting.setAttribute('id', 'plot'); + this.linePath.setAttribute('stroke', `${this.config.graphColor}`); + this.linePath.setAttribute( + 'stroke-width', + `${this.config.graphStrokeWidth}` + ); + this.linePath.setAttribute('d', this.pathData); + this.plotting.appendChild(this.linePath); // + this.graphObject.appendChild(this.plotting); + + // attaching to graphContainer + this.graphContainer.elt.appendChild(this.graphObject); + } + + axis() { + // coordinate system + this.coordinate = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'g' + ); + this.coordinate.setAttribute('id', 'coordinateSystem'); + let defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'); + defs.innerHTML += ``; + this.graphObject.appendChild(defs); + // this.graphObject.appendChild(arrowPath); + + // let frame = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + // frame.setAttribute('x', `${-this.svgWidth / 2}`); + // frame.setAttribute('y', `${-this.svgHeight / 2}`); + // frame.setAttribute('width', `${this.svgWidth}`); + // frame.setAttribute('height', `${this.svgHeight}`); + // frame.setAttribute('fill', `rgba(0,0,0,0)`); + // frame.setAttribute('stroke', `white`); + + //grid + defs.innerHTML += ` + + + + + + `; + + let grid = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + grid.setAttribute('x', `${-this.svgWidth / 2}`); + grid.setAttribute('y', `${-this.svgHeight / 2}`); + grid.setAttribute('width', `100%`); + grid.setAttribute('height', `100%`); + if (this.config.grid === 'true') { + grid.setAttribute('fill', `url(#grid)`); + } + if (this.config.graphBox === 'true') { + grid.setAttribute('stroke', `white`); + } + //this.coordinate.appendChild(frame); + this.coordinate.appendChild(grid); + + //axes + //console.log(this.config.axisX); + // console.log(this.config.tickX); + if (this.config.xAxis === 'true') { + let xAxis = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + xAxis.setAttribute('x1', `${-this.svgWidth / 2}`); + xAxis.setAttribute('y1', `${-this.config.originY * this.config.scaleY}`); + xAxis.setAttribute('x2', `${this.svgWidth / 2}`); + xAxis.setAttribute('y2', `${-this.config.originY * this.config.scaleY}`); + xAxis.setAttribute('marker-start', 'url(#marker-arrow)'); + xAxis.setAttribute('marker-end', 'url(#marker-arrow)'); + xAxis.setAttribute('stroke', `${this.config.axisColor}`); + xAxis.setAttribute('fill', `none`); + this.coordinate.appendChild(xAxis); + + if (this.config.tickX === 'true') { + let tick; + //x axis + //+ve axis + for ( + let i = 0; + i < + abs( + int(this.svgWidth / (2 * this.config.scaleX) - this.config.originX) + ) / + this.config.stepX; + i++ + ) { + let x = + this.config.originX * this.config.scaleX + + (i + 1) * this.config.stepX * this.config.scaleX; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute('x', `${x}`); + tick.setAttribute( + 'y', + `${ + -this.config.originY * this.config.scaleY - + this.config.tickMarginX * this.config.scaleY + }` + ); + tick.innerHTML = (i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + + //console.log(int(this.svgWidth / (2*this.config.scaleX)) + this.config.originX); + + //-ve axis + for ( + let i = abs( + int(this.svgWidth / (2 * this.config.scaleX)) + this.config.originX + ); + i >= 0; + i-- + ) { + let x = + this.config.originX * this.config.scaleX - + (i + 1) * this.config.stepX * this.config.scaleX; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute('x', `${x}`); + tick.setAttribute( + 'y', + `${ + -this.config.originY * this.config.scaleY - + this.config.tickMarginX * this.config.scaleY + }` + ); + tick.innerHTML = -(i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + } + } + + if (this.config.yAxis === 'true') { + let yAxis = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + yAxis.setAttribute('x1', `${this.config.originX * this.config.scaleX}`); + yAxis.setAttribute('y1', `${-this.svgHeight / 2}`); + yAxis.setAttribute('x2', `${this.config.originX * this.config.scaleX}`); + yAxis.setAttribute('y2', `${this.svgHeight / 2}`); + yAxis.setAttribute('marker-start', 'url(#marker-arrow)'); + yAxis.setAttribute('marker-end', 'url(#marker-arrow)'); + yAxis.setAttribute('stroke', `${this.config.axisColor}`); + yAxis.setAttribute('fill', `none`); + this.coordinate.appendChild(yAxis); + if (this.config.tickY === 'true') { + let tick; + //y axis + //+ve axis + for ( + let i = 0; + i <= + abs( + -int(this.svgHeight / (2 * this.config.scaleY)) + + this.config.originY + ); + i++ + ) { + let y = + -this.config.originY * this.config.scaleY - + (i + 1) * this.config.stepY * this.config.scaleY; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute( + 'x', + `${ + this.config.originX * this.config.scaleX + + this.config.tickMarginY * this.config.scaleX + }` + ); + tick.setAttribute('y', `${y}`); + tick.innerHTML = (i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + //-ve axis + for ( + let i = abs( + -int(this.svgHeight / (2 * this.config.scaleY)) - + this.config.originY + ); + i >= 0; + i-- + ) { + let y = + -this.config.originY * this.config.scaleY + + (i + 1) * this.config.stepY * this.config.scaleY; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute( + 'x', + `${ + this.config.originX * this.config.scaleX + + this.config.tickMarginY * this.config.scaleX + }` + ); + tick.setAttribute('y', `${y}`); + tick.innerHTML = -(i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + } + } + + //xAxis.setAttribute('stroke', color); + //xAxis.setAttribute('stroke-width', w); + + //ticks + + //this.plotting.appendChild(this.linePath); + this.graphObject.appendChild(this.coordinate); // + } + + update(eqn: Function) { + this.pathData = createSVGPath(eqn, this.config); + this.linePath.setAttribute('d', this.pathData); + } + + play(timeDuration: number = 5, startTime: number = 0) { + timeDuration = timeDuration * 1000; + startTime = startTime * 1000; //s to ms + const pathElement = this.graphContainer.elt.querySelectorAll('path'); + animationTimeline.add( + { + targets: this.graphContainer.elt.querySelectorAll('path'), + strokeDashoffset: [anime.setDashoffset, 0], + easing: 'easeOutSine', + duration: timeDuration, + begin: function (anim) { + //pathElement[0].setAttribute('stroke', 'black'); + pathElement[0].setAttribute('fill', 'none'); + }, + complete: function (anim) { + //document.querySelector('path').setAttribute("fill", "yellow"); + } + //autoplay: true + }, + startTime + ); + } +} + +/** + * createSVGPath function creates a graph object and returns graph object + * @param {Function} eqn function to plot + * @param {object} [config] config for graph + * @returns {Graph2D} 2D Graph object + */ + +export function createSVGPath(eqn: Function, config) { + //const pathElements = 1000; + // const scaleX = 9; + // const scaleY = 0.5; + // scaleX = width/(maxX - minX); + const stepSize = (config.maxX - config.minX) / config.pathElements; + + //minX = 0; + let SVG_path = `M${ + config.stepX * + (config.scaleX * config.minX + config.originX * config.scaleX) + },${ + config.stepY * + (config.scaleY * -eqn(config.minX + config.originX * config.scaleX) - + config.originY * config.scaleY) + }`; + for (let x = config.minX; x < config.maxX; x += stepSize) { + // SVG_path = SVG_path.concat(` L${1000*i},${1000*Math.sin(Math.PI / 2 * Math.pow(i, 1.5))/i}`); + SVG_path = SVG_path.concat( + ` L${ + config.stepX * (config.scaleX * x + config.originX * config.scaleX) + }, ${ + config.stepY * + (config.scaleY * -eqn(x) - config.originY * config.scaleY) + }` + ); + } + return SVG_path; +} + +/** + * create2DGraph function creates a graph object and return graph object + * @param {Function} eqn function to plot + * @param {number} [x] x-coordinate of graph + * @param {number} [y] y-coordinate of graph + * @param {Number} [svgWidth] width of the graph + * @param {Number} [svgHeight] height of the graph + * @returns {Graph2D} 2D Graph object + */ + +export function create2DGraph( + eqn: Function, + x: number = 10, + y: number = 10, + svgWidth: number = 300, + svgHeight: number = 300 +) { + //const _object = + return new Graph2D(eqn, x, y, svgWidth, svgHeight); +} + +export function plot2D(eqn: Function) { + //const plot2d = new Graph2D(eqn, sceneVariables.currentSVG.getBBox().x, sceneVariables.currentSVG.getBBox().y, sceneVariables.currentSVG.getBBox().width, sceneVariables.currentSVG.getBBox().height); + if (sceneVariables.isGraph === 'true') { + let linePath = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'path' + ); + linePath.setAttribute('fill', 'none'); + linePath.setAttribute('stroke', `${sceneVariables.currStrokeColor}`); + linePath.setAttribute('stroke-width', `${sceneVariables.currStrokeWidth}`); + let pathData = createSVGPath( + eqn, + sceneVariables.graph.config + ); + const plotting = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'g' + ); + plotting.setAttribute('id', 'plot'); + // linePath.setAttribute( + // 'stroke', + // `${sceneVariables.graph.config.graphColor}` + // ); + // linePath.setAttribute( + // 'stroke-width', + // `${sceneVariables.graph.config.graphStrokeWidth}` + // ); + linePath.setAttribute( + 'd', + pathData + ); + + plotting.appendChild(linePath); // + + sceneVariables.graph.graphObject.appendChild(plotting); + + // attaching to graphContainer + sceneVariables.graph.graphContainer.elt.appendChild( + sceneVariables.graph.graphObject + ); + // sceneVariables.currentSVG.appendChild; + } +} + +export function axis() { + const graph = sceneVariables.graph; + + if (sceneVariables.isGraph === 'true') { + graph.coordinate = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'g' + ); + graph.coordinate.setAttribute('id', 'coordinateSystem'); + let defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'); + defs.innerHTML += ``; + graph.graphObject.appendChild(defs); + // graph.graphObject.appendChild(arrowPath); + + // let frame = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + // frame.setAttribute('x', `${-graph.svgWidth / 2}`); + // frame.setAttribute('y', `${-graph.svgHeight / 2}`); + // frame.setAttribute('width', `${graph.svgWidth}`); + // frame.setAttribute('height', `${graph.svgHeight}`); + // frame.setAttribute('fill', `rgba(0,0,0,0)`); + // frame.setAttribute('stroke', `white`); + + //grid + defs.innerHTML += ` + + + + + + `; + + let grid = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + grid.setAttribute('x', `${-graph.svgWidth / 2}`); + grid.setAttribute('y', `${-graph.svgHeight / 2}`); + grid.setAttribute('width', `100%`); + grid.setAttribute('height', `100%`); + if (graph.config.grid === 'true') { + grid.setAttribute('fill', `url(#grid)`); + } + if (graph.config.graphBox === 'true') { + grid.setAttribute('stroke', `white`); + } + //graph.coordinate.appendChild(frame); + graph.coordinate.appendChild(grid); + + //axes + //console.log(graph.config.axisX); + // console.log(graph.config.tickX); + if (graph.config.xAxis === 'true') { + let xAxis = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + xAxis.setAttribute('x1', `${-graph.svgWidth / 2}`); + xAxis.setAttribute( + 'y1', + `${-graph.config.originY * graph.config.scaleY}` + ); + xAxis.setAttribute('x2', `${graph.svgWidth / 2}`); + xAxis.setAttribute( + 'y2', + `${-graph.config.originY * graph.config.scaleY}` + ); + xAxis.setAttribute('marker-start', 'url(#marker-arrow)'); + xAxis.setAttribute('marker-end', 'url(#marker-arrow)'); + xAxis.setAttribute('stroke', `${graph.config.axisColor}`); + xAxis.setAttribute('fill', `none`); + graph.coordinate.appendChild(xAxis); + + if (graph.config.tickX === 'true') { + let tick; + //x axis + //+ve axis + for ( + let i = 0; + i < + abs( + int( + graph.svgWidth / (2 * graph.config.scaleX) - graph.config.originX + ) + ) / + graph.config.stepX; + i++ + ) { + let x = + graph.config.originX * graph.config.scaleX + + (i + 1) * graph.config.stepX * graph.config.scaleX; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute('x', `${x}`); + tick.setAttribute( + 'y', + `${ + -graph.config.originY * graph.config.scaleY - + graph.config.tickMarginX * graph.config.scaleY + }` + ); + tick.innerHTML = (i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${graph.config.tickColor}`; + graph.coordinate.appendChild(tick); + } + + //console.log(int(graph.svgWidth / (2*graph.config.scaleX)) + graph.config.originX); + + //-ve axis + for ( + let i = abs( + int(graph.svgWidth / (2 * graph.config.scaleX)) + + graph.config.originX + ); + i >= 0; + i-- + ) { + let x = + graph.config.originX * graph.config.scaleX - + (i + 1) * graph.config.stepX * graph.config.scaleX; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute('x', `${x}`); + tick.setAttribute( + 'y', + `${ + -graph.config.originY * graph.config.scaleY - + graph.config.tickMarginX * graph.config.scaleY + }` + ); + tick.innerHTML = -(i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${graph.config.tickColor}`; + graph.coordinate.appendChild(tick); + } + } + } + + if (graph.config.yAxis === 'true') { + let yAxis = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + yAxis.setAttribute('x1', `${graph.config.originX * graph.config.scaleX}`); + yAxis.setAttribute('y1', `${-graph.svgHeight / 2}`); + yAxis.setAttribute('x2', `${graph.config.originX * graph.config.scaleX}`); + yAxis.setAttribute('y2', `${graph.svgHeight / 2}`); + yAxis.setAttribute('marker-start', 'url(#marker-arrow)'); + yAxis.setAttribute('marker-end', 'url(#marker-arrow)'); + yAxis.setAttribute('stroke', `${graph.config.axisColor}`); + yAxis.setAttribute('fill', `none`); + graph.coordinate.appendChild(yAxis); + if (graph.config.tickY === 'true') { + let tick; + //y axis + //+ve axis + for ( + let i = 0; + i <= + abs( + -int(graph.svgHeight / (2 * graph.config.scaleY)) + + graph.config.originY + ); + i++ + ) { + let y = + -graph.config.originY * graph.config.scaleY - + (i + 1) * graph.config.stepY * graph.config.scaleY; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute( + 'x', + `${ + graph.config.originX * graph.config.scaleX + + graph.config.tickMarginY * graph.config.scaleX + }` + ); + tick.setAttribute('y', `${y}`); + tick.innerHTML = (i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${graph.config.tickColor}`; + graph.coordinate.appendChild(tick); + } + //-ve axis + for ( + let i = abs( + -int(graph.svgHeight / (2 * graph.config.scaleY)) - + graph.config.originY + ); + i >= 0; + i-- + ) { + let y = + -graph.config.originY * graph.config.scaleY + + (i + 1) * graph.config.stepY * graph.config.scaleY; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute( + 'x', + `${ + graph.config.originX * graph.config.scaleX + + graph.config.tickMarginY * graph.config.scaleX + }` + ); + tick.setAttribute('y', `${y}`); + tick.innerHTML = -(i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${graph.config.tickColor}`; + graph.coordinate.appendChild(tick); + } + } + } + + //xAxis.setAttribute('stroke', color); + //xAxis.setAttribute('stroke-width', w); + + //ticks + + //graph.plotting.appendChild(graph.linePath); + graph.graphObject.appendChild(graph.coordinate); // + } +} diff --git a/src/lib/Geometry/parametric.ts b/src/lib/Geometry/parametric.ts new file mode 100644 index 0000000..de1ff6e --- /dev/null +++ b/src/lib/Geometry/parametric.ts @@ -0,0 +1,656 @@ +import anime from 'animejs'; +import { animationTimeline } from '../Scene/controls'; +import { sceneContainer, sceneVariables } from '../Scene/scene'; +import { transform } from '../Scene/transform'; +import { GObject } from './GObject'; + +const ULTRAMARINE40 = '#648fff'; +const MAGENTA50 = '#dc267f'; +const GOLD20 = '#ffb000'; +const INDIGO50 = '#785ef0'; +const ORANGE40 = '#fe6100'; + +export class GraphParametric2D extends GObject { + xeqn: Function; + yeqn: Function; + plotting!: SVGGElement; + coordinate!: SVGGElement; + parameterRange: number[]; + config: { + //configuration for graph + scaleX: any; + maxX: any; + minX: any; + scaleY: any; + maxY: any; + minY: any; + graphColor: any; + graphStrokeWidth: any; + arrowSize: any; + xAxis: any; + yAxis: any; + axisColor: any; + smallGridColor: any; + gridColor: any; + stepX: any; + stepY: any; + originX: any; + originY: any; + tickX: any; + tickY: any; + tickColor: any; + tickMarginX: any; + tickMarginY: any; + arrowFollowerColor: any; + }; + // pathData: any; + // graphObject: any; + // graphContainer: any; + // x: number; + // y: number; + // svgWidth: number; + // svgHeight: number; + // linePath: SVGPathElement; + + constructor( + xeqn: any, + yeqn: any, + parameterRange: number[] = [0, 2 * Math.PI], + x: number = 10, + y: number = 10, + svgWidth: number = 300, + svgHeight: number = 300 + ) { + super(x, y, svgWidth, svgHeight); + this.config = { + graphColor: GOLD20, + graphStrokeWidth: 1, + arrowSize: 3, + xAxis: 'true', + yAxis: 'true', + minX: -5, + maxX: 5, + minY: -5, + maxY: 5, + scaleX: 1, + scaleY: 1, + axisColor: INDIGO50, + smallGridColor: MAGENTA50, + gridColor: ORANGE40, + stepX: 1, + stepY: 1, + originX: 0, + originY: 0, + tickX: 'true', + tickY: 'true', + tickColor: ULTRAMARINE40, + tickMarginX: -0.5, + tickMarginY: -0.5, + arrowFollowerColor: MAGENTA50 + }; + this.xeqn = xeqn; + this.yeqn = yeqn; + this.parameterRange = parameterRange; + this.config.scaleX = abs( + this.svgWidth / (this.config.maxX - this.config.minX) + ); + this.config.scaleY = abs( + this.svgHeight / (this.config.maxY - this.config.minY) + ); + // this.x = x; + // this.y = y; + // this.svgWidth = svgWidth; + // this.svgHeight = svgHeight; + //this.pathData = createParametricSVGPath(this.xeqn, this.yeqn, this.parameterRange, this.config); + this.graphContainer = createElement('div'); + this.graphContainer.parent(sceneContainer); + this.linePath = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'path' + ); + this.linePath.setAttribute('fill', 'none'); + this.linePath.setAttribute('stroke', 'black'); + this.linePath.setAttribute( + 'stroke-width', + `${this.config.graphStrokeWidth}` + ); + this.graphContainer.position(this.x, this.y); + this.graphObject = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'svg' + ); + this.graphObject.setAttribute('width', `${this.svgWidth}`); + this.graphObject.setAttribute('height', `${this.svgHeight}`); + this.graphObject.setAttribute( + 'viewBox', + `${-this.svgWidth / 2} ${-this.svgHeight / 2} ${this.svgWidth} ${ + this.svgHeight + }` + ); + this.graphObject.setAttribute('preserveAspectRatio', 'xMidYMid meet'); + this.graphContainer.elt.appendChild(this.graphObject); + } + + position(x: number, y: number = 10) { + this.x = x; + this.y = y; + this.graphContainer.position(this.x, this.y); + } + + configure(config) { + this.config = { + graphColor: config.graphColor + ? config.graphColor + : this.config.graphColor, + graphStrokeWidth: config.graphStrokeWidth + ? config.graphStrokeWidth + : this.config.graphStrokeWidth, + arrowSize: config.arrowSize ? config.arrowSize : this.config.arrowSize, + xAxis: config.xAxis ? config.xAxis : this.config.xAxis, + yAxis: config.yAxis ? config.yAxis : this.config.yAxis, + minX: config.minX ? config.minX : this.config.minX, + maxX: config.maxX ? config.maxX : this.config.maxX, + minY: config.minY ? config.minY : this.config.minY, + maxY: config.maxY ? config.maxY : this.config.maxY, + scaleX: config.scaleX ? config.scaleX : this.config.scaleX, + scaleY: config.scaleY ? config.scaleY : this.config.scaleY, + axisColor: config.axisColor ? config.axisColor : this.config.axisColor, + smallGridColor: config.smallGridColor + ? config.smallGridColor + : this.config.smallGridColor, + gridColor: config.gridColor ? config.gridColor : this.config.gridColor, + stepX: config.stepX ? config.stepX : this.config.stepX, + stepY: config.stepY ? config.stepY : this.config.stepY, + originX: config.originX ? config.originX : this.config.originX, + originY: config.originY ? config.originY : this.config.originY, + tickX: config.tickX ? config.tickX : this.config.tickX, + tickY: config.tickY ? config.tickY : this.config.tickY, + tickColor: config.tickColor ? config.tickColor : this.config.tickColor, + tickMarginX: config.tickMarginX + ? config.tickMarginX + : this.config.tickMarginX, + tickMarginY: config.tickMarginY + ? config.tickMarginY + : this.config.tickMarginY, + arrowFollowerColor: config.arrowFollowerColor + ? config.arrowFollowerColor + : this.config.arrowFollowerColor + }; + //console.log(this.config); + } + + size(width, height) { + if (arguments.length === 0) { + return [this.svgWidth, this.svgHeight]; + } else { + this.svgWidth = width; + this.svgHeight = height; + this.graphObject.setAttribute('width', `${this.svgWidth}`); + this.graphObject.setAttribute('height', `${this.svgHeight}`); + this.graphObject.setAttribute( + 'viewBox', + `${-this.svgWidth / 2} ${-this.svgHeight / 2} ${this.svgWidth} ${ + this.svgHeight + }` + ); + } + } + + stroke(_stroke: any) { + this.config.graphColor = _stroke; + this.linePath.setAttribute('stroke', `${_stroke}`); + } + + plot() { + this.pathData = createParametricSVGPath( + this.xeqn, + this.yeqn, + this.parameterRange, + this.config + ); + + this.plotting = document.createElementNS('http://www.w3.org/2000/svg', 'g'); + this.plotting.setAttribute('id', 'plot'); + this.linePath.setAttribute('stroke', `${this.config.graphColor}`); + this.linePath.setAttribute( + 'stroke-width', + `${this.config.graphStrokeWidth}` + ); + this.linePath.setAttribute('d', this.pathData); + this.plotting.appendChild(this.linePath); // + + this.graphObject.appendChild(this.plotting); + + // attaching to graphContainer + this.graphContainer.elt.appendChild(this.graphObject); + } + + remove() { + this.graphContainer.elt.removeChild(this.graphObject); + } + + //TODO : only update linePath to increase performance + update(xeqn: any, yeqn: any) { + const plot = this.graphObject.getElementById('plot'); + + this.xeqn = xeqn; + this.yeqn = yeqn; + this.pathData = createParametricSVGPath( + this.xeqn, + this.yeqn, + this.parameterRange, + this.config + ); + plot.getElementsByTagName('path')[0].setAttribute('d', this.pathData); + + //this.plotting = document.createElementNS('http://www.w3.org/2000/svg', 'g'); + //this.plotting.setAttribute('id', 'plot'); + //console.log(this.plotting); + + //this.linePath.setAttribute('stroke', `${this.config.graphColor}`); + // this.linePath.setAttribute( + // 'stroke-width', + // `${this.config.graphStrokeWidth}` + // ); + //this.plotting.appendChild(this.linePath); // + //this.graphObject.appendChild(this.plotting); + } + + transform(object_finl: any, startTime: number = 0, endTime: number = 2) { + transform(this, object_finl, startTime, endTime); + } + + axis() { + // coordinate system + + if (this.coordinate) { + this.coordinate.remove(); + } + this.coordinate = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'g' + ); + this.coordinate.setAttribute('id', 'coordinateSystem'); + let defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'); + defs.innerHTML += ``; + this.coordinate.appendChild(defs); + // this.graphObject.appendChild(arrowPath); + + // let frame = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + // frame.setAttribute('x', `${-this.svgWidth / 2}`); + // frame.setAttribute('y', `${-this.svgHeight / 2}`); + // frame.setAttribute('width', `${this.svgWidth}`); + // frame.setAttribute('height', `${this.svgHeight}`); + // frame.setAttribute('fill', `rgba(0,0,0,0)`); + // frame.setAttribute('stroke', `white`); + + //grid + defs.innerHTML += ` + + + + + + `; + + let grid = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + grid.setAttribute('x', `${-this.svgWidth / 2}`); + grid.setAttribute('y', `${-this.svgHeight / 2}`); + grid.setAttribute('width', `100%`); + grid.setAttribute('height', `100%`); + grid.setAttribute('fill', `url(#grid)`); + grid.setAttribute('stroke', `white`); + //this.coordinate.appendChild(frame); + this.coordinate.appendChild(grid); + + //axes + //console.log(this.config.axisX); + // console.log(this.config.tickX); + if (this.config.xAxis === 'true') { + let xAxis = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + xAxis.setAttribute('x1', `${-this.svgWidth / 2}`); + xAxis.setAttribute('y1', `${-this.config.originY * this.config.scaleY}`); + xAxis.setAttribute('x2', `${this.svgWidth / 2}`); + xAxis.setAttribute('y2', `${-this.config.originY * this.config.scaleY}`); + xAxis.setAttribute('marker-start', 'url(#marker-arrow)'); + xAxis.setAttribute('marker-end', 'url(#marker-arrow)'); + xAxis.setAttribute('stroke', `${this.config.axisColor}`); + xAxis.setAttribute('fill', `none`); + this.coordinate.appendChild(xAxis); + + if (this.config.tickX === 'true') { + let tick; + //x axis + //+ve axis + let veEnd = + abs( + int(this.svgWidth / (2 * this.config.scaleX) - this.config.originX) + ) / this.config.stepX; + for (let i = 0; i < veEnd; i += 1) { + let x = + this.config.originX * this.config.scaleX + + (i + 1) * this.config.stepX * this.config.scaleX; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute('x', `${x}`); + tick.setAttribute( + 'y', + `${ + -this.config.originY * this.config.scaleY - + this.config.tickMarginX * this.config.scaleY + }` + ); + tick.innerHTML = (i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + + //console.log(int(this.svgWidth / (2*this.config.scaleX)) + this.config.originX); + + //-ve axis + veEnd = abs( + int(this.svgWidth / (2 * this.config.scaleX)) + this.config.originX + ); + for (let i = veEnd; i >= 0; i -= 1) { + let x = + this.config.originX * this.config.scaleX - + (i + 1) * this.config.stepX * this.config.scaleX; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute('x', `${x}`); + tick.setAttribute( + 'y', + `${ + -this.config.originY * this.config.scaleY - + this.config.tickMarginX * this.config.scaleY + }` + ); + tick.innerHTML = -(i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + } + } + + if (this.config.yAxis === 'true') { + let yAxis = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + yAxis.setAttribute('x1', `${this.config.originX * this.config.scaleX}`); + yAxis.setAttribute('y1', `${-this.svgHeight / 2}`); + yAxis.setAttribute('x2', `${this.config.originX * this.config.scaleX}`); + yAxis.setAttribute('y2', `${this.svgHeight / 2}`); + yAxis.setAttribute('marker-start', 'url(#marker-arrow)'); + yAxis.setAttribute('marker-end', 'url(#marker-arrow)'); + yAxis.setAttribute('stroke', `${this.config.axisColor}`); + yAxis.setAttribute('fill', `none`); + this.coordinate.appendChild(yAxis); + if (this.config.tickY === 'true') { + let tick; + //y axis + //+ve axis + let veEnd = abs( + -int(this.svgHeight / (2 * this.config.scaleY)) + this.config.originY + ); + for (let i = 0; i <= veEnd; i += 1) { + let y = + -this.config.originY * this.config.scaleY - + (i + 1) * this.config.stepY * this.config.scaleY; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute( + 'x', + `${ + this.config.originX * this.config.scaleX + + this.config.tickMarginY * this.config.scaleX + }` + ); + tick.setAttribute('y', `${y}`); + tick.innerHTML = (i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + //-ve axis + veEnd = abs( + -int(this.svgHeight / (2 * this.config.scaleY)) - this.config.originY + ); + for (let i = veEnd; i >= 0; i -= 1) { + let y = + -this.config.originY * this.config.scaleY + + (i + 1) * this.config.stepY * this.config.scaleY; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute( + 'x', + `${ + this.config.originX * this.config.scaleX + + this.config.tickMarginY * this.config.scaleX + }` + ); + tick.setAttribute('y', `${y}`); + tick.innerHTML = -(i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + } + } + + //xAxis.setAttribute('stroke', color); + //xAxis.setAttribute('stroke-width', w); + + //ticks + + //this.plotting.appendChild(this.linePath); + this.graphObject.appendChild(this.coordinate); // + } + + play(timeDuration, delayDuration = 0, element = 'coordinateSystem') { + const elementToAnimate = this.graphContainer.elt.querySelectorAll( + `${element}` + ); + let pathElement: Array = []; + let it = elementToAnimate; + //console.log(it); + + it.forEach((currentElement) => { + //console.log(currentElement); + pathElement.push( + currentElement.querySelectorAll('path, line, rect, circle, marker') + ); + }); + //console.log(pathElement); + + animationTimeline.add( + { + targets: pathElement, + strokeDashoffset: [anime.setDashoffset, 0], + opacity: [0, 1], + // fill : ['currentColor'], + easing: 'easeInOutCubic', + duration: timeDuration, + autoplay: true + }, + delayDuration + ); + } + //TODO : arrow follower + arrow(eqn: any) { + let arrowPath = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + arrowPath.setAttribute('fill', 'none'); + arrowPath.setAttribute('stroke', 'black'); + arrowPath.setAttribute('stroke-width', '40'); + let defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'); + defs.innerHTML = + ' '; + this.graphObject.appendChild(defs); + this.graphObject.appendChild(arrowPath); + let update = 0; + //this.graphObject.appendChild(arrowPath); + const arrowDrawing = anime({ + targets: arrowPath, + //strokeDashoffset: [anime.setDashoffset, 0], + easing: 'easeOutSine', + duration: 50000, + begin: function (anim) { + //pathElement[0].setAttribute('stroke', 'black'); + //pathElement[0].setAttribute('fill', 'none'); + }, + complete: function (anim) { + //document.querySelector('path').setAttribute("fill", "yellow"); + }, + update: function (anim) { + update += 0.01; + + let scaleX = 100; + let scaleY = 100; + arrowPath.setAttribute('x1', `${0}`); + + arrowPath.setAttribute( + 'x2', + `${scaleX * eqn(update) * Math.cos(update)}` + ); + arrowPath.setAttribute('y1', `${0}`); + arrowPath.setAttribute( + 'y2', + `${scaleY * eqn(update) * Math.sin(update)}` + ); + arrowPath.setAttribute('marker-end', 'url(#arrowhead)'); + //document.querySelector('path').setAttribute("fill", "yellow"); + }, + autoplay: true + }); + } +} + +export function createParametricSVGPath( + xeqn: any, + yeqn: any, + parameterRange: number[] = [0, 2 * Math.PI], + config +) { + const pathElements = 1000; + const stepSize = (parameterRange[1] - parameterRange[0]) / pathElements; + + //let minX = parameterRange[0]; + // let scaleX = 100; + // let scaleY = 100; + let svgPath = `M${ + config.scaleX * xeqn(parameterRange[0]) + config.originX * config.scaleX + },${ + -config.scaleY * yeqn(parameterRange[0]) - config.originY * config.scaleY + }`; + for (let p = parameterRange[0]; p <= parameterRange[1]; p += stepSize) { + // svgPath = svgPath.concat(` L${1000*i},${1000*Math.sin(Math.PI / 2 * Math.pow(i, 1.5))/i}`); + svgPath = svgPath.concat( + ` L${config.scaleX * xeqn(p) + config.originX * config.scaleX},${ + -config.scaleY * yeqn(p) - config.originY * config.scaleY + }` + ); + } + return svgPath; +} + +export function create2DParametricGraph( + xeqn: any, + yeqn: any, + parameterRange: number[] = [0, 2 * Math.PI], + x: number = 10, + y: number = 10, + svgWidth: number = 300, + svgHeight: number = 300 +) { + return new GraphParametric2D( + xeqn, + yeqn, + parameterRange, + x, + y, + svgWidth, + svgHeight + ); +} + +export function parametric2D(xeqn, yeqn, parameterRange : number[] = [0, 2 * Math.PI]) { + // sceneVariables.graph.xeqn = xeqn; + // sceneVariables.graph.yeqn = yeqn; + // sceneVariables.graph.parameterRange = parameterRange; + if (sceneVariables.isGraph === 'true') { + let linePath = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'path' + ); + linePath.setAttribute('fill', 'none'); + linePath.setAttribute('stroke', `${sceneVariables.currStrokeColor.toString()}`); + linePath.setAttribute('stroke-width', `${sceneVariables.currStrokeWidth}`); + let pathData = createParametricSVGPath( + xeqn, + yeqn, + parameterRange, + sceneVariables.graph.config + ); + + const plotting = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'g' + ); + plotting.setAttribute('id', 'plot'); + // linePath.setAttribute( + // 'stroke', + // `${sceneVariables.graph.config.graphColor}` + // ); + // linePath.setAttribute( + // 'stroke-width', + // `${sceneVariables.graph.config.graphStrokeWidth}` + // ); + linePath.setAttribute( + 'd', + pathData + ); + + plotting.appendChild(linePath); // + + sceneVariables.graph.graphObject.appendChild(plotting); + + // attaching to graphContainer + sceneVariables.graph.graphContainer.elt.appendChild( + sceneVariables.graph.graphObject + ); + } +} diff --git a/src/lib/Geometry/polar.ts b/src/lib/Geometry/polar.ts new file mode 100644 index 0000000..e152b19 --- /dev/null +++ b/src/lib/Geometry/polar.ts @@ -0,0 +1,736 @@ +import anime from 'animejs'; +import { animationTimeline } from '../Scene/controls'; +import { sceneContainer, sceneVariables } from '../Scene/scene'; +import { transform } from '../Scene/transform'; +import { GObject } from './GObject'; + +// color blind safe palette +const ULTRAMARINE40 = '#648fff'; +const MAGENTA50 = '#dc267f'; +const GOLD20 = '#ffb000'; +const INDIGO50 = '#785ef0'; +const ORANGE40 = '#fe6100'; + +export class GraphPolar2D extends GObject { + eqn: Function; + plotting!: SVGGElement; + coordinate!: SVGGElement; + thetaRange: number[]; + config: { + //configuration for graph + scaleX: any; + maxX: any; + minX: any; + scaleY: any; + maxY: any; + minY: any; + graphColor: any; + graphStrokeWidth: any; + arrowSize: any; + xAxis: any; + yAxis: any; + axisColor: any; + smallGridColor: any; + gridColor: any; + stepX: any; + stepY: any; + originX: any; + originY: any; + tickX: any; + tickY: any; + tickColor: any; + tickMarginX: any; + tickMarginY: any; + arrowFollowerColor: any; + }; + // pathData: any; + // graphObject: any; + // graphContainer: any; + // x: number; + // y: number; + // width_svg: number; + // height_svg: number; + // linePath: SVGPathElement; + + constructor( + eqn: Function, + thetaRange: number[] = [0, 2 * Math.PI], + x: number = 10, + y: number = 10, + svgWidth: number = 300, + svgHeight: number = 300 + ) { + super(x, y, svgWidth, svgHeight); + this.config = { + graphColor: GOLD20, + graphStrokeWidth: 1, + arrowSize: 3, + xAxis: 'true', + yAxis: 'true', + minX: -5, + maxX: 5, + minY: -5, + maxY: 5, + scaleX: 1, + scaleY: 1, + axisColor: INDIGO50, + smallGridColor: MAGENTA50, + gridColor: ORANGE40, + stepX: 1, + stepY: 1, + originX: 0, + originY: 0, + tickX: 'true', + tickY: 'true', + tickColor: ULTRAMARINE40, + tickMarginX: -0.5, + tickMarginY: -0.5, + arrowFollowerColor: MAGENTA50 + }; + + this.eqn = eqn; + this.thetaRange = thetaRange; + + this.config.scaleX = abs( + this.svgWidth / (this.config.maxX - this.config.minX) + ); + this.config.scaleY = abs( + this.svgHeight / (this.config.maxY - this.config.minY) + ); + + // this.x = x; + // this.y = y; + // this.width_svg = width_svg; + // this.height_svg = height_svg; + + this.graphContainer = createElement('div'); + this.graphContainer.parent(sceneContainer); + this.linePath = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'path' + ); + this.linePath.setAttribute('fill', 'none'); + this.linePath.setAttribute('stroke', 'black'); + this.linePath.setAttribute( + 'stroke-width', + `${this.config.graphStrokeWidth}` + ); + this.graphContainer.position(this.x, this.y); + this.graphObject = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'svg' + ); + this.graphObject.setAttribute('width', `${this.svgWidth}`); + this.graphObject.setAttribute('height', `${this.svgHeight}`); + this.graphObject.setAttribute( + 'viewBox', + `${-this.svgWidth / 2} ${-this.svgHeight / 2} ${this.svgWidth} ${ + this.svgHeight + }` + ); + this.graphObject.setAttribute('preserveAspectRatio', 'xMidYMid meet'); + } + + position(x: number, y: number = 10) { + this.x = x; + this.y = y; + this.graphContainer.position(this.x, this.y); + } + + configure(config) { + this.config = { + graphColor: config.graphColor + ? config.graphColor + : this.config.graphColor, + graphStrokeWidth: config.graphStrokeWidth + ? config.graphStrokeWidth + : this.config.graphStrokeWidth, + arrowSize: config.arrowSize ? config.arrowSize : this.config.arrowSize, + xAxis: config.xAxis ? config.xAxis : this.config.xAxis, + yAxis: config.yAxis ? config.yAxis : this.config.yAxis, + minX: config.minX ? config.minX : this.config.minX, + maxX: config.maxX ? config.maxX : this.config.maxX, + minY: config.minY ? config.minY : this.config.minY, + maxY: config.maxY ? config.maxY : this.config.maxY, + scaleX: config.scaleX ? config.scaleX : this.config.scaleX, + scaleY: config.scaleY ? config.scaleY : this.config.scaleY, + axisColor: config.axisColor ? config.axisColor : this.config.axisColor, + smallGridColor: config.smallGridColor + ? config.smallGridColor + : this.config.smallGridColor, + gridColor: config.gridColor ? config.gridColor : this.config.gridColor, + stepX: config.stepX ? config.stepX : this.config.stepX, + stepY: config.stepY ? config.stepY : this.config.stepY, + originX: config.originX ? config.originX : this.config.originX, + originY: config.originY ? config.originY : this.config.originY, + tickX: config.tickX ? config.tickX : this.config.tickX, + tickY: config.tickY ? config.tickY : this.config.tickY, + tickColor: config.tickColor ? config.tickColor : this.config.tickColor, + tickMarginX: config.tickMarginX + ? config.tickMarginX + : this.config.tickMarginX, + tickMarginY: config.tickMarginY + ? config.tickMarginY + : this.config.tickMarginY, + arrowFollowerColor: config.arrowFollowerColor + ? config.arrowFollowerColor + : this.config.arrowFollowerColor + }; + //console.log(this.config); + } + + size(width, height) { + if (arguments.length === 0) { + return [this.svgWidth, this.svgHeight]; + } else { + this.svgWidth = width; + this.svgHeight = height; + this.graphObject.setAttribute('width', `${this.svgWidth}`); + this.graphObject.setAttribute('height', `${this.svgHeight}`); + this.graphObject.setAttribute( + 'viewBox', + `${-this.svgWidth / 2} ${-this.svgHeight / 2} ${this.svgWidth} ${ + this.svgHeight + }` + ); + } + } + + stroke(_stroke: any) { + this.config.graphColor = _stroke; + this.linePath.setAttribute('stroke', `${_stroke}`); + } + + plot() { + this.pathData = createPolarSVGPath(this.eqn, this.thetaRange, this.config); + //this.graphObject.setAttribute('style', `translate(-50%, -50%)`); + this.graphObject.setAttribute('width', `${this.svgWidth}`); + this.graphObject.setAttribute('height', `${this.svgHeight}`); + this.linePath.setAttribute('stroke', `${this.config.graphColor}`); + //this.graphObject.setAttribute('viewBox', '-8500 -2000 18000 4000'); + //this.graphObject.setAttribute('preserveAspectRatio', 'xMidYMid meet'); + this.linePath.setAttribute('d', this.pathData); + this.graphObject.appendChild(this.linePath); + this.graphContainer.elt.appendChild(this.graphObject); + } + + remove() { + this.graphContainer.elt.removeChild(this.graphObject); + } + + update(eqn: any, thetaRange?) { + if (!(thetaRange.length === 0)) { + this.thetaRange = thetaRange; + } + this.eqn = eqn; + this.pathData = createPolarSVGPath(eqn, this.thetaRange, this.config); + this.linePath.setAttribute('d', this.pathData); + } + + transform(object_finl: any, startTime: number = 0, endTime: number = 2) { + transform(this, object_finl, startTime, endTime); + } + play() { + const pathElement = this.graphContainer.elt.querySelectorAll('path'); + const lineDrawing = anime({ + targets: this.graphContainer.elt.querySelectorAll('path'), + strokeDashoffset: [anime.setDashoffset, 0], + easing: 'easeOutSine', + duration: 50000, + begin: function (anim) { + //pathElement[0].setAttribute('stroke', 'black'); + pathElement[0].setAttribute('fill', 'none'); + }, + complete: function (anim) { + //document.querySelector('path').setAttribute("fill", "yellow"); + }, + autoplay: true + }); + } + + axis() { + // coordinate system + this.coordinate = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'g' + ); + this.coordinate.setAttribute('id', 'coordinateSystem'); + let defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'); + defs.innerHTML += ``; + + this.coordinate.style.transform += `scaleX(${1})`; + this.coordinate.style.transform += `scaleY(${1})`; + + this.graphObject.appendChild(defs); + // this.graphObject.appendChild(arrowPath); + + // let frame = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + // frame.setAttribute('x', `${-this.svgWidth / 2}`); + // frame.setAttribute('y', `${-this.svgHeight / 2}`); + // frame.setAttribute('width', `${this.svgWidth}`); + // frame.setAttribute('height', `${this.svgHeight}`); + // frame.setAttribute('fill', `rgba(0,0,0,0)`); + // frame.setAttribute('stroke', `white`); + + //polar grid + let grid = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + grid.setAttribute('x', `${-this.svgWidth / 2}`); + grid.setAttribute('y', `${-this.svgHeight / 2}`); + grid.setAttribute('width', `100%`); + grid.setAttribute('height', `100%`); + //grid.setAttribute('fill', `url(#grid)`); + grid.setAttribute('stroke', `white`); + //this.coordinate.appendChild(frame); + this.coordinate.appendChild(grid); + + const radialLineMax = Math.max( + dist( + this.config.originX * this.config.scaleX, + this.config.originY * this.config.scaleY, + this.svgWidth / 2, + this.svgHeight / 2 + ), + dist( + this.config.originX * this.config.scaleX, + this.config.originY * this.config.scaleY, + -this.svgWidth / 2, + -this.svgHeight / 2 + ), + dist( + this.config.originX * this.config.scaleX, + this.config.originY * this.config.scaleY, + this.svgWidth / 2, + -this.svgHeight / 2 + ), + dist( + this.config.originX * this.config.scaleX, + this.config.originY * this.config.scaleY, + -this.svgWidth / 2, + this.svgHeight / 2 + ) + ); + + //console.log(radialLineMax); + + let polarGrid: SVGCircleElement; + //Math.max(this.config.originX,this.svgWidth-this.originX) + let dr = + Math.max(this.config.scaleX, this.config.scaleY) * + Math.floor( + radialLineMax / (5 * Math.max(this.config.scaleX, this.config.scaleY)) + ); + for (let i = 0; i <= radialLineMax; i += dr) { + polarGrid = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'circle' + ); + polarGrid.setAttribute( + 'cx', + `${this.config.originX * this.config.scaleX}` + ); + polarGrid.setAttribute( + 'cy', + `${-this.config.originY * this.config.scaleY}` + ); + polarGrid.setAttribute('r', `${i}`); + + polarGrid.setAttribute('fill', `none`); + polarGrid.setAttribute('stroke', `${this.config.gridColor}`); + polarGrid.setAttribute('stroke-opacity', `0.5`); + this.coordinate.appendChild(polarGrid); + } + + let smallPolarGrid: SVGCircleElement; + dr = + (Math.max(this.config.scaleX, this.config.scaleY) * + Math.floor( + radialLineMax / (5 * Math.max(this.config.scaleX, this.config.scaleY)) + )) / + 5; + for (let i = 0; i <= radialLineMax; i += dr) { + smallPolarGrid = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'circle' + ); + smallPolarGrid.setAttribute( + 'cx', + `${this.config.originX * this.config.scaleX}` + ); + smallPolarGrid.setAttribute( + 'cy', + `${-this.config.originY * this.config.scaleY}` + ); + smallPolarGrid.setAttribute('r', `${i}`); + + smallPolarGrid.setAttribute('fill', `none`); + smallPolarGrid.setAttribute('stroke', `${this.config.smallGridColor}`); + smallPolarGrid.setAttribute('stroke-opacity', `0.25`); + this.coordinate.appendChild(smallPolarGrid); + } + + let radialLine; + + for (let i = 1; i <= 12; i += 1) { + radialLine = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + radialLine.setAttribute( + 'x1', + `${ + radialLineMax * Math.cos((i * PI) / 12) + + this.config.originX * this.config.scaleX + }` + ); + radialLine.setAttribute( + 'y1', + `${ + radialLineMax * Math.sin((i * PI) / 12) - + this.config.originY * this.config.scaleY + }` + ); + radialLine.setAttribute( + 'x2', + `${ + -radialLineMax * Math.cos((i * PI) / 12) + + this.config.originX * this.config.scaleX + }` + ); + radialLine.setAttribute( + 'y2', + `${ + -radialLineMax * Math.sin((i * PI) / 12) - + this.config.originY * this.config.scaleY + }` + ); + + radialLine.setAttribute('fill', `none`); + radialLine.setAttribute('stroke', `${this.config.gridColor}`); + radialLine.setAttribute('stroke-opacity', `0.25`); + this.coordinate.appendChild(radialLine); + } + + //axes + //console.log(this.config.axisX); + // console.log(this.config.tickX); + if (this.config.xAxis === 'true') { + let xAxis = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + xAxis.setAttribute('x1', `${-this.svgWidth / 2}`); + xAxis.setAttribute('y1', `${-this.config.originY * this.config.scaleY}`); + xAxis.setAttribute('x2', `${this.svgWidth / 2}`); + xAxis.setAttribute('y2', `${-this.config.originY * this.config.scaleY}`); + xAxis.setAttribute('marker-start', 'url(#marker-arrow)'); + xAxis.setAttribute('marker-end', 'url(#marker-arrow)'); + xAxis.setAttribute('stroke', `${this.config.axisColor}`); + xAxis.setAttribute('fill', `none`); + this.coordinate.appendChild(xAxis); + + if (this.config.tickX === 'true') { + let tick; + //x axis + //+ve axis + let veEnd = + abs( + int(this.svgWidth / (2 * this.config.scaleX) - this.config.originX) + ) / this.config.stepX; + for (let i = 0; i < veEnd; i += 1) { + let x = + this.config.originX * this.config.scaleX + + (i + 1) * this.config.stepX * this.config.scaleX; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute('x', `${x}`); + tick.setAttribute( + 'y', + `${ + -this.config.originY * this.config.scaleY - + this.config.tickMarginX * this.config.scaleY + }` + ); + tick.innerHTML = (i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + + //console.log(int(this.svgWidth / (2*this.config.scaleX)) + this.config.originX); + + //-ve axis + veEnd = abs( + int(this.svgWidth / (2 * this.config.scaleX)) + this.config.originX + ); + for (let i = veEnd; i >= 0; i -= 1) { + let x = + this.config.originX * this.config.scaleX - + (i + 1) * this.config.stepX * this.config.scaleX; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute('x', `${x}`); + tick.setAttribute( + 'y', + `${ + -this.config.originY * this.config.scaleY - + this.config.tickMarginX * this.config.scaleY + }` + ); + tick.innerHTML = -(i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + } + } + + if (this.config.yAxis === 'true') { + let yAxis = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + yAxis.setAttribute('x1', `${this.config.originX * this.config.scaleX}`); + yAxis.setAttribute('y1', `${-this.svgHeight / 2}`); + yAxis.setAttribute('x2', `${this.config.originX * this.config.scaleX}`); + yAxis.setAttribute('y2', `${this.svgHeight / 2}`); + yAxis.setAttribute('marker-start', 'url(#marker-arrow)'); + yAxis.setAttribute('marker-end', 'url(#marker-arrow)'); + yAxis.setAttribute('stroke', `${this.config.axisColor}`); + yAxis.setAttribute('fill', `none`); + this.coordinate.appendChild(yAxis); + if (this.config.tickY === 'true') { + let tick; + //y axis + //+ve axis + let veEnd = abs( + -int(this.svgHeight / (2 * this.config.scaleY)) + this.config.originY + ); + for (let i = 0; i <= veEnd; i += 1) { + let y = + -this.config.originY * this.config.scaleY - + (i + 1) * this.config.stepY * this.config.scaleY; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute( + 'x', + `${ + this.config.originX * this.config.scaleX + + this.config.tickMarginY * this.config.scaleX + }` + ); + tick.setAttribute('y', `${y}`); + tick.innerHTML = (i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + //-ve axis + veEnd = abs( + -int(this.svgHeight / (2 * this.config.scaleY)) - this.config.originY + ); + for (let i = veEnd; i >= 0; i -= 1) { + let y = + -this.config.originY * this.config.scaleY + + (i + 1) * this.config.stepY * this.config.scaleY; + tick = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + tick.setAttribute( + 'x', + `${ + this.config.originX * this.config.scaleX + + this.config.tickMarginY * this.config.scaleX + }` + ); + tick.setAttribute('y', `${y}`); + tick.innerHTML = -(i + 1).toString(); + tick.style.textAnchor = 'middle'; + tick.style.alignmentBaseline = 'middle'; + tick.style.strokeOpacity = '.2'; + tick.style.fill = `${this.config.tickColor}`; + this.coordinate.appendChild(tick); + } + } + } + + //xAxis.setAttribute('stroke', color); + //xAxis.setAttribute('stroke-width', w); + + //ticks + + //this.plotting.appendChild(this.linePath); + this.graphObject.appendChild(this.coordinate); // + } + + //TODO : arrow follower + arrow(timeDuration) { + let eqn = this.eqn; + let config = this.config; + // const scaleX = this.config.scaleX; + // const scaleY = this.config.scaleY; + // if(this.graphObject.elt.arrowPath){ + + // } + if (this.graphObject.getElementById('arrow')) { + this.graphObject.removeChild(this.graphObject.getElementById('arrow')); + } + + let arrowPath = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'line' + ); + arrowPath.setAttribute('id', 'arrow'); + arrowPath.setAttribute('fill', 'none'); + arrowPath.setAttribute('stroke', `${this.config.arrowFollowerColor}`); + arrowPath.setAttribute('stroke-width', '1'); + // let defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'); + // defs.innerHTML = + // ' '; + // this.graphObject.appendChild(defs); + this.graphObject.appendChild(arrowPath); + let update = 0; + //this.graphObject.appendChild(arrowPath); + animationTimeline.add({ + targets: arrowPath, + //strokeDashoffset: [anime.setDashoffset, 0], + easing: 'easeOutSine', + duration: timeDuration, + // begin: function (anim) { + // //pathElement[0].setAttribute('stroke', 'black'); + // //pathElement[0].setAttribute('fill', 'none'); + // }, + // complete: function (anim) { + // //document.querySelector('path').setAttribute("fill", "yellow"); + // }, + update: function (anim) { + update += 0.01; + + //let scaleX = 100; + //let scaleY = 100; + arrowPath.setAttribute('x1', `${config.originX * config.scaleX}`); + + arrowPath.setAttribute( + 'x2', + `${ + config.scaleX * eqn(update) * Math.cos(update) + + config.originX * config.scaleX + }` + ); + arrowPath.setAttribute('y1', `${-config.originY * config.scaleY}`); + arrowPath.setAttribute( + 'y2', + `${ + -config.scaleY * eqn(update) * Math.sin(update) - + config.originY * config.scaleY + }` + ); + arrowPath.setAttribute('marker-end', 'url(#marker-arrow)'); + //document.querySelector('path').setAttribute("fill", "yellow"); + }, + autoplay: true + }); + } +} + +export function createPolarSVGPath( + eqn: any, + thetaRange: number[] = [0, 2 * Math.PI], + config + //stepSize: number = 0.001 +) { + const pathElements = 1000; + const stepSize = (thetaRange[1] - thetaRange[0]) / pathElements; + + //let minX = 0; + //let scaleX = 100; + //let scaleY = 100; + //console.log(config.scaleX); + + let svgPath = `M${ + config.scaleX * eqn(thetaRange[0]) * Math.cos(0) + + config.originX * config.scaleX + },${ + -config.scaleY * eqn(thetaRange[0]) * Math.sin(0) - + config.originY * config.scaleY + }`; + for (let theta = thetaRange[0]; theta <= thetaRange[1]; theta += stepSize) { + // SVG_path = SVG_path.concat(` L${1000*i},${1000*Math.sin(Math.PI / 2 * Math.pow(i, 1.5))/i}`); + svgPath = svgPath.concat( + ` L${ + config.scaleX * eqn(theta) * Math.cos(theta) + + config.originX * config.scaleX + },${ + -config.scaleY * eqn(theta) * Math.sin(theta) - + config.originY * config.scaleY + }` + ); + } + return svgPath; +} + +export function create2DPolarGraph( + eqn: Function, + thetaRange: number[] = [0, 2 * Math.PI], + x: number = 10, + y: number = 10, + svgWidth: number = 300, + svgHeight: number = 300 +) { + return new GraphPolar2D(eqn, thetaRange, x, y, svgWidth, svgHeight); +} + +export function polar2D(eqn, thetaRange: number[] = [0, 2 * Math.PI]) { + // sceneVariables.graph.xeqn = xeqn; + // sceneVariables.graph.yeqn = yeqn; + // sceneVariables.graph.parameterRange = parameterRange; + if (sceneVariables.isGraph === 'true') { + let linePath = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'path' + ); + linePath.setAttribute('fill', 'none'); + linePath.setAttribute( + 'stroke', + `${sceneVariables.currStrokeColor.toString()}` + ); + linePath.setAttribute('stroke-width', `${sceneVariables.currStrokeWidth}`); + let pathData = createPolarSVGPath( + eqn, + thetaRange, + sceneVariables.graph.config + ); + + const plotting = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'g' + ); + plotting.setAttribute('id', 'plot'); + // linePath.setAttribute( + // 'stroke', + // `${sceneVariables.graph.config.graphColor}` + // ); + // linePath.setAttribute( + // 'stroke-width', + // `${sceneVariables.graph.config.graphStrokeWidth}` + // ); + linePath.setAttribute('d', pathData); + + plotting.appendChild(linePath); // + + sceneVariables.graph.graphObject.appendChild(plotting); + + // attaching to graphContainer + sceneVariables.graph.graphContainer.elt.appendChild( + sceneVariables.graph.graphObject + ); + } +} diff --git a/src/lib/MObject/MObject.ts b/src/lib/MObject/MObject.ts index efd5545..b531fe5 100644 --- a/src/lib/MObject/MObject.ts +++ b/src/lib/MObject/MObject.ts @@ -1,3 +1,5 @@ +import { animationTimeline } from '../Scene/controls'; + export class MObject { writeElement!: p5.Element; //
for animation sentence: string; //input string as tex or text @@ -12,4 +14,59 @@ export class MObject { this.fillColor = color('black'); this._size = _size; } + + moveTo(newX, newY, startTime, endTime) { + const object = this.writeElement; + const timeDuration = (endTime - startTime) * 1000; + const delayDuration = startTime * 1000; + const currCoord = { + currX: this.x, + currY: this.y + }; + animationTimeline.add( + { + targets: currCoord, //[this.x, this.y], + currX: newX, + currY: newY, + + //translateZ: 0, + easing: 'easeInOutCubic', + duration: timeDuration, + update: function (anim) { + this.x = currCoord.currX; + this.y = currCoord.currY; + object.position(this.x, this.y); + } + //delay: anime.stagger(CONFIG.PLAY.DISSOLVE_STAGGERING_DELAY) + //delay: anime.stagger(180, { start: timeDuration }) //time duration must be replaced with delay + }, + delayDuration + ); + } + + resizeTo(newSize, startTime, endTime) { + const object = this.writeElement; + const timeDuration = (endTime - startTime) * 1000; + const delayDuration = startTime * 1000; + const Size = { + currSize: this._size + }; + animationTimeline.add( + { + targets: Size, //[this.x, this.y], + currSize: newSize, + + //translateZ: 0, + easing: 'easeInOutCubic', + duration: timeDuration, + update: function (anim) { + object.style('font-size', `${this._size}px`); + this._size = Size.currSize; + } + //delay: anime.stagger(CONFIG.PLAY.DISSOLVE_STAGGERING_DELAY) + //delay: anime.stagger(180, { start: timeDuration }) //time duration must be replaced with delay + }, + delayDuration + ); + } } diff --git a/src/lib/MObject/TeX.ts b/src/lib/MObject/TeX.ts index 07cc048..d24dfe2 100644 --- a/src/lib/MObject/TeX.ts +++ b/src/lib/MObject/TeX.ts @@ -1,34 +1,16 @@ import TeXToSVG from 'tex-to-svg'; import { TexObject } from '../interfaces'; import { add } from '../Scene/add'; +//import { animationTimeline } from '../Scene/controls'; import { play } from '../Scene/play'; import { MObject } from './MObject'; //TODO : add test cases /** - * TeX class - * - * @param {String} - escaped TeX input - * @param {number} - x - * @param {number} - y - * @param {number} - width - * @param {number} - height - * - * @example - * - * example for playing animation of type 'appear' for TeX object: - * ```js - * let tex_1 = new TeX( - * '\\ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-}\\overrightarrow{F}_{12} = k_e \\frac{q_1 q_2}{r^2}', - * 200, - * 300, - * 200, - * 100 - * ); - * ``` - * @experimental + * class representing a tex */ + export class TeX extends MObject { svgEquation: string; //startTime: number; // left for later decision -> need not specify such details at initialisation @@ -39,22 +21,44 @@ export class TeX extends MObject { // svgHeight: number; _strokeWidth: number; strokeColor: p5.Color; - constructor({ - _tex, - x = 10, - y = 10, - _size = 28 - }: TexObject) { - super(_tex, x, y,_size); + + /** + * creates a tex object + * + * + * + * @param {String} - escaped TeX input + * @param {number} - x + * @param {number} - y + * @param {number} - font-size + * + * @example + * + * example for creating TeX object: + * ```js + * let tex = new TeX( + * '\\ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-}', 200, 300, 28); + * ``` + */ + + constructor({ _tex, x = 10, y = 10, _size = 28 }: TexObject) { + super(_tex, x, y, _size); //this._tex = _tex; // this._size = _size; //px // this.svgWidth = svgWidth; // this.svgHeight = svgHeight; + this.writeElement = createElement('div'); this.svgEquation = TeXToSVG(_tex); this._strokeWidth = 8; this.strokeColor = color('black'); } + /** + * sets position of tex + * @param {number} x-coordinate x-coordinate of tex + * @param {number} y-coordinate y-coordinate of tex + */ + position(x: number = 10, y: number = 10) { if (arguments.length === 0) { return [this.x, this.y]; @@ -64,6 +68,11 @@ export class TeX extends MObject { } } + /** + * sets font-size of tex + * @param {number} font-size font-size of the tex + */ + size(_size: number = 28) { if (arguments.length === 0) { return this._size; @@ -72,13 +81,24 @@ export class TeX extends MObject { } } - stroke(strokeColor: any = color('black')) { + /** + * sets stroke-color of tex + * @param {p5.Color} stroke-color stroke-color of tex + */ + + stroke(strokeColor: any = 'black') { if (arguments.length === 0) { return this.strokeColor; } else { - this.strokeColor = color(strokeColor); + this.strokeColor = strokeColor; } } + + /** + * sets stroke-width of tex + * @param {number} strokeWidth stroke-width of the tex + */ + strokeWidth(_strokeWidth: number = 8) { if (arguments.length === 0) { return this._strokeWidth; @@ -87,24 +107,75 @@ export class TeX extends MObject { } } - fill(fillColor: any = color('black')) { + /** + * sets fill-color of text + * @param {p5.Color} fill-color fill-color of text + */ + + fill(fillColor: any = 'black') { if (arguments.length === 0) { return this.fillColor; } else { - this.fillColor = color(fillColor); + this.fillColor = fillColor; } } + /** + * removes text object + */ + remove() { //TODO : should throw error if called on object which has not been added this.writeElement.remove(); } + /** + * adds text object + */ + add() { add(this); //this.writeTexElement.style('opacity', '1'); } + /** + * Sets the given style (css) property (1st arg) of the element with the + * given value (2nd arg). If the single argument + * is given in css syntax ('text-align:center'), .style() sets the css + * appropriately. + * + * @param {String} property property to be set + * @param {String} value value + */ + + style(property, value) { + this.writeElement.style(property, value); + } + + /** + * updates the tex + */ + update(_tex) { + this.svgEquation = TeXToSVG(_tex); + this.writeElement.html(this.svgEquation); + let svg = this.writeElement.elt.querySelectorAll('svg'); + let g = this.writeElement.elt.querySelectorAll('g'); + //svg[0].setAttribute('width', `${object.svgWidth}px`); + //svg[0].setAttribute('height', `${object.svgHeight}px`); + g[0].setAttribute('stroke', this.strokeColor); + g[0].setAttribute('stroke-width', this._strokeWidth); + g[0].setAttribute('fill', this.fillColor); + svg[0].setAttribute('fill', this.fillColor); + this.writeElement.position(this.x, this.y); + } + + /** + * play text animation + * @param {String} animationType type of animation to be played + * @param {Number} timeDuration duration of animation + * @param {Number} delayDuration delay + */ + play( animationType: string = 'write', startTime: number = 0, @@ -114,6 +185,24 @@ export class TeX extends MObject { } } +/** + * createTeX + * + * @param args + * + * ```js + * let tex = createTeX( + * '\\ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-}\\overrightarrow{F}_{12} = k_e \\frac{q_1 q_2}{r^2}', + * 200, + * 300, + * 20, + * ); + * ``` + *
+ * + * + * @returns + */ export function createTeX(...args: any[]) { const _texArg: TexObject = { _tex: args[0], diff --git a/src/lib/MObject/Text.ts b/src/lib/MObject/Text.ts index bcf2c3a..ee7e84b 100644 --- a/src/lib/MObject/Text.ts +++ b/src/lib/MObject/Text.ts @@ -3,6 +3,10 @@ import { add } from '../Scene/add'; import { play } from '../Scene/play'; import { MObject } from './MObject'; +/** + * class representing a text + */ + export class Text extends MObject { //writeElement!: p5.Element; //to be used by play function //to be used by play function @@ -11,15 +15,32 @@ export class Text extends MObject { // x: number; // y: number; - // strokeColor: string; // strokeWidth: number; //fillColor: p5.Color; + /** + * creates a text object + * + * @param {string} text text content + * @param {number} x-coordinate x-coordinate of text + * @param {number} y-coordinate y-coordinate of text + * @param {number} font-size font-size of the text + * + * @example + * + * example for creating text object: + * ```js + * let text = new Text('Hi!', width/2, height/2, 28) + * ``` + */ + constructor({ _text, x = 10, y = 10, _size = 28 }: TextObject) { super(_text, x, y, _size); + this.writeElement = createElement('div'); + //this._text = _text; - + //console.log('me', this._size); // this.strokeColor = 'black'; @@ -27,6 +48,12 @@ export class Text extends MObject { //this.fillColor = color('black'); } + /** + * sets position of text + * @param {number} x-coordinate x-coordinate of text + * @param {number} y-coordinate y-coordinate of text + */ + position(x: number = 10, y: number = 10) { if (arguments.length === 0) { return [this.x, this.y]; @@ -35,6 +62,12 @@ export class Text extends MObject { this.y = y; } } + + /** + * sets font-size of text + * @param {number} font-size font-size of the text + */ + size(_size: number = 28) { if (arguments.length === 0) { return this._size; //font-size @@ -61,6 +94,11 @@ export class Text extends MObject { // } // } + /** + * sets fill-color of text + * @param {p5.Color} fill-color fill-color of text + */ + fill(fillColor: any = color('black')) { if (arguments.length === 0) { return this.fillColor; @@ -69,14 +107,45 @@ export class Text extends MObject { } } + /** + * removes text object + */ + remove() { //TODO : should throw error if called on object which has not been added this.writeElement.remove(); } + + /** + * adds text object + */ + add() { add(this); this.writeElement.style('opacity', '1'); } + + /** + * Sets the given style (css) property (1st arg) of the element with the + * given value (2nd arg). If the single argument + * is given in css syntax ('text-align:center'), .style() sets the css + * appropriately. + * + * @param {String} property property to be set + * @param {String} value value + */ + + style(property, value) { + this.writeElement.style(property, value); + } + + /** + * play text animation + * @param {String} animationType type of animation to be played + * @param {Number} timeDuration duration of animation + * @param {Number} delayDuration delay + */ + play( animationType: string = 'write', timeDuration: number = 0, @@ -86,6 +155,15 @@ export class Text extends MObject { } } +/** + * createText function creates a text object and return text object + * @param {string} text text content + * @param {number} x-coordinate x-coordinate of text + * @param {number} y-coordinate y-coordinate of text + * @param {number} font-size font-size of the text + * @returns {Text} MObject of type Text + */ + export function createText(...args: any[]) { //TODO : convert into interface diff --git a/src/lib/Scene/add.ts b/src/lib/Scene/add.ts index d6a3135..c29d0a6 100644 --- a/src/lib/Scene/add.ts +++ b/src/lib/Scene/add.ts @@ -1,17 +1,19 @@ import { TeX } from '../MObject/TeX'; import { Text } from '../MObject/Text'; +import { sceneContainer } from './scene'; export function add(object: Text | TeX) { if (object instanceof TeX) { //tex animations - object.writeElement = createDiv(object.svgEquation); + object.writeElement.html(object.svgEquation); + object.writeElement.parent(sceneContainer); let svg = object.writeElement.elt.querySelectorAll('svg'); let g = object.writeElement.elt.querySelectorAll('g'); //svg[0].setAttribute('width', `${object.svgWidth}px`); //svg[0].setAttribute('height', `${object.svgHeight}px`); g[0].setAttribute('stroke', object.strokeColor.toString()); g[0].setAttribute('stroke-width', object._strokeWidth); - + g[0].setAttribute('fill', object.fillColor.toString()); svg[0].setAttribute('fill', object.fillColor.toString()); // svg[0].style.fontSize = `${object._size}px`; object.writeElement.style('font-size', `${object._size}px`); @@ -22,14 +24,15 @@ export function add(object: Text | TeX) { } else if (object instanceof Text) { const sentence = object.sentence; - object.writeElement = createElement( - 'div', + object.writeElement.html( sentence.replace(/\S/g, "$&") ); + object.writeElement.parent(sceneContainer); object.writeElement.position(object.x, object.y); object.writeElement.style('font-size', `${object._size}px`); object.writeElement.style('color', `${object.fillColor}`); //object.writeElement.style('text-stroke-width', `${object._strokeWidth}`); //TODO : not working without -webkit object.writeElement.style('opacity', '0'); //to hide text at initialisation + object.writeElement.style('white-space', 'nowrap'); //TODO : check for animations if breaking } } diff --git a/src/lib/Scene/controls.ts b/src/lib/Scene/controls.ts new file mode 100644 index 0000000..0258d2b --- /dev/null +++ b/src/lib/Scene/controls.ts @@ -0,0 +1,108 @@ +import anime from 'animejs'; +export function clock() { + return animationTimeline.duration * (animationTimeline.progress / 100); +} +export function addDuration(timeDuration) { + animationTimeline.add({ duration: timeDuration }); +} + +export function callAt(startTime, func) { + animationTimeline.add( + { + //duration: startTime, + complete: function (anim) { + // console.log("called"); + + func(); + } + //delay: anime.stagger(CONFIG.PLAY.DISSOLVE_STAGGERING_DELAY) + //delay: anime.stagger(180, { start: timeDuration }) //time duration must be replaced with delay + }, + startTime*1000 + ); +} + +export let animationTimeline = anime.timeline({}); //initilising a timeline +// animationTimeline.add({}); + +export function createControls() { + let p5Canvas = document + .getElementsByClassName('p5Canvas')[0] + .getBoundingClientRect(); + let controlsDiv = document.createElement('div'); + controlsDiv.setAttribute('class', 'controls'); + document.body.appendChild(controlsDiv); + + let progressBar = document.createElement('input'); + progressBar.setAttribute('type', 'range'); + progressBar.setAttribute('min', `${0}`); + progressBar.setAttribute('max', `${100}`); + progressBar.setAttribute('value', `${0}`); + progressBar.setAttribute('step', `${0.001}`); + progressBar.setAttribute( + 'style', + `appearance: none; width: ${p5Canvas.width}px; height: 1px; background: #d3d3d3; display: block; margin-top: 10px; margin-bottom: 10px;` + ); + controlsDiv.appendChild(progressBar); + + progressBar.oninput = function () { + animationTimeline.pause(); + //console.log(animationTimeline.duration * (progressBar.valueAsNumber / 100)); + animationTimeline.seek( + animationTimeline.duration * (progressBar.valueAsNumber / 100) + ); + //playScene(); + //animationTimeline.seek(parseInt(progressBar.value, 10)); + //animationTimeline.pause(); + }; + + //buttons + let playButton = document.createElement('button'); + let pauseButton = document.createElement('button'); + let restartButton = document.createElement('button'); + playButton.onclick = animationTimeline.play; + pauseButton.onclick = animationTimeline.pause; + restartButton.onclick = animationTimeline.restart; + + playButton.innerText = 'play'; + pauseButton.innerText = 'pause'; + restartButton.innerText = 'restart'; + + playButton.setAttribute( + 'style', + 'background-color: transparent; border: 1px solid #61C3FF; display: inline-block; align-items: flex-start; padding: 5px 10px;text-transform: uppercase; color : #61C3FF;' + ); + pauseButton.setAttribute( + 'style', + 'background-color: transparent; border: 1px solid #61C3FF; margin: 0 0 0 -1px; display: inline-block; align-items: flex-start;padding: 5px 10px;text-transform: uppercase; color : #61C3FF;' + ); + restartButton.setAttribute( + 'style', + 'background-color: transparent; border: 1px solid #61C3FF; margin: 0 0 0 -1px; display: inline-block; align-items: flex-start;padding: 5px 10px;text-transform: uppercase; color : #61C3FF;' + ); + controlsDiv.append(playButton, pauseButton, restartButton); //IE and Edge previous versions may not support + animationTimeline.add({ + update: function (anim) { + progressBar.value = animationTimeline.progress.toString(); + // console.log( + // animationTimeline.duration * (progressBar.valueAsNumber / 100) + // ); + } + }); +} + +// export function playScene() { +// animationTimeline.play(); +// } + +// export function pauseScene() { +// animationTimeline.pause(); +// } + +// export function restartScene() { +// animationTimeline.restart(); +// } + +// + +// button.onclick = animationTimeline.pause; diff --git a/src/lib/Scene/group.ts b/src/lib/Scene/group.ts new file mode 100644 index 0000000..e087c13 --- /dev/null +++ b/src/lib/Scene/group.ts @@ -0,0 +1,67 @@ +import { sceneContainer } from './scene'; +import { Text } from '../MObject/Text'; +import { TeX } from '../MObject/TeX'; + +//TODO : add graphs to groups +//import { Graph2D } from '../Geometry/graph'; + +export class Group { + group; + + constructor(...args: any[]) { + //console.log(args[0]); + let p5Canvas = document + .getElementsByClassName('p5Canvas')[0] + .getBoundingClientRect(); + //console.log(p5Canvas); + //sceneContainer.setAttribute('overflow', 'hidden'); + + const groupDiv = (this.group = createElement('div')); + this.group.parent(sceneContainer); + let i = 0; + while (document.getElementById(`group${i}`)) { + i++; + } + this.group.id(`group${i}`); + groupDiv.elt.setAttribute( + 'style', + `overflow: hidden; position: absolute; left: ${p5Canvas.x}px; top: ${p5Canvas.y}px; width: ${p5Canvas.width}px; height : ${p5Canvas.height}px` + ); + + function parentDiv(element) { + console.log('element', element + 1); + console.log('gap'); + + if (element instanceof Text) { + console.log('text foreach'); + element.writeElement.parent(groupDiv); + } else if (element instanceof TeX) { + element.writeElement.parent(groupDiv); + } + + //TODO : add graphs to groups + // else if (element instanceof Graph2D) { + // element.graphContainer.parent(groupDiv); + // } + else { + console.log('foreach'); + } + } + + args[0].forEach(parentDiv); + } + scale(scaleFactor) { + this.group.style('transform', `scale(${scaleFactor})`); + } + remove() { + this.group.remove(); + + //document.body.removeChild(this.group.elt); + } + //console.log(args[0]); +} + +export function createGroup(...args) { + //TODO : convert into interface + return new Group(args); +} diff --git a/src/lib/Scene/play.ts b/src/lib/Scene/play.ts index 421e480..b1a5219 100644 --- a/src/lib/Scene/play.ts +++ b/src/lib/Scene/play.ts @@ -3,6 +3,7 @@ import { TeX } from '../MObject/TeX'; import anime from 'animejs'; import { add } from './add'; import * as CONFIG from '../config.js'; +import { animationTimeline } from './controls'; //TODO : fix relative time //TODO : text animation for all-at-once @@ -22,7 +23,7 @@ import * as CONFIG from '../config.js'; * @experimental */ -let animationTimeline = anime.timeline(); //initilising a timeline +//let animationTimeline = anime.timeline(); //initilising a timeline export function play( //any, //TODO: use '...args' @@ -31,7 +32,7 @@ export function play( startTime: number = 0, //seconds // start time endTime: number = 0 //seconds // end time ) { - if (!(typeof startTime == 'number' || typeof endTime == 'number')) { + if (!(typeof startTime === 'number' || typeof endTime === 'number')) { //size throw new Error('startTime and endTime must be passed as number'); } else if (endTime - startTime < 0) { @@ -48,16 +49,16 @@ export function play( //TODO : fix this after testing end and start parameters // if (typeof delayDuration === 'number') { // delayDuration = 1000 * delayDuration; //sec to ms - // //console.log(delayDuration); + // ////console.log(delayDuration); // } else if (typeof delayDuration === 'string') { // if (delayDuration.charAt(0) === '+') { // delayDuration = 1000 * Number(delayDuration); // delayDuration = `+=${delayDuration}`; - // console.log(delayDuration); + // //console.log(delayDuration); // } else if (delayDuration.charAt(0) === '-') { // delayDuration = 1000 * Number(delayDuration); // delayDuration = `-=${-delayDuration}`; - // console.log(delayDuration); + // //console.log(delayDuration); // } // } @@ -69,14 +70,14 @@ export function play( if (object instanceof TeX) { //adding element before animation - console.log('TeX'); - if (!object.writeElement) { + ////console.log('TeX'); + if (!object.writeElement.elt.children.length) { add(object); } //tex animations - console.log('TeX'); + ////console.log('TeX'); if (animationType === 'write') { - console.log('writing'); + //console.log('writing'); //write(object, timeDuration); // object.writeElement = createDiv(object.SVGEquation); @@ -100,64 +101,67 @@ export function play( // object.writeElement.position(object.x, object.y); allAtOnceAnimatorTeX(object, timeDuration, delayDuration); } else if (animationType === 'growFromCenter') { - console.log('growFromCenter'); + //console.log('growFromCenter'); growFromCenterAnimatorTeX(object, timeDuration, delayDuration); + } else if (animationType === 'createFill') { + //console.log('createFill'); + createFillAnimatorTeX(object, timeDuration, delayDuration); } else if (animationType === 'fadeIn') { - console.log('fadeIn called'); + //console.log('fadeIn called'); fadeInAnimatorTeX(object, timeDuration, delayDuration); } else if (animationType === 'appear') { - console.log('appear called'); + //console.log('appear called'); appearAnimatorTeX(object, timeDuration, delayDuration); } else if (animationType === 'dissolve') { - console.log('dissolve called'); + //console.log('dissolve called'); //add(object); dissolveAnimatorTeX(object, timeDuration, delayDuration); } else if (animationType === 'fadeOut') { - console.log('fadeout called'); + //console.log('fadeout called'); fadeOutAnimatorTeX(object, timeDuration, delayDuration); } else if (animationType === 'blink') { - console.log('blink'); + //console.log('blink'); blinkAnimatorTeX(object, timeDuration, delayDuration); } } //Text animation else if (object instanceof Text) { - if (!object.writeElement) { + if (!object.writeElement.elt.children.length) { add(object); } - console.log('Text'); + ////console.log('Text'); object.writeElement.style('opacity', '1'); //make it visible else it will not appear - if (animationType == 'write') { - console.log(object); + if (animationType === 'write') { + //console.log(object); writeAnimatorText(object, timeDuration, delayDuration); } else if (animationType === 'growFromCenter') { - console.log('growFromCenter'); + //console.log('growFromCenter'); growFromCenterAnimatorText(object, timeDuration, delayDuration); - } else if (animationType == 'allAtOnce') { - console.log('all at once'); - } else if (animationType == 'fadeIn') { - console.log('fadeIn'); + } else if (animationType === 'allAtOnce') { + //console.log('all at once'); + } else if (animationType === 'fadeIn') { + //console.log('fadeIn'); fadeInAnimatorText(object, timeDuration, delayDuration); - } else if (animationType == 'fadeOut') { - console.log('fadeOut'); + } else if (animationType === 'fadeOut') { + //console.log('fadeOut'); fadeOutAnimatorText(object, timeDuration, delayDuration); - } else if (animationType == 'erase') { - console.log('erase'); + } else if (animationType === 'erase') { + //console.log('erase'); eraseAnimatorText(object, timeDuration, delayDuration); - } else if (animationType == 'dissolve') { - console.log('dissolve'); + } else if (animationType === 'dissolve') { + //console.log('dissolve'); dissolveAnimatorText(object, timeDuration, delayDuration); - } else if (animationType == 'waveIn') { - console.log('waveIn'); + } else if (animationType === 'waveIn') { + //console.log('waveIn'); waveInAnimatorText(object, timeDuration, delayDuration); - } else if (animationType == 'waveOut') { - console.log('waveOut'); + } else if (animationType === 'waveOut') { + //console.log('waveOut'); waveOutAnimatorText(object, timeDuration, delayDuration); - } else if (animationType == 'spinOut') { - console.log('spinOut'); + } else if (animationType === 'spinOut') { + //console.log('spinOut'); spinOutAnimatorText(object, timeDuration, delayDuration); } } @@ -168,7 +172,7 @@ function writeAnimatorText( timeDuration: number, delayDuration: number | string ) { - // console.log(object); + // //console.log(object); //object = object; // timeDuration = timeDuration; //seconds // delayDuration = delayDuration; //seconds @@ -193,7 +197,7 @@ function growFromCenterAnimatorText( timeDuration: number, delayDuration: number | string ) { - // console.log(object); + // //console.log(object); //object = object; // timeDuration = timeDuration; //seconds // delayDuration = delayDuration; //seconds @@ -443,7 +447,80 @@ function growFromCenterAnimatorTeX( delayDuration ); } +function createFillAnimatorTeX( + object: TeX, + timeDuration: number, + delayDuration: string | number +) { + const g = object.writeElement.elt.querySelectorAll('g'); + const use = object.writeElement.elt.querySelectorAll('use'); + let p: any[] = []; + use.forEach( + ( + element: { getAttribute: (arg0: string) => any }, + index: string | number + ) => { + p[index] = object.writeElement.elt.querySelectorAll( + element.getAttribute('xlink:href') + ); + } + ); + //console.log(p); + animationTimeline + .add( + { + targets: [ + object.writeElement.elt.querySelectorAll('path'), + object.writeElement.elt.querySelectorAll('rect') + ], + //scale: [4, 1], + //fill: [`${object.fillColor.toString('#rgb')}0` , object.fillColor.toString()], //TODO : fill is black by default can be customised through set fill methods + //stroke : "black", //TODO : customisable through config + //stroke-width: "10px", //customisable through config + strokeDashoffset: [anime.setDashoffset, 0], + //opacity: [0, 0.2, 1], + // begin: function (anim) { + // g[0].setAttribute('fill', 'none'); + // g[0].setAttribute('stroke-width', '10px'); + // }, + // complete: function (anim) { + // //g[0].setAttribute('fill', object.fillColor.toString()); + // }, + easing: 'easeOutSine', + duration: timeDuration + //delay: anime.stagger(timeDuration / (object.sentence.length + 1)) + //delay: anime.stagger(10) + }, + delayDuration + ) + .add( + { + targets: [use, g], + //scale: [4, 1], + fill: [ + `${object.fillColor.toString('#rgb')}0`, + object.fillColor.toString() + ], //TODO : fill is black by default can be customised through set fill methods + //stroke : "black", //TODO : customisable through config + //stroke-width: "10px", //customisable through config + //strokeDashoffset: [anime.setDashoffset, 0], + //opacity: [0, 0.2, 1], + begin: function (anim) { + //g[0].setAttribute('fill', 'none'); + //g[0].setAttribute('stroke-width', '10px'); + }, + complete: function (anim) { + //g[0].setAttribute('fill', object.fillColor.toString()); + }, + easing: 'easeInOutQuad', + duration: timeDuration + //delay: anime.stagger(timeDuration / (object.sentence.length + 1)) + //delay: anime.stagger(400) + }, + delayDuration + ); +} //TODO : fix timeline function allAtOnceAnimatorTeX( object: TeX, @@ -453,9 +530,8 @@ function allAtOnceAnimatorTeX( const g = object.writeElement.elt.querySelectorAll('g'); const pathEls = object.writeElement.elt.querySelectorAll('path'); //nodelist - for (var i = 0; i < pathEls.length; i++) { - var pathEl = pathEls[i]; - var offset: any = anime.setDashoffset(pathEl); + for (let pathEl of pathEls) { + let offset: any = anime.setDashoffset(pathEl); pathEl.setAttribute('stroke-dashoffset', offset); anime({ targets: pathEl, diff --git a/src/lib/Scene/scene.ts b/src/lib/Scene/scene.ts index 9f562c6..3885dcb 100644 --- a/src/lib/Scene/scene.ts +++ b/src/lib/Scene/scene.ts @@ -1,6 +1,74 @@ +import p5 from "p5"; + +export let sceneContainer: HTMLDivElement; +interface ISceneVariables { + isGraph: any, + graph : any, + currentSVG: SVGSVGElement, + currStrokeColor: p5.Color | string, + currStrokeWidth: string, + currFillColor: p5.Color | string, + currAngle: number, + selectedPoint: any, + currentPolygon +}; +export let sceneVariables : ISceneVariables = { + isGraph: 'false', + graph : 'false', + currentSVG: document.createElementNS('http://www.w3.org/2000/svg', 'svg'), + currStrokeColor: 'black', + currStrokeWidth: '1', + currFillColor: 'none', + currAngle: 0, + selectedPoint : document.createElementNS('http://www.w3.org/2000/svg', 'circle'), + currentPolygon : 'false' +}; +//export + export class Scene { - constructor() {} + constructor() { + //console.log(p5Canvas); + sceneContainer = document.createElement('div'); + //sceneContainer.setAttribute('overflow', 'hidden'); + sceneContainer.setAttribute('class', 'p5teach'); + // sceneContainer.style.overflow = value; + sceneContainer.style.left = 0 + 'px'; + sceneContainer.style.top = 0 + 'px'; + sceneContainer.style.position = 'absolute'; + sceneContainer.style.fill = 'none'; + // sceneContainer.style.width = 0 + 'px'; + // sceneContainer.style.height = 0 + 'px'; + // sceneContainer.setAttribute( + // 'style', + // `position: absolute; left: 0 px; top: 0 px; ` + // ); + // sceneContainer.setAttribute('height', `${p5Canvas.height}px`); + // sceneContainer.setAttribute('left', `${p5Canvas.x}px`); + // sceneContainer.setAttribute('top', `${p5Canvas.y}px`); + document.body.appendChild(sceneContainer); + } + + remove() { + document.body.removeChild(sceneContainer); + } //TODO : remove scene + async delay(sec: number) { return new Promise((resolve) => setTimeout(resolve, 1000 * sec)); //sec to ms } } + +export function overflow(value) { + if (value === 'visible') { + sceneContainer.style.overflow = value; + } else if (value === 'hidden') { + let p5Canvas = document + .getElementsByClassName('p5Canvas')[0] + .getBoundingClientRect(); + + sceneContainer.style.overflow = value; + sceneContainer.style.left = p5Canvas.x + 'px'; + sceneContainer.style.top = p5Canvas.y + 'px'; + sceneContainer.style.width = p5Canvas.width + 'px'; + sceneContainer.style.height = p5Canvas.height + 'px'; + } +} diff --git a/src/lib/Scene/transform.ts b/src/lib/Scene/transform.ts new file mode 100644 index 0000000..082e2c9 --- /dev/null +++ b/src/lib/Scene/transform.ts @@ -0,0 +1,133 @@ +//TODO : transform function : use morphing + +//import anime from 'animejs'; +import * as config from '../config.js'; +import { createSVGPath } from '../Geometry/graph'; +import { createParametricSVGPath } from '../Geometry/parametric'; +import { createPolarSVGPath } from '../Geometry/polar'; +import { animationTimeline } from './controls'; + +export function transform( + objectInit: any, + objectFinl: any, + startTime: number = 0, + endTime = 2 +) { + //console.log(config.hello[0]); + const timeDuration = (endTime - startTime) * 1000; + const delayDuration = startTime * 1000; + + if (objectInit.writeTexElement && objectFinl.writeTexElement) { + //TeX transformation + } else if (objectInit.writeTextElement && objectFinl.writeTextElement) { + } else if (objectInit.graphObject && objectFinl.graphContainer) { + if (objectFinl.thetaRange) { + //console.log('polar'); + + let svgPath = createPolarSVGPath( + objectFinl.eqn, + objectFinl.thetaRange, + objectFinl.config + ); + + animationTimeline.add( + { + targets: objectInit.graphContainer.elt.querySelectorAll('path'), + d: [ + //{value: shapes[0].d}, + { value: `${svgPath}` } + ], + + duration: timeDuration, + //direction: 'alternate', + autoplay: true, + easing: 'easeInOutCubic' + //elasticity: 1 + //loop: true + }, + delayDuration + ); + } else if (objectFinl.parameterRange) { + //console.log('parametric'); + + let svgPath = createParametricSVGPath( + objectFinl.xeqn, + objectFinl.yeqn, + objectFinl.parameterRange, + objectFinl.config + ); + //console.log(objectFinl.config); + + // objectInit.configure(objectInit.config); + + // // console.log(objectInit); + // objectInit.axis(); + const plot = objectInit.graphContainer.elt.querySelectorAll(`#plot`); + + //console.log(tar); + + animationTimeline + .add( + { + targets: plot[0].querySelectorAll('path'), + d: [ + //{value: shapes[0].d}, + { value: `${svgPath}` } + ], + complete: function (anime) { + objectInit.configure(objectFinl.config); + objectInit.axis(); + }, + duration: timeDuration, + //direction: 'alternate', + autoplay: true, + easing: 'easeInOutCubic' + //elasticity: 1 + //loop: true + }, + delayDuration + ) + .add( + { + targets: plot[0].querySelectorAll('path'), + d: [ + //{value: shapes[0].d}, + { value: `${svgPath}` } + ], + // begin: function (anime) { + // // objectInit.configure(objectFinl.config); + // // objectInit.axis(); + // }, + duration: timeDuration, + //direction: 'alternate', + autoplay: true, + easing: 'easeInOutCubic' + //elasticity: 1 + //loop: true + }, + delayDuration + ); + } else if (!objectFinl.thetaRange && !objectFinl.parameterRange) { + //console.log('non-polar'); + + animationTimeline.add( + { + targets: objectInit.graphContainer.elt.querySelectorAll('path'), + d: [ + //{value: shapes[0].d}, + { value: `${createSVGPath(objectFinl.eqn, objectFinl.config)}` } + ], + duration: timeDuration, + //direction: 'alternate', + autoplay: true, + easing: 'easeInOutCubic' + //elasticity: 1 + //loop: true + }, + delayDuration + ); + } + //console.log('inside transform'); + //console.log(`${objectFinl.eqn}`); + } +} diff --git a/src/test/Geometry/graph.test.ts b/src/test/Geometry/graph.test.ts new file mode 100644 index 0000000..69167e8 --- /dev/null +++ b/src/test/Geometry/graph.test.ts @@ -0,0 +1,47 @@ +/** + * @jest-environment jsdom + */ + +// // const p5Mock = p5 as jest.MockedClass; + +//import p5 from 'p5'; + +import p5 from 'p5'; +import { create2DGraph, Graph2D } from '../../lib/Geometry/graph'; + +// const graph = require('../../lib/Geometry/graph'); +global.createElement = jest.fn(); +global.abs = jest.fn((...args) => { + return Math.abs(...args); +}); + +it.skip('create2DGraph should return a object of class GObject', () => { + // console.log( + // create2DGraph( + // (t) => + // Math.cos(t) - + // Math.pow(t, 2) / 6 + + // Math.pow(t, 4) / 24 + + // Math.pow(t, 6) / 720 + // ) + // ); + expect( + create2DGraph( + (t) => + Math.cos(t) - + Math.pow(t, 2) / 6 + + Math.pow(t, 4) / 24 + + Math.pow(t, 6) / 720 + ) + ).toEqual({ + _size: 28, + x: 10, + y: 10, + sentence: '2^2', + svgEquation: + '', + fillColor: { model: 'rgb', color: [0, 0, 0], valpha: 1 }, + _strokeWidth: 8, + strokeColor: { model: 'rgb', color: [0, 0, 0], valpha: 1 } + }); +}); diff --git a/src/test/Geometry/transform.ts b/src/test/Geometry/transform.ts new file mode 100644 index 0000000..ca3fddc --- /dev/null +++ b/src/test/Geometry/transform.ts @@ -0,0 +1,5 @@ +/** + * @jest-environment jsdom + */ + +it.todo('transform the graph from 2D to 2D'); diff --git a/src/test/MObject/__mocks__/p5.ts b/src/test/MObject/__mocks__/p5.ts new file mode 100644 index 0000000..4c35bf8 --- /dev/null +++ b/src/test/MObject/__mocks__/p5.ts @@ -0,0 +1,11 @@ +// import p5 from 'p5'; +// import module = jest.requireActual('p5'); +// import * as p5Global from 'p5/global' + +// export = module; +// export as namespace p5; +// declare global { +// interface Window { +// p5: typeof module, +// } +// } diff --git a/src/test/MObject/tex.test.ts b/src/test/MObject/tex.test.ts index f828f3b..43c8192 100644 --- a/src/test/MObject/tex.test.ts +++ b/src/test/MObject/tex.test.ts @@ -2,12 +2,32 @@ * @jest-environment jsdom */ -import { createTeX } from '../../lib/MObject/TeX'; +import { createTeX, TeX } from '../../lib/MObject/TeX'; +//import * as tex from '../../lib/MObject/TeX'; +const tex = require('../../lib/MObject/TeX'); global.color = require('color'); +global.createElement = jest.fn(); + +// let createTeXMock = jest +// .spyOn(tex, 'createTeX') +// .mockImplementation((...args) => 0); it('createTeX should return a object of class TeX', () => { // console.log(createTeX('2^2')); + // tex.createTeX = jest.fn(() => { + // return { + // _size: 28, + // x: 10, + // y: 10, + // sentence: '2^2', + // svgEquation: + // '', + // fillColor: { model: 'rgb', color: [0, 0, 0], valpha: 1 }, + // _strokeWidth: 8, + // strokeColor: { model: 'rgb', color: [0, 0, 0], valpha: 1 } + // }; + // }); expect(createTeX('2^2')).toEqual({ _size: 28, x: 10, @@ -19,6 +39,18 @@ it('createTeX should return a object of class TeX', () => { _strokeWidth: 8, strokeColor: { model: 'rgb', color: [0, 0, 0], valpha: 1 } }); + + // expect(createTeX('2^2')).toEqual({ + // _size: 28, + // x: 10, + // y: 10, + // sentence: '2^2', + // svgEquation: + // '', + // fillColor: { model: 'rgb', color: [0, 0, 0], valpha: 1 }, + // _strokeWidth: 8, + // strokeColor: { model: 'rgb', color: [0, 0, 0], valpha: 1 } + // }); }); it('fill without argument should return object of type p5.Color', () => { diff --git a/src/test/MObject/text.test.ts b/src/test/MObject/text.test.ts index 55084d2..8251b66 100644 --- a/src/test/MObject/text.test.ts +++ b/src/test/MObject/text.test.ts @@ -3,6 +3,7 @@ */ import { createText } from '../../lib/MObject/Text'; global.color = require('color'); +global.createElement = jest.fn(); it('createText should return a object of class Text', () => { expect(createText('text')).toEqual({ diff --git a/src/test/Scene/add.test.ts b/src/test/Scene/add.test.ts index 99170a6..6210c91 100644 --- a/src/test/Scene/add.test.ts +++ b/src/test/Scene/add.test.ts @@ -7,6 +7,7 @@ import * as Add from '../../lib/Scene/add'; import { createText, Text } from '../../lib/MObject/Text'; import { add } from '../../lib/Scene/add'; global.color = require('color'); +global.createElement = jest.fn(); it('check if add is called with an object of type Text', () => { jest.spyOn(Add, 'add').mockImplementation(() => {}); diff --git a/src/test/Scene/play.test.ts b/src/test/Scene/play.test.ts index 994254f..4fa597b 100644 --- a/src/test/Scene/play.test.ts +++ b/src/test/Scene/play.test.ts @@ -7,6 +7,7 @@ import * as Play from '../../lib/Scene/play'; import { createText, Text } from '../../lib/MObject/Text'; import { play } from '../../lib/Scene/play'; global.color = require('color'); +global.createElement = jest.fn(); it('check if play is called with an object of type Text', () => { jest.spyOn(Play, 'play').mockImplementation(() => {}); diff --git a/yarn.lock b/yarn.lock index 0ce035c..523fe20 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2212,6 +2212,11 @@ command-exists@^1.2.6: resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== +commander@>=7.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.1.0.tgz#db36e3e66edf24ff591d639862c6ab2c52664362" + integrity sha512-mf45ldcuHSYShkplHHGKWb4TrmwQadxOn7v4WuhDJy0ZVoY5JFajaRDKD0PNe5qXzBX0rhovjTnP6Kz9LETcuA== + commander@^2.11.0, commander@^2.19.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -2936,6 +2941,11 @@ escodegen@~1.9.0: optionalDependencies: source-map "~0.6.1" +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + esprima@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -3309,7 +3319,7 @@ glob@^7.0.0, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.1, glob@^7.1.2: +glob@^7.1.1, glob@^7.1.2, glob@^7.1.7: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -3344,6 +3354,18 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= +handlebars@^4.7.7: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -4454,7 +4476,7 @@ json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@2.x, json5@^2.1.2: +json5@2.x, json5@^2.1.2, json5@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== @@ -4569,6 +4591,13 @@ log-symbols@^2.2.0: dependencies: chalk "^2.0.1" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -4576,6 +4605,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lunr@^2.3.9: + version "2.3.9" + resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" + integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== + magic-string@^0.22.4: version "0.22.5" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e" @@ -4614,6 +4648,21 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +marked@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.3.tgz#bd017cef6431724fd4b27e0657f5ceb14bff3753" + integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA== + +mathjax-full@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mathjax-full/-/mathjax-full-3.2.0.tgz#e53269842a943d4df10502937518991268996c5c" + integrity sha512-D2EBNvUG+mJyhn+M1C858k0f2Fc4KxXvbEX2WCMXroV10212JwfYqaBJ336ECBSz5X9L5LRoamxb7AJtg3KaJA== + dependencies: + esm "^3.2.25" + mhchemparser "^4.1.0" + mj-context-menu "^0.6.1" + speech-rule-engine "^3.3.3" + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -4650,6 +4699,11 @@ merge2@^1.2.3: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +mhchemparser@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/mhchemparser/-/mhchemparser-4.1.1.tgz#a2142fdab37a02ec8d1b48a445059287790becd5" + integrity sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA== + micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -4722,7 +4776,7 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@^3.0.4: +minimatch@^3.0.0, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -4742,6 +4796,11 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mj-context-menu@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/mj-context-menu/-/mj-context-menu-0.6.1.tgz#a043c5282bf7e1cf3821de07b13525ca6f85aa69" + integrity sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA== + mkdirp@1.x: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -4796,6 +4855,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +neo-async@^2.6.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -5025,6 +5089,13 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" +onigasm@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/onigasm/-/onigasm-2.2.5.tgz#cc4d2a79a0fa0b64caec1f4c7ea367585a676892" + integrity sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA== + dependencies: + lru-cache "^5.1.1" + opn@^5.1.0: version "5.5.0" resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" @@ -5721,6 +5792,11 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +progress@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + prompts@^2.0.1: version "2.4.1" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61" @@ -6275,6 +6351,15 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== +shiki@^0.9.3: + version "0.9.6" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.9.6.tgz#057d6d451b9c1124107635fdcb5c752560d6abc6" + integrity sha512-h2y5Uq9QEWsEmi97n+BOdPOVxkOUdVunl+jVIzU9EqJ6/QbIX+U6F7TsrWZQ2xqwPgvvQaC9r7/zeegi1b48dQ== + dependencies: + json5 "^2.2.0" + onigasm "^2.2.5" + vscode-textmate "5.2.0" + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -6392,6 +6477,15 @@ spdx-license-ids@^3.0.0: resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.8.tgz#eb1e97ad99b11bf3f82a3b71a0472dd9a00f2ecf" integrity sha512-NDgA96EnaLSvtbM7trJj+t1LUR3pirkDCcz9nOUlPb5DMBGsH7oES6C3hs3j7R9oHEa1EMvReS/BUAIT5Tcr0g== +speech-rule-engine@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/speech-rule-engine/-/speech-rule-engine-3.3.3.tgz#781ed03cbcf3279f94d1d80241025ea954c6d571" + integrity sha512-0exWw+0XauLjat+f/aFeo5T8SiDsO1JtwpY3qgJE4cWt+yL/Stl0WP4VNDWdh7lzGkubUD9lWP4J1ASnORXfyQ== + dependencies: + commander ">=7.0.0" + wicked-good-xpath "^1.3.0" + xmldom-sre "^0.1.31" + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -6692,6 +6786,13 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +tex-to-svg@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/tex-to-svg/-/tex-to-svg-0.2.0.tgz#614bcb56d431bf3487d04685e102aaf81ee0f30b" + integrity sha512-YkP5V4O3u+i2odO5ETEISjVTemfzrx+YeG/XHXRoq3sfL0p8q4zDdlP/h+mna/4tEu6EylJOKzJws3iOnzU/rA== + dependencies: + mathjax-full "^3.1.0" + throat@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" @@ -6882,11 +6983,35 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typedoc-default-themes@^0.12.10: + version "0.12.10" + resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz#614c4222fe642657f37693ea62cad4dafeddf843" + integrity sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA== + +typedoc@^0.21.5: + version "0.21.5" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.21.5.tgz#45643618ede5c3d75e2040b964d05fcffed7ca58" + integrity sha512-uRDRmYheE5Iju9Zz0X50pTASTpBorIHFt02F5Y8Dt4eBt55h3mwk1CBSY2+EfwBxY16N4Xm7f8KXhnfFZ0AmBw== + dependencies: + glob "^7.1.7" + handlebars "^4.7.7" + lunr "^2.3.9" + marked "^2.1.1" + minimatch "^3.0.0" + progress "^2.0.3" + shiki "^0.9.3" + typedoc-default-themes "^0.12.10" + typescript@^4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== +uglify-js@^3.1.4: + version "3.14.1" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.1.tgz#e2cb9fe34db9cb4cf7e35d1d26dfea28e09a7d06" + integrity sha512-JhS3hmcVaXlp/xSo3PKY5R0JqKs5M3IV+exdLHW99qKvKivPO4Z8qbej6mte17SOPqAOVMjt/XGgWacnFSzM3g== + uncss@^0.17.3: version "0.17.3" resolved "https://registry.yarnpkg.com/uncss/-/uncss-0.17.3.tgz#50fc1eb4ed573ffff763458d801cd86e4d69ea11" @@ -7086,6 +7211,11 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== +vscode-textmate@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" + integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== + w3c-hr-time@^1.0.1, w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" @@ -7187,11 +7317,21 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" +wicked-good-xpath@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz#81b0e95e8650e49c94b22298fff8686b5553cf6c" + integrity sha1-gbDpXoZQ5JyUsiKY//hoa1VTz2w= + word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -7245,6 +7385,11 @@ xmlchars@^2.1.1, xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== +xmldom-sre@^0.1.31: + version "0.1.31" + resolved "https://registry.yarnpkg.com/xmldom-sre/-/xmldom-sre-0.1.31.tgz#10860d5bab2c603144597d04bf2c4980e98067f4" + integrity sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw== + xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -7255,6 +7400,11 @@ y18n@^4.0.0: resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"