├── .eslintrc
├── .github
└── workflows
│ └── publish.yml
├── .gitignore
├── .prettierrc
├── LICENSE
├── README.md
├── dist
├── siriwave.esm.js
├── siriwave.esm.min.js
├── siriwave.umd.js
├── siriwave.umd.min.js
└── types
│ ├── classic-curve.d.ts
│ ├── index.d.ts
│ └── ios9-curve.d.ts
├── etc
├── classic.gif
├── dat.gui.js
├── gcx
│ ├── default.gcx
│ └── ios9.gcx
└── ios9.gif
├── index.html
├── package-lock.json
├── package.json
├── rollup.config.js
├── src
├── classic-curve.ts
├── index.ts
└── ios9-curve.ts
└── tsconfig.json
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "@typescript-eslint/parser",
3 | "extends": [
4 | "plugin:@typescript-eslint/recommended", // Uses the recommended rules from the @typescript-eslint/eslint-plugin
5 | "prettier/@typescript-eslint", // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
6 | "plugin:prettier/recommended" // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.],
7 | ],
8 | "parserOptions": {
9 | "ecmaVersion": 2018,
10 | "sourceType": "module"
11 | },
12 | "plugins": ["prettier"],
13 | "env": {
14 | "browser": true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3 |
4 | name: Node.js Package
5 |
6 | on:
7 | release:
8 | types: [created]
9 |
10 | jobs:
11 | publish-npm:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v2
15 | - uses: actions/setup-node@v1
16 | with:
17 | node-version: 18
18 | registry-url: https://registry.npmjs.org/
19 | - run: npm install
20 | - run: npm run build
21 | - run: npm publish
22 | env:
23 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
24 |
25 | publish-gpr:
26 | runs-on: ubuntu-latest
27 | steps:
28 | - uses: actions/checkout@v2
29 | - uses: actions/setup-node@v1
30 | with:
31 | node-version: 18
32 | registry-url: https://npm.pkg.github.com/
33 | - run: npm install
34 | - run: npm run build
35 | - run: npm publish
36 | env:
37 | NODE_AUTH_TOKEN: ${{secrets.GH_PKG_TOKEN}}
38 |
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | yarn-error.log
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "trailingComma": "all",
4 | "singleQuote": false,
5 | "printWidth": 120,
6 | "tabWidth": 2
7 | }
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Flavio Maria De Stefano
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SiriWave
2 |
3 | The "Apple Siri" wave replicated in pure Javascript using the Canvas API. To learn more about the project, [read the blog post here](https://dev.to/kopiro/how-i-built-the-siriwavejs-library-a-look-at-the-math-and-the-code-l0o), [check the demo](http://kopiro.github.io/siriwave) or [codepen](https://codepen.io/kopiro/pen/oNYepEb).
4 |
5 | [](https://badge.fury.io/js/siriwave)
6 |
7 | ### iOS (classic) style
8 |
9 | The classic, pre-iOS9 style.
10 |
11 |
12 |
13 | ### iOS9 style
14 |
15 | The new fluorescent wave introduced in iOS9.
16 |
17 |
18 |
19 | ### iOS13 style
20 |
21 | _work in progress_
22 |
23 | The wave reinvented as a bubble.
24 |
25 | ## Usage
26 |
27 | ### Browser (via CDN) usage
28 |
29 | Import the UMD package via the unpkg CDN and it's ready to use.
30 |
31 | ```html
32 |
33 | ```
34 |
35 | ### ES module
36 |
37 | Install it through `npm install siriwave` or `npm add siriwave` first:
38 |
39 | ```js
40 | import SiriWave from "siriwave";
41 | ```
42 |
43 | ## Initialize
44 |
45 | Create a div container and instantiate a new SiriWave object:
46 |
47 | ```html
48 |
49 |
56 | ```
57 |
58 | ## Constructor options
59 |
60 | | Key | Type | Description | Default | Required |
61 | | -------------------------- | ------------------------ | ---------------------------------------------------------------------- | ---------- | -------- |
62 | | `container` | DOMElement | The DOM container where the DOM canvas element will be added. | null | yes |
63 | | `style` | "ios", "ios9" | The style of the wave. | "ios" | no |
64 | | `ratio` | Number | Ratio of the display to use. Calculated by default. | calculated | no |
65 | | `speed` | Number | The speed of the animation. | 0.2 | no |
66 | | `amplitude` | Number | The amplitude of the complete wave-form. | 1 | no |
67 | | `frequency` | Number | The frequency of the complete wave-form. Only available in style "ios" | 6 | no |
68 | | `color` | String | Color of the wave. Only available in style "ios" | "#fff" | no |
69 | | `cover` | Bool | The `canvas` covers the entire width or height of the container | false | no |
70 | | `autostart` | Bool | Decide wether start the animation on boot. | false | no |
71 | | `pixelDepth` | Number | Number of step (in pixels) used when drawed on canvas. | 0.02 | no |
72 | | `lerpSpeed` | Number | Lerp speed to interpolate properties. | 0.01 | no |
73 | | `curveDefinition` | ICurveDefinition[] | Override definition of the curves, check above for more details. | null | no |
74 | | `ranges` | IiOS9Ranges | Override the default random ranges of the curves. | null | no |
75 | | `globalCompositeOperation` | GlobalCompositeOperation | globalCompositeOperation of the canvas, controls wave overlap design. | "lighter" | no |
76 |
77 | ### Ranges
78 |
79 | Each wave chooses a random parameter for each of these ranges that factors into their creation. You can override these ranges by passing a `ranges` object to the constructor.
80 |
81 | Here is the type of the ranges object:
82 |
83 | ```ts
84 | export type IiOS9Ranges = {
85 | noOfCurves?: [number, number];
86 | amplitude?: [number, number];
87 | offset?: [number, number];
88 | width?: [number, number];
89 | speed?: [number, number];
90 | despawnTimeout?: [number, number];
91 | };
92 | ```
93 |
94 | ## API
95 |
96 | #### `new SiriWave`
97 |
98 | #### `curveDefinition`
99 |
100 | By passing this argument, you're overriding the default curve definition resulting in a completely different style.
101 |
102 | The default definition for the `ios` classic style is:
103 |
104 | ```js
105 | [
106 | { attenuation: -2, lineWidth: 1, opacity: 0.1 },
107 | { attenuation: -6, lineWidth: 1, opacity: 0.2 },
108 | { attenuation: 4, lineWidth: 1, opacity: 0.4 },
109 | { attenuation: 2, lineWidth: 1, opacity: 0.6 },
110 | { attenuation: 1, lineWidth: 1.5, opacity: 1 },
111 | ];
112 | ```
113 |
114 | and it results in 5 different sin-waves with different parameters and amplitude.
115 |
116 | You can set 4 attributes for each curve:
117 |
118 | - `attenuation`: the power factor determining the attenuation
119 | - `lineWidth`: the line width
120 | - `opacity`: the opacity
121 | - `color`: the color, default to `SiriWave.color`; optional
122 |
123 | The `ios9` style definition is instead:
124 |
125 | ```js
126 | [
127 | { color: "255,255,255", supportLine: true },
128 | { color: "15, 82, 169" }, // blue
129 | { color: "173, 57, 76" }, // red
130 | { color: "48, 220, 155" }, // green
131 | ];
132 | ```
133 |
134 | and it results in 3 different colored waves + 1 support wave that needs to be there.
135 |
136 | Here you set:
137 |
138 | - `supportLine`: only one of these curves must have this to `true`, it will be used to draw the support line
139 | - `color`: the color of the wave
140 |
141 | #### `start()`
142 |
143 | Start the animation
144 |
145 | #### `stop()`
146 |
147 | Stop the animation.
148 |
149 | #### `setSpeed(newValue)`
150 |
151 | Set the new value of speed (animated)
152 |
153 | #### `setAmplitude(value)`
154 |
155 | Set the new value of amplitude (animated)
156 |
157 | #### `dispose()`
158 |
159 | Stop the animation and destroy the canvas, by removing it from the DOM.
160 | Subsequent `start()` calls on this SiriWave instance will fail with an exception.
161 |
162 | ## Grapher plots
163 |
164 | - [GCX default](etc/gcx/default.gcx)
165 | - [GCX iOS 9](etc/gcx/ios9.gcx)
166 |
167 | ## Build and development
168 |
169 | If you wanna make some modifications in your local environment, use:
170 |
171 | ```sh
172 | npm dev
173 | ```
174 |
175 | this will create a watchable build with RollupJS and automatically create a server to see your changes in the browser.
176 |
177 | To finally build all targets:
178 |
179 | ```sh
180 | npm build
181 | ```
182 |
183 | ## QA
184 |
185 | #### How do I integrate this library with a microphone user input?
186 |
187 | You can find an excellent demo [here](https://jsitor.com/PPQtOp9Yp) by @semmel
188 |
--------------------------------------------------------------------------------
/dist/siriwave.esm.js:
--------------------------------------------------------------------------------
1 | /*! *****************************************************************************
2 | Copyright (c) Microsoft Corporation.
3 |
4 | Permission to use, copy, modify, and/or distribute this software for any
5 | purpose with or without fee is hereby granted.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 | PERFORMANCE OF THIS SOFTWARE.
14 | ***************************************************************************** */
15 |
16 | function __rest(s, e) {
17 | var t = {};
18 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
19 | t[p] = s[p];
20 | if (s != null && typeof Object.getOwnPropertySymbols === "function")
21 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
22 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
23 | t[p[i]] = s[p[i]];
24 | }
25 | return t;
26 | }
27 |
28 | class ClassicCurve {
29 | constructor(ctrl, definition) {
30 | this.ATT_FACTOR = 4;
31 | this.GRAPH_X = 2;
32 | this.AMPLITUDE_FACTOR = 0.6;
33 | this.ctrl = ctrl;
34 | this.definition = definition;
35 | }
36 | globalAttFn(x) {
37 | return Math.pow(this.ATT_FACTOR / (this.ATT_FACTOR + Math.pow(x, this.ATT_FACTOR)), this.ATT_FACTOR);
38 | }
39 | xPos(i) {
40 | return this.ctrl.width * ((i + this.GRAPH_X) / (this.GRAPH_X * 2));
41 | }
42 | yPos(i) {
43 | return (this.AMPLITUDE_FACTOR *
44 | (this.globalAttFn(i) *
45 | (this.ctrl.heightMax * this.ctrl.amplitude) *
46 | (1 / this.definition.attenuation) *
47 | Math.sin(this.ctrl.opt.frequency * i - this.ctrl.phase)));
48 | }
49 | draw() {
50 | const { ctx } = this.ctrl;
51 | ctx.moveTo(0, 0);
52 | ctx.beginPath();
53 | const finalColor = this.definition.color || this.ctrl.color;
54 | const colorHex = finalColor.replace(/rgb\(/g, "").replace(/\)/g, "");
55 | ctx.strokeStyle = `rgba(${colorHex},${this.definition.opacity})`;
56 | ctx.lineWidth = this.definition.lineWidth;
57 | // Cycle the graph from -X to +X every PX_DEPTH and draw the line
58 | for (let i = -this.GRAPH_X; i <= this.GRAPH_X; i += this.ctrl.opt.pixelDepth) {
59 | ctx.lineTo(this.xPos(i), this.ctrl.heightMax + this.yPos(i));
60 | }
61 | ctx.stroke();
62 | }
63 | static getDefinition() {
64 | return [
65 | {
66 | attenuation: -2,
67 | lineWidth: 1,
68 | opacity: 0.1,
69 | },
70 | {
71 | attenuation: -6,
72 | lineWidth: 1,
73 | opacity: 0.2,
74 | },
75 | {
76 | attenuation: 4,
77 | lineWidth: 1,
78 | opacity: 0.4,
79 | },
80 | {
81 | attenuation: 2,
82 | lineWidth: 1,
83 | opacity: 0.6,
84 | },
85 | {
86 | attenuation: 1,
87 | lineWidth: 1.5,
88 | opacity: 1,
89 | },
90 | ];
91 | }
92 | }
93 |
94 | class iOS9Curve {
95 | constructor(ctrl, definition) {
96 | this.GRAPH_X = 25;
97 | this.AMPLITUDE_FACTOR = 0.8;
98 | this.SPEED_FACTOR = 1;
99 | this.DEAD_PX = 2;
100 | this.ATT_FACTOR = 4;
101 | this.DESPAWN_FACTOR = 0.02;
102 | this.DEFAULT_NOOFCURVES_RANGES = [2, 5];
103 | this.DEFAULT_AMPLITUDE_RANGES = [0.3, 1];
104 | this.DEFAULT_OFFSET_RANGES = [-3, 3];
105 | this.DEFAULT_WIDTH_RANGES = [1, 3];
106 | this.DEFAULT_SPEED_RANGES = [0.5, 1];
107 | this.DEFAULT_DESPAWN_TIMEOUT_RANGES = [500, 2000];
108 | this.ctrl = ctrl;
109 | this.definition = definition;
110 | this.noOfCurves = 0;
111 | this.spawnAt = 0;
112 | this.prevMaxY = 0;
113 | this.phases = [];
114 | this.offsets = [];
115 | this.speeds = [];
116 | this.finalAmplitudes = [];
117 | this.widths = [];
118 | this.amplitudes = [];
119 | this.despawnTimeouts = [];
120 | this.verses = [];
121 | }
122 | getRandomRange(e) {
123 | return e[0] + Math.random() * (e[1] - e[0]);
124 | }
125 | spawnSingle(ci) {
126 | var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
127 | this.phases[ci] = 0;
128 | this.amplitudes[ci] = 0;
129 | this.despawnTimeouts[ci] = this.getRandomRange((_b = (_a = this.ctrl.opt.ranges) === null || _a === void 0 ? void 0 : _a.despawnTimeout) !== null && _b !== void 0 ? _b : this.DEFAULT_DESPAWN_TIMEOUT_RANGES);
130 | this.offsets[ci] = this.getRandomRange((_d = (_c = this.ctrl.opt.ranges) === null || _c === void 0 ? void 0 : _c.offset) !== null && _d !== void 0 ? _d : this.DEFAULT_OFFSET_RANGES);
131 | this.speeds[ci] = this.getRandomRange((_f = (_e = this.ctrl.opt.ranges) === null || _e === void 0 ? void 0 : _e.speed) !== null && _f !== void 0 ? _f : this.DEFAULT_SPEED_RANGES);
132 | this.finalAmplitudes[ci] = this.getRandomRange((_h = (_g = this.ctrl.opt.ranges) === null || _g === void 0 ? void 0 : _g.amplitude) !== null && _h !== void 0 ? _h : this.DEFAULT_AMPLITUDE_RANGES);
133 | this.widths[ci] = this.getRandomRange((_k = (_j = this.ctrl.opt.ranges) === null || _j === void 0 ? void 0 : _j.width) !== null && _k !== void 0 ? _k : this.DEFAULT_WIDTH_RANGES);
134 | this.verses[ci] = this.getRandomRange([-1, 1]);
135 | }
136 | getEmptyArray(count) {
137 | return new Array(count);
138 | }
139 | spawn() {
140 | var _a, _b;
141 | this.spawnAt = Date.now();
142 | this.noOfCurves = Math.floor(this.getRandomRange((_b = (_a = this.ctrl.opt.ranges) === null || _a === void 0 ? void 0 : _a.noOfCurves) !== null && _b !== void 0 ? _b : this.DEFAULT_NOOFCURVES_RANGES));
143 | this.phases = this.getEmptyArray(this.noOfCurves);
144 | this.offsets = this.getEmptyArray(this.noOfCurves);
145 | this.speeds = this.getEmptyArray(this.noOfCurves);
146 | this.finalAmplitudes = this.getEmptyArray(this.noOfCurves);
147 | this.widths = this.getEmptyArray(this.noOfCurves);
148 | this.amplitudes = this.getEmptyArray(this.noOfCurves);
149 | this.despawnTimeouts = this.getEmptyArray(this.noOfCurves);
150 | this.verses = this.getEmptyArray(this.noOfCurves);
151 | for (let ci = 0; ci < this.noOfCurves; ci++) {
152 | this.spawnSingle(ci);
153 | }
154 | }
155 | globalAttFn(x) {
156 | return Math.pow(this.ATT_FACTOR / (this.ATT_FACTOR + Math.pow(x, 2)), this.ATT_FACTOR);
157 | }
158 | sin(x, phase) {
159 | return Math.sin(x - phase);
160 | }
161 | yRelativePos(i) {
162 | let y = 0;
163 | for (let ci = 0; ci < this.noOfCurves; ci++) {
164 | // Generate a static T so that each curve is distant from each oterh
165 | let t = 4 * (-1 + (ci / (this.noOfCurves - 1)) * 2);
166 | // but add a dynamic offset
167 | t += this.offsets[ci];
168 | const k = 1 / this.widths[ci];
169 | const x = i * k - t;
170 | y += Math.abs(this.amplitudes[ci] * this.sin(this.verses[ci] * x, this.phases[ci]) * this.globalAttFn(x));
171 | }
172 | // Divide for NoOfCurves so that y <= 1
173 | return y / this.noOfCurves;
174 | }
175 | yPos(i) {
176 | return (this.AMPLITUDE_FACTOR *
177 | this.ctrl.heightMax *
178 | this.ctrl.amplitude *
179 | this.yRelativePos(i) *
180 | this.globalAttFn((i / this.GRAPH_X) * 2));
181 | }
182 | xPos(i) {
183 | return this.ctrl.width * ((i + this.GRAPH_X) / (this.GRAPH_X * 2));
184 | }
185 | drawSupportLine() {
186 | const { ctx } = this.ctrl;
187 | const coo = [0, this.ctrl.heightMax, this.ctrl.width, 1];
188 | const gradient = ctx.createLinearGradient.apply(ctx, coo);
189 | gradient.addColorStop(0, "transparent");
190 | gradient.addColorStop(0.1, "rgba(255,255,255,.5)");
191 | gradient.addColorStop(1 - 0.1 - 0.1, "rgba(255,255,255,.5)");
192 | gradient.addColorStop(1, "transparent");
193 | ctx.fillStyle = gradient;
194 | ctx.fillRect.apply(ctx, coo);
195 | }
196 | draw() {
197 | const { ctx } = this.ctrl;
198 | ctx.globalAlpha = 0.7;
199 | ctx.globalCompositeOperation = this.ctrl.opt.globalCompositeOperation;
200 | if (this.spawnAt === 0) {
201 | this.spawn();
202 | }
203 | if (this.definition.supportLine) {
204 | // Draw the support line
205 | return this.drawSupportLine();
206 | }
207 | for (let ci = 0; ci < this.noOfCurves; ci++) {
208 | if (this.spawnAt + this.despawnTimeouts[ci] <= Date.now()) {
209 | this.amplitudes[ci] -= this.DESPAWN_FACTOR;
210 | }
211 | else {
212 | this.amplitudes[ci] += this.DESPAWN_FACTOR;
213 | }
214 | this.amplitudes[ci] = Math.min(Math.max(this.amplitudes[ci], 0), this.finalAmplitudes[ci]);
215 | this.phases[ci] = (this.phases[ci] + this.ctrl.speed * this.speeds[ci] * this.SPEED_FACTOR) % (2 * Math.PI);
216 | }
217 | let maxY = -Infinity;
218 | // Write two opposite waves
219 | for (const sign of [1, -1]) {
220 | ctx.beginPath();
221 | for (let i = -this.GRAPH_X; i <= this.GRAPH_X; i += this.ctrl.opt.pixelDepth) {
222 | const x = this.xPos(i);
223 | const y = this.yPos(i);
224 | ctx.lineTo(x, this.ctrl.heightMax - sign * y);
225 | maxY = Math.max(maxY, y);
226 | }
227 | ctx.closePath();
228 | ctx.fillStyle = `rgba(${this.definition.color}, 1)`;
229 | ctx.strokeStyle = `rgba(${this.definition.color}, 1)`;
230 | ctx.fill();
231 | }
232 | if (maxY < this.DEAD_PX && this.prevMaxY > maxY) {
233 | this.spawnAt = 0;
234 | }
235 | this.prevMaxY = maxY;
236 | return null;
237 | }
238 | static getDefinition() {
239 | return [
240 | {
241 | color: "255,255,255",
242 | supportLine: true,
243 | },
244 | {
245 | // blue
246 | color: "15, 82, 169",
247 | },
248 | {
249 | // red
250 | color: "173, 57, 76",
251 | },
252 | {
253 | // green
254 | color: "48, 220, 155",
255 | },
256 | ];
257 | }
258 | }
259 |
260 | class SiriWave {
261 | constructor(_a) {
262 | var { container } = _a, rest = __rest(_a, ["container"]);
263 | // Phase of the wave (passed to Math.sin function)
264 | this.phase = 0;
265 | // Boolean value indicating the the animation is running
266 | this.run = false;
267 | // Curves objects to animate
268 | this.curves = [];
269 | const csStyle = window.getComputedStyle(container);
270 | this.opt = Object.assign({ container, style: "ios", ratio: window.devicePixelRatio || 1, speed: 0.2, amplitude: 1, frequency: 6, color: "#fff", cover: false, width: parseInt(csStyle.width.replace("px", ""), 10), height: parseInt(csStyle.height.replace("px", ""), 10), autostart: true, pixelDepth: 0.02, lerpSpeed: 0.1, globalCompositeOperation: "lighter" }, rest);
271 | /**
272 | * Actual speed of the animation. Is not safe to change this value directly, use `setSpeed` instead.
273 | */
274 | this.speed = Number(this.opt.speed);
275 | /**
276 | * Actual amplitude of the animation. Is not safe to change this value directly, use `setAmplitude` instead.
277 | */
278 | this.amplitude = Number(this.opt.amplitude);
279 | /**
280 | * Width of the canvas multiplied by pixel ratio
281 | */
282 | this.width = Number(this.opt.ratio * this.opt.width);
283 | /**
284 | * Height of the canvas multiplied by pixel ratio
285 | */
286 | this.height = Number(this.opt.ratio * this.opt.height);
287 | /**
288 | * Maximum height for a single wave
289 | */
290 | this.heightMax = Number(this.height / 2) - 6;
291 | /**
292 | * Color of the wave (used in Classic iOS)
293 | */
294 | this.color = `rgb(${this.hex2rgb(this.opt.color)})`;
295 | /**
296 | * An object containing controller variables that need to be interpolated
297 | * to an another value before to be actually changed
298 | */
299 | this.interpolation = {
300 | speed: this.speed,
301 | amplitude: this.amplitude,
302 | };
303 | /**
304 | * Canvas DOM Element where curves will be drawn
305 | */
306 | this.canvas = document.createElement("canvas");
307 | /**
308 | * 2D Context from Canvas
309 | */
310 | const ctx = this.canvas.getContext("2d");
311 | if (ctx === null) {
312 | throw new Error("Unable to create 2D Context");
313 | }
314 | this.ctx = ctx;
315 | // Set dimensions
316 | this.canvas.width = this.width;
317 | this.canvas.height = this.height;
318 | // By covering, we ensure the canvas is in the same size of the parent
319 | if (this.opt.cover === true) {
320 | this.canvas.style.width = this.canvas.style.height = "100%";
321 | }
322 | else {
323 | this.canvas.style.width = `${this.width / this.opt.ratio}px`;
324 | this.canvas.style.height = `${this.height / this.opt.ratio}px`;
325 | }
326 | // Instantiate all curves based on the style
327 | switch (this.opt.style) {
328 | case "ios9":
329 | this.curves = (this.opt.curveDefinition || iOS9Curve.getDefinition()).map((def) => new iOS9Curve(this, def));
330 | break;
331 | case "ios":
332 | default:
333 | this.curves = (this.opt.curveDefinition || ClassicCurve.getDefinition()).map((def) => new ClassicCurve(this, def));
334 | break;
335 | }
336 | // Attach to the container
337 | this.opt.container.appendChild(this.canvas);
338 | // Start the animation
339 | if (this.opt.autostart) {
340 | this.start();
341 | }
342 | }
343 | /**
344 | * Convert an HEX color to RGB
345 | */
346 | hex2rgb(hex) {
347 | const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
348 | hex = hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b);
349 | const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
350 | return result
351 | ? `${parseInt(result[1], 16).toString()},${parseInt(result[2], 16).toString()},${parseInt(result[3], 16).toString()}`
352 | : null;
353 | }
354 | intLerp(v0, v1, t) {
355 | return v0 * (1 - t) + v1 * t;
356 | }
357 | /**
358 | * Interpolate a property to the value found in this.interpolation
359 | */
360 | lerp(propertyStr) {
361 | const prop = this.interpolation[propertyStr];
362 | if (prop !== null) {
363 | this[propertyStr] = this.intLerp(this[propertyStr], prop, this.opt.lerpSpeed);
364 | if (this[propertyStr] - prop === 0) {
365 | this.interpolation[propertyStr] = null;
366 | }
367 | }
368 | return this[propertyStr];
369 | }
370 | /**
371 | * Clear the canvas
372 | */
373 | clear() {
374 | this.ctx.globalCompositeOperation = "destination-out";
375 | this.ctx.fillRect(0, 0, this.width, this.height);
376 | this.ctx.globalCompositeOperation = "source-over";
377 | }
378 | /**
379 | * Draw all curves
380 | */
381 | draw() {
382 | this.curves.forEach((curve) => curve.draw());
383 | }
384 | /**
385 | * Clear the space, interpolate values, calculate new steps and draws
386 | * @returns
387 | */
388 | startDrawCycle() {
389 | this.clear();
390 | // Interpolate values
391 | this.lerp("amplitude");
392 | this.lerp("speed");
393 | this.draw();
394 | this.phase = (this.phase + (Math.PI / 2) * this.speed) % (2 * Math.PI);
395 | if (window.requestAnimationFrame) {
396 | this.animationFrameId = window.requestAnimationFrame(this.startDrawCycle.bind(this));
397 | }
398 | else {
399 | this.timeoutId = setTimeout(this.startDrawCycle.bind(this), 20);
400 | }
401 | }
402 | /* API */
403 | /**
404 | * Start the animation
405 | */
406 | start() {
407 | if (!this.canvas) {
408 | throw new Error("This instance of SiriWave has been disposed, please create a new instance");
409 | }
410 | this.phase = 0;
411 | // Ensure we don't re-launch the draw cycle
412 | if (!this.run) {
413 | this.run = true;
414 | this.startDrawCycle();
415 | }
416 | }
417 | /**
418 | * Stop the animation
419 | */
420 | stop() {
421 | this.phase = 0;
422 | this.run = false;
423 | // Clear old draw cycle on stop
424 | if (this.animationFrameId) {
425 | window.cancelAnimationFrame(this.animationFrameId);
426 | }
427 | if (this.timeoutId) {
428 | clearTimeout(this.timeoutId);
429 | }
430 | }
431 | /**
432 | * Dispose
433 | */
434 | dispose() {
435 | this.stop();
436 | if (this.canvas) {
437 | this.canvas.remove();
438 | this.canvas = null;
439 | }
440 | }
441 | /**
442 | * Set a new value for a property (interpolated)
443 | */
444 | set(propertyStr, value) {
445 | this.interpolation[propertyStr] = value;
446 | }
447 | /**
448 | * Set a new value for the speed property (interpolated)
449 | */
450 | setSpeed(value) {
451 | this.set("speed", value);
452 | }
453 | /**
454 | * Set a new value for the amplitude property (interpolated)
455 | */
456 | setAmplitude(value) {
457 | this.set("amplitude", value);
458 | }
459 | }
460 |
461 | export { SiriWave as default };
462 |
--------------------------------------------------------------------------------
/dist/siriwave.esm.min.js:
--------------------------------------------------------------------------------
1 | /*! *****************************************************************************
2 | Copyright (c) Microsoft Corporation.
3 |
4 | Permission to use, copy, modify, and/or distribute this software for any
5 | purpose with or without fee is hereby granted.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 | PERFORMANCE OF THIS SOFTWARE.
14 | ***************************************************************************** */
15 | class t{constructor(t,i){this.ATT_FACTOR=4,this.GRAPH_X=2,this.AMPLITUDE_FACTOR=.6,this.ctrl=t,this.definition=i}globalAttFn(t){return Math.pow(this.ATT_FACTOR/(this.ATT_FACTOR+Math.pow(t,this.ATT_FACTOR)),this.ATT_FACTOR)}xPos(t){return this.ctrl.width*((t+this.GRAPH_X)/(2*this.GRAPH_X))}yPos(t){return this.AMPLITUDE_FACTOR*(this.globalAttFn(t)*(this.ctrl.heightMax*this.ctrl.amplitude)*(1/this.definition.attenuation)*Math.sin(this.ctrl.opt.frequency*t-this.ctrl.phase))}draw(){const{ctx:t}=this.ctrl;t.moveTo(0,0),t.beginPath();const i=(this.definition.color||this.ctrl.color).replace(/rgb\(/g,"").replace(/\)/g,"");t.strokeStyle=`rgba(${i},${this.definition.opacity})`,t.lineWidth=this.definition.lineWidth;for(let i=-this.GRAPH_X;i<=this.GRAPH_X;i+=this.ctrl.opt.pixelDepth)t.lineTo(this.xPos(i),this.ctrl.heightMax+this.yPos(i));t.stroke()}static getDefinition(){return[{attenuation:-2,lineWidth:1,opacity:.1},{attenuation:-6,lineWidth:1,opacity:.2},{attenuation:4,lineWidth:1,opacity:.4},{attenuation:2,lineWidth:1,opacity:.6},{attenuation:1,lineWidth:1.5,opacity:1}]}}class i{constructor(t,i){this.GRAPH_X=25,this.AMPLITUDE_FACTOR=.8,this.SPEED_FACTOR=1,this.DEAD_PX=2,this.ATT_FACTOR=4,this.DESPAWN_FACTOR=.02,this.DEFAULT_NOOFCURVES_RANGES=[2,5],this.DEFAULT_AMPLITUDE_RANGES=[.3,1],this.DEFAULT_OFFSET_RANGES=[-3,3],this.DEFAULT_WIDTH_RANGES=[1,3],this.DEFAULT_SPEED_RANGES=[.5,1],this.DEFAULT_DESPAWN_TIMEOUT_RANGES=[500,2e3],this.ctrl=t,this.definition=i,this.noOfCurves=0,this.spawnAt=0,this.prevMaxY=0,this.phases=[],this.offsets=[],this.speeds=[],this.finalAmplitudes=[],this.widths=[],this.amplitudes=[],this.despawnTimeouts=[],this.verses=[]}getRandomRange(t){return t[0]+Math.random()*(t[1]-t[0])}spawnSingle(t){var i,s,e,h,o,a,r,n,l,p;this.phases[t]=0,this.amplitudes[t]=0,this.despawnTimeouts[t]=this.getRandomRange(null!==(s=null===(i=this.ctrl.opt.ranges)||void 0===i?void 0:i.despawnTimeout)&&void 0!==s?s:this.DEFAULT_DESPAWN_TIMEOUT_RANGES),this.offsets[t]=this.getRandomRange(null!==(h=null===(e=this.ctrl.opt.ranges)||void 0===e?void 0:e.offset)&&void 0!==h?h:this.DEFAULT_OFFSET_RANGES),this.speeds[t]=this.getRandomRange(null!==(a=null===(o=this.ctrl.opt.ranges)||void 0===o?void 0:o.speed)&&void 0!==a?a:this.DEFAULT_SPEED_RANGES),this.finalAmplitudes[t]=this.getRandomRange(null!==(n=null===(r=this.ctrl.opt.ranges)||void 0===r?void 0:r.amplitude)&&void 0!==n?n:this.DEFAULT_AMPLITUDE_RANGES),this.widths[t]=this.getRandomRange(null!==(p=null===(l=this.ctrl.opt.ranges)||void 0===l?void 0:l.width)&&void 0!==p?p:this.DEFAULT_WIDTH_RANGES),this.verses[t]=this.getRandomRange([-1,1])}getEmptyArray(t){return new Array(t)}spawn(){var t,i;this.spawnAt=Date.now(),this.noOfCurves=Math.floor(this.getRandomRange(null!==(i=null===(t=this.ctrl.opt.ranges)||void 0===t?void 0:t.noOfCurves)&&void 0!==i?i:this.DEFAULT_NOOFCURVES_RANGES)),this.phases=this.getEmptyArray(this.noOfCurves),this.offsets=this.getEmptyArray(this.noOfCurves),this.speeds=this.getEmptyArray(this.noOfCurves),this.finalAmplitudes=this.getEmptyArray(this.noOfCurves),this.widths=this.getEmptyArray(this.noOfCurves),this.amplitudes=this.getEmptyArray(this.noOfCurves),this.despawnTimeouts=this.getEmptyArray(this.noOfCurves),this.verses=this.getEmptyArray(this.noOfCurves);for(let t=0;ti&&(this.spawnAt=0),this.prevMaxY=i,null}static getDefinition(){return[{color:"255,255,255",supportLine:!0},{color:"15, 82, 169"},{color:"173, 57, 76"},{color:"48, 220, 155"}]}}class s{constructor(s){var{container:e}=s,h=function(t,i){var s={};for(var e in t)Object.prototype.hasOwnProperty.call(t,e)&&i.indexOf(e)<0&&(s[e]=t[e]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var h=0;for(e=Object.getOwnPropertySymbols(t);hnew i(this,t)));else this.curves=(this.opt.curveDefinition||t.getDefinition()).map((i=>new t(this,i)));this.opt.container.appendChild(this.canvas),this.opt.autostart&&this.start()}hex2rgb(t){t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,((t,i,s,e)=>i+i+s+s+e+e));const i=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return i?`${parseInt(i[1],16).toString()},${parseInt(i[2],16).toString()},${parseInt(i[3],16).toString()}`:null}intLerp(t,i,s){return t*(1-s)+i*s}lerp(t){const i=this.interpolation[t];return null!==i&&(this[t]=this.intLerp(this[t],i,this.opt.lerpSpeed),this[t]-i==0&&(this.interpolation[t]=null)),this[t]}clear(){this.ctx.globalCompositeOperation="destination-out",this.ctx.fillRect(0,0,this.width,this.height),this.ctx.globalCompositeOperation="source-over"}draw(){this.curves.forEach((t=>t.draw()))}startDrawCycle(){this.clear(),this.lerp("amplitude"),this.lerp("speed"),this.draw(),this.phase=(this.phase+Math.PI/2*this.speed)%(2*Math.PI),window.requestAnimationFrame?this.animationFrameId=window.requestAnimationFrame(this.startDrawCycle.bind(this)):this.timeoutId=setTimeout(this.startDrawCycle.bind(this),20)}start(){if(!this.canvas)throw new Error("This instance of SiriWave has been disposed, please create a new instance");this.phase=0,this.run||(this.run=!0,this.startDrawCycle())}stop(){this.phase=0,this.run=!1,this.animationFrameId&&window.cancelAnimationFrame(this.animationFrameId),this.timeoutId&&clearTimeout(this.timeoutId)}dispose(){this.stop(),this.canvas&&(this.canvas.remove(),this.canvas=null)}set(t,i){this.interpolation[t]=i}setSpeed(t){this.set("speed",t)}setAmplitude(t){this.set("amplitude",t)}}export{s as default};
16 |
--------------------------------------------------------------------------------
/dist/siriwave.umd.js:
--------------------------------------------------------------------------------
1 | (function (global, factory) {
2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 | typeof define === 'function' && define.amd ? define(factory) :
4 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.SiriWave = factory());
5 | })(this, (function () { 'use strict';
6 |
7 | /*! *****************************************************************************
8 | Copyright (c) Microsoft Corporation.
9 |
10 | Permission to use, copy, modify, and/or distribute this software for any
11 | purpose with or without fee is hereby granted.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 | PERFORMANCE OF THIS SOFTWARE.
20 | ***************************************************************************** */
21 |
22 | var __assign = function() {
23 | __assign = Object.assign || function __assign(t) {
24 | for (var s, i = 1, n = arguments.length; i < n; i++) {
25 | s = arguments[i];
26 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
27 | }
28 | return t;
29 | };
30 | return __assign.apply(this, arguments);
31 | };
32 |
33 | function __rest(s, e) {
34 | var t = {};
35 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
36 | t[p] = s[p];
37 | if (s != null && typeof Object.getOwnPropertySymbols === "function")
38 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
39 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
40 | t[p[i]] = s[p[i]];
41 | }
42 | return t;
43 | }
44 |
45 | var ClassicCurve = /** @class */ (function () {
46 | function ClassicCurve(ctrl, definition) {
47 | this.ATT_FACTOR = 4;
48 | this.GRAPH_X = 2;
49 | this.AMPLITUDE_FACTOR = 0.6;
50 | this.ctrl = ctrl;
51 | this.definition = definition;
52 | }
53 | ClassicCurve.prototype.globalAttFn = function (x) {
54 | return Math.pow(this.ATT_FACTOR / (this.ATT_FACTOR + Math.pow(x, this.ATT_FACTOR)), this.ATT_FACTOR);
55 | };
56 | ClassicCurve.prototype.xPos = function (i) {
57 | return this.ctrl.width * ((i + this.GRAPH_X) / (this.GRAPH_X * 2));
58 | };
59 | ClassicCurve.prototype.yPos = function (i) {
60 | return (this.AMPLITUDE_FACTOR *
61 | (this.globalAttFn(i) *
62 | (this.ctrl.heightMax * this.ctrl.amplitude) *
63 | (1 / this.definition.attenuation) *
64 | Math.sin(this.ctrl.opt.frequency * i - this.ctrl.phase)));
65 | };
66 | ClassicCurve.prototype.draw = function () {
67 | var ctx = this.ctrl.ctx;
68 | ctx.moveTo(0, 0);
69 | ctx.beginPath();
70 | var finalColor = this.definition.color || this.ctrl.color;
71 | var colorHex = finalColor.replace(/rgb\(/g, "").replace(/\)/g, "");
72 | ctx.strokeStyle = "rgba(".concat(colorHex, ",").concat(this.definition.opacity, ")");
73 | ctx.lineWidth = this.definition.lineWidth;
74 | // Cycle the graph from -X to +X every PX_DEPTH and draw the line
75 | for (var i = -this.GRAPH_X; i <= this.GRAPH_X; i += this.ctrl.opt.pixelDepth) {
76 | ctx.lineTo(this.xPos(i), this.ctrl.heightMax + this.yPos(i));
77 | }
78 | ctx.stroke();
79 | };
80 | ClassicCurve.getDefinition = function () {
81 | return [
82 | {
83 | attenuation: -2,
84 | lineWidth: 1,
85 | opacity: 0.1,
86 | },
87 | {
88 | attenuation: -6,
89 | lineWidth: 1,
90 | opacity: 0.2,
91 | },
92 | {
93 | attenuation: 4,
94 | lineWidth: 1,
95 | opacity: 0.4,
96 | },
97 | {
98 | attenuation: 2,
99 | lineWidth: 1,
100 | opacity: 0.6,
101 | },
102 | {
103 | attenuation: 1,
104 | lineWidth: 1.5,
105 | opacity: 1,
106 | },
107 | ];
108 | };
109 | return ClassicCurve;
110 | }());
111 |
112 | var iOS9Curve = /** @class */ (function () {
113 | function iOS9Curve(ctrl, definition) {
114 | this.GRAPH_X = 25;
115 | this.AMPLITUDE_FACTOR = 0.8;
116 | this.SPEED_FACTOR = 1;
117 | this.DEAD_PX = 2;
118 | this.ATT_FACTOR = 4;
119 | this.DESPAWN_FACTOR = 0.02;
120 | this.DEFAULT_NOOFCURVES_RANGES = [2, 5];
121 | this.DEFAULT_AMPLITUDE_RANGES = [0.3, 1];
122 | this.DEFAULT_OFFSET_RANGES = [-3, 3];
123 | this.DEFAULT_WIDTH_RANGES = [1, 3];
124 | this.DEFAULT_SPEED_RANGES = [0.5, 1];
125 | this.DEFAULT_DESPAWN_TIMEOUT_RANGES = [500, 2000];
126 | this.ctrl = ctrl;
127 | this.definition = definition;
128 | this.noOfCurves = 0;
129 | this.spawnAt = 0;
130 | this.prevMaxY = 0;
131 | this.phases = [];
132 | this.offsets = [];
133 | this.speeds = [];
134 | this.finalAmplitudes = [];
135 | this.widths = [];
136 | this.amplitudes = [];
137 | this.despawnTimeouts = [];
138 | this.verses = [];
139 | }
140 | iOS9Curve.prototype.getRandomRange = function (e) {
141 | return e[0] + Math.random() * (e[1] - e[0]);
142 | };
143 | iOS9Curve.prototype.spawnSingle = function (ci) {
144 | var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
145 | this.phases[ci] = 0;
146 | this.amplitudes[ci] = 0;
147 | this.despawnTimeouts[ci] = this.getRandomRange((_b = (_a = this.ctrl.opt.ranges) === null || _a === void 0 ? void 0 : _a.despawnTimeout) !== null && _b !== void 0 ? _b : this.DEFAULT_DESPAWN_TIMEOUT_RANGES);
148 | this.offsets[ci] = this.getRandomRange((_d = (_c = this.ctrl.opt.ranges) === null || _c === void 0 ? void 0 : _c.offset) !== null && _d !== void 0 ? _d : this.DEFAULT_OFFSET_RANGES);
149 | this.speeds[ci] = this.getRandomRange((_f = (_e = this.ctrl.opt.ranges) === null || _e === void 0 ? void 0 : _e.speed) !== null && _f !== void 0 ? _f : this.DEFAULT_SPEED_RANGES);
150 | this.finalAmplitudes[ci] = this.getRandomRange((_h = (_g = this.ctrl.opt.ranges) === null || _g === void 0 ? void 0 : _g.amplitude) !== null && _h !== void 0 ? _h : this.DEFAULT_AMPLITUDE_RANGES);
151 | this.widths[ci] = this.getRandomRange((_k = (_j = this.ctrl.opt.ranges) === null || _j === void 0 ? void 0 : _j.width) !== null && _k !== void 0 ? _k : this.DEFAULT_WIDTH_RANGES);
152 | this.verses[ci] = this.getRandomRange([-1, 1]);
153 | };
154 | iOS9Curve.prototype.getEmptyArray = function (count) {
155 | return new Array(count);
156 | };
157 | iOS9Curve.prototype.spawn = function () {
158 | var _a, _b;
159 | this.spawnAt = Date.now();
160 | this.noOfCurves = Math.floor(this.getRandomRange((_b = (_a = this.ctrl.opt.ranges) === null || _a === void 0 ? void 0 : _a.noOfCurves) !== null && _b !== void 0 ? _b : this.DEFAULT_NOOFCURVES_RANGES));
161 | this.phases = this.getEmptyArray(this.noOfCurves);
162 | this.offsets = this.getEmptyArray(this.noOfCurves);
163 | this.speeds = this.getEmptyArray(this.noOfCurves);
164 | this.finalAmplitudes = this.getEmptyArray(this.noOfCurves);
165 | this.widths = this.getEmptyArray(this.noOfCurves);
166 | this.amplitudes = this.getEmptyArray(this.noOfCurves);
167 | this.despawnTimeouts = this.getEmptyArray(this.noOfCurves);
168 | this.verses = this.getEmptyArray(this.noOfCurves);
169 | for (var ci = 0; ci < this.noOfCurves; ci++) {
170 | this.spawnSingle(ci);
171 | }
172 | };
173 | iOS9Curve.prototype.globalAttFn = function (x) {
174 | return Math.pow(this.ATT_FACTOR / (this.ATT_FACTOR + Math.pow(x, 2)), this.ATT_FACTOR);
175 | };
176 | iOS9Curve.prototype.sin = function (x, phase) {
177 | return Math.sin(x - phase);
178 | };
179 | iOS9Curve.prototype.yRelativePos = function (i) {
180 | var y = 0;
181 | for (var ci = 0; ci < this.noOfCurves; ci++) {
182 | // Generate a static T so that each curve is distant from each oterh
183 | var t = 4 * (-1 + (ci / (this.noOfCurves - 1)) * 2);
184 | // but add a dynamic offset
185 | t += this.offsets[ci];
186 | var k = 1 / this.widths[ci];
187 | var x = i * k - t;
188 | y += Math.abs(this.amplitudes[ci] * this.sin(this.verses[ci] * x, this.phases[ci]) * this.globalAttFn(x));
189 | }
190 | // Divide for NoOfCurves so that y <= 1
191 | return y / this.noOfCurves;
192 | };
193 | iOS9Curve.prototype.yPos = function (i) {
194 | return (this.AMPLITUDE_FACTOR *
195 | this.ctrl.heightMax *
196 | this.ctrl.amplitude *
197 | this.yRelativePos(i) *
198 | this.globalAttFn((i / this.GRAPH_X) * 2));
199 | };
200 | iOS9Curve.prototype.xPos = function (i) {
201 | return this.ctrl.width * ((i + this.GRAPH_X) / (this.GRAPH_X * 2));
202 | };
203 | iOS9Curve.prototype.drawSupportLine = function () {
204 | var ctx = this.ctrl.ctx;
205 | var coo = [0, this.ctrl.heightMax, this.ctrl.width, 1];
206 | var gradient = ctx.createLinearGradient.apply(ctx, coo);
207 | gradient.addColorStop(0, "transparent");
208 | gradient.addColorStop(0.1, "rgba(255,255,255,.5)");
209 | gradient.addColorStop(1 - 0.1 - 0.1, "rgba(255,255,255,.5)");
210 | gradient.addColorStop(1, "transparent");
211 | ctx.fillStyle = gradient;
212 | ctx.fillRect.apply(ctx, coo);
213 | };
214 | iOS9Curve.prototype.draw = function () {
215 | var ctx = this.ctrl.ctx;
216 | ctx.globalAlpha = 0.7;
217 | ctx.globalCompositeOperation = this.ctrl.opt.globalCompositeOperation;
218 | if (this.spawnAt === 0) {
219 | this.spawn();
220 | }
221 | if (this.definition.supportLine) {
222 | // Draw the support line
223 | return this.drawSupportLine();
224 | }
225 | for (var ci = 0; ci < this.noOfCurves; ci++) {
226 | if (this.spawnAt + this.despawnTimeouts[ci] <= Date.now()) {
227 | this.amplitudes[ci] -= this.DESPAWN_FACTOR;
228 | }
229 | else {
230 | this.amplitudes[ci] += this.DESPAWN_FACTOR;
231 | }
232 | this.amplitudes[ci] = Math.min(Math.max(this.amplitudes[ci], 0), this.finalAmplitudes[ci]);
233 | this.phases[ci] = (this.phases[ci] + this.ctrl.speed * this.speeds[ci] * this.SPEED_FACTOR) % (2 * Math.PI);
234 | }
235 | var maxY = -Infinity;
236 | // Write two opposite waves
237 | for (var _i = 0, _a = [1, -1]; _i < _a.length; _i++) {
238 | var sign = _a[_i];
239 | ctx.beginPath();
240 | for (var i = -this.GRAPH_X; i <= this.GRAPH_X; i += this.ctrl.opt.pixelDepth) {
241 | var x = this.xPos(i);
242 | var y = this.yPos(i);
243 | ctx.lineTo(x, this.ctrl.heightMax - sign * y);
244 | maxY = Math.max(maxY, y);
245 | }
246 | ctx.closePath();
247 | ctx.fillStyle = "rgba(".concat(this.definition.color, ", 1)");
248 | ctx.strokeStyle = "rgba(".concat(this.definition.color, ", 1)");
249 | ctx.fill();
250 | }
251 | if (maxY < this.DEAD_PX && this.prevMaxY > maxY) {
252 | this.spawnAt = 0;
253 | }
254 | this.prevMaxY = maxY;
255 | return null;
256 | };
257 | iOS9Curve.getDefinition = function () {
258 | return [
259 | {
260 | color: "255,255,255",
261 | supportLine: true,
262 | },
263 | {
264 | // blue
265 | color: "15, 82, 169",
266 | },
267 | {
268 | // red
269 | color: "173, 57, 76",
270 | },
271 | {
272 | // green
273 | color: "48, 220, 155",
274 | },
275 | ];
276 | };
277 | return iOS9Curve;
278 | }());
279 |
280 | var SiriWave = /** @class */ (function () {
281 | function SiriWave(_a) {
282 | var _this = this;
283 | var container = _a.container, rest = __rest(_a, ["container"]);
284 | // Phase of the wave (passed to Math.sin function)
285 | this.phase = 0;
286 | // Boolean value indicating the the animation is running
287 | this.run = false;
288 | // Curves objects to animate
289 | this.curves = [];
290 | var csStyle = window.getComputedStyle(container);
291 | this.opt = __assign({ container: container, style: "ios", ratio: window.devicePixelRatio || 1, speed: 0.2, amplitude: 1, frequency: 6, color: "#fff", cover: false, width: parseInt(csStyle.width.replace("px", ""), 10), height: parseInt(csStyle.height.replace("px", ""), 10), autostart: true, pixelDepth: 0.02, lerpSpeed: 0.1, globalCompositeOperation: "lighter" }, rest);
292 | /**
293 | * Actual speed of the animation. Is not safe to change this value directly, use `setSpeed` instead.
294 | */
295 | this.speed = Number(this.opt.speed);
296 | /**
297 | * Actual amplitude of the animation. Is not safe to change this value directly, use `setAmplitude` instead.
298 | */
299 | this.amplitude = Number(this.opt.amplitude);
300 | /**
301 | * Width of the canvas multiplied by pixel ratio
302 | */
303 | this.width = Number(this.opt.ratio * this.opt.width);
304 | /**
305 | * Height of the canvas multiplied by pixel ratio
306 | */
307 | this.height = Number(this.opt.ratio * this.opt.height);
308 | /**
309 | * Maximum height for a single wave
310 | */
311 | this.heightMax = Number(this.height / 2) - 6;
312 | /**
313 | * Color of the wave (used in Classic iOS)
314 | */
315 | this.color = "rgb(".concat(this.hex2rgb(this.opt.color), ")");
316 | /**
317 | * An object containing controller variables that need to be interpolated
318 | * to an another value before to be actually changed
319 | */
320 | this.interpolation = {
321 | speed: this.speed,
322 | amplitude: this.amplitude,
323 | };
324 | /**
325 | * Canvas DOM Element where curves will be drawn
326 | */
327 | this.canvas = document.createElement("canvas");
328 | /**
329 | * 2D Context from Canvas
330 | */
331 | var ctx = this.canvas.getContext("2d");
332 | if (ctx === null) {
333 | throw new Error("Unable to create 2D Context");
334 | }
335 | this.ctx = ctx;
336 | // Set dimensions
337 | this.canvas.width = this.width;
338 | this.canvas.height = this.height;
339 | // By covering, we ensure the canvas is in the same size of the parent
340 | if (this.opt.cover === true) {
341 | this.canvas.style.width = this.canvas.style.height = "100%";
342 | }
343 | else {
344 | this.canvas.style.width = "".concat(this.width / this.opt.ratio, "px");
345 | this.canvas.style.height = "".concat(this.height / this.opt.ratio, "px");
346 | }
347 | // Instantiate all curves based on the style
348 | switch (this.opt.style) {
349 | case "ios9":
350 | this.curves = (this.opt.curveDefinition || iOS9Curve.getDefinition()).map(function (def) { return new iOS9Curve(_this, def); });
351 | break;
352 | case "ios":
353 | default:
354 | this.curves = (this.opt.curveDefinition || ClassicCurve.getDefinition()).map(function (def) { return new ClassicCurve(_this, def); });
355 | break;
356 | }
357 | // Attach to the container
358 | this.opt.container.appendChild(this.canvas);
359 | // Start the animation
360 | if (this.opt.autostart) {
361 | this.start();
362 | }
363 | }
364 | /**
365 | * Convert an HEX color to RGB
366 | */
367 | SiriWave.prototype.hex2rgb = function (hex) {
368 | var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
369 | hex = hex.replace(shorthandRegex, function (m, r, g, b) { return r + r + g + g + b + b; });
370 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
371 | return result
372 | ? "".concat(parseInt(result[1], 16).toString(), ",").concat(parseInt(result[2], 16).toString(), ",").concat(parseInt(result[3], 16).toString())
373 | : null;
374 | };
375 | SiriWave.prototype.intLerp = function (v0, v1, t) {
376 | return v0 * (1 - t) + v1 * t;
377 | };
378 | /**
379 | * Interpolate a property to the value found in this.interpolation
380 | */
381 | SiriWave.prototype.lerp = function (propertyStr) {
382 | var prop = this.interpolation[propertyStr];
383 | if (prop !== null) {
384 | this[propertyStr] = this.intLerp(this[propertyStr], prop, this.opt.lerpSpeed);
385 | if (this[propertyStr] - prop === 0) {
386 | this.interpolation[propertyStr] = null;
387 | }
388 | }
389 | return this[propertyStr];
390 | };
391 | /**
392 | * Clear the canvas
393 | */
394 | SiriWave.prototype.clear = function () {
395 | this.ctx.globalCompositeOperation = "destination-out";
396 | this.ctx.fillRect(0, 0, this.width, this.height);
397 | this.ctx.globalCompositeOperation = "source-over";
398 | };
399 | /**
400 | * Draw all curves
401 | */
402 | SiriWave.prototype.draw = function () {
403 | this.curves.forEach(function (curve) { return curve.draw(); });
404 | };
405 | /**
406 | * Clear the space, interpolate values, calculate new steps and draws
407 | * @returns
408 | */
409 | SiriWave.prototype.startDrawCycle = function () {
410 | this.clear();
411 | // Interpolate values
412 | this.lerp("amplitude");
413 | this.lerp("speed");
414 | this.draw();
415 | this.phase = (this.phase + (Math.PI / 2) * this.speed) % (2 * Math.PI);
416 | if (window.requestAnimationFrame) {
417 | this.animationFrameId = window.requestAnimationFrame(this.startDrawCycle.bind(this));
418 | }
419 | else {
420 | this.timeoutId = setTimeout(this.startDrawCycle.bind(this), 20);
421 | }
422 | };
423 | /* API */
424 | /**
425 | * Start the animation
426 | */
427 | SiriWave.prototype.start = function () {
428 | if (!this.canvas) {
429 | throw new Error("This instance of SiriWave has been disposed, please create a new instance");
430 | }
431 | this.phase = 0;
432 | // Ensure we don't re-launch the draw cycle
433 | if (!this.run) {
434 | this.run = true;
435 | this.startDrawCycle();
436 | }
437 | };
438 | /**
439 | * Stop the animation
440 | */
441 | SiriWave.prototype.stop = function () {
442 | this.phase = 0;
443 | this.run = false;
444 | // Clear old draw cycle on stop
445 | if (this.animationFrameId) {
446 | window.cancelAnimationFrame(this.animationFrameId);
447 | }
448 | if (this.timeoutId) {
449 | clearTimeout(this.timeoutId);
450 | }
451 | };
452 | /**
453 | * Dispose
454 | */
455 | SiriWave.prototype.dispose = function () {
456 | this.stop();
457 | if (this.canvas) {
458 | this.canvas.remove();
459 | this.canvas = null;
460 | }
461 | };
462 | /**
463 | * Set a new value for a property (interpolated)
464 | */
465 | SiriWave.prototype.set = function (propertyStr, value) {
466 | this.interpolation[propertyStr] = value;
467 | };
468 | /**
469 | * Set a new value for the speed property (interpolated)
470 | */
471 | SiriWave.prototype.setSpeed = function (value) {
472 | this.set("speed", value);
473 | };
474 | /**
475 | * Set a new value for the amplitude property (interpolated)
476 | */
477 | SiriWave.prototype.setAmplitude = function (value) {
478 | this.set("amplitude", value);
479 | };
480 | return SiriWave;
481 | }());
482 |
483 | return SiriWave;
484 |
485 | }));
486 |
--------------------------------------------------------------------------------
/dist/siriwave.umd.min.js:
--------------------------------------------------------------------------------
1 | !function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(t="undefined"!=typeof globalThis?globalThis:t||self).SiriWave=i()}(this,(function(){"use strict";
2 | /*! *****************************************************************************
3 | Copyright (c) Microsoft Corporation.
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 | PERFORMANCE OF THIS SOFTWARE.
15 | ***************************************************************************** */var t=function(){return t=Object.assign||function(t){for(var i,s=1,e=arguments.length;ss&&(this.spawnAt=0),this.prevMaxY=s,null},t.getDefinition=function(){return[{color:"255,255,255",supportLine:!0},{color:"15, 82, 169"},{color:"173, 57, 76"},{color:"48, 220, 155"}]},t}();return function(){function e(e){var o=this,n=e.container,h=function(t,i){var s={};for(var e in t)Object.prototype.hasOwnProperty.call(t,e)&&i.indexOf(e)<0&&(s[e]=t[e]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(e=Object.getOwnPropertySymbols(t);o void;
42 | }
43 | export default class SiriWave {
44 | opt: Options;
45 | phase: number;
46 | run: boolean;
47 | curves: ICurve[];
48 | speed: number;
49 | amplitude: number;
50 | width: number;
51 | height: number;
52 | heightMax: number;
53 | color: string;
54 | interpolation: {
55 | speed: number | null;
56 | amplitude: number | null;
57 | };
58 | canvas: HTMLCanvasElement | null;
59 | ctx: CanvasRenderingContext2D;
60 | animationFrameId: number | undefined;
61 | timeoutId: ReturnType | undefined;
62 | constructor({ container, ...rest }: Options);
63 | /**
64 | * Convert an HEX color to RGB
65 | */
66 | private hex2rgb;
67 | private intLerp;
68 | /**
69 | * Interpolate a property to the value found in this.interpolation
70 | */
71 | private lerp;
72 | /**
73 | * Clear the canvas
74 | */
75 | private clear;
76 | /**
77 | * Draw all curves
78 | */
79 | private draw;
80 | /**
81 | * Clear the space, interpolate values, calculate new steps and draws
82 | * @returns
83 | */
84 | private startDrawCycle;
85 | /**
86 | * Start the animation
87 | */
88 | start(): void;
89 | /**
90 | * Stop the animation
91 | */
92 | stop(): void;
93 | /**
94 | * Dispose
95 | */
96 | dispose(): void;
97 | /**
98 | * Set a new value for a property (interpolated)
99 | */
100 | set(propertyStr: "amplitude" | "speed", value: number): void;
101 | /**
102 | * Set a new value for the speed property (interpolated)
103 | */
104 | setSpeed(value: number): void;
105 | /**
106 | * Set a new value for the amplitude property (interpolated)
107 | */
108 | setAmplitude(value: number): void;
109 | }
110 | export {};
111 |
--------------------------------------------------------------------------------
/dist/types/ios9-curve.d.ts:
--------------------------------------------------------------------------------
1 | import SiriWave, { ICurve, IiOS9CurveDefinition } from "./index";
2 | export declare class iOS9Curve implements ICurve {
3 | ctrl: SiriWave;
4 | definition: IiOS9CurveDefinition;
5 | spawnAt: number;
6 | noOfCurves: number;
7 | prevMaxY: number;
8 | phases: number[];
9 | amplitudes: number[];
10 | despawnTimeouts: number[];
11 | offsets: number[];
12 | speeds: number[];
13 | finalAmplitudes: number[];
14 | widths: number[];
15 | verses: number[];
16 | GRAPH_X: number;
17 | AMPLITUDE_FACTOR: number;
18 | SPEED_FACTOR: number;
19 | DEAD_PX: number;
20 | ATT_FACTOR: number;
21 | DESPAWN_FACTOR: number;
22 | DEFAULT_NOOFCURVES_RANGES: [number, number];
23 | DEFAULT_AMPLITUDE_RANGES: [number, number];
24 | DEFAULT_OFFSET_RANGES: [number, number];
25 | DEFAULT_WIDTH_RANGES: [number, number];
26 | DEFAULT_SPEED_RANGES: [number, number];
27 | DEFAULT_DESPAWN_TIMEOUT_RANGES: [number, number];
28 | constructor(ctrl: SiriWave, definition: IiOS9CurveDefinition);
29 | private getRandomRange;
30 | private spawnSingle;
31 | private getEmptyArray;
32 | private spawn;
33 | private globalAttFn;
34 | private sin;
35 | private yRelativePos;
36 | private yPos;
37 | private xPos;
38 | private drawSupportLine;
39 | draw(): void | null;
40 | static getDefinition(): IiOS9CurveDefinition[];
41 | }
42 |
--------------------------------------------------------------------------------
/etc/classic.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kopiro/siriwave/744cb00235b7900733efff25dc73b4d1ab77c92d/etc/classic.gif
--------------------------------------------------------------------------------
/etc/dat.gui.js:
--------------------------------------------------------------------------------
1 | /**
2 | * dat-gui JavaScript Controller Library
3 | * http://code.google.com/p/dat-gui
4 | *
5 | * Copyright 2011 Data Arts Team, Google Creative Lab
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | */
13 | ! function (e, t) {
14 | "object" == typeof exports && "undefined" != typeof module ? t(exports) : "function" == typeof define && define.amd ? define(["exports"], t) : t(e.dat = {})
15 | }(this, function (e) {
16 | "use strict";
17 |
18 | function t(e, t) {
19 | var n = e.__state.conversionName.toString(),
20 | o = Math.round(e.r),
21 | i = Math.round(e.g),
22 | r = Math.round(e.b),
23 | s = e.a,
24 | a = Math.round(e.h),
25 | l = e.s.toFixed(1),
26 | d = e.v.toFixed(1);
27 | if (t || "THREE_CHAR_HEX" === n || "SIX_CHAR_HEX" === n) {
28 | for (var c = e.hex.toString(16); c.length < 6;) c = "0" + c;
29 | return "#" + c
30 | }
31 | return "CSS_RGB" === n ? "rgb(" + o + "," + i + "," + r + ")" : "CSS_RGBA" === n ? "rgba(" + o + "," + i + "," + r + "," + s + ")" : "HEX" === n ? "0x" + e.hex.toString(16) : "RGB_ARRAY" === n ? "[" + o + "," + i + "," + r + "]" : "RGBA_ARRAY" === n ? "[" + o + "," + i + "," + r + "," + s + "]" : "RGB_OBJ" === n ? "{r:" + o + ",g:" + i + ",b:" + r + "}" : "RGBA_OBJ" === n ? "{r:" + o + ",g:" + i + ",b:" + r + ",a:" + s + "}" : "HSV_OBJ" === n ? "{h:" + a + ",s:" + l + ",v:" + d + "}" : "HSVA_OBJ" === n ? "{h:" + a + ",s:" + l + ",v:" + d + ",a:" + s + "}" : "unknown format"
32 | }
33 |
34 | function n(e, t, n) {
35 | Object.defineProperty(e, t, {
36 | get: function () {
37 | return "RGB" === this.__state.space ? this.__state[t] : (I.recalculateRGB(this, t, n), this.__state[t])
38 | },
39 | set: function (e) {
40 | "RGB" !== this.__state.space && (I.recalculateRGB(this, t, n), this.__state.space = "RGB"), this.__state[t] = e
41 | }
42 | })
43 | }
44 |
45 | function o(e, t) {
46 | Object.defineProperty(e, t, {
47 | get: function () {
48 | return "HSV" === this.__state.space ? this.__state[t] : (I.recalculateHSV(this), this.__state[t])
49 | },
50 | set: function (e) {
51 | "HSV" !== this.__state.space && (I.recalculateHSV(this), this.__state.space = "HSV"), this.__state[t] = e
52 | }
53 | })
54 | }
55 |
56 | function i(e) {
57 | if ("0" === e || S.isUndefined(e)) return 0;
58 | var t = e.match(U);
59 | return S.isNull(t) ? 0 : parseFloat(t[1])
60 | }
61 |
62 | function r(e) {
63 | var t = e.toString();
64 | return t.indexOf(".") > -1 ? t.length - t.indexOf(".") - 1 : 0
65 | }
66 |
67 | function s(e, t) {
68 | var n = Math.pow(10, t);
69 | return Math.round(e * n) / n
70 | }
71 |
72 | function a(e, t, n, o, i) {
73 | return o + (e - t) / (n - t) * (i - o)
74 | }
75 |
76 | function l(e, t, n, o) {
77 | e.style.background = "", S.each(ee, function (i) {
78 | e.style.cssText += "background: " + i + "linear-gradient(" + t + ", " + n + " 0%, " + o + " 100%); "
79 | })
80 | }
81 |
82 | function d(e) {
83 | e.style.background = "", e.style.cssText += "background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);", e.style.cssText += "background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);", e.style.cssText += "background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);", e.style.cssText += "background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);", e.style.cssText += "background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"
84 | }
85 |
86 | function c(e, t, n) {
87 | var o = document.createElement("li");
88 | return t && o.appendChild(t), n ? e.__ul.insertBefore(o, n) : e.__ul.appendChild(o), e.onResize(), o
89 | }
90 |
91 | function u(e) {
92 | X.unbind(window, "resize", e.__resizeHandler), e.saveToLocalStorageIfPossible && X.unbind(window, "unload", e.saveToLocalStorageIfPossible)
93 | }
94 |
95 | function _(e, t) {
96 | var n = e.__preset_select[e.__preset_select.selectedIndex];
97 | n.innerHTML = t ? n.value + "*" : n.value
98 | }
99 |
100 | function h(e, t, n) {
101 | if (n.__li = t, n.__gui = e, S.extend(n, {
102 | options: function (t) {
103 | if (arguments.length > 1) {
104 | var o = n.__li.nextElementSibling;
105 | return n.remove(), f(e, n.object, n.property, {
106 | before: o,
107 | factoryArgs: [S.toArray(arguments)]
108 | })
109 | }
110 | if (S.isArray(t) || S.isObject(t)) {
111 | var i = n.__li.nextElementSibling;
112 | return n.remove(), f(e, n.object, n.property, {
113 | before: i,
114 | factoryArgs: [t]
115 | })
116 | }
117 | },
118 | name: function (e) {
119 | return n.__li.firstElementChild.firstElementChild.innerHTML = e, n
120 | },
121 | listen: function () {
122 | return n.__gui.listen(n), n
123 | },
124 | remove: function () {
125 | return n.__gui.remove(n), n
126 | }
127 | }), n instanceof q) {
128 | var o = new Q(n.object, n.property, {
129 | min: n.__min,
130 | max: n.__max,
131 | step: n.__step
132 | });
133 | S.each(["updateDisplay", "onChange", "onFinishChange", "step"], function (e) {
134 | var t = n[e],
135 | i = o[e];
136 | n[e] = o[e] = function () {
137 | var e = Array.prototype.slice.call(arguments);
138 | return i.apply(o, e), t.apply(n, e)
139 | }
140 | }), X.addClass(t, "has-slider"), n.domElement.insertBefore(o.domElement, n.domElement.firstElementChild)
141 | } else if (n instanceof Q) {
142 | var i = function (t) {
143 | if (S.isNumber(n.__min) && S.isNumber(n.__max)) {
144 | var o = n.__li.firstElementChild.firstElementChild.innerHTML,
145 | i = n.__gui.__listening.indexOf(n) > -1;
146 | n.remove();
147 | var r = f(e, n.object, n.property, {
148 | before: n.__li.nextElementSibling,
149 | factoryArgs: [n.__min, n.__max, n.__step]
150 | });
151 | return r.name(o), i && r.listen(), r
152 | }
153 | return t
154 | };
155 | n.min = S.compose(i, n.min), n.max = S.compose(i, n.max)
156 | } else n instanceof K ? (X.bind(t, "click", function () {
157 | X.fakeEvent(n.__checkbox, "click")
158 | }), X.bind(n.__checkbox, "click", function (e) {
159 | e.stopPropagation()
160 | })) : n instanceof Z ? (X.bind(t, "click", function () {
161 | X.fakeEvent(n.__button, "click")
162 | }), X.bind(t, "mouseover", function () {
163 | X.addClass(n.__button, "hover")
164 | }), X.bind(t, "mouseout", function () {
165 | X.removeClass(n.__button, "hover")
166 | })) : n instanceof $ && (X.addClass(t, "color"), n.updateDisplay = S.compose(function (e) {
167 | return t.style.borderLeftColor = n.__color.toString(), e
168 | }, n.updateDisplay), n.updateDisplay());
169 | n.setValue = S.compose(function (t) {
170 | return e.getRoot().__preset_select && n.isModified() && _(e.getRoot(), !0), t
171 | }, n.setValue)
172 | }
173 |
174 | function p(e, t) {
175 | var n = e.getRoot(),
176 | o = n.__rememberedObjects.indexOf(t.object);
177 | if (-1 !== o) {
178 | var i = n.__rememberedObjectIndecesToControllers[o];
179 | if (void 0 === i && (i = {}, n.__rememberedObjectIndecesToControllers[o] = i), i[t.property] = t, n.load && n.load.remembered) {
180 | var r = n.load.remembered,
181 | s = void 0;
182 | if (r[e.preset]) s = r[e.preset];
183 | else {
184 | if (!r[se]) return;
185 | s = r[se]
186 | }
187 | if (s[o] && void 0 !== s[o][t.property]) {
188 | var a = s[o][t.property];
189 | t.initialValue = a, t.setValue(a)
190 | }
191 | }
192 | }
193 | }
194 |
195 | function f(e, t, n, o) {
196 | if (void 0 === t[n]) throw new Error('Object "' + t + '" has no property "' + n + '"');
197 | var i = void 0;
198 | if (o.color) i = new $(t, n);
199 | else {
200 | var r = [t, n].concat(o.factoryArgs);
201 | i = ne.apply(e, r)
202 | }
203 | o.before instanceof z && (o.before = o.before.__li), p(e, i), X.addClass(i.domElement, "c");
204 | var s = document.createElement("span");
205 | X.addClass(s, "property-name"), s.innerHTML = i.property;
206 | var a = document.createElement("div");
207 | a.appendChild(s), a.appendChild(i.domElement);
208 | var l = c(e, a, o.before);
209 | return X.addClass(l, he.CLASS_CONTROLLER_ROW), i instanceof $ ? X.addClass(l, "color") : X.addClass(l, H(i.getValue())), h(e, l, i), e.__controllers.push(i), i
210 | }
211 |
212 | function m(e, t) {
213 | return document.location.href + "." + t
214 | }
215 |
216 | function g(e, t, n) {
217 | var o = document.createElement("option");
218 | o.innerHTML = t, o.value = t, e.__preset_select.appendChild(o), n && (e.__preset_select.selectedIndex = e.__preset_select.length - 1)
219 | }
220 |
221 | function b(e, t) {
222 | t.style.display = e.useLocalStorage ? "block" : "none"
223 | }
224 |
225 | function v(e) {
226 | var t = e.__save_row = document.createElement("li");
227 | X.addClass(e.domElement, "has-save"), e.__ul.insertBefore(t, e.__ul.firstChild), X.addClass(t, "save-row");
228 | var n = document.createElement("span");
229 | n.innerHTML = " ", X.addClass(n, "button gears");
230 | var o = document.createElement("span");
231 | o.innerHTML = "Save", X.addClass(o, "button"), X.addClass(o, "save");
232 | var i = document.createElement("span");
233 | i.innerHTML = "New", X.addClass(i, "button"), X.addClass(i, "save-as");
234 | var r = document.createElement("span");
235 | r.innerHTML = "Revert", X.addClass(r, "button"), X.addClass(r, "revert");
236 | var s = e.__preset_select = document.createElement("select");
237 | if (e.load && e.load.remembered ? S.each(e.load.remembered, function (t, n) {
238 | g(e, n, n === e.preset)
239 | }) : g(e, se, !1), X.bind(s, "change", function () {
240 | for (var t = 0; t < e.__preset_select.length; t++) e.__preset_select[t].innerHTML = e.__preset_select[t].value;
241 | e.preset = this.value
242 | }), t.appendChild(s), t.appendChild(n), t.appendChild(o), t.appendChild(i), t.appendChild(r), ae) {
243 | var a = document.getElementById("dg-local-explain"),
244 | l = document.getElementById("dg-local-storage");
245 | document.getElementById("dg-save-locally").style.display = "block", "true" === localStorage.getItem(m(e, "isLocal")) && l.setAttribute("checked", "checked"), b(e, a), X.bind(l, "change", function () {
246 | e.useLocalStorage = !e.useLocalStorage, b(e, a)
247 | })
248 | }
249 | var d = document.getElementById("dg-new-constructor");
250 | X.bind(d, "keydown", function (e) {
251 | !e.metaKey || 67 !== e.which && 67 !== e.keyCode || le.hide()
252 | }), X.bind(n, "click", function () {
253 | d.innerHTML = JSON.stringify(e.getSaveObject(), void 0, 2), le.show(), d.focus(), d.select()
254 | }), X.bind(o, "click", function () {
255 | e.save()
256 | }), X.bind(i, "click", function () {
257 | var t = prompt("Enter a new preset name.");
258 | t && e.saveAs(t)
259 | }), X.bind(r, "click", function () {
260 | e.revert()
261 | })
262 | }
263 |
264 | function y(e) {
265 | function t(t) {
266 | return t.preventDefault(), e.width += i - t.clientX, e.onResize(), i = t.clientX, !1
267 | }
268 |
269 | function n() {
270 | X.removeClass(e.__closeButton, he.CLASS_DRAG), X.unbind(window, "mousemove", t), X.unbind(window, "mouseup", n)
271 | }
272 |
273 | function o(o) {
274 | return o.preventDefault(), i = o.clientX, X.addClass(e.__closeButton, he.CLASS_DRAG), X.bind(window, "mousemove", t), X.bind(window, "mouseup", n), !1
275 | }
276 | var i = void 0;
277 | e.__resize_handle = document.createElement("div"), S.extend(e.__resize_handle.style, {
278 | width: "6px",
279 | marginLeft: "-3px",
280 | height: "200px",
281 | cursor: "ew-resize",
282 | position: "absolute"
283 | }), X.bind(e.__resize_handle, "mousedown", o), X.bind(e.__closeButton, "mousedown", o), e.domElement.insertBefore(e.__resize_handle, e.domElement.firstElementChild)
284 | }
285 |
286 | function w(e, t) {
287 | e.domElement.style.width = t + "px", e.__save_row && e.autoPlace && (e.__save_row.style.width = t + "px"), e.__closeButton && (e.__closeButton.style.width = t + "px")
288 | }
289 |
290 | function x(e, t) {
291 | var n = {};
292 | return S.each(e.__rememberedObjects, function (o, i) {
293 | var r = {},
294 | s = e.__rememberedObjectIndecesToControllers[i];
295 | S.each(s, function (e, n) {
296 | r[n] = t ? e.initialValue : e.getValue()
297 | }), n[i] = r
298 | }), n
299 | }
300 |
301 | function E(e) {
302 | for (var t = 0; t < e.__preset_select.length; t++) e.__preset_select[t].value === e.preset && (e.__preset_select.selectedIndex = t)
303 | }
304 |
305 | function C(e) {
306 | 0 !== e.length && oe.call(window, function () {
307 | C(e)
308 | }), S.each(e, function (e) {
309 | e.updateDisplay()
310 | })
311 | }
312 | var A = Array.prototype.forEach,
313 | k = Array.prototype.slice,
314 | S = {
315 | BREAK: {},
316 | extend: function (e) {
317 | return this.each(k.call(arguments, 1), function (t) {
318 | (this.isObject(t) ? Object.keys(t) : []).forEach(function (n) {
319 | this.isUndefined(t[n]) || (e[n] = t[n])
320 | }.bind(this))
321 | }, this), e
322 | },
323 | defaults: function (e) {
324 | return this.each(k.call(arguments, 1), function (t) {
325 | (this.isObject(t) ? Object.keys(t) : []).forEach(function (n) {
326 | this.isUndefined(e[n]) && (e[n] = t[n])
327 | }.bind(this))
328 | }, this), e
329 | },
330 | compose: function () {
331 | var e = k.call(arguments);
332 | return function () {
333 | for (var t = k.call(arguments), n = e.length - 1; n >= 0; n--) t = [e[n].apply(this, t)];
334 | return t[0]
335 | }
336 | },
337 | each: function (e, t, n) {
338 | if (e)
339 | if (A && e.forEach && e.forEach === A) e.forEach(t, n);
340 | else if (e.length === e.length + 0) {
341 | var o = void 0,
342 | i = void 0;
343 | for (o = 0, i = e.length; o < i; o++)
344 | if (o in e && t.call(n, e[o], o) === this.BREAK) return
345 | } else
346 | for (var r in e)
347 | if (t.call(n, e[r], r) === this.BREAK) return
348 | },
349 | defer: function (e) {
350 | setTimeout(e, 0)
351 | },
352 | debounce: function (e, t, n) {
353 | var o = void 0;
354 | return function () {
355 | var i = this,
356 | r = arguments,
357 | s = n || !o;
358 | clearTimeout(o), o = setTimeout(function () {
359 | o = null, n || e.apply(i, r)
360 | }, t), s && e.apply(i, r)
361 | }
362 | },
363 | toArray: function (e) {
364 | return e.toArray ? e.toArray() : k.call(e)
365 | },
366 | isUndefined: function (e) {
367 | return void 0 === e
368 | },
369 | isNull: function (e) {
370 | return null === e
371 | },
372 | isNaN: function (e) {
373 | function t(t) {
374 | return e.apply(this, arguments)
375 | }
376 | return t.toString = function () {
377 | return e.toString()
378 | }, t
379 | }(function (e) {
380 | return isNaN(e)
381 | }),
382 | isArray: Array.isArray || function (e) {
383 | return e.constructor === Array
384 | },
385 | isObject: function (e) {
386 | return e === Object(e)
387 | },
388 | isNumber: function (e) {
389 | return e === e + 0
390 | },
391 | isString: function (e) {
392 | return e === e + ""
393 | },
394 | isBoolean: function (e) {
395 | return !1 === e || !0 === e
396 | },
397 | isFunction: function (e) {
398 | return "[object Function]" === Object.prototype.toString.call(e)
399 | }
400 | },
401 | O = [{
402 | litmus: S.isString,
403 | conversions: {
404 | THREE_CHAR_HEX: {
405 | read: function (e) {
406 | var t = e.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);
407 | return null !== t && {
408 | space: "HEX",
409 | hex: parseInt("0x" + t[1].toString() + t[1].toString() + t[2].toString() + t[2].toString() + t[3].toString() + t[3].toString(), 0)
410 | }
411 | },
412 | write: t
413 | },
414 | SIX_CHAR_HEX: {
415 | read: function (e) {
416 | var t = e.match(/^#([A-F0-9]{6})$/i);
417 | return null !== t && {
418 | space: "HEX",
419 | hex: parseInt("0x" + t[1].toString(), 0)
420 | }
421 | },
422 | write: t
423 | },
424 | CSS_RGB: {
425 | read: function (e) {
426 | var t = e.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
427 | return null !== t && {
428 | space: "RGB",
429 | r: parseFloat(t[1]),
430 | g: parseFloat(t[2]),
431 | b: parseFloat(t[3])
432 | }
433 | },
434 | write: t
435 | },
436 | CSS_RGBA: {
437 | read: function (e) {
438 | var t = e.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
439 | return null !== t && {
440 | space: "RGB",
441 | r: parseFloat(t[1]),
442 | g: parseFloat(t[2]),
443 | b: parseFloat(t[3]),
444 | a: parseFloat(t[4])
445 | }
446 | },
447 | write: t
448 | }
449 | }
450 | }, {
451 | litmus: S.isNumber,
452 | conversions: {
453 | HEX: {
454 | read: function (e) {
455 | return {
456 | space: "HEX",
457 | hex: e,
458 | conversionName: "HEX"
459 | }
460 | },
461 | write: function (e) {
462 | return e.hex
463 | }
464 | }
465 | }
466 | }, {
467 | litmus: S.isArray,
468 | conversions: {
469 | RGB_ARRAY: {
470 | read: function (e) {
471 | return 3 === e.length && {
472 | space: "RGB",
473 | r: e[0],
474 | g: e[1],
475 | b: e[2]
476 | }
477 | },
478 | write: function (e) {
479 | return [e.r, e.g, e.b]
480 | }
481 | },
482 | RGBA_ARRAY: {
483 | read: function (e) {
484 | return 4 === e.length && {
485 | space: "RGB",
486 | r: e[0],
487 | g: e[1],
488 | b: e[2],
489 | a: e[3]
490 | }
491 | },
492 | write: function (e) {
493 | return [e.r, e.g, e.b, e.a]
494 | }
495 | }
496 | }
497 | }, {
498 | litmus: S.isObject,
499 | conversions: {
500 | RGBA_OBJ: {
501 | read: function (e) {
502 | return !!(S.isNumber(e.r) && S.isNumber(e.g) && S.isNumber(e.b) && S.isNumber(e.a)) && {
503 | space: "RGB",
504 | r: e.r,
505 | g: e.g,
506 | b: e.b,
507 | a: e.a
508 | }
509 | },
510 | write: function (e) {
511 | return {
512 | r: e.r,
513 | g: e.g,
514 | b: e.b,
515 | a: e.a
516 | }
517 | }
518 | },
519 | RGB_OBJ: {
520 | read: function (e) {
521 | return !!(S.isNumber(e.r) && S.isNumber(e.g) && S.isNumber(e.b)) && {
522 | space: "RGB",
523 | r: e.r,
524 | g: e.g,
525 | b: e.b
526 | }
527 | },
528 | write: function (e) {
529 | return {
530 | r: e.r,
531 | g: e.g,
532 | b: e.b
533 | }
534 | }
535 | },
536 | HSVA_OBJ: {
537 | read: function (e) {
538 | return !!(S.isNumber(e.h) && S.isNumber(e.s) && S.isNumber(e.v) && S.isNumber(e.a)) && {
539 | space: "HSV",
540 | h: e.h,
541 | s: e.s,
542 | v: e.v,
543 | a: e.a
544 | }
545 | },
546 | write: function (e) {
547 | return {
548 | h: e.h,
549 | s: e.s,
550 | v: e.v,
551 | a: e.a
552 | }
553 | }
554 | },
555 | HSV_OBJ: {
556 | read: function (e) {
557 | return !!(S.isNumber(e.h) && S.isNumber(e.s) && S.isNumber(e.v)) && {
558 | space: "HSV",
559 | h: e.h,
560 | s: e.s,
561 | v: e.v
562 | }
563 | },
564 | write: function (e) {
565 | return {
566 | h: e.h,
567 | s: e.s,
568 | v: e.v
569 | }
570 | }
571 | }
572 | }
573 | }],
574 | T = void 0,
575 | L = void 0,
576 | R = function () {
577 | L = !1;
578 | var e = arguments.length > 1 ? S.toArray(arguments) : arguments[0];
579 | return S.each(O, function (t) {
580 | if (t.litmus(e)) return S.each(t.conversions, function (t, n) {
581 | if (T = t.read(e), !1 === L && !1 !== T) return L = T, T.conversionName = n, T.conversion = t, S.BREAK
582 | }), S.BREAK
583 | }), L
584 | },
585 | B = void 0,
586 | N = {
587 | hsv_to_rgb: function (e, t, n) {
588 | var o = Math.floor(e / 60) % 6,
589 | i = e / 60 - Math.floor(e / 60),
590 | r = n * (1 - t),
591 | s = n * (1 - i * t),
592 | a = n * (1 - (1 - i) * t),
593 | l = [
594 | [n, a, r],
595 | [s, n, r],
596 | [r, n, a],
597 | [r, s, n],
598 | [a, r, n],
599 | [n, r, s]
600 | ][o];
601 | return {
602 | r: 255 * l[0],
603 | g: 255 * l[1],
604 | b: 255 * l[2]
605 | }
606 | },
607 | rgb_to_hsv: function (e, t, n) {
608 | var o = Math.min(e, t, n),
609 | i = Math.max(e, t, n),
610 | r = i - o,
611 | s = void 0,
612 | a = void 0;
613 | return 0 === i ? {
614 | h: NaN,
615 | s: 0,
616 | v: 0
617 | } : (a = r / i, s = e === i ? (t - n) / r : t === i ? 2 + (n - e) / r : 4 + (e - t) / r, (s /= 6) < 0 && (s += 1), {
618 | h: 360 * s,
619 | s: a,
620 | v: i / 255
621 | })
622 | },
623 | rgb_to_hex: function (e, t, n) {
624 | var o = this.hex_with_component(0, 2, e);
625 | return o = this.hex_with_component(o, 1, t), o = this.hex_with_component(o, 0, n)
626 | },
627 | component_from_hex: function (e, t) {
628 | return e >> 8 * t & 255
629 | },
630 | hex_with_component: function (e, t, n) {
631 | return n << (B = 8 * t) | e & ~(255 << B)
632 | }
633 | },
634 | H = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) {
635 | return typeof e
636 | } : function (e) {
637 | return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e
638 | },
639 | F = function (e, t) {
640 | if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function")
641 | },
642 | P = function () {
643 | function e(e, t) {
644 | for (var n = 0; n < t.length; n++) {
645 | var o = t[n];
646 | o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, o.key, o)
647 | }
648 | }
649 | return function (t, n, o) {
650 | return n && e(t.prototype, n), o && e(t, o), t
651 | }
652 | }(),
653 | j = function e(t, n, o) {
654 | null === t && (t = Function.prototype);
655 | var i = Object.getOwnPropertyDescriptor(t, n);
656 | if (void 0 === i) {
657 | var r = Object.getPrototypeOf(t);
658 | return null === r ? void 0 : e(r, n, o)
659 | }
660 | if ("value" in i) return i.value;
661 | var s = i.get;
662 | if (void 0 !== s) return s.call(o)
663 | },
664 | D = function (e, t) {
665 | if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function, not " + typeof t);
666 | e.prototype = Object.create(t && t.prototype, {
667 | constructor: {
668 | value: e,
669 | enumerable: !1,
670 | writable: !0,
671 | configurable: !0
672 | }
673 | }), t && (Object.setPrototypeOf ? Object.setPrototypeOf(e, t) : e.__proto__ = t)
674 | },
675 | V = function (e, t) {
676 | if (!e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
677 | return !t || "object" != typeof t && "function" != typeof t ? e : t
678 | },
679 | I = function () {
680 | function e() {
681 | if (F(this, e), this.__state = R.apply(this, arguments), !1 === this.__state) throw new Error("Failed to interpret color arguments");
682 | this.__state.a = this.__state.a || 1
683 | }
684 | return P(e, [{
685 | key: "toString",
686 | value: function () {
687 | return t(this)
688 | }
689 | }, {
690 | key: "toHexString",
691 | value: function () {
692 | return t(this, !0)
693 | }
694 | }, {
695 | key: "toOriginal",
696 | value: function () {
697 | return this.__state.conversion.write(this)
698 | }
699 | }]), e
700 | }();
701 | I.recalculateRGB = function (e, t, n) {
702 | if ("HEX" === e.__state.space) e.__state[t] = N.component_from_hex(e.__state.hex, n);
703 | else {
704 | if ("HSV" !== e.__state.space) throw new Error("Corrupted color state");
705 | S.extend(e.__state, N.hsv_to_rgb(e.__state.h, e.__state.s, e.__state.v))
706 | }
707 | }, I.recalculateHSV = function (e) {
708 | var t = N.rgb_to_hsv(e.r, e.g, e.b);
709 | S.extend(e.__state, {
710 | s: t.s,
711 | v: t.v
712 | }), S.isNaN(t.h) ? S.isUndefined(e.__state.h) && (e.__state.h = 0) : e.__state.h = t.h
713 | }, I.COMPONENTS = ["r", "g", "b", "h", "s", "v", "hex", "a"], n(I.prototype, "r", 2), n(I.prototype, "g", 1), n(I.prototype, "b", 0), o(I.prototype, "h"), o(I.prototype, "s"), o(I.prototype, "v"), Object.defineProperty(I.prototype, "a", {
714 | get: function () {
715 | return this.__state.a
716 | },
717 | set: function (e) {
718 | this.__state.a = e
719 | }
720 | }), Object.defineProperty(I.prototype, "hex", {
721 | get: function () {
722 | return "HEX" !== !this.__state.space && (this.__state.hex = N.rgb_to_hex(this.r, this.g, this.b)), this.__state.hex
723 | },
724 | set: function (e) {
725 | this.__state.space = "HEX", this.__state.hex = e
726 | }
727 | });
728 | var z = function () {
729 | function e(t, n) {
730 | F(this, e), this.initialValue = t[n], this.domElement = document.createElement("div"), this.object = t, this.property = n, this.__onChange = void 0, this.__onFinishChange = void 0
731 | }
732 | return P(e, [{
733 | key: "onChange",
734 | value: function (e) {
735 | return this.__onChange = e, this
736 | }
737 | }, {
738 | key: "onFinishChange",
739 | value: function (e) {
740 | return this.__onFinishChange = e, this
741 | }
742 | }, {
743 | key: "setValue",
744 | value: function (e) {
745 | return this.object[this.property] = e, this.__onChange && this.__onChange.call(this, e), this.updateDisplay(), this
746 | }
747 | }, {
748 | key: "getValue",
749 | value: function () {
750 | return this.object[this.property]
751 | }
752 | }, {
753 | key: "updateDisplay",
754 | value: function () {
755 | return this
756 | }
757 | }, {
758 | key: "isModified",
759 | value: function () {
760 | return this.initialValue !== this.getValue()
761 | }
762 | }]), e
763 | }(),
764 | M = {
765 | HTMLEvents: ["change"],
766 | MouseEvents: ["click", "mousemove", "mousedown", "mouseup", "mouseover"],
767 | KeyboardEvents: ["keydown"]
768 | },
769 | G = {};
770 | S.each(M, function (e, t) {
771 | S.each(e, function (e) {
772 | G[e] = t
773 | })
774 | });
775 | var U = /(\d+(\.\d+)?)px/,
776 | X = {
777 | makeSelectable: function (e, t) {
778 | void 0 !== e && void 0 !== e.style && (e.onselectstart = t ? function () {
779 | return !1
780 | } : function () {}, e.style.MozUserSelect = t ? "auto" : "none", e.style.KhtmlUserSelect = t ? "auto" : "none", e.unselectable = t ? "on" : "off")
781 | },
782 | makeFullscreen: function (e, t, n) {
783 | var o = n,
784 | i = t;
785 | S.isUndefined(i) && (i = !0), S.isUndefined(o) && (o = !0), e.style.position = "absolute", i && (e.style.left = 0, e.style.right = 0), o && (e.style.top = 0, e.style.bottom = 0)
786 | },
787 | fakeEvent: function (e, t, n, o) {
788 | var i = n || {},
789 | r = G[t];
790 | if (!r) throw new Error("Event type " + t + " not supported.");
791 | var s = document.createEvent(r);
792 | switch (r) {
793 | case "MouseEvents":
794 | var a = i.x || i.clientX || 0,
795 | l = i.y || i.clientY || 0;
796 | s.initMouseEvent(t, i.bubbles || !1, i.cancelable || !0, window, i.clickCount || 1, 0, 0, a, l, !1, !1, !1, !1, 0, null);
797 | break;
798 | case "KeyboardEvents":
799 | var d = s.initKeyboardEvent || s.initKeyEvent;
800 | S.defaults(i, {
801 | cancelable: !0,
802 | ctrlKey: !1,
803 | altKey: !1,
804 | shiftKey: !1,
805 | metaKey: !1,
806 | keyCode: void 0,
807 | charCode: void 0
808 | }), d(t, i.bubbles || !1, i.cancelable, window, i.ctrlKey, i.altKey, i.shiftKey, i.metaKey, i.keyCode, i.charCode);
809 | break;
810 | default:
811 | s.initEvent(t, i.bubbles || !1, i.cancelable || !0)
812 | }
813 | S.defaults(s, o), e.dispatchEvent(s)
814 | },
815 | bind: function (e, t, n, o) {
816 | var i = o || !1;
817 | return e.addEventListener ? e.addEventListener(t, n, i) : e.attachEvent && e.attachEvent("on" + t, n), X
818 | },
819 | unbind: function (e, t, n, o) {
820 | var i = o || !1;
821 | return e.removeEventListener ? e.removeEventListener(t, n, i) : e.detachEvent && e.detachEvent("on" + t, n), X
822 | },
823 | addClass: function (e, t) {
824 | if (void 0 === e.className) e.className = t;
825 | else if (e.className !== t) {
826 | var n = e.className.split(/ +/); - 1 === n.indexOf(t) && (n.push(t), e.className = n.join(" ").replace(/^\s+/, "").replace(/\s+$/, ""))
827 | }
828 | return X
829 | },
830 | removeClass: function (e, t) {
831 | if (t)
832 | if (e.className === t) e.removeAttribute("class");
833 | else {
834 | var n = e.className.split(/ +/),
835 | o = n.indexOf(t); - 1 !== o && (n.splice(o, 1), e.className = n.join(" "))
836 | }
837 | else e.className = void 0;
838 | return X
839 | },
840 | hasClass: function (e, t) {
841 | return new RegExp("(?:^|\\s+)" + t + "(?:\\s+|$)").test(e.className) || !1
842 | },
843 | getWidth: function (e) {
844 | var t = getComputedStyle(e);
845 | return i(t["border-left-width"]) + i(t["border-right-width"]) + i(t["padding-left"]) + i(t["padding-right"]) + i(t.width)
846 | },
847 | getHeight: function (e) {
848 | var t = getComputedStyle(e);
849 | return i(t["border-top-width"]) + i(t["border-bottom-width"]) + i(t["padding-top"]) + i(t["padding-bottom"]) + i(t.height)
850 | },
851 | getOffset: function (e) {
852 | var t = e,
853 | n = {
854 | left: 0,
855 | top: 0
856 | };
857 | if (t.offsetParent)
858 | do {
859 | n.left += t.offsetLeft, n.top += t.offsetTop, t = t.offsetParent
860 | } while (t);
861 | return n
862 | },
863 | isActive: function (e) {
864 | return e === document.activeElement && (e.type || e.href)
865 | }
866 | },
867 | K = function (e) {
868 | function t(e, n) {
869 | F(this, t);
870 | var o = V(this, (t.__proto__ || Object.getPrototypeOf(t)).call(this, e, n)),
871 | i = o;
872 | return o.__prev = o.getValue(), o.__checkbox = document.createElement("input"), o.__checkbox.setAttribute("type", "checkbox"), X.bind(o.__checkbox, "change", function () {
873 | i.setValue(!i.__prev)
874 | }, !1), o.domElement.appendChild(o.__checkbox), o.updateDisplay(), o
875 | }
876 | return D(t, z), P(t, [{
877 | key: "setValue",
878 | value: function (e) {
879 | var n = j(t.prototype.__proto__ || Object.getPrototypeOf(t.prototype), "setValue", this).call(this, e);
880 | return this.__onFinishChange && this.__onFinishChange.call(this, this.getValue()), this.__prev = this.getValue(), n
881 | }
882 | }, {
883 | key: "updateDisplay",
884 | value: function () {
885 | return !0 === this.getValue() ? (this.__checkbox.setAttribute("checked", "checked"), this.__checkbox.checked = !0, this.__prev = !0) : (this.__checkbox.checked = !1, this.__prev = !1), j(t.prototype.__proto__ || Object.getPrototypeOf(t.prototype), "updateDisplay", this).call(this)
886 | }
887 | }]), t
888 | }(),
889 | Y = function (e) {
890 | function t(e, n, o) {
891 | F(this, t);
892 | var i = V(this, (t.__proto__ || Object.getPrototypeOf(t)).call(this, e, n)),
893 | r = o,
894 | s = i;
895 | if (i.__select = document.createElement("select"), S.isArray(r)) {
896 | var a = {};
897 | S.each(r, function (e) {
898 | a[e] = e
899 | }), r = a
900 | }
901 | return S.each(r, function (e, t) {
902 | var n = document.createElement("option");
903 | n.innerHTML = t, n.setAttribute("value", e), s.__select.appendChild(n)
904 | }), i.updateDisplay(), X.bind(i.__select, "change", function () {
905 | var e = this.options[this.selectedIndex].value;
906 | s.setValue(e)
907 | }), i.domElement.appendChild(i.__select), i
908 | }
909 | return D(t, z), P(t, [{
910 | key: "setValue",
911 | value: function (e) {
912 | var n = j(t.prototype.__proto__ || Object.getPrototypeOf(t.prototype), "setValue", this).call(this, e);
913 | return this.__onFinishChange && this.__onFinishChange.call(this, this.getValue()), n
914 | }
915 | }, {
916 | key: "updateDisplay",
917 | value: function () {
918 | return X.isActive(this.__select) ? this : (this.__select.value = this.getValue(), j(t.prototype.__proto__ || Object.getPrototypeOf(t.prototype), "updateDisplay", this).call(this))
919 | }
920 | }]), t
921 | }(),
922 | J = function (e) {
923 | function t(e, n) {
924 | function o() {
925 | r.setValue(r.__input.value)
926 | }
927 | F(this, t);
928 | var i = V(this, (t.__proto__ || Object.getPrototypeOf(t)).call(this, e, n)),
929 | r = i;
930 | return i.__input = document.createElement("input"), i.__input.setAttribute("type", "text"), X.bind(i.__input, "keyup", o), X.bind(i.__input, "change", o), X.bind(i.__input, "blur", function () {
931 | r.__onFinishChange && r.__onFinishChange.call(r, r.getValue())
932 | }), X.bind(i.__input, "keydown", function (e) {
933 | 13 === e.keyCode && this.blur()
934 | }), i.updateDisplay(), i.domElement.appendChild(i.__input), i
935 | }
936 | return D(t, z), P(t, [{
937 | key: "updateDisplay",
938 | value: function () {
939 | return X.isActive(this.__input) || (this.__input.value = this.getValue()), j(t.prototype.__proto__ || Object.getPrototypeOf(t.prototype), "updateDisplay", this).call(this)
940 | }
941 | }]), t
942 | }(),
943 | W = function (e) {
944 | function t(e, n, o) {
945 | F(this, t);
946 | var i = V(this, (t.__proto__ || Object.getPrototypeOf(t)).call(this, e, n)),
947 | s = o || {};
948 | return i.__min = s.min, i.__max = s.max, i.__step = s.step, S.isUndefined(i.__step) ? 0 === i.initialValue ? i.__impliedStep = 1 : i.__impliedStep = Math.pow(10, Math.floor(Math.log(Math.abs(i.initialValue)) / Math.LN10)) / 10 : i.__impliedStep = i.__step, i.__precision = r(i.__impliedStep), i
949 | }
950 | return D(t, z), P(t, [{
951 | key: "setValue",
952 | value: function (e) {
953 | var n = e;
954 | return void 0 !== this.__min && n < this.__min ? n = this.__min : void 0 !== this.__max && n > this.__max && (n = this.__max), void 0 !== this.__step && n % this.__step != 0 && (n = Math.round(n / this.__step) * this.__step), j(t.prototype.__proto__ || Object.getPrototypeOf(t.prototype), "setValue", this).call(this, n)
955 | }
956 | }, {
957 | key: "min",
958 | value: function (e) {
959 | return this.__min = e, this
960 | }
961 | }, {
962 | key: "max",
963 | value: function (e) {
964 | return this.__max = e, this
965 | }
966 | }, {
967 | key: "step",
968 | value: function (e) {
969 | return this.__step = e, this.__impliedStep = e, this.__precision = r(e), this
970 | }
971 | }]), t
972 | }(),
973 | Q = function (e) {
974 | function t(e, n, o) {
975 | function i() {
976 | l.__onFinishChange && l.__onFinishChange.call(l, l.getValue())
977 | }
978 |
979 | function r(e) {
980 | var t = d - e.clientY;
981 | l.setValue(l.getValue() + t * l.__impliedStep), d = e.clientY
982 | }
983 |
984 | function s() {
985 | X.unbind(window, "mousemove", r), X.unbind(window, "mouseup", s), i()
986 | }
987 | F(this, t);
988 | var a = V(this, (t.__proto__ || Object.getPrototypeOf(t)).call(this, e, n, o));
989 | a.__truncationSuspended = !1;
990 | var l = a,
991 | d = void 0;
992 | return a.__input = document.createElement("input"), a.__input.setAttribute("type", "text"), X.bind(a.__input, "change", function () {
993 | var e = parseFloat(l.__input.value);
994 | S.isNaN(e) || l.setValue(e)
995 | }), X.bind(a.__input, "blur", function () {
996 | i()
997 | }), X.bind(a.__input, "mousedown", function (e) {
998 | X.bind(window, "mousemove", r), X.bind(window, "mouseup", s), d = e.clientY
999 | }), X.bind(a.__input, "keydown", function (e) {
1000 | 13 === e.keyCode && (l.__truncationSuspended = !0, this.blur(), l.__truncationSuspended = !1, i())
1001 | }), a.updateDisplay(), a.domElement.appendChild(a.__input), a
1002 | }
1003 | return D(t, W), P(t, [{
1004 | key: "updateDisplay",
1005 | value: function () {
1006 | return this.__input.value = this.__truncationSuspended ? this.getValue() : s(this.getValue(), this.__precision), j(t.prototype.__proto__ || Object.getPrototypeOf(t.prototype), "updateDisplay", this).call(this)
1007 | }
1008 | }]), t
1009 | }(),
1010 | q = function (e) {
1011 | function t(e, n, o, i, r) {
1012 | function s(e) {
1013 | e.preventDefault();
1014 | var t = _.__background.getBoundingClientRect();
1015 | return _.setValue(a(e.clientX, t.left, t.right, _.__min, _.__max)), !1
1016 | }
1017 |
1018 | function l() {
1019 | X.unbind(window, "mousemove", s), X.unbind(window, "mouseup", l), _.__onFinishChange && _.__onFinishChange.call(_, _.getValue())
1020 | }
1021 |
1022 | function d(e) {
1023 | var t = e.touches[0].clientX,
1024 | n = _.__background.getBoundingClientRect();
1025 | _.setValue(a(t, n.left, n.right, _.__min, _.__max))
1026 | }
1027 |
1028 | function c() {
1029 | X.unbind(window, "touchmove", d), X.unbind(window, "touchend", c), _.__onFinishChange && _.__onFinishChange.call(_, _.getValue())
1030 | }
1031 | F(this, t);
1032 | var u = V(this, (t.__proto__ || Object.getPrototypeOf(t)).call(this, e, n, {
1033 | min: o,
1034 | max: i,
1035 | step: r
1036 | })),
1037 | _ = u;
1038 | return u.__background = document.createElement("div"), u.__foreground = document.createElement("div"), X.bind(u.__background, "mousedown", function (e) {
1039 | document.activeElement.blur(), X.bind(window, "mousemove", s), X.bind(window, "mouseup", l), s(e)
1040 | }), X.bind(u.__background, "touchstart", function (e) {
1041 | 1 === e.touches.length && (X.bind(window, "touchmove", d), X.bind(window, "touchend", c), d(e))
1042 | }), X.addClass(u.__background, "slider"), X.addClass(u.__foreground, "slider-fg"), u.updateDisplay(), u.__background.appendChild(u.__foreground), u.domElement.appendChild(u.__background), u
1043 | }
1044 | return D(t, W), P(t, [{
1045 | key: "updateDisplay",
1046 | value: function () {
1047 | var e = (this.getValue() - this.__min) / (this.__max - this.__min);
1048 | return this.__foreground.style.width = 100 * e + "%", j(t.prototype.__proto__ || Object.getPrototypeOf(t.prototype), "updateDisplay", this).call(this)
1049 | }
1050 | }]), t
1051 | }(),
1052 | Z = function (e) {
1053 | function t(e, n, o) {
1054 | F(this, t);
1055 | var i = V(this, (t.__proto__ || Object.getPrototypeOf(t)).call(this, e, n)),
1056 | r = i;
1057 | return i.__button = document.createElement("div"), i.__button.innerHTML = void 0 === o ? "Fire" : o, X.bind(i.__button, "click", function (e) {
1058 | return e.preventDefault(), r.fire(), !1
1059 | }), X.addClass(i.__button, "button"), i.domElement.appendChild(i.__button), i
1060 | }
1061 | return D(t, z), P(t, [{
1062 | key: "fire",
1063 | value: function () {
1064 | this.__onChange && this.__onChange.call(this), this.getValue().call(this.object), this.__onFinishChange && this.__onFinishChange.call(this, this.getValue())
1065 | }
1066 | }]), t
1067 | }(),
1068 | $ = function (e) {
1069 | function t(e, n) {
1070 | function o(e) {
1071 | u(e), X.bind(window, "mousemove", u), X.bind(window, "touchmove", u), X.bind(window, "mouseup", r), X.bind(window, "touchend", r)
1072 | }
1073 |
1074 | function i(e) {
1075 | _(e), X.bind(window, "mousemove", _), X.bind(window, "touchmove", _), X.bind(window, "mouseup", s), X.bind(window, "touchend", s)
1076 | }
1077 |
1078 | function r() {
1079 | X.unbind(window, "mousemove", u), X.unbind(window, "touchmove", u), X.unbind(window, "mouseup", r), X.unbind(window, "touchend", r), c()
1080 | }
1081 |
1082 | function s() {
1083 | X.unbind(window, "mousemove", _), X.unbind(window, "touchmove", _), X.unbind(window, "mouseup", s), X.unbind(window, "touchend", s), c()
1084 | }
1085 |
1086 | function a() {
1087 | var e = R(this.value);
1088 | !1 !== e ? (p.__color.__state = e, p.setValue(p.__color.toOriginal())) : this.value = p.__color.toString()
1089 | }
1090 |
1091 | function c() {
1092 | p.__onFinishChange && p.__onFinishChange.call(p, p.__color.toOriginal())
1093 | }
1094 |
1095 | function u(e) {
1096 | -1 === e.type.indexOf("touch") && e.preventDefault();
1097 | var t = p.__saturation_field.getBoundingClientRect(),
1098 | n = e.touches && e.touches[0] || e,
1099 | o = n.clientX,
1100 | i = n.clientY,
1101 | r = (o - t.left) / (t.right - t.left),
1102 | s = 1 - (i - t.top) / (t.bottom - t.top);
1103 | return s > 1 ? s = 1 : s < 0 && (s = 0), r > 1 ? r = 1 : r < 0 && (r = 0), p.__color.v = s, p.__color.s = r, p.setValue(p.__color.toOriginal()), !1
1104 | }
1105 |
1106 | function _(e) {
1107 | -1 === e.type.indexOf("touch") && e.preventDefault();
1108 | var t = p.__hue_field.getBoundingClientRect(),
1109 | n = 1 - ((e.touches && e.touches[0] || e).clientY - t.top) / (t.bottom - t.top);
1110 | return n > 1 ? n = 1 : n < 0 && (n = 0), p.__color.h = 360 * n, p.setValue(p.__color.toOriginal()), !1
1111 | }
1112 | F(this, t);
1113 | var h = V(this, (t.__proto__ || Object.getPrototypeOf(t)).call(this, e, n));
1114 | h.__color = new I(h.getValue()), h.__temp = new I(0);
1115 | var p = h;
1116 | h.domElement = document.createElement("div"), X.makeSelectable(h.domElement, !1), h.__selector = document.createElement("div"), h.__selector.className = "selector", h.__saturation_field = document.createElement("div"), h.__saturation_field.className = "saturation-field", h.__field_knob = document.createElement("div"), h.__field_knob.className = "field-knob", h.__field_knob_border = "2px solid ", h.__hue_knob = document.createElement("div"), h.__hue_knob.className = "hue-knob", h.__hue_field = document.createElement("div"), h.__hue_field.className = "hue-field", h.__input = document.createElement("input"), h.__input.type = "text", h.__input_textShadow = "0 1px 1px ", X.bind(h.__input, "keydown", function (e) {
1117 | 13 === e.keyCode && a.call(this)
1118 | }), X.bind(h.__input, "blur", a), X.bind(h.__selector, "mousedown", function () {
1119 | X.addClass(this, "drag").bind(window, "mouseup", function () {
1120 | X.removeClass(p.__selector, "drag")
1121 | })
1122 | }), X.bind(h.__selector, "touchstart", function () {
1123 | X.addClass(this, "drag").bind(window, "touchend", function () {
1124 | X.removeClass(p.__selector, "drag")
1125 | })
1126 | });
1127 | var f = document.createElement("div");
1128 | return S.extend(h.__selector.style, {
1129 | width: "122px",
1130 | height: "102px",
1131 | padding: "3px",
1132 | backgroundColor: "#222",
1133 | boxShadow: "0px 1px 3px rgba(0,0,0,0.3)"
1134 | }), S.extend(h.__field_knob.style, {
1135 | position: "absolute",
1136 | width: "12px",
1137 | height: "12px",
1138 | border: h.__field_knob_border + (h.__color.v < .5 ? "#fff" : "#000"),
1139 | boxShadow: "0px 1px 3px rgba(0,0,0,0.5)",
1140 | borderRadius: "12px",
1141 | zIndex: 1
1142 | }), S.extend(h.__hue_knob.style, {
1143 | position: "absolute",
1144 | width: "15px",
1145 | height: "2px",
1146 | borderRight: "4px solid #fff",
1147 | zIndex: 1
1148 | }), S.extend(h.__saturation_field.style, {
1149 | width: "100px",
1150 | height: "100px",
1151 | border: "1px solid #555",
1152 | marginRight: "3px",
1153 | display: "inline-block",
1154 | cursor: "pointer"
1155 | }), S.extend(f.style, {
1156 | width: "100%",
1157 | height: "100%",
1158 | background: "none"
1159 | }), l(f, "top", "rgba(0,0,0,0)", "#000"), S.extend(h.__hue_field.style, {
1160 | width: "15px",
1161 | height: "100px",
1162 | border: "1px solid #555",
1163 | cursor: "ns-resize",
1164 | position: "absolute",
1165 | top: "3px",
1166 | right: "3px"
1167 | }), d(h.__hue_field), S.extend(h.__input.style, {
1168 | outline: "none",
1169 | textAlign: "center",
1170 | color: "#fff",
1171 | border: 0,
1172 | fontWeight: "bold",
1173 | textShadow: h.__input_textShadow + "rgba(0,0,0,0.7)"
1174 | }), X.bind(h.__saturation_field, "mousedown", o), X.bind(h.__saturation_field, "touchstart", o), X.bind(h.__field_knob, "mousedown", o), X.bind(h.__field_knob, "touchstart", o), X.bind(h.__hue_field, "mousedown", i), X.bind(h.__hue_field, "touchstart", i), h.__saturation_field.appendChild(f), h.__selector.appendChild(h.__field_knob), h.__selector.appendChild(h.__saturation_field), h.__selector.appendChild(h.__hue_field), h.__hue_field.appendChild(h.__hue_knob), h.domElement.appendChild(h.__input), h.domElement.appendChild(h.__selector), h.updateDisplay(), h
1175 | }
1176 | return D(t, z), P(t, [{
1177 | key: "updateDisplay",
1178 | value: function () {
1179 | var e = R(this.getValue());
1180 | if (!1 !== e) {
1181 | var t = !1;
1182 | S.each(I.COMPONENTS, function (n) {
1183 | if (!S.isUndefined(e[n]) && !S.isUndefined(this.__color.__state[n]) && e[n] !== this.__color.__state[n]) return t = !0, {}
1184 | }, this), t && S.extend(this.__color.__state, e)
1185 | }
1186 | S.extend(this.__temp.__state, this.__color.__state), this.__temp.a = 1;
1187 | var n = this.__color.v < .5 || this.__color.s > .5 ? 255 : 0,
1188 | o = 255 - n;
1189 | S.extend(this.__field_knob.style, {
1190 | marginLeft: 100 * this.__color.s - 7 + "px",
1191 | marginTop: 100 * (1 - this.__color.v) - 7 + "px",
1192 | backgroundColor: this.__temp.toHexString(),
1193 | border: this.__field_knob_border + "rgb(" + n + "," + n + "," + n + ")"
1194 | }), this.__hue_knob.style.marginTop = 100 * (1 - this.__color.h / 360) + "px", this.__temp.s = 1, this.__temp.v = 1, l(this.__saturation_field, "left", "#fff", this.__temp.toHexString()), this.__input.value = this.__color.toString(), S.extend(this.__input.style, {
1195 | backgroundColor: this.__color.toHexString(),
1196 | color: "rgb(" + n + "," + n + "," + n + ")",
1197 | textShadow: this.__input_textShadow + "rgba(" + o + "," + o + "," + o + ",.7)"
1198 | })
1199 | }
1200 | }]), t
1201 | }(),
1202 | ee = ["-moz-", "-o-", "-webkit-", "-ms-", ""],
1203 | te = {
1204 | load: function (e, t) {
1205 | var n = t || document,
1206 | o = n.createElement("link");
1207 | o.type = "text/css", o.rel = "stylesheet", o.href = e, n.getElementsByTagName("head")[0].appendChild(o)
1208 | },
1209 | inject: function (e, t) {
1210 | var n = t || document,
1211 | o = document.createElement("style");
1212 | o.type = "text/css", o.innerHTML = e;
1213 | var i = n.getElementsByTagName("head")[0];
1214 | try {
1215 | i.appendChild(o)
1216 | } catch (e) {}
1217 | }
1218 | },
1219 | ne = function (e, t) {
1220 | var n = e[t];
1221 | return S.isArray(arguments[2]) || S.isObject(arguments[2]) ? new Y(e, t, arguments[2]) : S.isNumber(n) ? S.isNumber(arguments[2]) && S.isNumber(arguments[3]) ? S.isNumber(arguments[4]) ? new q(e, t, arguments[2], arguments[3], arguments[4]) : new q(e, t, arguments[2], arguments[3]) : S.isNumber(arguments[4]) ? new Q(e, t, {
1222 | min: arguments[2],
1223 | max: arguments[3],
1224 | step: arguments[4]
1225 | }) : new Q(e, t, {
1226 | min: arguments[2],
1227 | max: arguments[3]
1228 | }) : S.isString(n) ? new J(e, t) : S.isFunction(n) ? new Z(e, t, "") : S.isBoolean(n) ? new K(e, t) : null
1229 | },
1230 | oe = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (e) {
1231 | setTimeout(e, 1e3 / 60)
1232 | },
1233 | ie = function () {
1234 | function e() {
1235 | F(this, e), this.backgroundElement = document.createElement("div"), S.extend(this.backgroundElement.style, {
1236 | backgroundColor: "rgba(0,0,0,0.8)",
1237 | top: 0,
1238 | left: 0,
1239 | display: "none",
1240 | zIndex: "1000",
1241 | opacity: 0,
1242 | WebkitTransition: "opacity 0.2s linear",
1243 | transition: "opacity 0.2s linear"
1244 | }), X.makeFullscreen(this.backgroundElement), this.backgroundElement.style.position = "fixed", this.domElement = document.createElement("div"), S.extend(this.domElement.style, {
1245 | position: "fixed",
1246 | display: "none",
1247 | zIndex: "1001",
1248 | opacity: 0,
1249 | WebkitTransition: "-webkit-transform 0.2s ease-out, opacity 0.2s linear",
1250 | transition: "transform 0.2s ease-out, opacity 0.2s linear"
1251 | }), document.body.appendChild(this.backgroundElement), document.body.appendChild(this.domElement);
1252 | var t = this;
1253 | X.bind(this.backgroundElement, "click", function () {
1254 | t.hide()
1255 | })
1256 | }
1257 | return P(e, [{
1258 | key: "show",
1259 | value: function () {
1260 | var e = this;
1261 | this.backgroundElement.style.display = "block", this.domElement.style.display = "block", this.domElement.style.opacity = 0, this.domElement.style.webkitTransform = "scale(1.1)", this.layout(), S.defer(function () {
1262 | e.backgroundElement.style.opacity = 1, e.domElement.style.opacity = 1, e.domElement.style.webkitTransform = "scale(1)"
1263 | })
1264 | }
1265 | }, {
1266 | key: "hide",
1267 | value: function () {
1268 | var e = this,
1269 | t = function t() {
1270 | e.domElement.style.display = "none", e.backgroundElement.style.display = "none", X.unbind(e.domElement, "webkitTransitionEnd", t), X.unbind(e.domElement, "transitionend", t), X.unbind(e.domElement, "oTransitionEnd", t)
1271 | };
1272 | X.bind(this.domElement, "webkitTransitionEnd", t), X.bind(this.domElement, "transitionend", t), X.bind(this.domElement, "oTransitionEnd", t), this.backgroundElement.style.opacity = 0, this.domElement.style.opacity = 0, this.domElement.style.webkitTransform = "scale(1.1)"
1273 | }
1274 | }, {
1275 | key: "layout",
1276 | value: function () {
1277 | this.domElement.style.left = window.innerWidth / 2 - X.getWidth(this.domElement) / 2 + "px", this.domElement.style.top = window.innerHeight / 2 - X.getHeight(this.domElement) / 2 + "px"
1278 | }
1279 | }]), e
1280 | }(),
1281 | re = function (e) {
1282 | if (e && "undefined" != typeof window) {
1283 | var t = document.createElement("style");
1284 | return t.setAttribute("type", "text/css"), t.innerHTML = e, document.head.appendChild(t), e
1285 | }
1286 | }(".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n");
1287 | te.inject(re);
1288 | var se = "Default",
1289 | ae = function () {
1290 | try {
1291 | return !!window.localStorage
1292 | } catch (e) {
1293 | return !1
1294 | }
1295 | }(),
1296 | le = void 0,
1297 | de = !0,
1298 | ce = void 0,
1299 | ue = !1,
1300 | _e = [],
1301 | he = function e(t) {
1302 | var n = this,
1303 | o = t || {};
1304 | this.domElement = document.createElement("div"), this.__ul = document.createElement("ul"), this.domElement.appendChild(this.__ul), X.addClass(this.domElement, "dg"), this.__folders = {}, this.__controllers = [], this.__rememberedObjects = [], this.__rememberedObjectIndecesToControllers = [], this.__listening = [], o = S.defaults(o, {
1305 | closeOnTop: !1,
1306 | autoPlace: !0,
1307 | width: e.DEFAULT_WIDTH
1308 | }), o = S.defaults(o, {
1309 | resizable: o.autoPlace,
1310 | hideable: o.autoPlace
1311 | }), S.isUndefined(o.load) ? o.load = {
1312 | preset: se
1313 | } : o.preset && (o.load.preset = o.preset), S.isUndefined(o.parent) && o.hideable && _e.push(this), o.resizable = S.isUndefined(o.parent) && o.resizable, o.autoPlace && S.isUndefined(o.scrollable) && (o.scrollable = !0);
1314 | var i = ae && "true" === localStorage.getItem(m(this, "isLocal")),
1315 | r = void 0,
1316 | s = void 0;
1317 | if (Object.defineProperties(this, {
1318 | parent: {
1319 | get: function () {
1320 | return o.parent
1321 | }
1322 | },
1323 | scrollable: {
1324 | get: function () {
1325 | return o.scrollable
1326 | }
1327 | },
1328 | autoPlace: {
1329 | get: function () {
1330 | return o.autoPlace
1331 | }
1332 | },
1333 | closeOnTop: {
1334 | get: function () {
1335 | return o.closeOnTop
1336 | }
1337 | },
1338 | preset: {
1339 | get: function () {
1340 | return n.parent ? n.getRoot().preset : o.load.preset
1341 | },
1342 | set: function (e) {
1343 | n.parent ? n.getRoot().preset = e : o.load.preset = e, E(this), n.revert()
1344 | }
1345 | },
1346 | width: {
1347 | get: function () {
1348 | return o.width
1349 | },
1350 | set: function (e) {
1351 | o.width = e, w(n, e)
1352 | }
1353 | },
1354 | name: {
1355 | get: function () {
1356 | return o.name
1357 | },
1358 | set: function (e) {
1359 | o.name = e, s && (s.innerHTML = o.name)
1360 | }
1361 | },
1362 | closed: {
1363 | get: function () {
1364 | return o.closed
1365 | },
1366 | set: function (t) {
1367 | o.closed = t, o.closed ? X.addClass(n.__ul, e.CLASS_CLOSED) : X.removeClass(n.__ul, e.CLASS_CLOSED), this.onResize(), n.__closeButton && (n.__closeButton.innerHTML = t ? e.TEXT_OPEN : e.TEXT_CLOSED)
1368 | }
1369 | },
1370 | load: {
1371 | get: function () {
1372 | return o.load
1373 | }
1374 | },
1375 | useLocalStorage: {
1376 | get: function () {
1377 | return i
1378 | },
1379 | set: function (e) {
1380 | ae && (i = e, e ? X.bind(window, "unload", r) : X.unbind(window, "unload", r), localStorage.setItem(m(n, "isLocal"), e))
1381 | }
1382 | }
1383 | }), S.isUndefined(o.parent)) {
1384 | if (o.closed = !1, X.addClass(this.domElement, e.CLASS_MAIN), X.makeSelectable(this.domElement, !1), ae && i) {
1385 | n.useLocalStorage = !0;
1386 | var a = localStorage.getItem(m(this, "gui"));
1387 | a && (o.load = JSON.parse(a))
1388 | }
1389 | this.__closeButton = document.createElement("div"), this.__closeButton.innerHTML = e.TEXT_CLOSED, X.addClass(this.__closeButton, e.CLASS_CLOSE_BUTTON), o.closeOnTop ? (X.addClass(this.__closeButton, e.CLASS_CLOSE_TOP), this.domElement.insertBefore(this.__closeButton, this.domElement.childNodes[0])) : (X.addClass(this.__closeButton, e.CLASS_CLOSE_BOTTOM), this.domElement.appendChild(this.__closeButton)), X.bind(this.__closeButton, "click", function () {
1390 | n.closed = !n.closed
1391 | })
1392 | } else {
1393 | void 0 === o.closed && (o.closed = !0);
1394 | var l = document.createTextNode(o.name);
1395 | X.addClass(l, "controller-name"), s = c(n, l);
1396 | X.addClass(this.__ul, e.CLASS_CLOSED), X.addClass(s, "title"), X.bind(s, "click", function (e) {
1397 | return e.preventDefault(), n.closed = !n.closed, !1
1398 | }), o.closed || (this.closed = !1)
1399 | }
1400 | o.autoPlace && (S.isUndefined(o.parent) && (de && (ce = document.createElement("div"), X.addClass(ce, "dg"), X.addClass(ce, e.CLASS_AUTO_PLACE_CONTAINER), document.body.appendChild(ce), de = !1), ce.appendChild(this.domElement), X.addClass(this.domElement, e.CLASS_AUTO_PLACE)), this.parent || w(n, o.width)), this.__resizeHandler = function () {
1401 | n.onResizeDebounced()
1402 | }, X.bind(window, "resize", this.__resizeHandler), X.bind(this.__ul, "webkitTransitionEnd", this.__resizeHandler), X.bind(this.__ul, "transitionend", this.__resizeHandler), X.bind(this.__ul, "oTransitionEnd", this.__resizeHandler), this.onResize(), o.resizable && y(this), r = function () {
1403 | ae && "true" === localStorage.getItem(m(n, "isLocal")) && localStorage.setItem(m(n, "gui"), JSON.stringify(n.getSaveObject()))
1404 | }, this.saveToLocalStorageIfPossible = r, o.parent || function () {
1405 | var e = n.getRoot();
1406 | e.width += 1, S.defer(function () {
1407 | e.width -= 1
1408 | })
1409 | }()
1410 | };
1411 | he.toggleHide = function () {
1412 | ue = !ue, S.each(_e, function (e) {
1413 | e.domElement.style.display = ue ? "none" : ""
1414 | })
1415 | }, he.CLASS_AUTO_PLACE = "a", he.CLASS_AUTO_PLACE_CONTAINER = "ac", he.CLASS_MAIN = "main", he.CLASS_CONTROLLER_ROW = "cr", he.CLASS_TOO_TALL = "taller-than-window", he.CLASS_CLOSED = "closed", he.CLASS_CLOSE_BUTTON = "close-button", he.CLASS_CLOSE_TOP = "close-top", he.CLASS_CLOSE_BOTTOM = "close-bottom", he.CLASS_DRAG = "drag", he.DEFAULT_WIDTH = 245, he.TEXT_CLOSED = "Close Controls", he.TEXT_OPEN = "Open Controls", he._keydownHandler = function (e) {
1416 | "text" === document.activeElement.type || 72 !== e.which && 72 !== e.keyCode || he.toggleHide()
1417 | }, X.bind(window, "keydown", he._keydownHandler, !1), S.extend(he.prototype, {
1418 | add: function (e, t) {
1419 | return f(this, e, t, {
1420 | factoryArgs: Array.prototype.slice.call(arguments, 2)
1421 | })
1422 | },
1423 | addColor: function (e, t) {
1424 | return f(this, e, t, {
1425 | color: !0
1426 | })
1427 | },
1428 | remove: function (e) {
1429 | this.__ul.removeChild(e.__li), this.__controllers.splice(this.__controllers.indexOf(e), 1);
1430 | var t = this;
1431 | S.defer(function () {
1432 | t.onResize()
1433 | })
1434 | },
1435 | destroy: function () {
1436 | if (this.parent) throw new Error("Only the root GUI should be removed with .destroy(). For subfolders, use gui.removeFolder(folder) instead.");
1437 | this.autoPlace && ce.removeChild(this.domElement);
1438 | var e = this;
1439 | S.each(this.__folders, function (t) {
1440 | e.removeFolder(t)
1441 | }), X.unbind(window, "keydown", he._keydownHandler, !1), u(this)
1442 | },
1443 | addFolder: function (e) {
1444 | if (void 0 !== this.__folders[e]) throw new Error('You already have a folder in this GUI by the name "' + e + '"');
1445 | var t = {
1446 | name: e,
1447 | parent: this
1448 | };
1449 | t.autoPlace = this.autoPlace, this.load && this.load.folders && this.load.folders[e] && (t.closed = this.load.folders[e].closed, t.load = this.load.folders[e]);
1450 | var n = new he(t);
1451 | this.__folders[e] = n;
1452 | var o = c(this, n.domElement);
1453 | return X.addClass(o, "folder"), n
1454 | },
1455 | removeFolder: function (e) {
1456 | this.__ul.removeChild(e.domElement.parentElement), delete this.__folders[e.name], this.load && this.load.folders && this.load.folders[e.name] && delete this.load.folders[e.name], u(e);
1457 | var t = this;
1458 | S.each(e.__folders, function (t) {
1459 | e.removeFolder(t)
1460 | }), S.defer(function () {
1461 | t.onResize()
1462 | })
1463 | },
1464 | open: function () {
1465 | this.closed = !1
1466 | },
1467 | close: function () {
1468 | this.closed = !0
1469 | },
1470 | onResize: function () {
1471 | var e = this.getRoot();
1472 | if (e.scrollable) {
1473 | var t = X.getOffset(e.__ul).top,
1474 | n = 0;
1475 | S.each(e.__ul.childNodes, function (t) {
1476 | e.autoPlace && t === e.__save_row || (n += X.getHeight(t))
1477 | }), window.innerHeight - t - 20 < n ? (X.addClass(e.domElement, he.CLASS_TOO_TALL), e.__ul.style.height = window.innerHeight - t - 20 + "px") : (X.removeClass(e.domElement, he.CLASS_TOO_TALL), e.__ul.style.height = "auto")
1478 | }
1479 | e.__resize_handle && S.defer(function () {
1480 | e.__resize_handle.style.height = e.__ul.offsetHeight + "px"
1481 | }), e.__closeButton && (e.__closeButton.style.width = e.width + "px")
1482 | },
1483 | onResizeDebounced: S.debounce(function () {
1484 | this.onResize()
1485 | }, 50),
1486 | remember: function () {
1487 | if (S.isUndefined(le) && ((le = new ie).domElement.innerHTML = '
\n\n Here\'s the new load parameter for your GUI\'s constructor:\n\n \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n\n
\n\n
\n\n
'), this.parent) throw new Error("You can only call remember on a top level GUI.");
1488 | var e = this;
1489 | S.each(Array.prototype.slice.call(arguments), function (t) {
1490 | 0 === e.__rememberedObjects.length && v(e), -1 === e.__rememberedObjects.indexOf(t) && e.__rememberedObjects.push(t)
1491 | }), this.autoPlace && w(this, this.width)
1492 | },
1493 | getRoot: function () {
1494 | for (var e = this; e.parent;) e = e.parent;
1495 | return e
1496 | },
1497 | getSaveObject: function () {
1498 | var e = this.load;
1499 | return e.closed = this.closed, this.__rememberedObjects.length > 0 && (e.preset = this.preset, e.remembered || (e.remembered = {}), e.remembered[this.preset] = x(this)), e.folders = {}, S.each(this.__folders, function (t, n) {
1500 | e.folders[n] = t.getSaveObject()
1501 | }), e
1502 | },
1503 | save: function () {
1504 | this.load.remembered || (this.load.remembered = {}), this.load.remembered[this.preset] = x(this), _(this, !1), this.saveToLocalStorageIfPossible()
1505 | },
1506 | saveAs: function (e) {
1507 | this.load.remembered || (this.load.remembered = {}, this.load.remembered[se] = x(this, !0)), this.load.remembered[e] = x(this), this.preset = e, g(this, e, !0), this.saveToLocalStorageIfPossible()
1508 | },
1509 | revert: function (e) {
1510 | S.each(this.__controllers, function (t) {
1511 | this.getRoot().load.remembered ? p(e || this.getRoot(), t) : t.setValue(t.initialValue), t.__onFinishChange && t.__onFinishChange.call(t, t.getValue())
1512 | }, this), S.each(this.__folders, function (e) {
1513 | e.revert(e)
1514 | }), e || _(this.getRoot(), !1)
1515 | },
1516 | listen: function (e) {
1517 | var t = 0 === this.__listening.length;
1518 | this.__listening.push(e), t && C(this.__listening)
1519 | },
1520 | updateDisplay: function () {
1521 | S.each(this.__controllers, function (e) {
1522 | e.updateDisplay()
1523 | }), S.each(this.__folders, function (e) {
1524 | e.updateDisplay()
1525 | })
1526 | }
1527 | });
1528 | var pe = {
1529 | Color: I,
1530 | math: N,
1531 | interpret: R
1532 | },
1533 | fe = {
1534 | Controller: z,
1535 | BooleanController: K,
1536 | OptionController: Y,
1537 | StringController: J,
1538 | NumberController: W,
1539 | NumberControllerBox: Q,
1540 | NumberControllerSlider: q,
1541 | FunctionController: Z,
1542 | ColorController: $
1543 | },
1544 | me = {
1545 | dom: X
1546 | },
1547 | ge = {
1548 | GUI: he
1549 | },
1550 | be = he,
1551 | ve = {
1552 | color: pe,
1553 | controllers: fe,
1554 | dom: me,
1555 | gui: ge,
1556 | GUI: be
1557 | };
1558 | e.color = pe, e.controllers = fe, e.dom = me, e.gui = ge, e.GUI = be, e.default = ve, Object.defineProperty(e, "__esModule", {
1559 | value: !0
1560 | })
1561 | });
--------------------------------------------------------------------------------
/etc/gcx/default.gcx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kopiro/siriwave/744cb00235b7900733efff25dc73b4d1ab77c92d/etc/gcx/default.gcx
--------------------------------------------------------------------------------
/etc/gcx/ios9.gcx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kopiro/siriwave/744cb00235b7900733efff25dc73b4d1ab77c92d/etc/gcx/ios9.gcx
--------------------------------------------------------------------------------
/etc/ios9.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kopiro/siriwave/744cb00235b7900733efff25dc73b4d1ab77c92d/etc/ios9.gif
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Siriwave
7 |
41 |
42 |
43 |
44 |
45 |
SiriwaveJS
46 |
The Apple® Siri wave-form replicated in a JS library.