diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 6540f1c..47965c1 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,76 +1,76 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, sex characteristics, gender identity and expression,
-level of experience, education, socio-economic status, nationality, personal
-appearance, race, religion, or sexual identity and orientation.
-
-## Our Standards
-
-Examples of behavior that contributes to creating a positive environment
-include:
-
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
-* The use of sexualized language or imagery and unwelcome sexual attention or
- advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
- address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
- professional setting
-
-## Our Responsibilities
-
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
-
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
-
-## Scope
-
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at austinthemichaud@gmail.com. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
-
-[homepage]: https://www.contributor-covenant.org
-
-For answers to common questions about this code of conduct, see
-https://www.contributor-covenant.org/faq
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at austinthemichaud@gmail.com. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e04f568..1ef5759 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,11 +1,11 @@
-# Development Workflow
-
-
- Fork Wave.js repo
- Clone to your local computer
- Run "npm i" in the root folder to install dependencies
- Run "npm run test" to start the dev server and code watcher
- Open the src folder and make a change to one of the src files
- Save changes and refresh browser window to see changes
- Push to remote branch and create a pull request to the Wave.js master branch
-
+# Development Workflow
+
+
+ Fork Wave.js repo
+ Clone to your local computer
+ Run "npm i" in the root folder to install dependencies
+ Run "npm run test" to start the dev server and code watcher
+ Open the src folder and make a change to one of the src files
+ Save changes and refresh browser window to see changes
+ Push to remote branch and create a pull request to the Wave.js master branch
+
diff --git a/LICENSE b/LICENSE
index 3728abe..6968e59 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,21 @@
-MIT License
-
-Copyright (c) 2020 Austin Michaud
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+MIT License
+
+Copyright (c) 2020 Austin Michaud
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index 23c0e21..be6abe4 100644
--- a/README.md
+++ b/README.md
@@ -1,101 +1,101 @@
-# [Wave.js](https://foobar404.github.io/Wave.js/#/) ![version](https://img.shields.io/badge/version-1.2.4-purple.svg)
-
-Audio visualizer library for javascript
-(20+ designs).
-
-[DOCUMENTATION](https://foobar404.github.io/Wave.js/#/docs)
-
-[LIVE EXAMPLES](https://foobar404.github.io/Wave.js/#/)
-
-
-# Installation
-
-Install With CDN
-
-```html
-
-```
-
-Or NPM
-
-```html
-npm i @foobar404/wave
-```
-
-# Setup
-
-If your using npm use a default import to include wave.
-
-```javascript
-import Wave from "@foobar404/wave"
-```
-
-Create a new wave object.
-
-```javascript
-var wave = new Wave();
-```
-
-If your working with React, put the wave instance in state.
-
-```javascript
-let [wave] = useState(new Wave());
-```
-
-
-# Usage
-
-Call one of the three main function on the wave object, fromFile, fromStream, fromElement.
-
-```javascript
-wave.fromElement("audio_element_id","canvas_id",{type:"wave"});
-```
-
-# Documentation
-
-View the current documentation for Wave.js here .
-
-Example
-
-```html
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-# Contributor Workflow
-
-
- Fork Wave.js repo.
- Clone to your local computer.
- Run "npm i" in the root folder to install dependencies.
- Run "npm run test" to start the dev server and code watcher.
- Open the src folder and make a change to one of the src files.
- Save changes and refresh browser window to see changes.
- Push to remote branch and create a pull request to the Wave.js master branch.
+# [Wave.js](https://foobar404.github.io/Wave.js/#/)
+
+Audio visualizer library for javascript
+(20+ designs).
+
+[DOCUMENTATION](https://foobar404.github.io/Wave.js/#/docs)
+
+[LIVE EXAMPLES](https://foobar404.github.io/Wave.js/#/)
+
+
+# Installation
+
+Install With CDN
+
+```html
+
+```
+
+Or NPM
+
+```html
+npm i @foobar404/wave
+```
+
+# Setup
+
+If your using npm use a default import to include wave.
+
+```javascript
+import Wave from "@foobar404/wave"
+```
+
+Create a new wave object.
+
+```javascript
+var wave = new Wave();
+```
+
+If your working with React, put the wave instance in state.
+
+```javascript
+let [wave] = useState(new Wave());
+```
+
+
+# Usage
+
+Call one of the three main function on the wave object, fromFile, fromStream, fromElement.
+
+```javascript
+wave.fromElement("audio_element_id","canvas_id",{type:"wave"});
+```
+
+# Documentation
+
+View the current documentation for Wave.js here .
+
+Example
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+# Contributor Workflow
+
+
+ Fork Wave.js repo.
+ Clone to your local computer.
+ Run "npm i" in the root folder to install dependencies.
+ Run "npm run test" to start the dev server and code watcher.
+ Open the src folder and make a change to one of the src files.
+ Save changes and refresh browser window to see changes.
+ Push to remote branch and create a pull request to the Wave.js master branch.
\ No newline at end of file
diff --git a/dist/bundle.cjs.js b/dist/bundle.cjs.js
index e860aae..5f0ab91 100644
--- a/dist/bundle.cjs.js
+++ b/dist/bundle.cjs.js
@@ -1,1300 +1,2479 @@
'use strict';
-function fromElement(element_id, canvas_id, options) {
-
- const waveContext = this;
- let element = document.getElementById(element_id);
- if (!element) return
- element.crossOrigin = "anonymous";
-
- function run() {
- //user gesture has happened
- this.activated = true;
-
- //track current wave for canvas
- this.activeCanvas = this.activeCanvas || {};
- this.activeCanvas[canvas_id] = JSON.stringify(options);
-
- //track elements used so multiple elements use the same data
- this.activeElements[element_id] = this.activeElements[element_id] || {};
- if (this.activeElements[element_id].count) this.activeElements[element_id].count += 1;
- else this.activeElements[element_id].count = 1;
-
- const currentCount = this.activeElements[element_id].count;
-
- //fix "AudioContext already connected" error
- window.$wave = window.$wave || {};
- window.$wave[element.id] = window.$wave[element.id] || {};
-
- let audioCtx = window.$wave[element.id].audioCtx || new AudioContext();
- window.$wave[element.id].audioCtx = audioCtx;
-
- let analyser = window.$wave[element.id].analyzer || audioCtx.createAnalyser();
- window.$wave[element.id].analyser = analyser;
-
- //check if the element has a source already assigned and make sure they point to the same
- //reference because React will make a new element with a different reference
- let source = null;
- if (window.$wave[element.id].source)
- if (window.$wave[element.id].source.mediaElement === element)
- source = window.$wave[element.id].source;
- else
- source = audioCtx.createMediaElementSource(element);
- else
- source = audioCtx.createMediaElementSource(element);
-
- window.$wave[element.id].source = source;
-
- //beep test for ios
- let oscillator = audioCtx.createOscillator();
- oscillator.frequency.value = 1;
- oscillator.connect(audioCtx.destination);
- oscillator.start(0);
- oscillator.stop(0);
-
- source.connect(analyser);
- source.connect(audioCtx.destination);
-
- analyser.fftsize = 32768;
- let bufferLength = analyser.frequencyBinCount;
- let data = new Uint8Array(bufferLength);
- let frameCount = 1;
-
- function renderFrame() {
- //only run one wave visual per canvas
- if (JSON.stringify(options) != this.activeCanvas[canvas_id]) {
- return
- }
-
- //if the element or canvas go out of scope, stop animation
- if (!document.getElementById(element_id) || !document.getElementById(canvas_id))
- return
-
- requestAnimationFrame(renderFrame);
- frameCount++;
-
- //check if this element is the last to be called
- if (!(currentCount < this.activeElements[element_id].count)) {
- analyser.getByteFrequencyData(data);
- this.activeElements[element_id].data = data;
- }
-
- this.visualize(this.activeElements[element_id].data, canvas_id, options, frameCount);
- }
-
- renderFrame = renderFrame.bind(this);
- renderFrame();
-
- }
-
-
- const create = () => {
- //remove all events
- ["touchstart", "touchmove", "touchend", "mouseup", "click", "play"].forEach(event => {
- element.removeEventListener(event, create, { once: true });
- });
-
- run.call(waveContext);
- };
-
- if (this.activated) {
- run.call(waveContext);
- } else {
- //wait for a valid user gesture
- document.body.addEventListener("touchstart", create, { once: true });
- document.body.addEventListener("touchmove", create, { once: true });
- document.body.addEventListener("touchend", create, { once: true });
- document.body.addEventListener("mouseup", create, { once: true });
- document.body.addEventListener("click", create, { once: true });
- element.addEventListener("play", create, { once: true });
- }
-
-
-
+function fromElement(element_id, canvas_id, options) {
+
+ const waveContext = this;
+ let element = document.getElementById(element_id);
+ if (!element) return
+ element.crossOrigin = "anonymous";
+
+ function run() {
+ //user gesture has happened
+ this.activated = true;
+
+ //track current wave for canvas
+ this.activeCanvas = this.activeCanvas || {};
+ this.activeCanvas[canvas_id] = JSON.stringify(options);
+
+ //track elements used so multiple elements use the same data
+ this.activeElements[element_id] = this.activeElements[element_id] || {};
+ if (this.activeElements[element_id].count) this.activeElements[element_id].count += 1;
+ else this.activeElements[element_id].count = 1;
+
+ const currentCount = this.activeElements[element_id].count;
+
+ //fix "AudioContext already connected" error
+ window.$wave = window.$wave || {};
+ window.$wave[element.id] = window.$wave[element.id] || {};
+
+ let audioCtx = window.$wave[element.id].audioCtx || new AudioContext();
+ window.$wave[element.id].audioCtx = audioCtx;
+
+ let analyser = window.$wave[element.id].analyzer || audioCtx.createAnalyser();
+ window.$wave[element.id].analyser = analyser;
+
+ //check if the element has a source already assigned and make sure they point to the same
+ //reference because React will make a new element with a different reference
+ let source = null;
+ if (window.$wave[element.id].source)
+ if (window.$wave[element.id].source.mediaElement === element)
+ source = window.$wave[element.id].source;
+ else
+ source = audioCtx.createMediaElementSource(element);
+ else
+ source = audioCtx.createMediaElementSource(element);
+
+ window.$wave[element.id].source = source;
+
+ //beep test for ios
+ let oscillator = audioCtx.createOscillator();
+ oscillator.frequency.value = 1;
+ oscillator.connect(audioCtx.destination);
+ oscillator.start(0);
+ oscillator.stop(0);
+
+ source.connect(analyser);
+ source.connect(audioCtx.destination);
+
+ analyser.fftsize = 32768;
+ let bufferLength = analyser.frequencyBinCount;
+ let data = new Uint8Array(bufferLength);
+ let frameCount = 1;
+
+ function renderFrame() {
+ //only run one wave visual per canvas
+ if (JSON.stringify(options) != this.activeCanvas[canvas_id]) {
+ return
+ }
+
+ //if the element or canvas go out of scope, stop animation
+ if (!document.getElementById(element_id) || !document.getElementById(canvas_id))
+ return
+
+ requestAnimationFrame(renderFrame);
+ frameCount++;
+
+ //check if this element is the last to be called
+ if (!(currentCount < this.activeElements[element_id].count)) {
+ analyser.getByteFrequencyData(data);
+ this.activeElements[element_id].data = data;
+ }
+
+ this.visualize(this.activeElements[element_id].data, canvas_id, options, frameCount);
+ }
+
+ renderFrame = renderFrame.bind(this);
+ renderFrame();
+
+ }
+
+
+ const create = () => {
+ //remove all events
+ ["touchstart", "touchmove", "touchend", "mouseup", "click", "play"].forEach(event => {
+ element.removeEventListener(event, create, { once: true });
+ });
+
+ run.call(waveContext);
+ };
+
+ if (this.activated) {
+ run.call(waveContext);
+ } else {
+ //wait for a valid user gesture
+ document.body.addEventListener("touchstart", create, { once: true });
+ document.body.addEventListener("touchmove", create, { once: true });
+ document.body.addEventListener("touchend", create, { once: true });
+ document.body.addEventListener("mouseup", create, { once: true });
+ document.body.addEventListener("click", create, { once: true });
+ element.addEventListener("play", create, { once: true });
+ }
+
+
+
}
-function fromFile(file, options = {}) {
- //options
- if (!options.stroke) options.stroke = 10;
-
- let audio = new Audio();
- audio.src = file;
-
- let audioCtx = new AudioContext();
- let analyser = audioCtx.createAnalyser();
-
- let source = audioCtx.createMediaElementSource(audio);
- source.connect(analyser);
-
- analyser.fftSize = 64;
- let bufferLength = analyser.frequencyBinCount;
-
- let file_data;
- let temp_data = new Uint8Array(bufferLength);
- let getWave;
- let fdi = 0;
- let self = this;
-
- audio.addEventListener('loadedmetadata', async function () {
-
- while (audio.duration === Infinity) {
- await new Promise(r => setTimeout(r, 1000));
- audio.currentTime = 10000000 * Math.random();
- }
-
- audio.currentTime = 0;
- audio.play();
- });
-
- audio.onplay = function () {
- let findSize = (size) => {
-
- for (let range = 1; range <= 40; range++) {
- let power = 2 ** range;
-
- if (size <= power) return power;
- }
-
- };
- let d = audio.duration;
- audio.playbackRate = 16;
-
- d = d / audio.playbackRate;
-
- let drawRate = 20; //ms
-
- let size = ((d / (drawRate / 1000)) * (analyser.fftSize / 2));
- size = findSize(size);
- file_data = new Uint8Array(size);
-
-
- getWave = setInterval(function () {
- analyser.getByteFrequencyData(temp_data);
-
- for (let data in temp_data) {
- data = temp_data[data];
- file_data[fdi] = data;
- fdi++;
- }
-
- }, drawRate);
-
-
- };
-
- audio.onended = function () {
-
- if (audio.currentTime === audio.duration && file_data !== undefined) {
-
- clearInterval(getWave);
-
- let canvas = document.createElement("canvas");
- canvas.height = window.innerHeight;
- canvas.width = window.innerWidth;
-
- self.visualize(file_data, canvas, options);
- let image = canvas.toDataURL("image/jpg");
- self.onFileLoad(image);
-
- canvas.remove();
- }
-
- };
-
+function fromFile(file, options = {}) {
+ //options
+ if (!options.stroke) options.stroke = 10;
+
+ let audio = new Audio();
+ audio.src = file;
+
+ let audioCtx = new AudioContext();
+ let analyser = audioCtx.createAnalyser();
+
+ let source = audioCtx.createMediaElementSource(audio);
+ source.connect(analyser);
+
+ analyser.fftSize = 64;
+ let bufferLength = analyser.frequencyBinCount;
+
+ let file_data;
+ let temp_data = new Uint8Array(bufferLength);
+ let getWave;
+ let fdi = 0;
+ let self = this;
+
+ audio.addEventListener('loadedmetadata', async function () {
+
+ while (audio.duration === Infinity) {
+ await new Promise(r => setTimeout(r, 1000));
+ audio.currentTime = 10000000 * Math.random();
+ }
+
+ audio.currentTime = 0;
+ audio.play();
+ });
+
+ audio.onplay = function () {
+ let findSize = (size) => {
+
+ for (let range = 1; range <= 40; range++) {
+ let power = 2 ** range;
+
+ if (size <= power) return power;
+ }
+
+ };
+ let d = audio.duration;
+ audio.playbackRate = 16;
+
+ d = d / audio.playbackRate;
+
+ let drawRate = 20; //ms
+
+ let size = ((d / (drawRate / 1000)) * (analyser.fftSize / 2));
+ size = findSize(size);
+ file_data = new Uint8Array(size);
+
+
+ getWave = setInterval(function () {
+ analyser.getByteFrequencyData(temp_data);
+
+ for (let data in temp_data) {
+ data = temp_data[data];
+ file_data[fdi] = data;
+ fdi++;
+ }
+
+ }, drawRate);
+
+
+ };
+
+ audio.onended = function () {
+
+ if (audio.currentTime === audio.duration && file_data !== undefined) {
+
+ clearInterval(getWave);
+
+ let canvas = document.createElement("canvas");
+ canvas.height = window.innerHeight;
+ canvas.width = window.innerWidth;
+
+ self.visualize(file_data, canvas, options);
+ let image = canvas.toDataURL("image/jpg");
+ self.onFileLoad(image);
+
+ canvas.remove();
+ }
+
+ };
+
}
-function fromStream(stream, canvas_id, options = {}) {
-
- this.current_stream.id = canvas_id;
- this.current_stream.options = options;
-
- let audioCtx, analyser, source;
- if (!this.sources[stream.toString()]) {
- audioCtx = new AudioContext();
- analyser = audioCtx.createAnalyser();
-
- source = audioCtx.createMediaStreamSource(stream);
- source.connect(analyser);
- source.connect(audioCtx.destination); //playback audio
-
- this.sources[stream.toString()] = {
- "audioCtx": audioCtx,
- "analyser": analyser,
- "source": source
- };
- } else {
- cancelAnimationFrame(this.sources[stream.toString()].animation);
- audioCtx = this.sources[stream.toString()].audioCtx;
- analyser = this.sources[stream.toString()].analyser;
- source = this.sources[stream.toString()].source;
- }
-
- analyser.fftsize = 32768;
- let bufferLength = analyser.frequencyBinCount;
- this.current_stream.data = new Uint8Array(bufferLength);
-
- let self = this;
-
- function renderFrame() {
- self.current_stream.animation = requestAnimationFrame(self.current_stream.loop);
- self.sources[stream.toString()].animation = self.current_stream.animation;
- analyser.getByteFrequencyData(self.current_stream.data);
-
- self.visualize(self.current_stream.data, self.current_stream.id, self.current_stream.options);
- }
-
- this.current_stream.loop = renderFrame;
- renderFrame();
-
-}
-
-function stopStream() {
- cancelAnimationFrame(this.current_stream.animation);
-}
-
-function playStream() {
- this.current_stream.loop();
-}
-
-var fromStream$1 = {
- fromStream,
- stopStream,
- playStream
+function fromStream(stream, canvas_id, options = {}) {
+
+ this.current_stream.id = canvas_id;
+ this.current_stream.options = options;
+
+ let audioCtx, analyser, source;
+ if (!this.sources[stream.toString()]) {
+ audioCtx = new AudioContext();
+ analyser = audioCtx.createAnalyser();
+
+ source = audioCtx.createMediaStreamSource(stream);
+ source.connect(analyser);
+ source.connect(audioCtx.destination); //playback audio
+
+ this.sources[stream.toString()] = {
+ "audioCtx": audioCtx,
+ "analyser": analyser,
+ "source": source
+ };
+ } else {
+ cancelAnimationFrame(this.sources[stream.toString()].animation);
+ audioCtx = this.sources[stream.toString()].audioCtx;
+ analyser = this.sources[stream.toString()].analyser;
+ source = this.sources[stream.toString()].source;
+ }
+
+ analyser.fftsize = 32768;
+ let bufferLength = analyser.frequencyBinCount;
+ this.current_stream.data = new Uint8Array(bufferLength);
+
+ let self = this;
+
+ function renderFrame() {
+ self.current_stream.animation = requestAnimationFrame(self.current_stream.loop);
+ self.sources[stream.toString()].animation = self.current_stream.animation;
+ analyser.getByteFrequencyData(self.current_stream.data);
+
+ self.visualize(self.current_stream.data, self.current_stream.id, self.current_stream.options);
+ }
+
+ this.current_stream.loop = renderFrame;
+ renderFrame();
+
+}
+
+function stopStream() {
+ cancelAnimationFrame(this.current_stream.animation);
+}
+
+function playStream() {
+ this.current_stream.loop();
+}
+
+var fromStream$1 = {
+ fromStream,
+ stopStream,
+ playStream
};
-var drawWave = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- const helper = new Helper(ctx);
-
- // data = helper.mutateData(data, "shrink", 200)
- data = helper.mutateData(data, "split", 4)[0];
- data = helper.mutateData(data, "scale", h);
-
- let points = helper.getPoints("line", w, [0, h], data.length, data, { offset: 100 });
- points.start = points.start.slice(0, points.end.length - 1);
- points.start.push([w, h]);
- points.start.push([0, h]);
-
- helper.drawPolygon(points.start, { lineColor: colors[0], color: colors[1], radius: (h * .008) });
-
-
+var drawWave = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ const helper = new Helper(ctx);
+
+ // data = helper.mutateData(data, "shrink", 200)
+ data = helper.mutateData(data, "split", 4)[0];
+ data = helper.mutateData(data, "scale", h);
+
+ let points = helper.getPoints("line", w, [0, h], data.length, data, { offset: 100 });
+ points.start = points.start.slice(0, points.end.length - 1);
+ points.start.push([w, h]);
+ points.start.push([0, h]);
+
+ helper.drawPolygon(points.start, { lineColor: colors[0], color: colors[1], radius: (h * .008) });
+
+
};
-var drawShine = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let cx = w / 2;
- let cy = h / 2;
- let r = h / 4;
- let percent = (h / 2 - r) / 255;
- let point_count = 512;
- let increase = (360 / point_count) * Math.PI / 180;
-
- for (let point = 1; point <= point_count; point++) {
- let p = data[600 % point]; //get value
- p *= percent;
- point++; //start at 1
- let a = point * increase;
-
- let sx = cx + r * Math.cos(a);
- let sy = cy + r * Math.sin(a);
- ctx.moveTo(sx, sy);
-
- let dx = cx + (r + p) * Math.cos(a);
- let dy = cy + (r + p) * Math.sin(a);
- ctx.lineTo(dx, dy);
-
- }
- ctx.stroke();
+var drawShine = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let cx = w / 2;
+ let cy = h / 2;
+ let r = h / 4;
+ let percent = (h / 2 - r) / 255;
+ let point_count = 512;
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = data[600 % point]; //get value
+ p *= percent;
+ point++; //start at 1
+ let a = point * increase;
+
+ let sx = cx + r * Math.cos(a);
+ let sy = cy + r * Math.sin(a);
+ ctx.moveTo(sx, sy);
+
+ let dx = cx + (r + p) * Math.cos(a);
+ let dy = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+
+ }
+ ctx.stroke();
+
+ if (options.colors[1]) {
+ ctx.arc(cx, cy, r * .90, 0, 2 * Math.PI);
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+};
- if (options.colors[1]) {
- ctx.arc(cx, cy, r * .90, 0, 2 * Math.PI);
- ctx.fillStyle = options.colors[1];
- ctx.fill();
- }
+var drawRing = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let cx = w / 2;
+ let cy = h / 2;
+ let r = (h - 10) / 2;
+ let offset = r / 5;
+ let percent = (r - offset) / 255;
+ let point_count = 150;
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ ctx.arc(cx, cy, r, 0, 2 * Math.PI, true);
+
+ let fa = 0;
+ let fx = cx + (r - (data[0] * percent)) * Math.cos(fa);
+ let fy = cy + (r - (data[0] * percent)) * Math.sin(fa);
+ ctx.moveTo(fx, fy);
+
+ let q = 0;
+ for (let point = 0; point < point_count; point++) {
+ q += 1;
+ if (point >= point_count / 2) {
+ q -= 2;
+ }
+
+ let p = data[q]; //get value
+ p *= percent;
+
+ let a = point * increase;
+ let x = cx + (r - p) * Math.cos(a);
+ let y = cy + (r - p) * Math.sin(a);
+
+ ctx.lineTo(x, y);
+ ctx.arc(x, y, 2, 0, 2 * Math.PI);
+
+ }
+ ctx.lineTo(fx, fy);
+
+ ctx.stroke();
+ ctx.fillStyle = options.colors[1] || "#fff0";
+ ctx.fill();
};
-var drawRing = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
+var drawBars = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let point_count = 64;
+ let percent = h / 255;
+ let increase = w / 64;
+ let breakpoint = Math.floor(point_count / options.colors.length);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = data[point]; //get value
+ p *= percent;
+
+ let x = increase * point;
+
+ ctx.moveTo(x, h);
+ ctx.lineTo(x, h - p);
+
+ if (point % breakpoint === 0) {
+ let i = (point / breakpoint) - 1;
+ ctx.strokeStyle = options.colors[i];
+ ctx.stroke();
+ ctx.beginPath();
+ }
+
+ }
+};
- let cx = w / 2;
- let cy = h / 2;
- let r = (h - 10) / 2;
- let offset = r / 5;
- let percent = (r - offset) / 255;
- let point_count = 150;
- let increase = (360 / point_count) * Math.PI / 180;
+var drawDualbars = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let percent = h / 255;
+ let increase = w / 128;
+ let point_count = 128;
+ let min = 5;
+ let breakpoint = Math.floor(point_count / options.colors.length);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = data[point]; //get value
+ p += min;
+ p *= percent;
+
+ let x = increase * point;
+
+ let mid = (h / 2) + (p / 2);
+
+ ctx.moveTo(x, mid);
+ ctx.lineTo(x, mid - p);
+
+ if (point % breakpoint === 0) {
+ let i = (point / breakpoint) - 1;
+ ctx.strokeStyle = options.colors[i];
+ ctx.stroke();
+ ctx.beginPath();
+ }
+
+ }
+};
- ctx.arc(cx, cy, r, 0, 2 * Math.PI, true);
+var drawOrbs = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ const helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "organize").mids;
+ data = helper.mutateData(data, "split", 2)[0];
+ data = helper.mutateData(data, "shrink", 100);
+ data = helper.mutateData(data, "mirror");
+ data = helper.mutateData(data, "scale", h);
+ data = helper.mutateData(data, "amp", .75);
+
+ let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
+ points.start.forEach((start, i) => {
+ helper.drawLine(start, points.end[i], { lineColor: colors[0] });
+
+ helper.drawCircle(start, h * .01, { color: colors[1] || colors[0] });
+ helper.drawCircle(points.end[i], h * .01, { color: colors[1] || colors[0] });
+ });
+};
- let fa = 0;
- let fx = cx + (r - (data[0] * percent)) * Math.cos(fa);
- let fy = cy + (r - (data[0] * percent)) * Math.sin(fa);
- ctx.moveTo(fx, fy);
+var drawFlower = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let min = 5;
+ let r = h / 4;
+ let offset = r / 2;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 128;
+ let percent = (r - offset) / 255;
+ let increase = (360 / point_count) * Math.PI / 180;
+ let breakpoint = Math.floor(point_count / options.colors.length);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = (data[point] + min) * percent;
+ let a = point * increase;
+
+ let sx = cx + (r - (p - offset)) * Math.cos(a);
+ let sy = cy + (r - (p - offset)) * Math.sin(a);
+ ctx.moveTo(sx, sy);
+
+ let dx = cx + (r + p) * Math.cos(a);
+ let dy = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+
+ if (point % breakpoint === 0) {
+ let i = (point / breakpoint) - 1;
+ ctx.strokeStyle = options.colors[i];
+ ctx.stroke();
+ ctx.beginPath();
+ }
+ }
+
+ ctx.stroke();
+};
- let q = 0;
- for (let point = 0; point < point_count; point++) {
- q += 1;
- if (point >= point_count / 2) {
- q -= 2;
- }
+var drawFlowerBlocks = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+ let r = h / 4;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 56;
+ let percent = r / 255;
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = (data[point]) * percent;
+ let a = point * increase;
+
+ let ax = cx + (r - (p / 2)) * Math.cos(a);
+ let ay = cy + (r - (p / 2)) * Math.sin(a);
+ ctx.moveTo(ax, ay);
+
+ let bx = cx + (r + p) * Math.cos(a);
+ let by = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(bx, by);
+
+ let dx = cx + (r + p) * Math.cos(a + increase);
+ let dy = cy + (r + p) * Math.sin(a + increase);
+ ctx.lineTo(dx, dy);
+
+ let ex = cx + (r - (p / 2)) * Math.cos(a + increase);
+ let ey = cy + (r - (p / 2)) * Math.sin(a + increase);
+
+ ctx.lineTo(ex, ey);
+ ctx.lineTo(ax, ay);
+ }
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+
+ ctx.stroke();
+};
- let p = data[q]; //get value
- p *= percent;
+var drawBarsBlocks = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let percent = h / 255;
+ let width = w / 64;
+
+ for (let point = 0; point < 64; point++) {
+ let p = data[point]; //get value
+ p *= percent;
+ let x = width * point;
+
+ ctx.rect(x, h, width, -(p));
+ }
+
+ ctx.fillStyle = options.colors[1] || options.colors[0];
+ ctx.stroke();
+ ctx.fill();
+};
- let a = point * increase;
- let x = cx + (r - p) * Math.cos(a);
- let y = cy + (r - p) * Math.sin(a);
+var drawDualbarsBlocks = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let percent = h / 255;
+ let width = w / 50;
+
+ for (let point = 0; point <= 50; point++) {
+ let p = data[point]; //get value
+ p *= percent;
+ let x = width * point;
+
+ ctx.rect(x, (h / 2) + (p / 2), width, -(p));
+ }
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+
+ ctx.stroke();
+};
- ctx.lineTo(x, y);
- ctx.arc(x, y, 2, 0, 2 * Math.PI);
+var drawStar = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let r = h / 4;
+ let offset = r / 4;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 120;
+ let percent = (r - offset - 35) / (255);
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ let top = [];
+ let bottom = [];
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = ((data[200 % point])) * percent;
+ let a = point * increase;
+
+ let sx = cx + ((r) - p + offset) * Math.cos(a);
+ let sy = cy + ((r) - p + offset) * Math.sin(a);
+ ctx.moveTo(sx, sy);
+ bottom.push({
+ x: sx,
+ y: sy
+ });
+
+ let dx = cx + (r + p + offset) * Math.cos(a);
+ let dy = cy + (r + p + offset) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+ top.push({
+ x: dx,
+ y: dy
+ });
+
+ }
+
+
+ ctx.moveTo(top[0].x, top[0].y);
+ for (let t in top) {
+ t = top[t];
+
+ ctx.lineTo(t.x, t.y);
+ }
+ ctx.closePath();
+
+ ctx.moveTo(bottom[0].x, bottom[0].y);
+ for (let b = bottom.length - 1; b >= 0; b++) {
+ b = bottom[b];
+
+ ctx.lineTo(b.x, b.y);
+ }
+ ctx.closePath();
+
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+ ctx.stroke();
+
+ //inner color
+ ctx.beginPath();
+ ctx.moveTo(bottom[0].x, bottom[0].y);
+ for (let b in bottom) {
+ b = bottom[b];
+
+ ctx.lineTo(b.x, b.y);
+ }
+ ctx.closePath();
+
+
+ if (options.colors[2]) {
+ ctx.fillStyle = options.colors[2];
+ ctx.fill();
+ }
+ ctx.stroke();
+};
- }
- ctx.lineTo(fx, fy);
+var drawRoundWave = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let r = h / 4;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 100;
+ let percent = r / 255;
+ let increase = (360 / point_count) * Math.PI / 180;
+ let p = 0;
+
+ // let z = (data[0] + min + offset) * percent;
+ let sx = cx + (r + p) * Math.cos(0);
+ let sy = cy + (r + p) * Math.sin(0);
+ ctx.moveTo(sx, sy);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = (data[350 % point]) * percent;
+ let a = point * increase;
+
+ let dx = cx + (r + p) * Math.cos(a);
+ let dy = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+ }
+
+ ctx.closePath();
+ ctx.stroke();
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+};
- ctx.stroke();
- ctx.fillStyle = options.colors[1] || "#fff0";
- ctx.fill();
+var drawRings = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ let helper = new Helper(ctx);
+ let minDimension = (h < w) ? h : w;
+
+ data = helper.mutateData(data, "organize");
+ data = [data.mids, data.vocals];
+
+ data[0] = helper.mutateData(data[0], "scale", minDimension / 4);
+ data[1] = helper.mutateData(data[1], "scale", minDimension / 8);
+
+ data[0] = helper.mutateData(data[0], "shrink", 1 / 5);
+ data[0] = helper.mutateData(data[0], "split", 2)[0];
+
+ data[0] = helper.mutateData(data[0], "reverb");
+ data[1] = helper.mutateData(data[1], "reverb");
+
+
+ let outerCircle = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data[0].length, data[0]);
+ let innerCircle = helper.getPoints("circle", minDimension / 4, [w / 2, h / 2], data[1].length, data[1]);
+
+ helper.drawPolygon(outerCircle.end, { close: true, radius: 4, lineColor: colors[0], color: colors[1] });
+ helper.drawPolygon(innerCircle.end, { close: true, radius: 4, lineColor: colors[2], color: colors[3] });
+
+ let middle = ((minDimension / 4) + (minDimension / 2)) / 2;
+ let largerInner = data[1] = helper.mutateData(data[1], "scale", ((minDimension / 4) - (minDimension / 2)));
+ let innerBars = helper.getPoints("circle", middle, [w / 2, h / 2], data[1].length, largerInner);
+ innerBars.start.forEach((start, i) => {
+ helper.drawLine(start, innerBars.end[i], { lineColor: colors[4] || colors[2] });
+ });
};
-var drawBars = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
+var drawShineRings = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+
+ let helper = new Helper(ctx);
+ let minDimension = (h < w) ? h : w;
+
+ data = helper.mutateData(data, "organize");
+ data.vocals = helper.mutateData(data.vocals, "scale", (minDimension / 2) / 2);
+ data.base = helper.mutateData(data.base, "scale", (minDimension / 2) / 2);
+
+ let outerBars = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals);
+ let innerWave = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals, { offset: 100 });
+ let thinLine = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.base.length, data.base, { offset: 100 });
+
+ outerBars.start.forEach((start, i) => {
+ helper.drawLine(start, outerBars.end[i], { lineColor: colors[0] });
+ });
+
+ helper.drawPolygon(innerWave.start, { close: true, lineColor: colors[1], color: colors[3], radius: 5 });
+ helper.drawPolygon(thinLine.start, { close: true, lineColor: colors[2], color: colors[4], radius: 5 });
+};
- let point_count = 64;
- let percent = h / 255;
- let increase = w / 64;
- let breakpoint = Math.floor(point_count / options.colors.length);
+var drawCubes = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ let helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "organize").base;
+
+ data = helper.mutateData(data, "shrink", 20).slice(0, 19);
+ data = helper.mutateData(data, "scale", h);
+
+ let points = helper.getPoints("line", w, [0, h], data.length, data);
+
+ let spacing = 5;
+ let squareSize = (w / 20) - spacing;
+ let colorIndex = 0;
+
+ points.start.forEach((start, i) => {
+ let squareCount = Math.ceil(data[i] / squareSize);
+
+ //find color stops from total possible squares in bar
+ let totalSquares = (h - (spacing * (h / squareSize))) / squareSize;
+ let colorStop = Math.ceil(totalSquares / colors.length);
+
+ for (let j = 1; j <= squareCount; j++) {
+ let origin = [start[0], (start[1] - (squareSize * j) - (spacing * j))];
+ helper.drawSquare(origin, squareSize, { color: colors[colorIndex], lineColor: "black" });
+ if (j % colorStop == 0) {
+ colorIndex++;
+ if (colorIndex >= colors.length) colorIndex = colors.length - 1;
+ }
+ }
+ colorIndex = 0;
+ });
+};
- for (let point = 1; point <= point_count; point++) {
- let p = data[point]; //get value
- p *= percent;
+var drawBigBars = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ const helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "organize").vocals;
+ data = helper.mutateData(data, "shrink", 10);
+ data = helper.mutateData(data, "scale", h);
+ data = helper.mutateData(data, "amp", 1);
+ let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
+
+ let colorIndex = 0;
+ let colorStop = Math.ceil(data.length / colors.length);
+ points.start.forEach((start, i) => {
+ if ((i + 1) % colorStop == 0) colorIndex++;
+ helper.drawRectangle(start, data[i], w / data.length, { color: colors[colorIndex] });
+ });
+
+};
- let x = increase * point;
+var drawShockwave = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+
+ let helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "shrink", 300);
+ data = helper.mutateData(data, "scale", h / 2);
+ data = helper.mutateData(data, "split", 4).slice(0, 3);
+
+ let colorIndex = 0;
+ data.forEach((points) => {
+ let wavePoints = helper.getPoints("line", w, [0, h / 2], points.length, points);
+ helper.drawPolygon(wavePoints.end, { lineColor: colors[colorIndex], radius: (h * .015) });
+
+ let invertedPoints = helper.getPoints("line", w, [0, h / 2], points.length, points, { offset: 100 });
+ helper.drawPolygon(invertedPoints.start, { lineColor: colors[colorIndex], radius: (h * .015) });
+ colorIndex++;
+ });
+};
- ctx.moveTo(x, h);
- ctx.lineTo(x, h - p);
+var drawFireworks = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ const helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "shrink", 200).slice(0, 120);
+ data = helper.mutateData(data, "mirror");
+ data = helper.mutateData(data, "scale", (h / 4) + ((h / 4) * .35));
+
+ let points = helper.getPoints("circle", h / 2, [w / 2, h / 2], data.length, data, { offset: 35, rotate: 270 });
+
+ points.start.forEach((start, i) => {
+ helper.drawLine(start, points.end[i]);
+ });
+
+ helper.drawPolygon(points.start, { close: true });
+
+ points.end.forEach((end, i) => {
+ helper.drawCircle(end, h * .01, { color: colors[0] });
+ });
+};
- if (point % breakpoint === 0) {
- let i = (point / breakpoint) - 1;
- ctx.strokeStyle = options.colors[i];
- ctx.stroke();
- ctx.beginPath();
- }
+var drawStatic = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "shrink", 1 / 8);
+ data = helper.mutateData(data, "split", 2)[0];
+ data = helper.mutateData(data, "scale", h);
+
+ let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
+ let prevPoint = null;
+ points.start.forEach((start, i) => {
+ if (prevPoint) {
+ helper.drawLine(prevPoint, start);
+ }
+ helper.drawLine(start, points.end[i]);
+ prevPoint = points.end[i];
+ });
+
+
+};
- }
+var drawWeb = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ const helper = new Helper(ctx);
+ let minDimension = (h < w) ? h : w;
+
+ data = helper.mutateData(data, "shrink", 100);
+ data = helper.mutateData(data, "split", 2)[0];
+ data = helper.mutateData(data, "scale", h / 4);
+
+ let dataCopy = data;
+
+ let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
+ helper.drawPolygon(points.end, { close: true });
+
+ points.start.forEach((start, i) => {
+ helper.drawLine(start, points.end[i]);
+ });
+
+ data = helper.mutateData(data, "scale", .7);
+ points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
+ helper.drawPolygon(points.end, { close: true });
+
+ data = helper.mutateData(data, "scale", .3);
+ points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
+ helper.drawPolygon(points.end, { close: true });
+
+ helper.drawCircle([w / 2, h / 2], minDimension / 2, { color: colors[2] });
+
+ dataCopy = helper.mutateData(dataCopy, "scale", 1.4);
+ points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], dataCopy.length, dataCopy);
+ points.end.forEach((end, i) => {
+ helper.drawCircle(end, minDimension * .01, { color: colors[1], lineColor: colors[1] || colors[0] });
+ });
};
-var drawDualbars = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
+var drawStitches = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let helper = new Helper(ctx);
+ let minDimension = (h < w) ? h : w;
+
+ data = helper.mutateData(data, "shrink", 200);
+ data = helper.mutateData(data, "split", 2)[0];
+ data = helper.mutateData(data, "scale", h / 2);
+
+ let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data, { offset: 50 });
+
+ helper.drawPolygon(points.end, { close: true });
+ helper.drawPolygon(points.start, { close: true });
+
+ for (let i = 0; i < points.start.length; i += 1) {
+ let start = points.start[i];
+ i++;
+ let end = points.end[i] || points.end[0];
+
+ helper.drawLine(start, end);
+ helper.drawLine(end, points.start[i + 1] || points.start[0]);
+ }
+};
- let percent = h / 255;
- let increase = w / 128;
- let point_count = 128;
- let min = 5;
- let breakpoint = Math.floor(point_count / options.colors.length);
+var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
- for (let point = 1; point <= point_count; point++) {
- let p = data[point]; //get value
- p += min;
- p *= percent;
+function createCommonjsModule(fn, module) {
+ return module = { exports: {} }, fn(module, module.exports), module.exports;
+}
- let x = increase * point;
+var origami_1 = createCommonjsModule(function (module, exports) {
+/*!
+ * Origami.js 0.5.0
+ * https://origamijs.com/
+ *
+ * Copyright Raphael Amorim 2016
+ * Released under the GPL-4.0 license
+ *
+ * Date: 2016-09-23T03:42Z
+ */
+
+(function( window ) {
+
+/**
+ * Config object: Maintain internal state
+ * Later exposed as Origami.config
+ * `config` initialized at top of scope
+ */
+
+var Origami = {
+ // Current Paper
+ paper: null
+};
- let mid = (h / 2) + (p / 2);
+var config = {
+ // Document Styles
+ documentStyles: [],
- ctx.moveTo(x, mid);
- ctx.lineTo(x, mid - p);
+ // Virtual Styles
+ virtualStyles: {},
- if (point % breakpoint === 0) {
- let i = (point / breakpoint) - 1;
- ctx.strokeStyle = options.colors[i];
- ctx.stroke();
- ctx.beginPath();
- }
+ // All contexts saved
+ contexts: [],
+ // Origami Shapes Defaults
+ defaults: {
+ arc: {
+ background: 'rgba(0, 0, 0, 0)',
+ strokeStyle: 'rgba(0, 0, 0, 0)',
+ lineWidth: null,
+ },
+ rect: {
+ background: 'rgba(0, 0, 0, 0)',
+ strokeStyle: 'rgba(0, 0, 0, 0)',
+ lineWidth: null,
+ },
+ polygon: {
+ background: 'rgba(0, 0, 0, 0)',
+ strokeStyle: 'rgba(0, 0, 0, 0)',
+ lineWidth: null,
+ },
+ line: {
+ strokeStyle: 'rgba(0, 0, 0, 0)',
+ lineWidth: null,
+ },
+ text: {
+ font: '14px Helvetica',
+ strokeStyle: 'rgba(0, 0, 0, 0)',
+ color: '#000',
+ lineWidth: null,
}
+ }
};
-var drawOrbs = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- const helper = new Helper(ctx);
+var prefix = "[origami.js]";
- data = helper.mutateData(data, "organize").mids;
- data = helper.mutateData(data, "split", 2)[0];
- data = helper.mutateData(data, "shrink", 100);
- data = helper.mutateData(data, "mirror");
- data = helper.mutateData(data, "scale", h);
- data = helper.mutateData(data, "amp", .75);
+Origami.warning = function warning(message, obj){
+ if (console && console.warn)
+ console.warn(prefix, message, obj);
+};
- let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
- points.start.forEach((start, i) => {
- helper.drawLine(start, points.end[i], { lineColor: colors[0] });
+Origami.error = function error(message){
+ throw new Error(prefix.concat(' ' + message));
+};
+Origami.init = function(el) {
+ if (el.canvas) {
+ el = el.canvas;
+ } else {
+ el = document.querySelector(el);
+ }
+
+ if (!el)
+ this.error('Please use a valid selector or canvas context');
+
+ var existentContext = exists(el, config.contexts);
+ if (existentContext) {
+ this.paper = existentContext;
+ return this;
+ }
+
+ if (!el.getContext)
+ this.error('Please verify if it\'s a valid canvas element');
+
+ el.width = el.clientWidth;
+ el.height = el.clientHeight;
+ var context = el.getContext('2d');
+ var current = {
+ element: el,
+ queue: [],
+ index: config.contexts.length,
+ flip: false,
+ frame: null,
+ ctx: context,
+ width: el.width,
+ height: el.height,
+ };
+
+ config.contexts.push(current);
+ this.paper = current;
+ return this;
+};
- helper.drawCircle(start, h * .01, { color: colors[1] || colors[0] });
- helper.drawCircle(points.end[i], h * .01, { color: colors[1] || colors[0] });
- });
+Origami.styles = function() {
+ if (!config.virtualStyles.length)
+ defineDocumentStyles();
+
+ var selectors = arguments;
+ if (!selectors.length) {
+ config.virtualStyles['empty'] = true;
+ return this;
+ }
+
+ for (var i = 0; i < selectors.length; i++) {
+ var style = styleRuleValueFrom(selectors[i], (config.documentStyles[0] || []));
+ config.virtualStyles[selectors[i]] = style;
+ }
+ return this;
};
-var drawFlower = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let min = 5;
- let r = h / 4;
- let offset = r / 2;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 128;
- let percent = (r - offset) / 255;
- let increase = (360 / point_count) * Math.PI / 180;
- let breakpoint = Math.floor(point_count / options.colors.length);
-
- for (let point = 1; point <= point_count; point++) {
- let p = (data[point] + min) * percent;
- let a = point * increase;
-
- let sx = cx + (r - (p - offset)) * Math.cos(a);
- let sy = cy + (r - (p - offset)) * Math.sin(a);
- ctx.moveTo(sx, sy);
-
- let dx = cx + (r + p) * Math.cos(a);
- let dy = cy + (r + p) * Math.sin(a);
- ctx.lineTo(dx, dy);
-
- if (point % breakpoint === 0) {
- let i = (point / breakpoint) - 1;
- ctx.strokeStyle = options.colors[i];
- ctx.stroke();
- ctx.beginPath();
- }
- }
+Origami.getPaper = function() {
+ return this.paper;
+};
- ctx.stroke();
+Origami.canvasCtx = function() {
+ return this.paper.ctx;
};
-var drawFlowerBlocks = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
- let r = h / 4;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 56;
- let percent = r / 255;
- let increase = (360 / point_count) * Math.PI / 180;
+Origami.getContexts = function() {
+ return config.contexts;
+};
- for (let point = 1; point <= point_count; point++) {
- let p = (data[point]) * percent;
- let a = point * increase;
+Origami.cleanContexts = function() {
+ config.contexts = [];
+};
- let ax = cx + (r - (p / 2)) * Math.cos(a);
- let ay = cy + (r - (p / 2)) * Math.sin(a);
- ctx.moveTo(ax, ay);
+Origami.createComponent = function(component, fn) {
+ Origami[component] = function(props) {
+ fn.bind(this, this, props)();
+ return this;
+ };
+};
- let bx = cx + (r + p) * Math.cos(a);
- let by = cy + (r + p) * Math.sin(a);
- ctx.lineTo(bx, by);
+Origami.fn = {};
- let dx = cx + (r + p) * Math.cos(a + increase);
- let dy = cy + (r + p) * Math.sin(a + increase);
- ctx.lineTo(dx, dy);
+Origami.draw = function(options) {
+ var self = this,
+ customRender = false,
+ ctx = self.paper.ctx;
- let ex = cx + (r - (p / 2)) * Math.cos(a + increase);
- let ey = cy + (r - (p / 2)) * Math.sin(a + increase);
+ if (typeof(options) === 'string') {
+ customRender = new origami.fn[options](self.paper);
+ self.paper['ctx'] = customRender;
+ }
- ctx.lineTo(ex, ey);
- ctx.lineTo(ax, ay);
- }
+ var abs = new Screen(self.paper),
+ queueList = self.paper.queue;
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
+ for (var i = 0; i < queueList.length; i++) {
+ if (queueList[i].loaded === false || queueList[i].failed) {
+ Origami.warning('couldn\'t able to load:', queueList[i].params);
}
+ abs[queueList[i].assign](queueList[i].params);
+ }
+ self.paper.queue = [];
- ctx.stroke();
-};
-
-var drawBarsBlocks = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
+ if (customRender) {
+ customRender.draw();
+ self.paper.ctx = ctx;
+ }
- let percent = h / 255;
- let width = w / 64;
-
- for (let point = 0; point < 64; point++) {
- let p = data[point]; //get value
- p *= percent;
- let x = width * point;
-
- ctx.rect(x, h, width, -(p));
- }
-
- ctx.fillStyle = options.colors[1] || options.colors[0];
- ctx.stroke();
- ctx.fill();
+ if (typeof(options) === 'function')
+ options();
};
-var drawDualbarsBlocks = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let percent = h / 255;
- let width = w / 50;
-
- for (let point = 0; point <= 50; point++) {
- let p = data[point]; //get value
- p *= percent;
- let x = width * point;
-
- ctx.rect(x, (h / 2) + (p / 2), width, -(p));
- }
+Origami.load = function(fn) {
+ var mOrigami = clone(this);
+ mOrigami.paper = this.paper;
+ var loadInterval = setInterval(function() {
+ var dataLoad = mOrigami.paper.queue.filter(function(item) {
+ return (item.loaded === false && !item.failed);
+ });
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
+ // When already loaded
+ if (!dataLoad.length) {
+ clearInterval(loadInterval);
+ fn.bind(mOrigami, mOrigami)();
}
-
- ctx.stroke();
+ }, 1);
};
-var drawStar = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let r = h / 4;
- let offset = r / 4;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 120;
- let percent = (r - offset - 35) / (255);
- let increase = (360 / point_count) * Math.PI / 180;
+function Queue(assign, params, loaded) {
+ this.paper.queue.push({
+ assign: assign,
+ params: params,
+ loaded: loaded
+ });
+}
- let top = [];
- let bottom = [];
+var queue = Queue.bind(Origami);
- for (let point = 1; point <= point_count; point++) {
- let p = ((data[200 % point])) * percent;
- let a = point * increase;
+// Utilities.js
- let sx = cx + ((r) - p + offset) * Math.cos(a);
- let sy = cy + ((r) - p + offset) * Math.sin(a);
- ctx.moveTo(sx, sy);
- bottom.push({
- x: sx,
- y: sy
- });
+var hasOwn = Object.prototype.hasOwnProperty;
- let dx = cx + (r + p + offset) * Math.cos(a);
- let dy = cy + (r + p + offset) * Math.sin(a);
- ctx.lineTo(dx, dy);
- top.push({
- x: dx,
- y: dy
- });
+/**
+ * Check if element exists in a Array of NodeItems
+ * @param {NodeItem} current nodeItem to check
+ * @param {Array} array of NodeItems
+ * @returns {NodeItem} NodeItem exitent in array
+ */
+function exists(el, arr) {
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i].element.isEqualNode(el))
+ return arr[i];
+ }
+ return false;
+}
- }
+/**
+ * Filter arguments by rules
+ * @param {Array} methods arguments
+ * @param {Object} rules to apply
+ * @returns {Object} arguments filtered
+ */
+function argsByRules(argsArray, rules) {
+ var params = rules || ['x', 'y', 'width', 'height'],
+ args = {};
+
+ for (var i = 0; i < argsArray.length; i++) {
+ if (typeof(argsArray[i]) === "object")
+ args["style"] = argsArray[i];
+ else
+ if (params.length)
+ args[params.shift()] = argsArray[i];
+ }
+
+ args.style = normalizeStyle(args.style);
+
+ if ((typeof(args.x) === 'string') && (typeof(args.y) === 'string'))
+ args = smartCoordinates(args);
+
+ return args;
+}
+function getBorderStyleObject(prop) {
+ return normalizeStyle({border: prop});
+}
- ctx.moveTo(top[0].x, top[0].y);
- for (let t in top) {
- t = top[t];
+function normalizeStyle(style) {
+ if (!style)
+ style = {};
+
+ var borderSize = (style.borderSize || null),
+ borderColor = (style.borderColor || null),
+ borderStyle = (style.borderStyle || []);
+
+ if (style.border) {
+ var border = [],
+ borderString = style.border;
+
+ // 0 - Size: [0-9]px
+ border = border.concat(style.border.match(/[0-9]*\.?[0-9]px?/i));
+ borderString = borderString.replace(/[0-9]*\.?[0-9]px?/i, '');
+
+ // 1 - Style
+ border = border.concat(borderString.match(/solid|dashed|dotted/i));
+ borderString = borderString.replace(/solid|dashed|dotted/i, '');
+
+ // 2 - Color
+ border = border.concat(borderString.match(/[^\s]+/i));
+
+ if (!borderSize)
+ borderSize = border[0];
+ if (!borderColor)
+ borderColor = border[2];
+
+ borderStyle = border[1];
+ }
+
+ if (borderSize)
+ borderSize = borderSize.replace(/[^0-9]/g, '');
+
+ if (typeof(borderStyle) === 'string') {
+ if (borderStyle === 'dashed')
+ borderStyle = [12];
+ else if (borderStyle === 'dotted')
+ borderStyle = [3];
+ else
+ borderStyle = [];
+ }
+
+ style['borderSize'] = borderSize;
+ style['borderStyle'] = borderStyle;
+ style['borderColor'] = borderColor;
+ return style;
+}
- ctx.lineTo(t.x, t.y);
- }
- ctx.closePath();
+/**
+ * Return args object with new coordinates based on behavior
+ * @returns {Object} args
+ */
+function smartCoordinates(args) {
+ var x = args.x,
+ y = args.y;
+
+ var paper = Origami.getPaper(),
+ elmWidth = paper.element.width,
+ elmHeight = paper.element.height,
+ radius = (args.r || 0);
+
+ var width = (args.width || radius),
+ height = (args.height || width);
+
+ var axis = {
+ x: [ 'right', 'center', 'left' ],
+ y: [ 'top', 'center', 'bottom' ]
+ };
+
+ if (axis.x.indexOf(x) !== -1) {
+ if (x === 'right')
+ x = Math.floor(elmWidth - width);
+ else if (x === 'center')
+ if (radius)
+ x = Math.floor(elmWidth / 2);
+ else
+ x = Math.floor((elmWidth / 2) - (width / 2));
+ else if (x === 'left')
+ x = radius;
+ } else if ((x + '').substr(-1) === '%') {
+ x = (elmWidth * parseInt(x, 10)) / 100;
+ } else {
+ x = 0;
+ }
+
+ if (axis.y.indexOf(y) !== -1) {
+ if (y === 'top')
+ y = radius;
+ else if (y === 'center')
+ if (radius)
+ y = Math.floor(elmHeight / 2);
+ else
+ y = Math.floor((elmHeight / 2) - (height / 2));
+ else if (y === 'bottom')
+ y = Math.floor(elmHeight - height);
+ } else if ((y + '').substr(-1) === '%') {
+ y = (elmHeight * parseInt(y, 10)) / 100;
+ } else {
+ y = 0;
+ }
+
+ args.y = y;
+ args.x = x;
+ return args;
+}
- ctx.moveTo(bottom[0].x, bottom[0].y);
- for (let b = bottom.length - 1; b >= 0; b++) {
- b = bottom[b];
+/**
+ * Return all documentStyles to a especified origami context
+ * @returns undefined
+ */
+function defineDocumentStyles() {
+ for (var i = 0; i < document.styleSheets.length; i++) {
+ var mysheet = document.styleSheets[i],
+ myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
+ config.documentStyles.push(myrules);
+ }
+}
- ctx.lineTo(b.x, b.y);
+/**
+ * Merge defaults with user options
+ * @param {Object} defaults Default settings
+ * @param {Object} options User options
+ * @returns {Object} Merged values of defaults and options
+ */
+function extend(a, b, undefOnly) {
+ for (var prop in b) {
+ if (hasOwn.call(b, prop)) {
+
+ // Avoid "Member not found" error in IE8 caused by messing with window.constructor
+ // This block runs on every environment, so `global` is being used instead of `window`
+ // to avoid errors on node.
+ if (prop !== "constructor" || a !== commonjsGlobal) {
+ if (b[prop] === undefined) {
+ delete a[prop];
+ } else if (!(undefOnly && typeof a[prop] !== "undefined")) {
+ a[prop] = b[prop];
+ }
+ }
}
- ctx.closePath();
-
+ }
+ return a;
+}
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
+/**
+ * Get Style Rule from a specified element
+ * @param {String} selector from element
+ * @param {Array} Document Style Rules
+ * @returns {Object} Merged values of defaults and options
+ */
+function styleRuleValueFrom(selector, documentStyleRules) {
+ for (var j = 0; j < documentStyleRules.length; j++) {
+ if (documentStyleRules[j].selectorText && documentStyleRules[j].selectorText.toLowerCase() === selector) {
+ return documentStyleRules[j].style;
}
- ctx.stroke();
-
- //inner color
- ctx.beginPath();
- ctx.moveTo(bottom[0].x, bottom[0].y);
- for (let b in bottom) {
- b = bottom[b];
+ }
+}
- ctx.lineTo(b.x, b.y);
- }
- ctx.closePath();
+/**
+ * Clone a object
+ * @param {Object} object
+ * @returns {Object} cloned object
+ */
+function clone(obj) {
+ if (null == obj || "object" != typeof obj) return obj;
+ var copy = obj.constructor();
+ for (var attr in obj) {
+ if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
+ }
+ return copy;
+}
+function Screen(currentContext) {
+ this.paper = currentContext;
+}
- if (options.colors[2]) {
- ctx.fillStyle = options.colors[2];
- ctx.fill();
- }
- ctx.stroke();
+Screen.prototype.translate = function(params) {
+ this.paper.ctx.translate(params.x, params.y);
};
-var drawRoundWave = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let r = h / 4;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 100;
- let percent = r / 255;
- let increase = (360 / point_count) * Math.PI / 180;
- let p = 0;
-
- // let z = (data[0] + min + offset) * percent;
- let sx = cx + (r + p) * Math.cos(0);
- let sy = cy + (r + p) * Math.sin(0);
- ctx.moveTo(sx, sy);
-
- for (let point = 1; point <= point_count; point++) {
- let p = (data[350 % point]) * percent;
- let a = point * increase;
-
- let dx = cx + (r + p) * Math.cos(a);
- let dy = cy + (r + p) * Math.sin(a);
- ctx.lineTo(dx, dy);
- }
-
- ctx.closePath();
- ctx.stroke();
-
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
- }
+Screen.prototype.background = function(params) {
+ this.paper.element.style.backgroundColor = params.color;
};
-var drawRings = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- let helper = new Helper(ctx);
- let minDimension = (h < w) ? h : w;
-
- data = helper.mutateData(data, "organize");
- data = [data.mids, data.vocals];
-
- data[0] = helper.mutateData(data[0], "scale", minDimension / 4);
- data[1] = helper.mutateData(data[1], "scale", minDimension / 8);
-
- data[0] = helper.mutateData(data[0], "shrink", 1 / 5);
- data[0] = helper.mutateData(data[0], "split", 2)[0];
-
- data[0] = helper.mutateData(data[0], "reverb");
- data[1] = helper.mutateData(data[1], "reverb");
-
-
- let outerCircle = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data[0].length, data[0]);
- let innerCircle = helper.getPoints("circle", minDimension / 4, [w / 2, h / 2], data[1].length, data[1]);
-
- helper.drawPolygon(outerCircle.end, { close: true, radius: 4, lineColor: colors[0], color: colors[1] });
- helper.drawPolygon(innerCircle.end, { close: true, radius: 4, lineColor: colors[2], color: colors[3] });
-
- let middle = ((minDimension / 4) + (minDimension / 2)) / 2;
- let largerInner = data[1] = helper.mutateData(data[1], "scale", ((minDimension / 4) - (minDimension / 2)));
- let innerBars = helper.getPoints("circle", middle, [w / 2, h / 2], data[1].length, largerInner);
- innerBars.start.forEach((start, i) => {
- helper.drawLine(start, innerBars.end[i], { lineColor: colors[4] || colors[2] });
- });
+Screen.prototype.restore = function() {
+ this.paper.ctx.restore();
};
-var drawShineRings = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
-
- let helper = new Helper(ctx);
- let minDimension = (h < w) ? h : w;
-
- data = helper.mutateData(data, "organize");
- data.vocals = helper.mutateData(data.vocals, "scale", (minDimension / 2) / 2);
- data.base = helper.mutateData(data.base, "scale", (minDimension / 2) / 2);
-
- let outerBars = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals);
- let innerWave = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals, { offset: 100 });
- let thinLine = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.base.length, data.base, { offset: 100 });
-
- outerBars.start.forEach((start, i) => {
- helper.drawLine(start, outerBars.end[i], { lineColor: colors[0] });
- });
-
- helper.drawPolygon(innerWave.start, { close: true, lineColor: colors[1], color: colors[3], radius: 5 });
- helper.drawPolygon(thinLine.start, { close: true, lineColor: colors[2], color: colors[4], radius: 5 });
+Screen.prototype.save = function() {
+ this.paper.ctx.save();
};
-var drawCubes = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- let helper = new Helper(ctx);
-
- data = helper.mutateData(data, "organize").base;
-
- data = helper.mutateData(data, "shrink", 20).slice(0, 19);
- data = helper.mutateData(data, "scale", h);
-
- let points = helper.getPoints("line", w, [0, h], data.length, data);
-
- let spacing = 5;
- let squareSize = (w / 20) - spacing;
- let colorIndex = 0;
-
- points.start.forEach((start, i) => {
- let squareCount = Math.ceil(data[i] / squareSize);
-
- //find color stops from total possible squares in bar
- let totalSquares = (h - (spacing * (h / squareSize))) / squareSize;
- let colorStop = Math.ceil(totalSquares / colors.length);
-
- for (let j = 1; j <= squareCount; j++) {
- let origin = [start[0], (start[1] - (squareSize * j) - (spacing * j))];
- helper.drawSquare(origin, squareSize, { color: colors[colorIndex], lineColor: "black" });
- if (j % colorStop == 0) {
- colorIndex++;
- if (colorIndex >= colors.length) colorIndex = colors.length - 1;
- }
- }
- colorIndex = 0;
- });
+Screen.prototype.composition = function(params) {
+ this.paper.ctx.globalCompositeOperation = params.globalComposite;
};
-var drawBigBars = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- const helper = new Helper(ctx);
-
- data = helper.mutateData(data, "organize").vocals;
- data = helper.mutateData(data, "shrink", 10);
- data = helper.mutateData(data, "scale", h);
- data = helper.mutateData(data, "amp", 1);
- let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
-
- let colorIndex = 0;
- let colorStop = Math.ceil(data.length / colors.length);
- points.start.forEach((start, i) => {
- if ((i + 1) % colorStop == 0) colorIndex++;
- helper.drawRectangle(start, data[i], w / data.length, { color: colors[colorIndex] });
- });
-
+Screen.prototype.rotate = function(params) {
+ this.paper.ctx.rotate(params.degrees);
};
-var drawShockwave = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
-
- let helper = new Helper(ctx);
-
- data = helper.mutateData(data, "shrink", 300);
- data = helper.mutateData(data, "scale", h / 2);
- data = helper.mutateData(data, "split", 4).slice(0, 3);
-
- let colorIndex = 0;
- data.forEach((points) => {
- let wavePoints = helper.getPoints("line", w, [0, h / 2], points.length, points);
- helper.drawPolygon(wavePoints.end, { lineColor: colors[colorIndex], radius: (h * .015) });
+Screen.prototype.scale = function(params) {
+ this.paper.ctx.scale(params.width, params.height);
+};
- let invertedPoints = helper.getPoints("line", w, [0, h / 2], points.length, points, { offset: 100 });
- helper.drawPolygon(invertedPoints.start, { lineColor: colors[colorIndex], radius: (h * .015) });
- colorIndex++;
- });
+Screen.prototype.flip = function(params) {
+ this.paper.flip = 'horizontal';
+ if (params.type && typeof(params.type) === 'string')
+ this.paper.flip = params.type;
};
-var drawFireworks = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- const helper = new Helper(ctx);
+Screen.prototype.flipEnd = function() {
+ this.paper.flip = false;
+};
- data = helper.mutateData(data, "shrink", 200).slice(0, 120);
- data = helper.mutateData(data, "mirror");
- data = helper.mutateData(data, "scale", (h / 4) + ((h / 4) * .35));
+Screen.prototype.clear = function() {
+ this.paper.ctx.clearRect(0, 0, this.paper.width, this.paper.height);
+};
- let points = helper.getPoints("circle", h / 2, [w / 2, h / 2], data.length, data, { offset: 35, rotate: 270 });
+function ArcShape(params) {
+ var args = params.args,
+ style = args.style,
+ def = config.defaults.arc;
+
+ this.paper.ctx.beginPath();
+ this.paper.ctx.setLineDash(style.borderStyle);
+ this.paper.ctx.arc(args.x, args.y, (args.r || def.radius), (args.sAngle || 0), (args.eAngle || 2 * Math.PI));
+ this.paper.ctx.fillStyle = (style.background || style.bg) ? (style.background || style.bg) : def.background;
+ this.paper.ctx.fill();
+ this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
+ this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
+ this.paper.ctx.stroke();
+ this.paper.ctx.setLineDash([]);
+ this.paper.ctx.closePath();
+}
- points.start.forEach((start, i) => {
- helper.drawLine(start, points.end[i]);
- });
+Screen.prototype.arc = ArcShape;
- helper.drawPolygon(points.start, { close: true });
+Origami.arc = function() {
+ var args = [].slice.call(arguments);
+ args = argsByRules(args, ['x', 'y', 'r', 'sAngle', 'eAngle']);
- points.end.forEach((end, i) => {
- helper.drawCircle(end, h * .01, { color: colors[0] });
- });
+ queue('arc', {
+ args: args
+ });
+ return this;
};
-var drawStatic = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let helper = new Helper(ctx);
-
- data = helper.mutateData(data, "shrink", 1 / 8);
- data = helper.mutateData(data, "split", 2)[0];
- data = helper.mutateData(data, "scale", h);
-
- let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
- let prevPoint = null;
- points.start.forEach((start, i) => {
- if (prevPoint) {
- helper.drawLine(prevPoint, start);
- }
- helper.drawLine(start, points.end[i]);
- prevPoint = points.end[i];
- });
+function ImageShape(params) {
+ var image = params.image,
+ x = params.x,
+ y = params.y,
+ width = params.width,
+ height = params.height;
+
+ this.paper.ctx.save();
+ if (this.paper.flip) {
+ if (this.paper.flip === 'horizontal') {
+ this.paper.ctx.scale(-1, 1);
+ width = width * -1;
+ x = x * -1;
+ }
+ if (this.paper.flip === 'vertical') {
+ this.paper.ctx.scale(1, -1);
+ height = height * -1;
+ y = y * -1;
+ }
+ }
+ this.paper.ctx.beginPath();
+ this.paper.ctx.drawImage(image, Math.floor((x || 0)), Math.floor((y || 0)), width, height);
+ this.paper.ctx.closePath();
+ this.paper.ctx.restore();
+}
+Screen.prototype.image = ImageShape;
+
+Origami.image = function(image, x, y, width, height) {
+ var self = this;
+ if (!image)
+ return this;
+
+ if (typeof(image) === 'string') {
+ var img = new Image();
+ img.src = image;
+ image = img;
+ }
+
+ var item = {
+ image: image,
+ x: x,
+ y: y,
+ width: width,
+ height: height
+ };
+
+ if ((typeof(item.x) === 'string') && (typeof(item.y) === 'string'))
+ item = smartCoordinates(item);
+
+ if (image.complete) {
+ item.width = width || image.naturalWidth;
+ item.height = height || image.naturalHeight;
+
+ queue('image', item);
+ return self;
+ }
+
+ queue('image', item, false);
+ var reference = (self.paper.queue.length - 1),
+ currentQueue = config.contexts[this.paper.index].queue[reference];
+
+ image.addEventListener('load', function() {
+ if (!currentQueue)
+ return false;
+ currentQueue.params.width = (item.width || image.naturalWidth);
+ currentQueue.params.height = (item.height || image.naturalHeight);
+ currentQueue.loaded = true;
+ });
+
+ image.addEventListener('error', function() {
+ if (!currentQueue)
+ return false;
+ currentQueue.failed = true;
+ });
+
+ return self;
};
-var drawWeb = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- const helper = new Helper(ctx);
- let minDimension = (h < w) ? h : w;
-
- data = helper.mutateData(data, "shrink", 100);
- data = helper.mutateData(data, "split", 2)[0];
- data = helper.mutateData(data, "scale", h / 4);
+function LineShape(params) {
+ var def = config.defaults.line,
+ style = params.style,
+ pointA = params.pointA,
+ pointB = params.pointB;
+
+ this.paper.ctx.beginPath();
+ this.paper.ctx.setLineDash(style.borderStyle);
+ this.paper.ctx.moveTo((pointA.x || 0), (pointA.y || 0));
+ this.paper.ctx.lineTo((pointB.x || 0), (pointB.y || 0));
+
+ this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
+ this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
+ this.paper.ctx.stroke();
+ this.paper.ctx.setLineDash([]);
+ this.paper.ctx.closePath();
+}
- let dataCopy = data;
+Screen.prototype.line = LineShape;
- let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
- helper.drawPolygon(points.end, { close: true });
+Origami.line = function(pointA, pointB, style) {
+ style = normalizeStyle(style);
- points.start.forEach((start, i) => {
- helper.drawLine(start, points.end[i]);
- });
+ queue('line', {
+ pointA: pointA,
+ pointB: pointB,
+ style: style
+ });
+ return this;
+};
- data = helper.mutateData(data, "scale", .7);
- points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
- helper.drawPolygon(points.end, { close: true });
+function PolygonShape(params) {
+ var args = params.args,
+ style = params.style,
+ def = config.defaults.polygon;
+
+ this.paper.ctx.beginPath();
+ this.paper.ctx.setLineDash(style.borderStyle);
+ this.paper.ctx.fillStyle = (style.background) ? style.background : def.background;
+ this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
+ this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
+
+ for (var p = 0; p < args.length; p++) {
+ if (!args[p].x)
+ continue;
+
+ if (p)
+ this.paper.ctx.lineTo(args[p].x, args[p].y);
+ else
+ this.paper.ctx.moveTo(args[p].x, args[p].y);
+ }
+
+ this.paper.ctx.fill();
+ this.paper.ctx.stroke();
+ this.paper.ctx.setLineDash([]);
+ this.paper.ctx.closePath();
+}
- data = helper.mutateData(data, "scale", .3);
- points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
- helper.drawPolygon(points.end, { close: true });
+Screen.prototype.polygon = PolygonShape;
- helper.drawCircle([w / 2, h / 2], minDimension / 2, { color: colors[2] });
+Origami.polygon = function() {
+ var args = [].slice.call(arguments),
+ settedArgs = argsByRules(args);
- dataCopy = helper.mutateData(dataCopy, "scale", 1.4);
- points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], dataCopy.length, dataCopy);
- points.end.forEach((end, i) => {
- helper.drawCircle(end, minDimension * .01, { color: colors[1], lineColor: colors[1] || colors[0] });
- });
+ queue('polygon', {
+ style: settedArgs.style,
+ args: args
+ });
+ return this;
};
-var drawStitches = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let helper = new Helper(ctx);
- let minDimension = (h < w) ? h : w;
-
- data = helper.mutateData(data, "shrink", 200);
- data = helper.mutateData(data, "split", 2)[0];
- data = helper.mutateData(data, "scale", h / 2);
+function RectShape(params) {
+ var def = config.defaults.rect,
+ style = params.style,
+ args = params.args;
+
+ this.paper.ctx.beginPath();
+ this.paper.ctx.setLineDash(style.borderStyle);
+ this.paper.ctx.fillStyle = (style.background) ? style.background : def.background;
+ this.paper.ctx.fillRect(args.x, args.y, args.width, (args.height || args.width));
+
+ this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
+ this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
+ this.paper.ctx.strokeRect(args.x, args.y, args.width, (args.height || args.width));
+ this.paper.ctx.setLineDash([]);
+ this.paper.ctx.closePath();
+}
- let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data, { offset: 50 });
+Screen.prototype.rect = RectShape;
- helper.drawPolygon(points.end, { close: true });
- helper.drawPolygon(points.start, { close: true });
+Origami.rect = function() {
+ var args = [].slice.call(arguments);
+ args = argsByRules(args);
- for (let i = 0; i < points.start.length; i += 1) {
- let start = points.start[i];
- i++;
- let end = points.end[i] || points.end[0];
+ queue('rect', {
+ style: args.style,
+ args: args
+ });
+ return this;
+};
- helper.drawLine(start, end);
- helper.drawLine(end, points.start[i + 1] || points.start[0]);
+Origami.border = function() {
+ var args = [].slice.call(arguments);
+ args = argsByRules(args);
+
+ queue('rect', {
+ style: args.style,
+ args: {
+ x: 0,
+ y: 0,
+ width: this.paper.width,
+ height: this.paper.height
}
+ });
+ return this;
};
-//options:type,colors,stroke
-function visualize(data, canvas, options = {}, frame) {
- //make a clone of options
- options = { ...options };
- //options
- if (!options.stroke) options.stroke = 1;
- if (!options.colors) options.colors = ["#d92027", "#ff9234", "#ffcd3c", "#35d0ba"];
-
- if (typeof canvas == "string") {
- canvas = document.getElementById(canvas);
- }
- if (!canvas) return;
-
- let ctx = canvas.getContext("2d");
- let h = canvas.height;
- let w = canvas.width;
-
-
-
- ctx.strokeStyle = options.colors[0];
- ctx.lineWidth = options.stroke;
-
- let typeMap = {
- "bars": drawBars,
- "bars blocks": drawBarsBlocks,
- "big bars": drawBigBars,
- "cubes": drawCubes,
- "dualbars": drawDualbars,
- "dualbars blocks": drawDualbarsBlocks,
- "fireworks": drawFireworks,
- "flower": drawFlower,
- "flower blocks": drawFlowerBlocks,
- "orbs": drawOrbs,
- "ring": drawRing,
- "rings": drawRings,
- "round wave": drawRoundWave,
- "shine": drawShine,
- "shine rings": drawShineRings,
- "shockwave": drawShockwave,
- "star": drawStar,
- "static": drawStatic,
- "stitches": drawStitches,
- "wave": drawWave,
- "web": drawWeb
- };
-
- let frameRateMap = {
- "bars": 1,
- "bars blocks": 1,
- "big bars": 1,
- "cubes": 1,
- "dualbars": 1,
- "dualbars blocks": 1,
- "fireworks": 1,
- "flower": 1,
- "flower blocks": 1,
- "ring": 1,
- "rings": 1,
- "round wave": 1,
- "orbs": 1,
- "shine": 1,
- "shine rings": 1,
- "shockwave": 1,
- "star": 1,
- "static": 1,
- "stitches": 1,
- "wave": 1,
- "web": 1
- };
-
- const functionContext = {
- data, options, ctx, h, w, Helper: this.Helper
- };
-
- if (typeof options.type == "string") options.type = [options.type];
-
- options.type.forEach(type => {
- //abide by the frame rate
- if (frame % frameRateMap[type] === 0) {
- //clear canvas
- ctx.clearRect(0, 0, w, h);
- ctx.beginPath();
-
- typeMap[type](functionContext);
- }
+function CSSShape(style) {
+ var self = this,
+ style = config.virtualStyles[style];
+
+ if (!style)
+ return self;
+
+ // TODO: Draw in all canvas
+ var data = '' +
+ '' +
+ ' ' +
+ ' ';
+
+ var DOMURL = window.URL || window.webkitURL || window,
+ img = new Image(),
+ svg = new Blob([data], {
+ type: 'image/svg+xml;charset=utf-8'
});
-}
+ var url = DOMURL.createObjectURL(svg);
+ img.src = url;
-function Helper(ctx) {
- this.ctx = ctx;
- this.mainColor = "black";
+ img.addEventListener('load', function() {
+ self.paper.ctx.beginPath();
+ self.paper.ctx.drawImage(img, 0, 0);
+ DOMURL.revokeObjectURL(url);
+ self.paper.ctx.closePath();
+ });
+
+ return self;
}
-Helper.prototype = {
- __toRadians__(degree) {
- return (degree * Math.PI) / 180;
- },
- __rotatePoint__([pointX, pointY], [originX, originY], degree) {
- //clockwise
- let angle = this.__toRadians__(degree);
- let rotatedX = Math.cos(angle) * (pointX - originX) - Math.sin(angle) * (pointY - originY) + originX;
- let rotatedY = Math.sin(angle) * (pointX - originX) + Math.cos(angle) * (pointY - originY) + originY;
+Screen.prototype.CSSShape = CSSShape;
- return [rotatedX, rotatedY]
- },
- mutateData(data, type, extra = null) {
- if (type === "mirror") {
- let rtn = [];
+Origami.shape = function(style) {
+ queue('CSSShape', style);
+ return this;
+};
- for (let i = 0; i < data.length; i += 2) {
- rtn.push(data[i]);
- }
+function SpriteShape(params) {
+ var properties = params.properties,
+ dw = params.width / properties.frames;
+
+ drawSprite.call(this, {
+ image: params.image,
+ posX: 0,
+ posY: 0,
+ frame: properties.frames,
+ loop: properties.loop,
+ width: dw,
+ widthTotal: params.width,
+ height: params.height,
+ dx: params.x,
+ dy: params.y,
+ speed: properties.speed,
+ animation: null
+ });
+}
- rtn = [...rtn, ...rtn.reverse()];
- return rtn
- }
+function drawSprite(sprite) {
+ var self = this;
- if (type === "shrink") {
- //resize array by % of current array
- if (extra < 1) {
- extra = data.length * extra;
- }
+ if (sprite.posX === sprite.widthTotal) {
+ if (sprite.loop === false) {
+ window.cancelAnimationFrame(sprite.animation);
+ return;
+ }
+ sprite.posX = 0;
+ }
- let rtn = [];
- let splitAt = Math.floor(data.length / extra);
+ self.paper.ctx.clearRect(sprite.dx, sprite.dy, sprite.width, sprite.height);
- for (let i = 1; i <= extra; i++) {
- let arraySection = data.slice(i * splitAt, (i * splitAt) + splitAt);
- let middle = arraySection[Math.floor(arraySection.length / 2)];
- rtn.push(middle);
- }
+ self.paper.ctx.beginPath();
+ self.paper.ctx.drawImage(sprite.image, sprite.posX, sprite.posY,
+ sprite.width, sprite.height, sprite.dx, sprite.dy,
+ sprite.width, sprite.height);
+ self.paper.ctx.closePath();
- return rtn
- }
+ sprite.posX = sprite.posX + sprite.width;
- if (type === "split") {
- let size = Math.floor(data.length / extra);
- let rtn = [];
- let temp = [];
+ setTimeout(function() {
+ sprite.animation = window.requestAnimationFrame(drawSprite.bind(self, sprite));
+ }, sprite.speed);
+}
- let track = 0;
- for (let i = 0; i <= size * extra; i++) {
- if (track === size) {
- rtn.push(temp);
- temp = [];
- track = 0;
- }
+Screen.prototype.sprite = SpriteShape;
+
+Origami.sprite = function(x, y, properties) {
+ var self = this;
+
+ if (!properties || !properties.src)
+ return this;
+
+ var image = new Image(),
+ frames = (properties.frames || 0),
+ loop = (properties.loop || true),
+ speed = (properties.speed || 10);
+
+ image.src = properties.src;
+
+ var item = {
+ x: x,
+ y: y,
+ image: image,
+ properties: properties,
+ width: 0,
+ height: 0
+ };
+
+ if (image.complete) {
+ item.width = image.naturalWidth;
+ item.height = image.naturalHeight;
+ queue('sprite', item);
+ return self;
+ }
+
+ queue('sprite', item, false);
+ var reference = (self.paper.queue.length - 1),
+ currentQueue = config.contexts[this.paper.index].queue[reference];
+
+ image.addEventListener('load', function() {
+ if (!currentQueue)
+ return false;
+ currentQueue.params.width = image.naturalWidth;
+ currentQueue.params.height = image.naturalHeight;
+ currentQueue.loaded = true;
+ });
+
+ image.addEventListener('error', function() {
+ if (!currentQueue)
+ return false;
+ currentQueue.failed = true;
+ });
+
+ return this;
+};
- temp.push(data[i]);
- track++;
- }
+function TextShape(params) {
+ var def = config.defaults.text,
+ text = params.text,
+ x = params.x,
+ y = params.y,
+ style = params.style;
+
+ this.paper.ctx.beginPath();
+ this.paper.ctx.setLineDash(style.borderStyle);
+ this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
+ this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
+ this.paper.ctx.font = (style.font || def.font);
+ this.paper.ctx.fillStyle = (style.color || def.color);
+ this.paper.ctx.textAlign = (style.align || def.align);
+ this.paper.ctx.fillText(text, x, y);
+ this.paper.ctx.strokeText(text, x, y);
+ this.paper.ctx.fill();
+ this.paper.ctx.stroke();
+ this.paper.ctx.setLineDash([]);
+ this.paper.ctx.closePath();
+}
- return rtn
- }
+Screen.prototype.text = TextShape;
- if (type === "scale") {
- let scalePercent = extra / 255;
- if (extra <= 3 && extra >= 0) scalePercent = extra;
- let rtn = data.map(value => value * scalePercent);
- return rtn
- }
+Origami.text = function(text, x, y, style) {
+ style = normalizeStyle(style);
- if (type === "organize") {
- let rtn = {};
- rtn.base = data.slice(60, 120);
- rtn.vocals = data.slice(120, 255);
- rtn.mids = data.slice(255, 2000);
- return rtn
- }
+ var item = {
+ text: text,
+ x: x,
+ y: y,
+ style: style
+ };
- if (type === "reverb") {
- let rtn = [];
- data.forEach((val, i) => {
- rtn.push(val - (data[i + 1] || 0));
- });
- return rtn
- }
+ if ((typeof(item.x) === 'string') && (typeof(item.y) === 'string'))
+ item = smartCoordinates(item);
- if (type === "amp") {
- let rtn = [];
- data.forEach(val => {
- rtn.push(val * (extra + 1));
- });
- return rtn
- }
+ queue('text', item);
+ return this;
+};
- if (type === "min") {
- let rtn = [];
- data.forEach(value => {
- if (value < extra) value = extra;
- rtn.push(value);
- });
- return rtn
- }
- },
- getPoints(shape, size, [originX, originY], pointCount, endPoints, options = {}) {
- let { offset = 0, rotate = 0, customOrigin = [] } = options;
- let rtn = {
- start: [],
- end: []
- };
+function ChartLine(config) {
+ var ctx = this.paper.ctx,
+ width = this.paper.width,
+ height = this.paper.height;
- if (shape === "circle") {
+ var line = getBorderStyleObject(config.line || "1px solid #000");
+ var lineVariance = 2;
- let degreePerPoint = 360 / pointCount;
- let radianPerPoint = this.__toRadians__(degreePerPoint);
- let radius = size / 2;
+ var xPadding = 40;
+ var yPadding = 40;
+ var data = [];
- for (let i = 1; i <= pointCount; i++) {
- let currentRadian = radianPerPoint * i;
- let currentEndPoint = endPoints[i - 1];
- let pointOffset = endPoints[i - 1] * (offset / 100);
+ var gridLines = {
+ vertical: true,
+ horizontal: true
+ };
- let x = originX + (radius - pointOffset) * Math.cos(currentRadian);
- let y = originY + (radius - pointOffset) * Math.sin(currentRadian);
- let point1 = this.__rotatePoint__([x, y], [originX, originY], rotate);
+ if (config.gridLines) {
+ if (config.gridLines.vertical === false)
+ gridLines.vertical = false;
- rtn.start.push(point1);
+ if (config.gridLines.horizontal === false)
+ gridLines.horizontal = false;
+ }
- x = originX + ((radius - pointOffset) + currentEndPoint) * Math.cos(currentRadian);
- y = originY + ((radius - pointOffset) + currentEndPoint) * Math.sin(currentRadian);
- let point2 = this.__rotatePoint__([x, y], [originX, originY], rotate);
+ for (var i = 0; i < config.labels.length; i++) {
+ data.push({
+ X: config.labels[i],
+ Y: config.data[i]
+ });
+ }
- rtn.end.push(point2);
+ function getMaxY() {
+ var max = 0;
- }
+ for (var i = 0; i < data.length; i++) {
+ if (data[i].Y > max) {
+ max = data[i].Y;
+ }
+ }
- return rtn
- }
+ max += 10 - max % 10;
+ return max;
+ }
+
+ function getXPixel(val) {
+ return ((width - xPadding) / data.length) * val + xPadding;
+ }
+
+ function getYPixel(val) {
+ return height - (((height - yPadding) / getMaxY()) * val) - yPadding;
+ }
+
+ ctx.lineWidth = 0.8;
+ ctx.strokeStyle = '#999';
+ ctx.font = 'normal 12px Helvetica';
+ ctx.fillStyle = '#5e5e5e';
+ ctx.textAlign = "center";
+
+ ctx.beginPath();
+ ctx.moveTo(xPadding, yPadding / lineVariance);
+ ctx.lineTo(xPadding, height - yPadding);
+ ctx.lineTo(width - (xPadding / lineVariance), height - yPadding);
+ ctx.stroke();
+
+ // Data
+ ctx.textAlign = "right";
+ ctx.textBaseline = "middle";
+ for (var i = 0; i < getMaxY(); i += 10) {
+ if (gridLines.horizontal) {
+ ctx.beginPath();
+ ctx.lineWidth = 0.8;
+ ctx.strokeStyle = '#e7e7e7';
+ ctx.moveTo(xPadding - 5, getYPixel(i));
+ ctx.lineTo(width - (xPadding / lineVariance), getYPixel(i));
+ ctx.stroke();
+ }
- if (shape === "line") {
- let increment = size / pointCount;
+ ctx.fillText(i, xPadding - 10, getYPixel(i));
+ }
+
+ // Labels
+ ctx.textAlign = "left";
+ for (var i = 0; i < data.length; i++) {
+ if (gridLines.vertical) {
+ ctx.beginPath();
+ ctx.lineWidth = 0.8;
+ ctx.strokeStyle = '#e7e7e7';
+ ctx.moveTo(getXPixel(i), height - yPadding + 10);
+ ctx.lineTo(getXPixel(i), yPadding / lineVariance);
+ ctx.stroke();
+ }
- originX = customOrigin[0] || originX;
- originY = customOrigin[1] || originY;
+ ctx.fillText(data[i].X, getXPixel(i), height - yPadding + 20);
+ }
+
+ ctx.beginPath();
+ ctx.lineWidth = line.borderSize;
+ ctx.setLineDash(line.borderStyle);
+ ctx.strokeStyle = line.borderColor;
+ ctx.moveTo(getXPixel(0), getYPixel(data[0].Y));
+
+ for (var i = 1; i < data.length; i++) {
+ ctx.lineTo(getXPixel(i), getYPixel(data[i].Y));
+ }
+ ctx.stroke();
+ ctx.setLineDash([]);
+
+ if (config.points) {
+ ctx.fillStyle = (config.pointsColor) ? config.pointsColor : 'rgb(75,75,75)';
+ for (var i = 0; i < data.length; i++) {
+ ctx.beginPath();
+ ctx.arc(getXPixel(i), getYPixel(data[i].Y), 3, 0, Math.PI * 2, true);
+ ctx.fill();
+ }
+ }
+}
- for (let i = 0; i <= pointCount; i++) {
- let degree = rotate;
- let pointOffset = endPoints[i] * (offset / 100);
+Screen.prototype.chartLine = ChartLine;
- let startingPoint = this.__rotatePoint__([originX + (i * increment), originY - pointOffset],
- [originX, originY], degree);
- rtn.start.push(startingPoint);
+Origami.chartLine = function(config) {
+ queue('chartLine', config);
+ return this;
+};
+// Resource.js
- let endingPoint = this.__rotatePoint__([originX + (i * increment), (originY + endPoints[i]) - pointOffset],
- [originX, originY], degree);
- rtn.end.push(endingPoint);
- }
+Origami.background = function(color) {
+ queue('background', {
+ color: color
+ });
+ return this;
+};
- return rtn
+Origami.restore = function() {
+ queue('restore');
+ return this;
+};
- }
+Origami.save = function() {
+ queue('save');
+ return this;
+};
- },
- drawCircle([x, y], diameter, options = {}) {
- let { color, lineColor = this.ctx.strokeStyle } = options;
-
- this.ctx.beginPath();
- this.ctx.arc(x, y, diameter / 2, 0, 2 * Math.PI);
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke();
- this.ctx.fillStyle = color;
- if (color) this.ctx.fill();
- },
- drawOval([x, y], height, width, options = {}) {
- let { rotation = 0, color, lineColor = this.ctx.strokeStyle } = options;
- if (rotation) rotation = this.__toRadians__(rotation);
-
- this.ctx.beginPath();
- this.ctx.ellipse(x, y, width, height, rotation, 0, 2 * Math.PI);
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke();
- this.ctx.fillStyle = color;
- if (color) this.ctx.fill();
- },
- drawSquare([x, y], diameter, options = {}) {
- this.drawRectangle([x, y], diameter, diameter, options);
- },
- drawRectangle([x, y], height, width, options = {}) {
- let { color, lineColor = this.ctx.strokeStyle, radius = 0, rotate = 0 } = options;
+Origami.composition = function(globalComposite) {
+ queue('composition', {
+ globalComposite: globalComposite
+ });
+ return this;
+};
- // if (width < 2 * radius) radius = width / 2;
- // if (height < 2 * radius) radius = height / 2;
+Origami.translate = function(x, y) {
+ if (x === undefined || x === null) {
+ x = 'reset';
+ }
- this.ctx.beginPath();
- this.ctx.moveTo(x + radius, y);
- let p1 = this.__rotatePoint__([x + width, y], [x, y], rotate);
- let p2 = this.__rotatePoint__([x + width, y + height], [x, y], rotate);
- this.ctx.arcTo(p1[0], p1[1], p2[0], p2[1], radius);
+ if (typeof(x) === 'string') {
+ if (x === 'center') {
+ x = context.width / 2;
+ y = context.height / 2;
+ }
+ if (x === 'reset') {
+ x = -context.width / 2;
+ y = -context.height / 2;
+ }
+ }
- let p3 = this.__rotatePoint__([x + width, y + height], [x, y], rotate);
- let p4 = this.__rotatePoint__([x, y + height], [x, y], rotate);
- this.ctx.arcTo(p3[0], p3[1], p4[0], p4[1], radius);
+ queue('translate', {
+ x: x,
+ y: y
+ });
+ return this;
+};
- let p5 = this.__rotatePoint__([x, y + height], [x, y], rotate);
- let p6 = this.__rotatePoint__([x, y], [x, y], rotate);
- this.ctx.arcTo(p5[0], p5[1], p6[0], p6[1], radius);
+Origami.rotate = function(degrees) {
+ if (typeof(degrees) === 'undefined')
+ degrees = 'slow';
+
+ if (typeof(degrees) === 'string') {
+ // Slow
+ if (degrees === 'slow')
+ degrees = ((2 * Math.PI) / 60) * new Date().getSeconds() +
+ ((2 * Math.PI) / 60000) * new Date().getMilliseconds();
+
+ // Normal
+ else if (degrees === 'normal')
+ degrees = ((2 * Math.PI) / 30) * new Date().getSeconds() +
+ ((2 * Math.PI) / 30000) * new Date().getMilliseconds();
+
+ // Fast
+ else if (degrees === 'fast')
+ degrees = ((2 * Math.PI) / 6) * new Date().getSeconds() +
+ ((2 * Math.PI) / 6000) * new Date().getMilliseconds();
+ }
+
+ queue('rotate', {
+ degrees: degrees
+ });
+ return this;
+};
- let p7 = this.__rotatePoint__([x, y], [x, y], rotate);
- let p8 = this.__rotatePoint__([x + width, y], [x, y], rotate);
- this.ctx.arcTo(p7[0], p7[1], p8[0], p8[1], radius);
- this.ctx.closePath();
+Origami.stopRender = function() {
+ window.cancelAnimationFrame(this.paper.frame);
+ this.paper.frame = false;
+};
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke();
- this.ctx.fillStyle = color;
- if (color) this.ctx.fill();
+Origami.play = function() {
+ this.paper.frame = 1;
+ return this;
+};
- },
- drawLine([fromX, fromY], [toX, toY], options = {}) {
- let { lineColor = this.ctx.strokeStyle } = options;
-
- this.ctx.beginPath();
- this.ctx.moveTo(fromX, fromY);
- this.ctx.lineTo(toX, toY);
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke();
- },
- drawPolygon(points, options = {}) {
- let { color, lineColor = this.ctx.strokeStyle, radius = 0, close = false } = options;
+Origami.startRender = function(fn) {
+ var self = this;
+ if (self.paper.frame === false)
+ return;
- function getRoundedPoint(x1, y1, x2, y2, radius, first) {
- let total = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
- let idx = first ? radius / total : (total - radius) / total;
+ self.draw(function() {
+ self.paper.frame = window.requestAnimationFrame(fn.bind(this));
+ });
+};
- return [x1 + (idx * (x2 - x1)), y1 + (idx * (y2 - y1))];
- }
+Origami.scale = function(width, height) {
+ queue('scale', {
+ width: width,
+ height: height
+ });
+ return this;
+};
- function getRoundedPoints(pts, radius) {
- let len = pts.length;
- let res = new Array(len);
+Origami.flip = function(type) {
+ queue('flip', {
+ type: type
+ });
+ return this;
+};
- for (let i2 = 0; i2 < len; i2++) {
- let i1 = i2 - 1;
- let i3 = i2 + 1;
+Origami.flipEnd = function() {
+ queue('flipEnd');
+ return this;
+};
- if (i1 < 0) i1 = len - 1;
- if (i3 == len) i3 = 0;
+Origami.clear = function() {
+ queue('clear');
+ return this;
+};
- let p1 = pts[i1];
- let p2 = pts[i2];
- let p3 = pts[i3];
+Origami.on = function(ev, fn) {
+ this.paper.element.addEventListener(ev, fn);
+ return this;
+};
- let prevPt = getRoundedPoint(p1[0], p1[1], p2[0], p2[1], radius, false);
- let nextPt = getRoundedPoint(p2[0], p2[1], p3[0], p3[1], radius, true);
- res[i2] = [prevPt[0], prevPt[1], p2[0], p2[1], nextPt[0], nextPt[1]];
- }
- return res;
- }
- if (radius > 0) {
- points = getRoundedPoints(points, radius);
- }
+var factory = extend(Origami.init.bind(this), Origami);
- let i, pt, len = points.length;
- for (i = 0; i < len; i++) {
- pt = points[i];
- if (i == 0) {
- this.ctx.beginPath();
- this.ctx.moveTo(pt[0], pt[1]);
- } else {
- this.ctx.lineTo(pt[0], pt[1]);
- }
- if (radius > 0) {
- this.ctx.quadraticCurveTo(pt[2], pt[3], pt[4], pt[5]);
- }
- }
+// For consistency with CommonJS environments' exports
+if ( module && module.exports ){
+ module.exports = factory;
+}
- if (close) this.ctx.closePath();
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke();
+// For CommonJS with exports, but without module.exports, like Rhino
+else if ( exports ) {
+ exports.origami = factory;
+}
- this.ctx.fillStyle = color;
- if (color) this.ctx.fill();
- }
+// For browser, export only select globals
+else if ( typeof window === "object" ) {
+ window.origami = extend(Origami.init.bind(Origami), Origami);
+}
+// Get a reference to the global object
+}( (function() {
+ return this;
+})() ));
+});
+var origami_2 = origami_1.origami;
+
+var drawRoundLayers = (functionContext) => {
+ let { data, options, ctx, h, w, Helper, canvasId } = functionContext;
+ let helper = new Helper(ctx);
+
+ let origamiContext = {};
+ let origami = origami_1.bind(origamiContext);
+
+ origami(ctx)
+ .rect(10, 10, 40, 40)
+ .draw();
+
+
};
-function Wave() {
- this.current_stream = {};
- this.sources = {};
- this.onFileLoad = null;
- this.activeElements = {};
- this.activated = false;
-
- window.AudioContext = window.AudioContext || window.webkitAudioContext;
+//options:type,colors,stroke
+function visualize(data, canvasId, options = {}, frame) {
+ //make a clone of options
+ options = { ...options };
+ //options
+ if (!options.stroke) options.stroke = 1;
+ if (!options.colors) options.colors = ["#d92027", "#ff9234", "#ffcd3c", "#35d0ba"];
+
+
+ let canvas = document.getElementById(canvasId);
+
+ if (!canvas) return;
+
+ let ctx = canvas.getContext("2d");
+ let h = canvas.height;
+ let w = canvas.width;
+
+
+
+ ctx.strokeStyle = options.colors[0];
+ ctx.lineWidth = options.stroke;
+
+ let typeMap = {
+ "bars": drawBars,
+ "bars blocks": drawBarsBlocks,
+ "big bars": drawBigBars,
+ "cubes": drawCubes,
+ "dualbars": drawDualbars,
+ "dualbars blocks": drawDualbarsBlocks,
+ "fireworks": drawFireworks,
+ "flower": drawFlower,
+ "flower blocks": drawFlowerBlocks,
+ "orbs": drawOrbs,
+ "ring": drawRing,
+ "rings": drawRings,
+ "round layers": drawRoundLayers,
+ "round wave": drawRoundWave,
+ "shine": drawShine,
+ "shine rings": drawShineRings,
+ "shockwave": drawShockwave,
+ "star": drawStar,
+ "static": drawStatic,
+ "stitches": drawStitches,
+ "wave": drawWave,
+ "web": drawWeb
+ };
+
+ let frameRateMap = {
+ "bars": 1,
+ "bars blocks": 1,
+ "big bars": 1,
+ "cubes": 1,
+ "dualbars": 1,
+ "dualbars blocks": 1,
+ "fireworks": 1,
+ "flower": 1,
+ "flower blocks": 1,
+ "ring": 1,
+ "rings": 1,
+ "round layers": 1,
+ "round wave": 1,
+ "orbs": 1,
+ "shine": 1,
+ "shine rings": 1,
+ "shockwave": 1,
+ "star": 1,
+ "static": 1,
+ "stitches": 1,
+ "wave": 1,
+ "web": 1
+ };
+
+ const functionContext = {
+ data, options, ctx, h, w, Helper: this.Helper, canvasId
+ };
+
+ if (typeof options.type == "string") options.type = [options.type];
+
+ options.type.forEach(type => {
+ //abide by the frame rate
+ if (frame % frameRateMap[type] === 0) {
+ //clear canvas
+ ctx.clearRect(0, 0, w, h);
+ ctx.beginPath();
+
+ typeMap[type](functionContext);
+ }
+ });
+
}
-Wave.prototype = {
- fromElement,
- fromFile,
- ...fromStream$1,
- visualize,
- Helper
+function Helper(ctx) {
+ this.ctx = ctx;
+ this.mainColor = "black";
+}
+
+Helper.prototype = {
+ __toRadians__(degree) {
+ return (degree * Math.PI) / 180;
+ },
+ __rotatePoint__([pointX, pointY], [originX, originY], degree) {
+ //clockwise
+ let angle = this.__toRadians__(degree);
+ let rotatedX = Math.cos(angle) * (pointX - originX) - Math.sin(angle) * (pointY - originY) + originX;
+ let rotatedY = Math.sin(angle) * (pointX - originX) + Math.cos(angle) * (pointY - originY) + originY;
+
+ return [rotatedX, rotatedY]
+ },
+ mutateData(data, type, extra = null) {
+ if (type === "mirror") {
+ let rtn = [];
+
+ for (let i = 0; i < data.length; i += 2) {
+ rtn.push(data[i]);
+ }
+
+ rtn = [...rtn, ...rtn.reverse()];
+ return rtn
+ }
+
+ if (type === "shrink") {
+ //resize array by % of current array
+ if (extra < 1) {
+ extra = data.length * extra;
+ }
+
+ let rtn = [];
+ let splitAt = Math.floor(data.length / extra);
+
+ for (let i = 1; i <= extra; i++) {
+ let arraySection = data.slice(i * splitAt, (i * splitAt) + splitAt);
+ let middle = arraySection[Math.floor(arraySection.length / 2)];
+ rtn.push(middle);
+ }
+
+ return rtn
+ }
+
+ if (type === "split") {
+ let size = Math.floor(data.length / extra);
+ let rtn = [];
+ let temp = [];
+
+ let track = 0;
+ for (let i = 0; i <= size * extra; i++) {
+ if (track === size) {
+ rtn.push(temp);
+ temp = [];
+ track = 0;
+ }
+
+ temp.push(data[i]);
+ track++;
+ }
+
+ return rtn
+ }
+
+ if (type === "scale") {
+ let scalePercent = extra / 255;
+ if (extra <= 3 && extra >= 0) scalePercent = extra;
+ let rtn = data.map(value => value * scalePercent);
+ return rtn
+ }
+
+ if (type === "organize") {
+ let rtn = {};
+ rtn.base = data.slice(60, 120);
+ rtn.vocals = data.slice(120, 255);
+ rtn.mids = data.slice(255, 2000);
+ return rtn
+ }
+
+ if (type === "reverb") {
+ let rtn = [];
+ data.forEach((val, i) => {
+ rtn.push(val - (data[i + 1] || 0));
+ });
+ return rtn
+ }
+
+ if (type === "amp") {
+ let rtn = [];
+ data.forEach(val => {
+ rtn.push(val * (extra + 1));
+ });
+ return rtn
+ }
+
+ if (type === "min") {
+ let rtn = [];
+ data.forEach(value => {
+ if (value < extra) value = extra;
+ rtn.push(value);
+ });
+ return rtn
+ }
+ },
+ getPoints(shape, size, [originX, originY], pointCount, endPoints, options = {}) {
+ let { offset = 0, rotate = 0, customOrigin = [] } = options;
+ let rtn = {
+ start: [],
+ end: []
+ };
+
+ if (shape === "circle") {
+
+ let degreePerPoint = 360 / pointCount;
+ let radianPerPoint = this.__toRadians__(degreePerPoint);
+ let radius = size / 2;
+
+ for (let i = 1; i <= pointCount; i++) {
+ let currentRadian = radianPerPoint * i;
+ let currentEndPoint = endPoints[i - 1];
+ let pointOffset = endPoints[i - 1] * (offset / 100);
+
+ let x = originX + (radius - pointOffset) * Math.cos(currentRadian);
+ let y = originY + (radius - pointOffset) * Math.sin(currentRadian);
+ let point1 = this.__rotatePoint__([x, y], [originX, originY], rotate);
+
+ rtn.start.push(point1);
+
+ x = originX + ((radius - pointOffset) + currentEndPoint) * Math.cos(currentRadian);
+ y = originY + ((radius - pointOffset) + currentEndPoint) * Math.sin(currentRadian);
+ let point2 = this.__rotatePoint__([x, y], [originX, originY], rotate);
+
+ rtn.end.push(point2);
+
+ }
+
+ return rtn
+ }
+
+ if (shape === "line") {
+ let increment = size / pointCount;
+
+ originX = customOrigin[0] || originX;
+ originY = customOrigin[1] || originY;
+
+ for (let i = 0; i <= pointCount; i++) {
+ let degree = rotate;
+ let pointOffset = endPoints[i] * (offset / 100);
+
+ let startingPoint = this.__rotatePoint__([originX + (i * increment), originY - pointOffset],
+ [originX, originY], degree);
+ rtn.start.push(startingPoint);
+
+ let endingPoint = this.__rotatePoint__([originX + (i * increment), (originY + endPoints[i]) - pointOffset],
+ [originX, originY], degree);
+ rtn.end.push(endingPoint);
+ }
+
+ return rtn
+
+ }
+
+ },
+ drawCircle([x, y], diameter, options = {}) {
+ let { color, lineColor = this.ctx.strokeStyle } = options;
+
+ this.ctx.beginPath();
+ this.ctx.arc(x, y, diameter / 2, 0, 2 * Math.PI);
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke();
+ this.ctx.fillStyle = color;
+ if (color) this.ctx.fill();
+ },
+ drawOval([x, y], height, width, options = {}) {
+ let { rotation = 0, color, lineColor = this.ctx.strokeStyle } = options;
+ if (rotation) rotation = this.__toRadians__(rotation);
+
+ this.ctx.beginPath();
+ this.ctx.ellipse(x, y, width, height, rotation, 0, 2 * Math.PI);
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke();
+ this.ctx.fillStyle = color;
+ if (color) this.ctx.fill();
+ },
+ drawSquare([x, y], diameter, options = {}) {
+ this.drawRectangle([x, y], diameter, diameter, options);
+ },
+ drawRectangle([x, y], height, width, options = {}) {
+ let { color, lineColor = this.ctx.strokeStyle, radius = 0, rotate = 0 } = options;
+
+ // if (width < 2 * radius) radius = width / 2;
+ // if (height < 2 * radius) radius = height / 2;
+
+ this.ctx.beginPath();
+ this.ctx.moveTo(x + radius, y);
+ let p1 = this.__rotatePoint__([x + width, y], [x, y], rotate);
+ let p2 = this.__rotatePoint__([x + width, y + height], [x, y], rotate);
+ this.ctx.arcTo(p1[0], p1[1], p2[0], p2[1], radius);
+
+ let p3 = this.__rotatePoint__([x + width, y + height], [x, y], rotate);
+ let p4 = this.__rotatePoint__([x, y + height], [x, y], rotate);
+ this.ctx.arcTo(p3[0], p3[1], p4[0], p4[1], radius);
+
+ let p5 = this.__rotatePoint__([x, y + height], [x, y], rotate);
+ let p6 = this.__rotatePoint__([x, y], [x, y], rotate);
+ this.ctx.arcTo(p5[0], p5[1], p6[0], p6[1], radius);
+
+ let p7 = this.__rotatePoint__([x, y], [x, y], rotate);
+ let p8 = this.__rotatePoint__([x + width, y], [x, y], rotate);
+ this.ctx.arcTo(p7[0], p7[1], p8[0], p8[1], radius);
+ this.ctx.closePath();
+
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke();
+ this.ctx.fillStyle = color;
+ if (color) this.ctx.fill();
+
+ },
+ drawLine([fromX, fromY], [toX, toY], options = {}) {
+ let { lineColor = this.ctx.strokeStyle } = options;
+
+ this.ctx.beginPath();
+ this.ctx.moveTo(fromX, fromY);
+ this.ctx.lineTo(toX, toY);
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke();
+ },
+ drawPolygon(points, options = {}) {
+ let { color, lineColor = this.ctx.strokeStyle, radius = 0, close = false } = options;
+
+ function getRoundedPoint(x1, y1, x2, y2, radius, first) {
+ let total = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
+ let idx = first ? radius / total : (total - radius) / total;
+
+ return [x1 + (idx * (x2 - x1)), y1 + (idx * (y2 - y1))];
+ }
+
+ function getRoundedPoints(pts, radius) {
+ let len = pts.length;
+ let res = new Array(len);
+
+ for (let i2 = 0; i2 < len; i2++) {
+ let i1 = i2 - 1;
+ let i3 = i2 + 1;
+
+ if (i1 < 0) i1 = len - 1;
+ if (i3 == len) i3 = 0;
+
+ let p1 = pts[i1];
+ let p2 = pts[i2];
+ let p3 = pts[i3];
+
+ let prevPt = getRoundedPoint(p1[0], p1[1], p2[0], p2[1], radius, false);
+ let nextPt = getRoundedPoint(p2[0], p2[1], p3[0], p3[1], radius, true);
+ res[i2] = [prevPt[0], prevPt[1], p2[0], p2[1], nextPt[0], nextPt[1]];
+ }
+ return res;
+ }
+ if (radius > 0) {
+ points = getRoundedPoints(points, radius);
+ }
+
+ let i, pt, len = points.length;
+ for (i = 0; i < len; i++) {
+ pt = points[i];
+ if (i == 0) {
+ this.ctx.beginPath();
+ this.ctx.moveTo(pt[0], pt[1]);
+ } else {
+ this.ctx.lineTo(pt[0], pt[1]);
+ }
+ if (radius > 0) {
+ this.ctx.quadraticCurveTo(pt[2], pt[3], pt[4], pt[5]);
+ }
+ }
+
+ if (close) this.ctx.closePath();
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke();
+
+ this.ctx.fillStyle = color;
+ if (color) this.ctx.fill();
+ }
+
+};
+
+function Wave() {
+ this.current_stream = {};
+ this.sources = {};
+ this.onFileLoad = null;
+ this.activeElements = {};
+ this.activated = false;
+
+ window.AudioContext = window.AudioContext || window.webkitAudioContext;
+}
+
+Wave.prototype = {
+ fromElement,
+ fromFile,
+ ...fromStream$1,
+ visualize,
+ Helper
};
module.exports = Wave;
diff --git a/dist/bundle.iife.js b/dist/bundle.iife.js
index 3c40204..9f07543 100644
--- a/dist/bundle.iife.js
+++ b/dist/bundle.iife.js
@@ -1,1301 +1,2480 @@
var Wave = (function () {
'use strict';
- function fromElement(element_id, canvas_id, options) {
-
- const waveContext = this;
- let element = document.getElementById(element_id);
- if (!element) return
- element.crossOrigin = "anonymous";
-
- function run() {
- //user gesture has happened
- this.activated = true;
-
- //track current wave for canvas
- this.activeCanvas = this.activeCanvas || {};
- this.activeCanvas[canvas_id] = JSON.stringify(options);
-
- //track elements used so multiple elements use the same data
- this.activeElements[element_id] = this.activeElements[element_id] || {};
- if (this.activeElements[element_id].count) this.activeElements[element_id].count += 1;
- else this.activeElements[element_id].count = 1;
-
- const currentCount = this.activeElements[element_id].count;
-
- //fix "AudioContext already connected" error
- window.$wave = window.$wave || {};
- window.$wave[element.id] = window.$wave[element.id] || {};
-
- let audioCtx = window.$wave[element.id].audioCtx || new AudioContext();
- window.$wave[element.id].audioCtx = audioCtx;
-
- let analyser = window.$wave[element.id].analyzer || audioCtx.createAnalyser();
- window.$wave[element.id].analyser = analyser;
-
- //check if the element has a source already assigned and make sure they point to the same
- //reference because React will make a new element with a different reference
- let source = null;
- if (window.$wave[element.id].source)
- if (window.$wave[element.id].source.mediaElement === element)
- source = window.$wave[element.id].source;
- else
- source = audioCtx.createMediaElementSource(element);
- else
- source = audioCtx.createMediaElementSource(element);
-
- window.$wave[element.id].source = source;
-
- //beep test for ios
- let oscillator = audioCtx.createOscillator();
- oscillator.frequency.value = 1;
- oscillator.connect(audioCtx.destination);
- oscillator.start(0);
- oscillator.stop(0);
-
- source.connect(analyser);
- source.connect(audioCtx.destination);
-
- analyser.fftsize = 32768;
- let bufferLength = analyser.frequencyBinCount;
- let data = new Uint8Array(bufferLength);
- let frameCount = 1;
-
- function renderFrame() {
- //only run one wave visual per canvas
- if (JSON.stringify(options) != this.activeCanvas[canvas_id]) {
- return
- }
-
- //if the element or canvas go out of scope, stop animation
- if (!document.getElementById(element_id) || !document.getElementById(canvas_id))
- return
-
- requestAnimationFrame(renderFrame);
- frameCount++;
-
- //check if this element is the last to be called
- if (!(currentCount < this.activeElements[element_id].count)) {
- analyser.getByteFrequencyData(data);
- this.activeElements[element_id].data = data;
- }
-
- this.visualize(this.activeElements[element_id].data, canvas_id, options, frameCount);
- }
-
- renderFrame = renderFrame.bind(this);
- renderFrame();
-
- }
-
-
- const create = () => {
- //remove all events
- ["touchstart", "touchmove", "touchend", "mouseup", "click", "play"].forEach(event => {
- element.removeEventListener(event, create, { once: true });
- });
-
- run.call(waveContext);
- };
-
- if (this.activated) {
- run.call(waveContext);
- } else {
- //wait for a valid user gesture
- document.body.addEventListener("touchstart", create, { once: true });
- document.body.addEventListener("touchmove", create, { once: true });
- document.body.addEventListener("touchend", create, { once: true });
- document.body.addEventListener("mouseup", create, { once: true });
- document.body.addEventListener("click", create, { once: true });
- element.addEventListener("play", create, { once: true });
- }
-
-
-
+ function fromElement(element_id, canvas_id, options) {
+
+ const waveContext = this;
+ let element = document.getElementById(element_id);
+ if (!element) return
+ element.crossOrigin = "anonymous";
+
+ function run() {
+ //user gesture has happened
+ this.activated = true;
+
+ //track current wave for canvas
+ this.activeCanvas = this.activeCanvas || {};
+ this.activeCanvas[canvas_id] = JSON.stringify(options);
+
+ //track elements used so multiple elements use the same data
+ this.activeElements[element_id] = this.activeElements[element_id] || {};
+ if (this.activeElements[element_id].count) this.activeElements[element_id].count += 1;
+ else this.activeElements[element_id].count = 1;
+
+ const currentCount = this.activeElements[element_id].count;
+
+ //fix "AudioContext already connected" error
+ window.$wave = window.$wave || {};
+ window.$wave[element.id] = window.$wave[element.id] || {};
+
+ let audioCtx = window.$wave[element.id].audioCtx || new AudioContext();
+ window.$wave[element.id].audioCtx = audioCtx;
+
+ let analyser = window.$wave[element.id].analyzer || audioCtx.createAnalyser();
+ window.$wave[element.id].analyser = analyser;
+
+ //check if the element has a source already assigned and make sure they point to the same
+ //reference because React will make a new element with a different reference
+ let source = null;
+ if (window.$wave[element.id].source)
+ if (window.$wave[element.id].source.mediaElement === element)
+ source = window.$wave[element.id].source;
+ else
+ source = audioCtx.createMediaElementSource(element);
+ else
+ source = audioCtx.createMediaElementSource(element);
+
+ window.$wave[element.id].source = source;
+
+ //beep test for ios
+ let oscillator = audioCtx.createOscillator();
+ oscillator.frequency.value = 1;
+ oscillator.connect(audioCtx.destination);
+ oscillator.start(0);
+ oscillator.stop(0);
+
+ source.connect(analyser);
+ source.connect(audioCtx.destination);
+
+ analyser.fftsize = 32768;
+ let bufferLength = analyser.frequencyBinCount;
+ let data = new Uint8Array(bufferLength);
+ let frameCount = 1;
+
+ function renderFrame() {
+ //only run one wave visual per canvas
+ if (JSON.stringify(options) != this.activeCanvas[canvas_id]) {
+ return
+ }
+
+ //if the element or canvas go out of scope, stop animation
+ if (!document.getElementById(element_id) || !document.getElementById(canvas_id))
+ return
+
+ requestAnimationFrame(renderFrame);
+ frameCount++;
+
+ //check if this element is the last to be called
+ if (!(currentCount < this.activeElements[element_id].count)) {
+ analyser.getByteFrequencyData(data);
+ this.activeElements[element_id].data = data;
+ }
+
+ this.visualize(this.activeElements[element_id].data, canvas_id, options, frameCount);
+ }
+
+ renderFrame = renderFrame.bind(this);
+ renderFrame();
+
+ }
+
+
+ const create = () => {
+ //remove all events
+ ["touchstart", "touchmove", "touchend", "mouseup", "click", "play"].forEach(event => {
+ element.removeEventListener(event, create, { once: true });
+ });
+
+ run.call(waveContext);
+ };
+
+ if (this.activated) {
+ run.call(waveContext);
+ } else {
+ //wait for a valid user gesture
+ document.body.addEventListener("touchstart", create, { once: true });
+ document.body.addEventListener("touchmove", create, { once: true });
+ document.body.addEventListener("touchend", create, { once: true });
+ document.body.addEventListener("mouseup", create, { once: true });
+ document.body.addEventListener("click", create, { once: true });
+ element.addEventListener("play", create, { once: true });
+ }
+
+
+
}
- function fromFile(file, options = {}) {
- //options
- if (!options.stroke) options.stroke = 10;
-
- let audio = new Audio();
- audio.src = file;
-
- let audioCtx = new AudioContext();
- let analyser = audioCtx.createAnalyser();
-
- let source = audioCtx.createMediaElementSource(audio);
- source.connect(analyser);
-
- analyser.fftSize = 64;
- let bufferLength = analyser.frequencyBinCount;
-
- let file_data;
- let temp_data = new Uint8Array(bufferLength);
- let getWave;
- let fdi = 0;
- let self = this;
-
- audio.addEventListener('loadedmetadata', async function () {
-
- while (audio.duration === Infinity) {
- await new Promise(r => setTimeout(r, 1000));
- audio.currentTime = 10000000 * Math.random();
- }
-
- audio.currentTime = 0;
- audio.play();
- });
-
- audio.onplay = function () {
- let findSize = (size) => {
-
- for (let range = 1; range <= 40; range++) {
- let power = 2 ** range;
-
- if (size <= power) return power;
- }
-
- };
- let d = audio.duration;
- audio.playbackRate = 16;
-
- d = d / audio.playbackRate;
-
- let drawRate = 20; //ms
-
- let size = ((d / (drawRate / 1000)) * (analyser.fftSize / 2));
- size = findSize(size);
- file_data = new Uint8Array(size);
-
-
- getWave = setInterval(function () {
- analyser.getByteFrequencyData(temp_data);
-
- for (let data in temp_data) {
- data = temp_data[data];
- file_data[fdi] = data;
- fdi++;
- }
-
- }, drawRate);
-
-
- };
-
- audio.onended = function () {
-
- if (audio.currentTime === audio.duration && file_data !== undefined) {
-
- clearInterval(getWave);
-
- let canvas = document.createElement("canvas");
- canvas.height = window.innerHeight;
- canvas.width = window.innerWidth;
-
- self.visualize(file_data, canvas, options);
- let image = canvas.toDataURL("image/jpg");
- self.onFileLoad(image);
-
- canvas.remove();
- }
-
- };
-
+ function fromFile(file, options = {}) {
+ //options
+ if (!options.stroke) options.stroke = 10;
+
+ let audio = new Audio();
+ audio.src = file;
+
+ let audioCtx = new AudioContext();
+ let analyser = audioCtx.createAnalyser();
+
+ let source = audioCtx.createMediaElementSource(audio);
+ source.connect(analyser);
+
+ analyser.fftSize = 64;
+ let bufferLength = analyser.frequencyBinCount;
+
+ let file_data;
+ let temp_data = new Uint8Array(bufferLength);
+ let getWave;
+ let fdi = 0;
+ let self = this;
+
+ audio.addEventListener('loadedmetadata', async function () {
+
+ while (audio.duration === Infinity) {
+ await new Promise(r => setTimeout(r, 1000));
+ audio.currentTime = 10000000 * Math.random();
+ }
+
+ audio.currentTime = 0;
+ audio.play();
+ });
+
+ audio.onplay = function () {
+ let findSize = (size) => {
+
+ for (let range = 1; range <= 40; range++) {
+ let power = 2 ** range;
+
+ if (size <= power) return power;
+ }
+
+ };
+ let d = audio.duration;
+ audio.playbackRate = 16;
+
+ d = d / audio.playbackRate;
+
+ let drawRate = 20; //ms
+
+ let size = ((d / (drawRate / 1000)) * (analyser.fftSize / 2));
+ size = findSize(size);
+ file_data = new Uint8Array(size);
+
+
+ getWave = setInterval(function () {
+ analyser.getByteFrequencyData(temp_data);
+
+ for (let data in temp_data) {
+ data = temp_data[data];
+ file_data[fdi] = data;
+ fdi++;
+ }
+
+ }, drawRate);
+
+
+ };
+
+ audio.onended = function () {
+
+ if (audio.currentTime === audio.duration && file_data !== undefined) {
+
+ clearInterval(getWave);
+
+ let canvas = document.createElement("canvas");
+ canvas.height = window.innerHeight;
+ canvas.width = window.innerWidth;
+
+ self.visualize(file_data, canvas, options);
+ let image = canvas.toDataURL("image/jpg");
+ self.onFileLoad(image);
+
+ canvas.remove();
+ }
+
+ };
+
}
- function fromStream(stream, canvas_id, options = {}) {
-
- this.current_stream.id = canvas_id;
- this.current_stream.options = options;
-
- let audioCtx, analyser, source;
- if (!this.sources[stream.toString()]) {
- audioCtx = new AudioContext();
- analyser = audioCtx.createAnalyser();
-
- source = audioCtx.createMediaStreamSource(stream);
- source.connect(analyser);
- source.connect(audioCtx.destination); //playback audio
-
- this.sources[stream.toString()] = {
- "audioCtx": audioCtx,
- "analyser": analyser,
- "source": source
- };
- } else {
- cancelAnimationFrame(this.sources[stream.toString()].animation);
- audioCtx = this.sources[stream.toString()].audioCtx;
- analyser = this.sources[stream.toString()].analyser;
- source = this.sources[stream.toString()].source;
- }
-
- analyser.fftsize = 32768;
- let bufferLength = analyser.frequencyBinCount;
- this.current_stream.data = new Uint8Array(bufferLength);
-
- let self = this;
-
- function renderFrame() {
- self.current_stream.animation = requestAnimationFrame(self.current_stream.loop);
- self.sources[stream.toString()].animation = self.current_stream.animation;
- analyser.getByteFrequencyData(self.current_stream.data);
-
- self.visualize(self.current_stream.data, self.current_stream.id, self.current_stream.options);
- }
-
- this.current_stream.loop = renderFrame;
- renderFrame();
-
- }
-
- function stopStream() {
- cancelAnimationFrame(this.current_stream.animation);
- }
-
- function playStream() {
- this.current_stream.loop();
- }
-
- var fromStream$1 = {
- fromStream,
- stopStream,
- playStream
+ function fromStream(stream, canvas_id, options = {}) {
+
+ this.current_stream.id = canvas_id;
+ this.current_stream.options = options;
+
+ let audioCtx, analyser, source;
+ if (!this.sources[stream.toString()]) {
+ audioCtx = new AudioContext();
+ analyser = audioCtx.createAnalyser();
+
+ source = audioCtx.createMediaStreamSource(stream);
+ source.connect(analyser);
+ source.connect(audioCtx.destination); //playback audio
+
+ this.sources[stream.toString()] = {
+ "audioCtx": audioCtx,
+ "analyser": analyser,
+ "source": source
+ };
+ } else {
+ cancelAnimationFrame(this.sources[stream.toString()].animation);
+ audioCtx = this.sources[stream.toString()].audioCtx;
+ analyser = this.sources[stream.toString()].analyser;
+ source = this.sources[stream.toString()].source;
+ }
+
+ analyser.fftsize = 32768;
+ let bufferLength = analyser.frequencyBinCount;
+ this.current_stream.data = new Uint8Array(bufferLength);
+
+ let self = this;
+
+ function renderFrame() {
+ self.current_stream.animation = requestAnimationFrame(self.current_stream.loop);
+ self.sources[stream.toString()].animation = self.current_stream.animation;
+ analyser.getByteFrequencyData(self.current_stream.data);
+
+ self.visualize(self.current_stream.data, self.current_stream.id, self.current_stream.options);
+ }
+
+ this.current_stream.loop = renderFrame;
+ renderFrame();
+
+ }
+
+ function stopStream() {
+ cancelAnimationFrame(this.current_stream.animation);
+ }
+
+ function playStream() {
+ this.current_stream.loop();
+ }
+
+ var fromStream$1 = {
+ fromStream,
+ stopStream,
+ playStream
};
- var drawWave = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- const helper = new Helper(ctx);
-
- // data = helper.mutateData(data, "shrink", 200)
- data = helper.mutateData(data, "split", 4)[0];
- data = helper.mutateData(data, "scale", h);
-
- let points = helper.getPoints("line", w, [0, h], data.length, data, { offset: 100 });
- points.start = points.start.slice(0, points.end.length - 1);
- points.start.push([w, h]);
- points.start.push([0, h]);
-
- helper.drawPolygon(points.start, { lineColor: colors[0], color: colors[1], radius: (h * .008) });
-
-
+ var drawWave = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ const helper = new Helper(ctx);
+
+ // data = helper.mutateData(data, "shrink", 200)
+ data = helper.mutateData(data, "split", 4)[0];
+ data = helper.mutateData(data, "scale", h);
+
+ let points = helper.getPoints("line", w, [0, h], data.length, data, { offset: 100 });
+ points.start = points.start.slice(0, points.end.length - 1);
+ points.start.push([w, h]);
+ points.start.push([0, h]);
+
+ helper.drawPolygon(points.start, { lineColor: colors[0], color: colors[1], radius: (h * .008) });
+
+
};
- var drawShine = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let cx = w / 2;
- let cy = h / 2;
- let r = h / 4;
- let percent = (h / 2 - r) / 255;
- let point_count = 512;
- let increase = (360 / point_count) * Math.PI / 180;
-
- for (let point = 1; point <= point_count; point++) {
- let p = data[600 % point]; //get value
- p *= percent;
- point++; //start at 1
- let a = point * increase;
-
- let sx = cx + r * Math.cos(a);
- let sy = cy + r * Math.sin(a);
- ctx.moveTo(sx, sy);
-
- let dx = cx + (r + p) * Math.cos(a);
- let dy = cy + (r + p) * Math.sin(a);
- ctx.lineTo(dx, dy);
-
- }
- ctx.stroke();
+ var drawShine = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let cx = w / 2;
+ let cy = h / 2;
+ let r = h / 4;
+ let percent = (h / 2 - r) / 255;
+ let point_count = 512;
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = data[600 % point]; //get value
+ p *= percent;
+ point++; //start at 1
+ let a = point * increase;
+
+ let sx = cx + r * Math.cos(a);
+ let sy = cy + r * Math.sin(a);
+ ctx.moveTo(sx, sy);
+
+ let dx = cx + (r + p) * Math.cos(a);
+ let dy = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+
+ }
+ ctx.stroke();
+
+ if (options.colors[1]) {
+ ctx.arc(cx, cy, r * .90, 0, 2 * Math.PI);
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+ };
- if (options.colors[1]) {
- ctx.arc(cx, cy, r * .90, 0, 2 * Math.PI);
- ctx.fillStyle = options.colors[1];
- ctx.fill();
- }
+ var drawRing = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let cx = w / 2;
+ let cy = h / 2;
+ let r = (h - 10) / 2;
+ let offset = r / 5;
+ let percent = (r - offset) / 255;
+ let point_count = 150;
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ ctx.arc(cx, cy, r, 0, 2 * Math.PI, true);
+
+ let fa = 0;
+ let fx = cx + (r - (data[0] * percent)) * Math.cos(fa);
+ let fy = cy + (r - (data[0] * percent)) * Math.sin(fa);
+ ctx.moveTo(fx, fy);
+
+ let q = 0;
+ for (let point = 0; point < point_count; point++) {
+ q += 1;
+ if (point >= point_count / 2) {
+ q -= 2;
+ }
+
+ let p = data[q]; //get value
+ p *= percent;
+
+ let a = point * increase;
+ let x = cx + (r - p) * Math.cos(a);
+ let y = cy + (r - p) * Math.sin(a);
+
+ ctx.lineTo(x, y);
+ ctx.arc(x, y, 2, 0, 2 * Math.PI);
+
+ }
+ ctx.lineTo(fx, fy);
+
+ ctx.stroke();
+ ctx.fillStyle = options.colors[1] || "#fff0";
+ ctx.fill();
};
- var drawRing = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
+ var drawBars = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let point_count = 64;
+ let percent = h / 255;
+ let increase = w / 64;
+ let breakpoint = Math.floor(point_count / options.colors.length);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = data[point]; //get value
+ p *= percent;
+
+ let x = increase * point;
+
+ ctx.moveTo(x, h);
+ ctx.lineTo(x, h - p);
+
+ if (point % breakpoint === 0) {
+ let i = (point / breakpoint) - 1;
+ ctx.strokeStyle = options.colors[i];
+ ctx.stroke();
+ ctx.beginPath();
+ }
+
+ }
+ };
- let cx = w / 2;
- let cy = h / 2;
- let r = (h - 10) / 2;
- let offset = r / 5;
- let percent = (r - offset) / 255;
- let point_count = 150;
- let increase = (360 / point_count) * Math.PI / 180;
+ var drawDualbars = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let percent = h / 255;
+ let increase = w / 128;
+ let point_count = 128;
+ let min = 5;
+ let breakpoint = Math.floor(point_count / options.colors.length);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = data[point]; //get value
+ p += min;
+ p *= percent;
+
+ let x = increase * point;
+
+ let mid = (h / 2) + (p / 2);
+
+ ctx.moveTo(x, mid);
+ ctx.lineTo(x, mid - p);
+
+ if (point % breakpoint === 0) {
+ let i = (point / breakpoint) - 1;
+ ctx.strokeStyle = options.colors[i];
+ ctx.stroke();
+ ctx.beginPath();
+ }
+
+ }
+ };
- ctx.arc(cx, cy, r, 0, 2 * Math.PI, true);
+ var drawOrbs = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ const helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "organize").mids;
+ data = helper.mutateData(data, "split", 2)[0];
+ data = helper.mutateData(data, "shrink", 100);
+ data = helper.mutateData(data, "mirror");
+ data = helper.mutateData(data, "scale", h);
+ data = helper.mutateData(data, "amp", .75);
+
+ let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
+ points.start.forEach((start, i) => {
+ helper.drawLine(start, points.end[i], { lineColor: colors[0] });
+
+ helper.drawCircle(start, h * .01, { color: colors[1] || colors[0] });
+ helper.drawCircle(points.end[i], h * .01, { color: colors[1] || colors[0] });
+ });
+ };
- let fa = 0;
- let fx = cx + (r - (data[0] * percent)) * Math.cos(fa);
- let fy = cy + (r - (data[0] * percent)) * Math.sin(fa);
- ctx.moveTo(fx, fy);
+ var drawFlower = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let min = 5;
+ let r = h / 4;
+ let offset = r / 2;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 128;
+ let percent = (r - offset) / 255;
+ let increase = (360 / point_count) * Math.PI / 180;
+ let breakpoint = Math.floor(point_count / options.colors.length);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = (data[point] + min) * percent;
+ let a = point * increase;
+
+ let sx = cx + (r - (p - offset)) * Math.cos(a);
+ let sy = cy + (r - (p - offset)) * Math.sin(a);
+ ctx.moveTo(sx, sy);
+
+ let dx = cx + (r + p) * Math.cos(a);
+ let dy = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+
+ if (point % breakpoint === 0) {
+ let i = (point / breakpoint) - 1;
+ ctx.strokeStyle = options.colors[i];
+ ctx.stroke();
+ ctx.beginPath();
+ }
+ }
+
+ ctx.stroke();
+ };
- let q = 0;
- for (let point = 0; point < point_count; point++) {
- q += 1;
- if (point >= point_count / 2) {
- q -= 2;
- }
+ var drawFlowerBlocks = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+ let r = h / 4;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 56;
+ let percent = r / 255;
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = (data[point]) * percent;
+ let a = point * increase;
+
+ let ax = cx + (r - (p / 2)) * Math.cos(a);
+ let ay = cy + (r - (p / 2)) * Math.sin(a);
+ ctx.moveTo(ax, ay);
+
+ let bx = cx + (r + p) * Math.cos(a);
+ let by = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(bx, by);
+
+ let dx = cx + (r + p) * Math.cos(a + increase);
+ let dy = cy + (r + p) * Math.sin(a + increase);
+ ctx.lineTo(dx, dy);
+
+ let ex = cx + (r - (p / 2)) * Math.cos(a + increase);
+ let ey = cy + (r - (p / 2)) * Math.sin(a + increase);
+
+ ctx.lineTo(ex, ey);
+ ctx.lineTo(ax, ay);
+ }
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+
+ ctx.stroke();
+ };
- let p = data[q]; //get value
- p *= percent;
+ var drawBarsBlocks = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let percent = h / 255;
+ let width = w / 64;
+
+ for (let point = 0; point < 64; point++) {
+ let p = data[point]; //get value
+ p *= percent;
+ let x = width * point;
+
+ ctx.rect(x, h, width, -(p));
+ }
+
+ ctx.fillStyle = options.colors[1] || options.colors[0];
+ ctx.stroke();
+ ctx.fill();
+ };
- let a = point * increase;
- let x = cx + (r - p) * Math.cos(a);
- let y = cy + (r - p) * Math.sin(a);
+ var drawDualbarsBlocks = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let percent = h / 255;
+ let width = w / 50;
+
+ for (let point = 0; point <= 50; point++) {
+ let p = data[point]; //get value
+ p *= percent;
+ let x = width * point;
+
+ ctx.rect(x, (h / 2) + (p / 2), width, -(p));
+ }
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+
+ ctx.stroke();
+ };
- ctx.lineTo(x, y);
- ctx.arc(x, y, 2, 0, 2 * Math.PI);
+ var drawStar = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let r = h / 4;
+ let offset = r / 4;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 120;
+ let percent = (r - offset - 35) / (255);
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ let top = [];
+ let bottom = [];
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = ((data[200 % point])) * percent;
+ let a = point * increase;
+
+ let sx = cx + ((r) - p + offset) * Math.cos(a);
+ let sy = cy + ((r) - p + offset) * Math.sin(a);
+ ctx.moveTo(sx, sy);
+ bottom.push({
+ x: sx,
+ y: sy
+ });
+
+ let dx = cx + (r + p + offset) * Math.cos(a);
+ let dy = cy + (r + p + offset) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+ top.push({
+ x: dx,
+ y: dy
+ });
+
+ }
+
+
+ ctx.moveTo(top[0].x, top[0].y);
+ for (let t in top) {
+ t = top[t];
+
+ ctx.lineTo(t.x, t.y);
+ }
+ ctx.closePath();
+
+ ctx.moveTo(bottom[0].x, bottom[0].y);
+ for (let b = bottom.length - 1; b >= 0; b++) {
+ b = bottom[b];
+
+ ctx.lineTo(b.x, b.y);
+ }
+ ctx.closePath();
+
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+ ctx.stroke();
+
+ //inner color
+ ctx.beginPath();
+ ctx.moveTo(bottom[0].x, bottom[0].y);
+ for (let b in bottom) {
+ b = bottom[b];
+
+ ctx.lineTo(b.x, b.y);
+ }
+ ctx.closePath();
+
+
+ if (options.colors[2]) {
+ ctx.fillStyle = options.colors[2];
+ ctx.fill();
+ }
+ ctx.stroke();
+ };
- }
- ctx.lineTo(fx, fy);
+ var drawRoundWave = (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let r = h / 4;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 100;
+ let percent = r / 255;
+ let increase = (360 / point_count) * Math.PI / 180;
+ let p = 0;
+
+ // let z = (data[0] + min + offset) * percent;
+ let sx = cx + (r + p) * Math.cos(0);
+ let sy = cy + (r + p) * Math.sin(0);
+ ctx.moveTo(sx, sy);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = (data[350 % point]) * percent;
+ let a = point * increase;
+
+ let dx = cx + (r + p) * Math.cos(a);
+ let dy = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+ }
+
+ ctx.closePath();
+ ctx.stroke();
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+ };
- ctx.stroke();
- ctx.fillStyle = options.colors[1] || "#fff0";
- ctx.fill();
+ var drawRings = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ let helper = new Helper(ctx);
+ let minDimension = (h < w) ? h : w;
+
+ data = helper.mutateData(data, "organize");
+ data = [data.mids, data.vocals];
+
+ data[0] = helper.mutateData(data[0], "scale", minDimension / 4);
+ data[1] = helper.mutateData(data[1], "scale", minDimension / 8);
+
+ data[0] = helper.mutateData(data[0], "shrink", 1 / 5);
+ data[0] = helper.mutateData(data[0], "split", 2)[0];
+
+ data[0] = helper.mutateData(data[0], "reverb");
+ data[1] = helper.mutateData(data[1], "reverb");
+
+
+ let outerCircle = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data[0].length, data[0]);
+ let innerCircle = helper.getPoints("circle", minDimension / 4, [w / 2, h / 2], data[1].length, data[1]);
+
+ helper.drawPolygon(outerCircle.end, { close: true, radius: 4, lineColor: colors[0], color: colors[1] });
+ helper.drawPolygon(innerCircle.end, { close: true, radius: 4, lineColor: colors[2], color: colors[3] });
+
+ let middle = ((minDimension / 4) + (minDimension / 2)) / 2;
+ let largerInner = data[1] = helper.mutateData(data[1], "scale", ((minDimension / 4) - (minDimension / 2)));
+ let innerBars = helper.getPoints("circle", middle, [w / 2, h / 2], data[1].length, largerInner);
+ innerBars.start.forEach((start, i) => {
+ helper.drawLine(start, innerBars.end[i], { lineColor: colors[4] || colors[2] });
+ });
};
- var drawBars = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
+ var drawShineRings = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+
+ let helper = new Helper(ctx);
+ let minDimension = (h < w) ? h : w;
+
+ data = helper.mutateData(data, "organize");
+ data.vocals = helper.mutateData(data.vocals, "scale", (minDimension / 2) / 2);
+ data.base = helper.mutateData(data.base, "scale", (minDimension / 2) / 2);
+
+ let outerBars = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals);
+ let innerWave = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals, { offset: 100 });
+ let thinLine = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.base.length, data.base, { offset: 100 });
+
+ outerBars.start.forEach((start, i) => {
+ helper.drawLine(start, outerBars.end[i], { lineColor: colors[0] });
+ });
+
+ helper.drawPolygon(innerWave.start, { close: true, lineColor: colors[1], color: colors[3], radius: 5 });
+ helper.drawPolygon(thinLine.start, { close: true, lineColor: colors[2], color: colors[4], radius: 5 });
+ };
- let point_count = 64;
- let percent = h / 255;
- let increase = w / 64;
- let breakpoint = Math.floor(point_count / options.colors.length);
+ var drawCubes = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ let helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "organize").base;
+
+ data = helper.mutateData(data, "shrink", 20).slice(0, 19);
+ data = helper.mutateData(data, "scale", h);
+
+ let points = helper.getPoints("line", w, [0, h], data.length, data);
+
+ let spacing = 5;
+ let squareSize = (w / 20) - spacing;
+ let colorIndex = 0;
+
+ points.start.forEach((start, i) => {
+ let squareCount = Math.ceil(data[i] / squareSize);
+
+ //find color stops from total possible squares in bar
+ let totalSquares = (h - (spacing * (h / squareSize))) / squareSize;
+ let colorStop = Math.ceil(totalSquares / colors.length);
+
+ for (let j = 1; j <= squareCount; j++) {
+ let origin = [start[0], (start[1] - (squareSize * j) - (spacing * j))];
+ helper.drawSquare(origin, squareSize, { color: colors[colorIndex], lineColor: "black" });
+ if (j % colorStop == 0) {
+ colorIndex++;
+ if (colorIndex >= colors.length) colorIndex = colors.length - 1;
+ }
+ }
+ colorIndex = 0;
+ });
+ };
- for (let point = 1; point <= point_count; point++) {
- let p = data[point]; //get value
- p *= percent;
+ var drawBigBars = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ const helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "organize").vocals;
+ data = helper.mutateData(data, "shrink", 10);
+ data = helper.mutateData(data, "scale", h);
+ data = helper.mutateData(data, "amp", 1);
+ let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
+
+ let colorIndex = 0;
+ let colorStop = Math.ceil(data.length / colors.length);
+ points.start.forEach((start, i) => {
+ if ((i + 1) % colorStop == 0) colorIndex++;
+ helper.drawRectangle(start, data[i], w / data.length, { color: colors[colorIndex] });
+ });
+
+ };
- let x = increase * point;
+ var drawShockwave = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+
+ let helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "shrink", 300);
+ data = helper.mutateData(data, "scale", h / 2);
+ data = helper.mutateData(data, "split", 4).slice(0, 3);
+
+ let colorIndex = 0;
+ data.forEach((points) => {
+ let wavePoints = helper.getPoints("line", w, [0, h / 2], points.length, points);
+ helper.drawPolygon(wavePoints.end, { lineColor: colors[colorIndex], radius: (h * .015) });
+
+ let invertedPoints = helper.getPoints("line", w, [0, h / 2], points.length, points, { offset: 100 });
+ helper.drawPolygon(invertedPoints.start, { lineColor: colors[colorIndex], radius: (h * .015) });
+ colorIndex++;
+ });
+ };
- ctx.moveTo(x, h);
- ctx.lineTo(x, h - p);
+ var drawFireworks = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ const helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "shrink", 200).slice(0, 120);
+ data = helper.mutateData(data, "mirror");
+ data = helper.mutateData(data, "scale", (h / 4) + ((h / 4) * .35));
+
+ let points = helper.getPoints("circle", h / 2, [w / 2, h / 2], data.length, data, { offset: 35, rotate: 270 });
+
+ points.start.forEach((start, i) => {
+ helper.drawLine(start, points.end[i]);
+ });
+
+ helper.drawPolygon(points.start, { close: true });
+
+ points.end.forEach((end, i) => {
+ helper.drawCircle(end, h * .01, { color: colors[0] });
+ });
+ };
- if (point % breakpoint === 0) {
- let i = (point / breakpoint) - 1;
- ctx.strokeStyle = options.colors[i];
- ctx.stroke();
- ctx.beginPath();
- }
+ var drawStatic = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "shrink", 1 / 8);
+ data = helper.mutateData(data, "split", 2)[0];
+ data = helper.mutateData(data, "scale", h);
+
+ let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
+ let prevPoint = null;
+ points.start.forEach((start, i) => {
+ if (prevPoint) {
+ helper.drawLine(prevPoint, start);
+ }
+ helper.drawLine(start, points.end[i]);
+ prevPoint = points.end[i];
+ });
+
+
+ };
- }
+ var drawWeb = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ const helper = new Helper(ctx);
+ let minDimension = (h < w) ? h : w;
+
+ data = helper.mutateData(data, "shrink", 100);
+ data = helper.mutateData(data, "split", 2)[0];
+ data = helper.mutateData(data, "scale", h / 4);
+
+ let dataCopy = data;
+
+ let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
+ helper.drawPolygon(points.end, { close: true });
+
+ points.start.forEach((start, i) => {
+ helper.drawLine(start, points.end[i]);
+ });
+
+ data = helper.mutateData(data, "scale", .7);
+ points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
+ helper.drawPolygon(points.end, { close: true });
+
+ data = helper.mutateData(data, "scale", .3);
+ points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
+ helper.drawPolygon(points.end, { close: true });
+
+ helper.drawCircle([w / 2, h / 2], minDimension / 2, { color: colors[2] });
+
+ dataCopy = helper.mutateData(dataCopy, "scale", 1.4);
+ points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], dataCopy.length, dataCopy);
+ points.end.forEach((end, i) => {
+ helper.drawCircle(end, minDimension * .01, { color: colors[1], lineColor: colors[1] || colors[0] });
+ });
};
- var drawDualbars = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
+ var drawStitches = (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let helper = new Helper(ctx);
+ let minDimension = (h < w) ? h : w;
+
+ data = helper.mutateData(data, "shrink", 200);
+ data = helper.mutateData(data, "split", 2)[0];
+ data = helper.mutateData(data, "scale", h / 2);
+
+ let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data, { offset: 50 });
+
+ helper.drawPolygon(points.end, { close: true });
+ helper.drawPolygon(points.start, { close: true });
+
+ for (let i = 0; i < points.start.length; i += 1) {
+ let start = points.start[i];
+ i++;
+ let end = points.end[i] || points.end[0];
+
+ helper.drawLine(start, end);
+ helper.drawLine(end, points.start[i + 1] || points.start[0]);
+ }
+ };
- let percent = h / 255;
- let increase = w / 128;
- let point_count = 128;
- let min = 5;
- let breakpoint = Math.floor(point_count / options.colors.length);
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
- for (let point = 1; point <= point_count; point++) {
- let p = data[point]; //get value
- p += min;
- p *= percent;
+ function createCommonjsModule(fn, module) {
+ return module = { exports: {} }, fn(module, module.exports), module.exports;
+ }
- let x = increase * point;
+ var origami_1 = createCommonjsModule(function (module, exports) {
+ /*!
+ * Origami.js 0.5.0
+ * https://origamijs.com/
+ *
+ * Copyright Raphael Amorim 2016
+ * Released under the GPL-4.0 license
+ *
+ * Date: 2016-09-23T03:42Z
+ */
+
+ (function( window ) {
+
+ /**
+ * Config object: Maintain internal state
+ * Later exposed as Origami.config
+ * `config` initialized at top of scope
+ */
+
+ var Origami = {
+ // Current Paper
+ paper: null
+ };
- let mid = (h / 2) + (p / 2);
+ var config = {
+ // Document Styles
+ documentStyles: [],
- ctx.moveTo(x, mid);
- ctx.lineTo(x, mid - p);
+ // Virtual Styles
+ virtualStyles: {},
- if (point % breakpoint === 0) {
- let i = (point / breakpoint) - 1;
- ctx.strokeStyle = options.colors[i];
- ctx.stroke();
- ctx.beginPath();
- }
+ // All contexts saved
+ contexts: [],
+ // Origami Shapes Defaults
+ defaults: {
+ arc: {
+ background: 'rgba(0, 0, 0, 0)',
+ strokeStyle: 'rgba(0, 0, 0, 0)',
+ lineWidth: null,
+ },
+ rect: {
+ background: 'rgba(0, 0, 0, 0)',
+ strokeStyle: 'rgba(0, 0, 0, 0)',
+ lineWidth: null,
+ },
+ polygon: {
+ background: 'rgba(0, 0, 0, 0)',
+ strokeStyle: 'rgba(0, 0, 0, 0)',
+ lineWidth: null,
+ },
+ line: {
+ strokeStyle: 'rgba(0, 0, 0, 0)',
+ lineWidth: null,
+ },
+ text: {
+ font: '14px Helvetica',
+ strokeStyle: 'rgba(0, 0, 0, 0)',
+ color: '#000',
+ lineWidth: null,
}
+ }
};
- var drawOrbs = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- const helper = new Helper(ctx);
+ var prefix = "[origami.js]";
- data = helper.mutateData(data, "organize").mids;
- data = helper.mutateData(data, "split", 2)[0];
- data = helper.mutateData(data, "shrink", 100);
- data = helper.mutateData(data, "mirror");
- data = helper.mutateData(data, "scale", h);
- data = helper.mutateData(data, "amp", .75);
+ Origami.warning = function warning(message, obj){
+ if (console && console.warn)
+ console.warn(prefix, message, obj);
+ };
- let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
- points.start.forEach((start, i) => {
- helper.drawLine(start, points.end[i], { lineColor: colors[0] });
+ Origami.error = function error(message){
+ throw new Error(prefix.concat(' ' + message));
+ };
+ Origami.init = function(el) {
+ if (el.canvas) {
+ el = el.canvas;
+ } else {
+ el = document.querySelector(el);
+ }
+
+ if (!el)
+ this.error('Please use a valid selector or canvas context');
+
+ var existentContext = exists(el, config.contexts);
+ if (existentContext) {
+ this.paper = existentContext;
+ return this;
+ }
+
+ if (!el.getContext)
+ this.error('Please verify if it\'s a valid canvas element');
+
+ el.width = el.clientWidth;
+ el.height = el.clientHeight;
+ var context = el.getContext('2d');
+ var current = {
+ element: el,
+ queue: [],
+ index: config.contexts.length,
+ flip: false,
+ frame: null,
+ ctx: context,
+ width: el.width,
+ height: el.height,
+ };
+
+ config.contexts.push(current);
+ this.paper = current;
+ return this;
+ };
- helper.drawCircle(start, h * .01, { color: colors[1] || colors[0] });
- helper.drawCircle(points.end[i], h * .01, { color: colors[1] || colors[0] });
- });
+ Origami.styles = function() {
+ if (!config.virtualStyles.length)
+ defineDocumentStyles();
+
+ var selectors = arguments;
+ if (!selectors.length) {
+ config.virtualStyles['empty'] = true;
+ return this;
+ }
+
+ for (var i = 0; i < selectors.length; i++) {
+ var style = styleRuleValueFrom(selectors[i], (config.documentStyles[0] || []));
+ config.virtualStyles[selectors[i]] = style;
+ }
+ return this;
};
- var drawFlower = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let min = 5;
- let r = h / 4;
- let offset = r / 2;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 128;
- let percent = (r - offset) / 255;
- let increase = (360 / point_count) * Math.PI / 180;
- let breakpoint = Math.floor(point_count / options.colors.length);
-
- for (let point = 1; point <= point_count; point++) {
- let p = (data[point] + min) * percent;
- let a = point * increase;
-
- let sx = cx + (r - (p - offset)) * Math.cos(a);
- let sy = cy + (r - (p - offset)) * Math.sin(a);
- ctx.moveTo(sx, sy);
-
- let dx = cx + (r + p) * Math.cos(a);
- let dy = cy + (r + p) * Math.sin(a);
- ctx.lineTo(dx, dy);
-
- if (point % breakpoint === 0) {
- let i = (point / breakpoint) - 1;
- ctx.strokeStyle = options.colors[i];
- ctx.stroke();
- ctx.beginPath();
- }
- }
+ Origami.getPaper = function() {
+ return this.paper;
+ };
- ctx.stroke();
+ Origami.canvasCtx = function() {
+ return this.paper.ctx;
};
- var drawFlowerBlocks = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
- let r = h / 4;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 56;
- let percent = r / 255;
- let increase = (360 / point_count) * Math.PI / 180;
+ Origami.getContexts = function() {
+ return config.contexts;
+ };
- for (let point = 1; point <= point_count; point++) {
- let p = (data[point]) * percent;
- let a = point * increase;
+ Origami.cleanContexts = function() {
+ config.contexts = [];
+ };
- let ax = cx + (r - (p / 2)) * Math.cos(a);
- let ay = cy + (r - (p / 2)) * Math.sin(a);
- ctx.moveTo(ax, ay);
+ Origami.createComponent = function(component, fn) {
+ Origami[component] = function(props) {
+ fn.bind(this, this, props)();
+ return this;
+ };
+ };
- let bx = cx + (r + p) * Math.cos(a);
- let by = cy + (r + p) * Math.sin(a);
- ctx.lineTo(bx, by);
+ Origami.fn = {};
- let dx = cx + (r + p) * Math.cos(a + increase);
- let dy = cy + (r + p) * Math.sin(a + increase);
- ctx.lineTo(dx, dy);
+ Origami.draw = function(options) {
+ var self = this,
+ customRender = false,
+ ctx = self.paper.ctx;
- let ex = cx + (r - (p / 2)) * Math.cos(a + increase);
- let ey = cy + (r - (p / 2)) * Math.sin(a + increase);
+ if (typeof(options) === 'string') {
+ customRender = new origami.fn[options](self.paper);
+ self.paper['ctx'] = customRender;
+ }
- ctx.lineTo(ex, ey);
- ctx.lineTo(ax, ay);
- }
+ var abs = new Screen(self.paper),
+ queueList = self.paper.queue;
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
+ for (var i = 0; i < queueList.length; i++) {
+ if (queueList[i].loaded === false || queueList[i].failed) {
+ Origami.warning('couldn\'t able to load:', queueList[i].params);
}
+ abs[queueList[i].assign](queueList[i].params);
+ }
+ self.paper.queue = [];
- ctx.stroke();
- };
-
- var drawBarsBlocks = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
+ if (customRender) {
+ customRender.draw();
+ self.paper.ctx = ctx;
+ }
- let percent = h / 255;
- let width = w / 64;
-
- for (let point = 0; point < 64; point++) {
- let p = data[point]; //get value
- p *= percent;
- let x = width * point;
-
- ctx.rect(x, h, width, -(p));
- }
-
- ctx.fillStyle = options.colors[1] || options.colors[0];
- ctx.stroke();
- ctx.fill();
+ if (typeof(options) === 'function')
+ options();
};
- var drawDualbarsBlocks = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let percent = h / 255;
- let width = w / 50;
-
- for (let point = 0; point <= 50; point++) {
- let p = data[point]; //get value
- p *= percent;
- let x = width * point;
-
- ctx.rect(x, (h / 2) + (p / 2), width, -(p));
- }
+ Origami.load = function(fn) {
+ var mOrigami = clone(this);
+ mOrigami.paper = this.paper;
+ var loadInterval = setInterval(function() {
+ var dataLoad = mOrigami.paper.queue.filter(function(item) {
+ return (item.loaded === false && !item.failed);
+ });
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
+ // When already loaded
+ if (!dataLoad.length) {
+ clearInterval(loadInterval);
+ fn.bind(mOrigami, mOrigami)();
}
-
- ctx.stroke();
+ }, 1);
};
- var drawStar = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let r = h / 4;
- let offset = r / 4;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 120;
- let percent = (r - offset - 35) / (255);
- let increase = (360 / point_count) * Math.PI / 180;
+ function Queue(assign, params, loaded) {
+ this.paper.queue.push({
+ assign: assign,
+ params: params,
+ loaded: loaded
+ });
+ }
- let top = [];
- let bottom = [];
+ var queue = Queue.bind(Origami);
- for (let point = 1; point <= point_count; point++) {
- let p = ((data[200 % point])) * percent;
- let a = point * increase;
+ // Utilities.js
- let sx = cx + ((r) - p + offset) * Math.cos(a);
- let sy = cy + ((r) - p + offset) * Math.sin(a);
- ctx.moveTo(sx, sy);
- bottom.push({
- x: sx,
- y: sy
- });
+ var hasOwn = Object.prototype.hasOwnProperty;
- let dx = cx + (r + p + offset) * Math.cos(a);
- let dy = cy + (r + p + offset) * Math.sin(a);
- ctx.lineTo(dx, dy);
- top.push({
- x: dx,
- y: dy
- });
+ /**
+ * Check if element exists in a Array of NodeItems
+ * @param {NodeItem} current nodeItem to check
+ * @param {Array} array of NodeItems
+ * @returns {NodeItem} NodeItem exitent in array
+ */
+ function exists(el, arr) {
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i].element.isEqualNode(el))
+ return arr[i];
+ }
+ return false;
+ }
- }
+ /**
+ * Filter arguments by rules
+ * @param {Array} methods arguments
+ * @param {Object} rules to apply
+ * @returns {Object} arguments filtered
+ */
+ function argsByRules(argsArray, rules) {
+ var params = rules || ['x', 'y', 'width', 'height'],
+ args = {};
+
+ for (var i = 0; i < argsArray.length; i++) {
+ if (typeof(argsArray[i]) === "object")
+ args["style"] = argsArray[i];
+ else
+ if (params.length)
+ args[params.shift()] = argsArray[i];
+ }
+
+ args.style = normalizeStyle(args.style);
+
+ if ((typeof(args.x) === 'string') && (typeof(args.y) === 'string'))
+ args = smartCoordinates(args);
+
+ return args;
+ }
+ function getBorderStyleObject(prop) {
+ return normalizeStyle({border: prop});
+ }
- ctx.moveTo(top[0].x, top[0].y);
- for (let t in top) {
- t = top[t];
+ function normalizeStyle(style) {
+ if (!style)
+ style = {};
+
+ var borderSize = (style.borderSize || null),
+ borderColor = (style.borderColor || null),
+ borderStyle = (style.borderStyle || []);
+
+ if (style.border) {
+ var border = [],
+ borderString = style.border;
+
+ // 0 - Size: [0-9]px
+ border = border.concat(style.border.match(/[0-9]*\.?[0-9]px?/i));
+ borderString = borderString.replace(/[0-9]*\.?[0-9]px?/i, '');
+
+ // 1 - Style
+ border = border.concat(borderString.match(/solid|dashed|dotted/i));
+ borderString = borderString.replace(/solid|dashed|dotted/i, '');
+
+ // 2 - Color
+ border = border.concat(borderString.match(/[^\s]+/i));
+
+ if (!borderSize)
+ borderSize = border[0];
+ if (!borderColor)
+ borderColor = border[2];
+
+ borderStyle = border[1];
+ }
+
+ if (borderSize)
+ borderSize = borderSize.replace(/[^0-9]/g, '');
+
+ if (typeof(borderStyle) === 'string') {
+ if (borderStyle === 'dashed')
+ borderStyle = [12];
+ else if (borderStyle === 'dotted')
+ borderStyle = [3];
+ else
+ borderStyle = [];
+ }
+
+ style['borderSize'] = borderSize;
+ style['borderStyle'] = borderStyle;
+ style['borderColor'] = borderColor;
+ return style;
+ }
- ctx.lineTo(t.x, t.y);
- }
- ctx.closePath();
+ /**
+ * Return args object with new coordinates based on behavior
+ * @returns {Object} args
+ */
+ function smartCoordinates(args) {
+ var x = args.x,
+ y = args.y;
+
+ var paper = Origami.getPaper(),
+ elmWidth = paper.element.width,
+ elmHeight = paper.element.height,
+ radius = (args.r || 0);
+
+ var width = (args.width || radius),
+ height = (args.height || width);
+
+ var axis = {
+ x: [ 'right', 'center', 'left' ],
+ y: [ 'top', 'center', 'bottom' ]
+ };
+
+ if (axis.x.indexOf(x) !== -1) {
+ if (x === 'right')
+ x = Math.floor(elmWidth - width);
+ else if (x === 'center')
+ if (radius)
+ x = Math.floor(elmWidth / 2);
+ else
+ x = Math.floor((elmWidth / 2) - (width / 2));
+ else if (x === 'left')
+ x = radius;
+ } else if ((x + '').substr(-1) === '%') {
+ x = (elmWidth * parseInt(x, 10)) / 100;
+ } else {
+ x = 0;
+ }
+
+ if (axis.y.indexOf(y) !== -1) {
+ if (y === 'top')
+ y = radius;
+ else if (y === 'center')
+ if (radius)
+ y = Math.floor(elmHeight / 2);
+ else
+ y = Math.floor((elmHeight / 2) - (height / 2));
+ else if (y === 'bottom')
+ y = Math.floor(elmHeight - height);
+ } else if ((y + '').substr(-1) === '%') {
+ y = (elmHeight * parseInt(y, 10)) / 100;
+ } else {
+ y = 0;
+ }
+
+ args.y = y;
+ args.x = x;
+ return args;
+ }
- ctx.moveTo(bottom[0].x, bottom[0].y);
- for (let b = bottom.length - 1; b >= 0; b++) {
- b = bottom[b];
+ /**
+ * Return all documentStyles to a especified origami context
+ * @returns undefined
+ */
+ function defineDocumentStyles() {
+ for (var i = 0; i < document.styleSheets.length; i++) {
+ var mysheet = document.styleSheets[i],
+ myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
+ config.documentStyles.push(myrules);
+ }
+ }
- ctx.lineTo(b.x, b.y);
+ /**
+ * Merge defaults with user options
+ * @param {Object} defaults Default settings
+ * @param {Object} options User options
+ * @returns {Object} Merged values of defaults and options
+ */
+ function extend(a, b, undefOnly) {
+ for (var prop in b) {
+ if (hasOwn.call(b, prop)) {
+
+ // Avoid "Member not found" error in IE8 caused by messing with window.constructor
+ // This block runs on every environment, so `global` is being used instead of `window`
+ // to avoid errors on node.
+ if (prop !== "constructor" || a !== commonjsGlobal) {
+ if (b[prop] === undefined) {
+ delete a[prop];
+ } else if (!(undefOnly && typeof a[prop] !== "undefined")) {
+ a[prop] = b[prop];
+ }
+ }
}
- ctx.closePath();
-
+ }
+ return a;
+ }
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
+ /**
+ * Get Style Rule from a specified element
+ * @param {String} selector from element
+ * @param {Array} Document Style Rules
+ * @returns {Object} Merged values of defaults and options
+ */
+ function styleRuleValueFrom(selector, documentStyleRules) {
+ for (var j = 0; j < documentStyleRules.length; j++) {
+ if (documentStyleRules[j].selectorText && documentStyleRules[j].selectorText.toLowerCase() === selector) {
+ return documentStyleRules[j].style;
}
- ctx.stroke();
-
- //inner color
- ctx.beginPath();
- ctx.moveTo(bottom[0].x, bottom[0].y);
- for (let b in bottom) {
- b = bottom[b];
+ }
+ }
- ctx.lineTo(b.x, b.y);
- }
- ctx.closePath();
+ /**
+ * Clone a object
+ * @param {Object} object
+ * @returns {Object} cloned object
+ */
+ function clone(obj) {
+ if (null == obj || "object" != typeof obj) return obj;
+ var copy = obj.constructor();
+ for (var attr in obj) {
+ if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
+ }
+ return copy;
+ }
+ function Screen(currentContext) {
+ this.paper = currentContext;
+ }
- if (options.colors[2]) {
- ctx.fillStyle = options.colors[2];
- ctx.fill();
- }
- ctx.stroke();
+ Screen.prototype.translate = function(params) {
+ this.paper.ctx.translate(params.x, params.y);
};
- var drawRoundWave = (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let r = h / 4;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 100;
- let percent = r / 255;
- let increase = (360 / point_count) * Math.PI / 180;
- let p = 0;
-
- // let z = (data[0] + min + offset) * percent;
- let sx = cx + (r + p) * Math.cos(0);
- let sy = cy + (r + p) * Math.sin(0);
- ctx.moveTo(sx, sy);
-
- for (let point = 1; point <= point_count; point++) {
- let p = (data[350 % point]) * percent;
- let a = point * increase;
-
- let dx = cx + (r + p) * Math.cos(a);
- let dy = cy + (r + p) * Math.sin(a);
- ctx.lineTo(dx, dy);
- }
-
- ctx.closePath();
- ctx.stroke();
-
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
- }
+ Screen.prototype.background = function(params) {
+ this.paper.element.style.backgroundColor = params.color;
};
- var drawRings = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- let helper = new Helper(ctx);
- let minDimension = (h < w) ? h : w;
-
- data = helper.mutateData(data, "organize");
- data = [data.mids, data.vocals];
-
- data[0] = helper.mutateData(data[0], "scale", minDimension / 4);
- data[1] = helper.mutateData(data[1], "scale", minDimension / 8);
-
- data[0] = helper.mutateData(data[0], "shrink", 1 / 5);
- data[0] = helper.mutateData(data[0], "split", 2)[0];
-
- data[0] = helper.mutateData(data[0], "reverb");
- data[1] = helper.mutateData(data[1], "reverb");
-
-
- let outerCircle = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data[0].length, data[0]);
- let innerCircle = helper.getPoints("circle", minDimension / 4, [w / 2, h / 2], data[1].length, data[1]);
-
- helper.drawPolygon(outerCircle.end, { close: true, radius: 4, lineColor: colors[0], color: colors[1] });
- helper.drawPolygon(innerCircle.end, { close: true, radius: 4, lineColor: colors[2], color: colors[3] });
-
- let middle = ((minDimension / 4) + (minDimension / 2)) / 2;
- let largerInner = data[1] = helper.mutateData(data[1], "scale", ((minDimension / 4) - (minDimension / 2)));
- let innerBars = helper.getPoints("circle", middle, [w / 2, h / 2], data[1].length, largerInner);
- innerBars.start.forEach((start, i) => {
- helper.drawLine(start, innerBars.end[i], { lineColor: colors[4] || colors[2] });
- });
+ Screen.prototype.restore = function() {
+ this.paper.ctx.restore();
};
- var drawShineRings = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
-
- let helper = new Helper(ctx);
- let minDimension = (h < w) ? h : w;
-
- data = helper.mutateData(data, "organize");
- data.vocals = helper.mutateData(data.vocals, "scale", (minDimension / 2) / 2);
- data.base = helper.mutateData(data.base, "scale", (minDimension / 2) / 2);
-
- let outerBars = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals);
- let innerWave = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals, { offset: 100 });
- let thinLine = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.base.length, data.base, { offset: 100 });
-
- outerBars.start.forEach((start, i) => {
- helper.drawLine(start, outerBars.end[i], { lineColor: colors[0] });
- });
-
- helper.drawPolygon(innerWave.start, { close: true, lineColor: colors[1], color: colors[3], radius: 5 });
- helper.drawPolygon(thinLine.start, { close: true, lineColor: colors[2], color: colors[4], radius: 5 });
+ Screen.prototype.save = function() {
+ this.paper.ctx.save();
};
- var drawCubes = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- let helper = new Helper(ctx);
-
- data = helper.mutateData(data, "organize").base;
-
- data = helper.mutateData(data, "shrink", 20).slice(0, 19);
- data = helper.mutateData(data, "scale", h);
-
- let points = helper.getPoints("line", w, [0, h], data.length, data);
-
- let spacing = 5;
- let squareSize = (w / 20) - spacing;
- let colorIndex = 0;
-
- points.start.forEach((start, i) => {
- let squareCount = Math.ceil(data[i] / squareSize);
-
- //find color stops from total possible squares in bar
- let totalSquares = (h - (spacing * (h / squareSize))) / squareSize;
- let colorStop = Math.ceil(totalSquares / colors.length);
-
- for (let j = 1; j <= squareCount; j++) {
- let origin = [start[0], (start[1] - (squareSize * j) - (spacing * j))];
- helper.drawSquare(origin, squareSize, { color: colors[colorIndex], lineColor: "black" });
- if (j % colorStop == 0) {
- colorIndex++;
- if (colorIndex >= colors.length) colorIndex = colors.length - 1;
- }
- }
- colorIndex = 0;
- });
+ Screen.prototype.composition = function(params) {
+ this.paper.ctx.globalCompositeOperation = params.globalComposite;
};
- var drawBigBars = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- const helper = new Helper(ctx);
-
- data = helper.mutateData(data, "organize").vocals;
- data = helper.mutateData(data, "shrink", 10);
- data = helper.mutateData(data, "scale", h);
- data = helper.mutateData(data, "amp", 1);
- let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
-
- let colorIndex = 0;
- let colorStop = Math.ceil(data.length / colors.length);
- points.start.forEach((start, i) => {
- if ((i + 1) % colorStop == 0) colorIndex++;
- helper.drawRectangle(start, data[i], w / data.length, { color: colors[colorIndex] });
- });
-
+ Screen.prototype.rotate = function(params) {
+ this.paper.ctx.rotate(params.degrees);
};
- var drawShockwave = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
-
- let helper = new Helper(ctx);
-
- data = helper.mutateData(data, "shrink", 300);
- data = helper.mutateData(data, "scale", h / 2);
- data = helper.mutateData(data, "split", 4).slice(0, 3);
-
- let colorIndex = 0;
- data.forEach((points) => {
- let wavePoints = helper.getPoints("line", w, [0, h / 2], points.length, points);
- helper.drawPolygon(wavePoints.end, { lineColor: colors[colorIndex], radius: (h * .015) });
+ Screen.prototype.scale = function(params) {
+ this.paper.ctx.scale(params.width, params.height);
+ };
- let invertedPoints = helper.getPoints("line", w, [0, h / 2], points.length, points, { offset: 100 });
- helper.drawPolygon(invertedPoints.start, { lineColor: colors[colorIndex], radius: (h * .015) });
- colorIndex++;
- });
+ Screen.prototype.flip = function(params) {
+ this.paper.flip = 'horizontal';
+ if (params.type && typeof(params.type) === 'string')
+ this.paper.flip = params.type;
};
- var drawFireworks = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- const helper = new Helper(ctx);
+ Screen.prototype.flipEnd = function() {
+ this.paper.flip = false;
+ };
- data = helper.mutateData(data, "shrink", 200).slice(0, 120);
- data = helper.mutateData(data, "mirror");
- data = helper.mutateData(data, "scale", (h / 4) + ((h / 4) * .35));
+ Screen.prototype.clear = function() {
+ this.paper.ctx.clearRect(0, 0, this.paper.width, this.paper.height);
+ };
- let points = helper.getPoints("circle", h / 2, [w / 2, h / 2], data.length, data, { offset: 35, rotate: 270 });
+ function ArcShape(params) {
+ var args = params.args,
+ style = args.style,
+ def = config.defaults.arc;
+
+ this.paper.ctx.beginPath();
+ this.paper.ctx.setLineDash(style.borderStyle);
+ this.paper.ctx.arc(args.x, args.y, (args.r || def.radius), (args.sAngle || 0), (args.eAngle || 2 * Math.PI));
+ this.paper.ctx.fillStyle = (style.background || style.bg) ? (style.background || style.bg) : def.background;
+ this.paper.ctx.fill();
+ this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
+ this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
+ this.paper.ctx.stroke();
+ this.paper.ctx.setLineDash([]);
+ this.paper.ctx.closePath();
+ }
- points.start.forEach((start, i) => {
- helper.drawLine(start, points.end[i]);
- });
+ Screen.prototype.arc = ArcShape;
- helper.drawPolygon(points.start, { close: true });
+ Origami.arc = function() {
+ var args = [].slice.call(arguments);
+ args = argsByRules(args, ['x', 'y', 'r', 'sAngle', 'eAngle']);
- points.end.forEach((end, i) => {
- helper.drawCircle(end, h * .01, { color: colors[0] });
- });
+ queue('arc', {
+ args: args
+ });
+ return this;
};
- var drawStatic = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let helper = new Helper(ctx);
-
- data = helper.mutateData(data, "shrink", 1 / 8);
- data = helper.mutateData(data, "split", 2)[0];
- data = helper.mutateData(data, "scale", h);
-
- let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
- let prevPoint = null;
- points.start.forEach((start, i) => {
- if (prevPoint) {
- helper.drawLine(prevPoint, start);
- }
- helper.drawLine(start, points.end[i]);
- prevPoint = points.end[i];
- });
+ function ImageShape(params) {
+ var image = params.image,
+ x = params.x,
+ y = params.y,
+ width = params.width,
+ height = params.height;
+
+ this.paper.ctx.save();
+ if (this.paper.flip) {
+ if (this.paper.flip === 'horizontal') {
+ this.paper.ctx.scale(-1, 1);
+ width = width * -1;
+ x = x * -1;
+ }
+ if (this.paper.flip === 'vertical') {
+ this.paper.ctx.scale(1, -1);
+ height = height * -1;
+ y = y * -1;
+ }
+ }
+ this.paper.ctx.beginPath();
+ this.paper.ctx.drawImage(image, Math.floor((x || 0)), Math.floor((y || 0)), width, height);
+ this.paper.ctx.closePath();
+ this.paper.ctx.restore();
+ }
+ Screen.prototype.image = ImageShape;
+
+ Origami.image = function(image, x, y, width, height) {
+ var self = this;
+ if (!image)
+ return this;
+
+ if (typeof(image) === 'string') {
+ var img = new Image();
+ img.src = image;
+ image = img;
+ }
+
+ var item = {
+ image: image,
+ x: x,
+ y: y,
+ width: width,
+ height: height
+ };
+
+ if ((typeof(item.x) === 'string') && (typeof(item.y) === 'string'))
+ item = smartCoordinates(item);
+
+ if (image.complete) {
+ item.width = width || image.naturalWidth;
+ item.height = height || image.naturalHeight;
+
+ queue('image', item);
+ return self;
+ }
+
+ queue('image', item, false);
+ var reference = (self.paper.queue.length - 1),
+ currentQueue = config.contexts[this.paper.index].queue[reference];
+
+ image.addEventListener('load', function() {
+ if (!currentQueue)
+ return false;
+ currentQueue.params.width = (item.width || image.naturalWidth);
+ currentQueue.params.height = (item.height || image.naturalHeight);
+ currentQueue.loaded = true;
+ });
+
+ image.addEventListener('error', function() {
+ if (!currentQueue)
+ return false;
+ currentQueue.failed = true;
+ });
+
+ return self;
};
- var drawWeb = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- const helper = new Helper(ctx);
- let minDimension = (h < w) ? h : w;
-
- data = helper.mutateData(data, "shrink", 100);
- data = helper.mutateData(data, "split", 2)[0];
- data = helper.mutateData(data, "scale", h / 4);
+ function LineShape(params) {
+ var def = config.defaults.line,
+ style = params.style,
+ pointA = params.pointA,
+ pointB = params.pointB;
+
+ this.paper.ctx.beginPath();
+ this.paper.ctx.setLineDash(style.borderStyle);
+ this.paper.ctx.moveTo((pointA.x || 0), (pointA.y || 0));
+ this.paper.ctx.lineTo((pointB.x || 0), (pointB.y || 0));
+
+ this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
+ this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
+ this.paper.ctx.stroke();
+ this.paper.ctx.setLineDash([]);
+ this.paper.ctx.closePath();
+ }
- let dataCopy = data;
+ Screen.prototype.line = LineShape;
- let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
- helper.drawPolygon(points.end, { close: true });
+ Origami.line = function(pointA, pointB, style) {
+ style = normalizeStyle(style);
- points.start.forEach((start, i) => {
- helper.drawLine(start, points.end[i]);
- });
+ queue('line', {
+ pointA: pointA,
+ pointB: pointB,
+ style: style
+ });
+ return this;
+ };
- data = helper.mutateData(data, "scale", .7);
- points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
- helper.drawPolygon(points.end, { close: true });
+ function PolygonShape(params) {
+ var args = params.args,
+ style = params.style,
+ def = config.defaults.polygon;
+
+ this.paper.ctx.beginPath();
+ this.paper.ctx.setLineDash(style.borderStyle);
+ this.paper.ctx.fillStyle = (style.background) ? style.background : def.background;
+ this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
+ this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
+
+ for (var p = 0; p < args.length; p++) {
+ if (!args[p].x)
+ continue;
+
+ if (p)
+ this.paper.ctx.lineTo(args[p].x, args[p].y);
+ else
+ this.paper.ctx.moveTo(args[p].x, args[p].y);
+ }
+
+ this.paper.ctx.fill();
+ this.paper.ctx.stroke();
+ this.paper.ctx.setLineDash([]);
+ this.paper.ctx.closePath();
+ }
- data = helper.mutateData(data, "scale", .3);
- points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
- helper.drawPolygon(points.end, { close: true });
+ Screen.prototype.polygon = PolygonShape;
- helper.drawCircle([w / 2, h / 2], minDimension / 2, { color: colors[2] });
+ Origami.polygon = function() {
+ var args = [].slice.call(arguments),
+ settedArgs = argsByRules(args);
- dataCopy = helper.mutateData(dataCopy, "scale", 1.4);
- points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], dataCopy.length, dataCopy);
- points.end.forEach((end, i) => {
- helper.drawCircle(end, minDimension * .01, { color: colors[1], lineColor: colors[1] || colors[0] });
- });
+ queue('polygon', {
+ style: settedArgs.style,
+ args: args
+ });
+ return this;
};
- var drawStitches = (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let helper = new Helper(ctx);
- let minDimension = (h < w) ? h : w;
-
- data = helper.mutateData(data, "shrink", 200);
- data = helper.mutateData(data, "split", 2)[0];
- data = helper.mutateData(data, "scale", h / 2);
+ function RectShape(params) {
+ var def = config.defaults.rect,
+ style = params.style,
+ args = params.args;
+
+ this.paper.ctx.beginPath();
+ this.paper.ctx.setLineDash(style.borderStyle);
+ this.paper.ctx.fillStyle = (style.background) ? style.background : def.background;
+ this.paper.ctx.fillRect(args.x, args.y, args.width, (args.height || args.width));
+
+ this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
+ this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
+ this.paper.ctx.strokeRect(args.x, args.y, args.width, (args.height || args.width));
+ this.paper.ctx.setLineDash([]);
+ this.paper.ctx.closePath();
+ }
- let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data, { offset: 50 });
+ Screen.prototype.rect = RectShape;
- helper.drawPolygon(points.end, { close: true });
- helper.drawPolygon(points.start, { close: true });
+ Origami.rect = function() {
+ var args = [].slice.call(arguments);
+ args = argsByRules(args);
- for (let i = 0; i < points.start.length; i += 1) {
- let start = points.start[i];
- i++;
- let end = points.end[i] || points.end[0];
+ queue('rect', {
+ style: args.style,
+ args: args
+ });
+ return this;
+ };
- helper.drawLine(start, end);
- helper.drawLine(end, points.start[i + 1] || points.start[0]);
+ Origami.border = function() {
+ var args = [].slice.call(arguments);
+ args = argsByRules(args);
+
+ queue('rect', {
+ style: args.style,
+ args: {
+ x: 0,
+ y: 0,
+ width: this.paper.width,
+ height: this.paper.height
}
+ });
+ return this;
};
- //options:type,colors,stroke
- function visualize(data, canvas, options = {}, frame) {
- //make a clone of options
- options = { ...options };
- //options
- if (!options.stroke) options.stroke = 1;
- if (!options.colors) options.colors = ["#d92027", "#ff9234", "#ffcd3c", "#35d0ba"];
-
- if (typeof canvas == "string") {
- canvas = document.getElementById(canvas);
- }
- if (!canvas) return;
-
- let ctx = canvas.getContext("2d");
- let h = canvas.height;
- let w = canvas.width;
-
-
-
- ctx.strokeStyle = options.colors[0];
- ctx.lineWidth = options.stroke;
-
- let typeMap = {
- "bars": drawBars,
- "bars blocks": drawBarsBlocks,
- "big bars": drawBigBars,
- "cubes": drawCubes,
- "dualbars": drawDualbars,
- "dualbars blocks": drawDualbarsBlocks,
- "fireworks": drawFireworks,
- "flower": drawFlower,
- "flower blocks": drawFlowerBlocks,
- "orbs": drawOrbs,
- "ring": drawRing,
- "rings": drawRings,
- "round wave": drawRoundWave,
- "shine": drawShine,
- "shine rings": drawShineRings,
- "shockwave": drawShockwave,
- "star": drawStar,
- "static": drawStatic,
- "stitches": drawStitches,
- "wave": drawWave,
- "web": drawWeb
- };
-
- let frameRateMap = {
- "bars": 1,
- "bars blocks": 1,
- "big bars": 1,
- "cubes": 1,
- "dualbars": 1,
- "dualbars blocks": 1,
- "fireworks": 1,
- "flower": 1,
- "flower blocks": 1,
- "ring": 1,
- "rings": 1,
- "round wave": 1,
- "orbs": 1,
- "shine": 1,
- "shine rings": 1,
- "shockwave": 1,
- "star": 1,
- "static": 1,
- "stitches": 1,
- "wave": 1,
- "web": 1
- };
-
- const functionContext = {
- data, options, ctx, h, w, Helper: this.Helper
- };
-
- if (typeof options.type == "string") options.type = [options.type];
-
- options.type.forEach(type => {
- //abide by the frame rate
- if (frame % frameRateMap[type] === 0) {
- //clear canvas
- ctx.clearRect(0, 0, w, h);
- ctx.beginPath();
-
- typeMap[type](functionContext);
- }
+ function CSSShape(style) {
+ var self = this,
+ style = config.virtualStyles[style];
+
+ if (!style)
+ return self;
+
+ // TODO: Draw in all canvas
+ var data = '' +
+ '' +
+ ' ' +
+ ' ';
+
+ var DOMURL = window.URL || window.webkitURL || window,
+ img = new Image(),
+ svg = new Blob([data], {
+ type: 'image/svg+xml;charset=utf-8'
});
- }
+ var url = DOMURL.createObjectURL(svg);
+ img.src = url;
- function Helper(ctx) {
- this.ctx = ctx;
- this.mainColor = "black";
+ img.addEventListener('load', function() {
+ self.paper.ctx.beginPath();
+ self.paper.ctx.drawImage(img, 0, 0);
+ DOMURL.revokeObjectURL(url);
+ self.paper.ctx.closePath();
+ });
+
+ return self;
}
- Helper.prototype = {
- __toRadians__(degree) {
- return (degree * Math.PI) / 180;
- },
- __rotatePoint__([pointX, pointY], [originX, originY], degree) {
- //clockwise
- let angle = this.__toRadians__(degree);
- let rotatedX = Math.cos(angle) * (pointX - originX) - Math.sin(angle) * (pointY - originY) + originX;
- let rotatedY = Math.sin(angle) * (pointX - originX) + Math.cos(angle) * (pointY - originY) + originY;
+ Screen.prototype.CSSShape = CSSShape;
- return [rotatedX, rotatedY]
- },
- mutateData(data, type, extra = null) {
- if (type === "mirror") {
- let rtn = [];
+ Origami.shape = function(style) {
+ queue('CSSShape', style);
+ return this;
+ };
- for (let i = 0; i < data.length; i += 2) {
- rtn.push(data[i]);
- }
+ function SpriteShape(params) {
+ var properties = params.properties,
+ dw = params.width / properties.frames;
+
+ drawSprite.call(this, {
+ image: params.image,
+ posX: 0,
+ posY: 0,
+ frame: properties.frames,
+ loop: properties.loop,
+ width: dw,
+ widthTotal: params.width,
+ height: params.height,
+ dx: params.x,
+ dy: params.y,
+ speed: properties.speed,
+ animation: null
+ });
+ }
- rtn = [...rtn, ...rtn.reverse()];
- return rtn
- }
+ function drawSprite(sprite) {
+ var self = this;
- if (type === "shrink") {
- //resize array by % of current array
- if (extra < 1) {
- extra = data.length * extra;
- }
+ if (sprite.posX === sprite.widthTotal) {
+ if (sprite.loop === false) {
+ window.cancelAnimationFrame(sprite.animation);
+ return;
+ }
+ sprite.posX = 0;
+ }
- let rtn = [];
- let splitAt = Math.floor(data.length / extra);
+ self.paper.ctx.clearRect(sprite.dx, sprite.dy, sprite.width, sprite.height);
- for (let i = 1; i <= extra; i++) {
- let arraySection = data.slice(i * splitAt, (i * splitAt) + splitAt);
- let middle = arraySection[Math.floor(arraySection.length / 2)];
- rtn.push(middle);
- }
+ self.paper.ctx.beginPath();
+ self.paper.ctx.drawImage(sprite.image, sprite.posX, sprite.posY,
+ sprite.width, sprite.height, sprite.dx, sprite.dy,
+ sprite.width, sprite.height);
+ self.paper.ctx.closePath();
- return rtn
- }
+ sprite.posX = sprite.posX + sprite.width;
- if (type === "split") {
- let size = Math.floor(data.length / extra);
- let rtn = [];
- let temp = [];
+ setTimeout(function() {
+ sprite.animation = window.requestAnimationFrame(drawSprite.bind(self, sprite));
+ }, sprite.speed);
+ }
- let track = 0;
- for (let i = 0; i <= size * extra; i++) {
- if (track === size) {
- rtn.push(temp);
- temp = [];
- track = 0;
- }
+ Screen.prototype.sprite = SpriteShape;
+
+ Origami.sprite = function(x, y, properties) {
+ var self = this;
+
+ if (!properties || !properties.src)
+ return this;
+
+ var image = new Image(),
+ frames = (properties.frames || 0),
+ loop = (properties.loop || true),
+ speed = (properties.speed || 10);
+
+ image.src = properties.src;
+
+ var item = {
+ x: x,
+ y: y,
+ image: image,
+ properties: properties,
+ width: 0,
+ height: 0
+ };
+
+ if (image.complete) {
+ item.width = image.naturalWidth;
+ item.height = image.naturalHeight;
+ queue('sprite', item);
+ return self;
+ }
+
+ queue('sprite', item, false);
+ var reference = (self.paper.queue.length - 1),
+ currentQueue = config.contexts[this.paper.index].queue[reference];
+
+ image.addEventListener('load', function() {
+ if (!currentQueue)
+ return false;
+ currentQueue.params.width = image.naturalWidth;
+ currentQueue.params.height = image.naturalHeight;
+ currentQueue.loaded = true;
+ });
+
+ image.addEventListener('error', function() {
+ if (!currentQueue)
+ return false;
+ currentQueue.failed = true;
+ });
+
+ return this;
+ };
- temp.push(data[i]);
- track++;
- }
+ function TextShape(params) {
+ var def = config.defaults.text,
+ text = params.text,
+ x = params.x,
+ y = params.y,
+ style = params.style;
+
+ this.paper.ctx.beginPath();
+ this.paper.ctx.setLineDash(style.borderStyle);
+ this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
+ this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
+ this.paper.ctx.font = (style.font || def.font);
+ this.paper.ctx.fillStyle = (style.color || def.color);
+ this.paper.ctx.textAlign = (style.align || def.align);
+ this.paper.ctx.fillText(text, x, y);
+ this.paper.ctx.strokeText(text, x, y);
+ this.paper.ctx.fill();
+ this.paper.ctx.stroke();
+ this.paper.ctx.setLineDash([]);
+ this.paper.ctx.closePath();
+ }
- return rtn
- }
+ Screen.prototype.text = TextShape;
- if (type === "scale") {
- let scalePercent = extra / 255;
- if (extra <= 3 && extra >= 0) scalePercent = extra;
- let rtn = data.map(value => value * scalePercent);
- return rtn
- }
+ Origami.text = function(text, x, y, style) {
+ style = normalizeStyle(style);
- if (type === "organize") {
- let rtn = {};
- rtn.base = data.slice(60, 120);
- rtn.vocals = data.slice(120, 255);
- rtn.mids = data.slice(255, 2000);
- return rtn
- }
+ var item = {
+ text: text,
+ x: x,
+ y: y,
+ style: style
+ };
- if (type === "reverb") {
- let rtn = [];
- data.forEach((val, i) => {
- rtn.push(val - (data[i + 1] || 0));
- });
- return rtn
- }
+ if ((typeof(item.x) === 'string') && (typeof(item.y) === 'string'))
+ item = smartCoordinates(item);
- if (type === "amp") {
- let rtn = [];
- data.forEach(val => {
- rtn.push(val * (extra + 1));
- });
- return rtn
- }
+ queue('text', item);
+ return this;
+ };
- if (type === "min") {
- let rtn = [];
- data.forEach(value => {
- if (value < extra) value = extra;
- rtn.push(value);
- });
- return rtn
- }
- },
- getPoints(shape, size, [originX, originY], pointCount, endPoints, options = {}) {
- let { offset = 0, rotate = 0, customOrigin = [] } = options;
- let rtn = {
- start: [],
- end: []
- };
+ function ChartLine(config) {
+ var ctx = this.paper.ctx,
+ width = this.paper.width,
+ height = this.paper.height;
- if (shape === "circle") {
+ var line = getBorderStyleObject(config.line || "1px solid #000");
+ var lineVariance = 2;
- let degreePerPoint = 360 / pointCount;
- let radianPerPoint = this.__toRadians__(degreePerPoint);
- let radius = size / 2;
+ var xPadding = 40;
+ var yPadding = 40;
+ var data = [];
- for (let i = 1; i <= pointCount; i++) {
- let currentRadian = radianPerPoint * i;
- let currentEndPoint = endPoints[i - 1];
- let pointOffset = endPoints[i - 1] * (offset / 100);
+ var gridLines = {
+ vertical: true,
+ horizontal: true
+ };
- let x = originX + (radius - pointOffset) * Math.cos(currentRadian);
- let y = originY + (radius - pointOffset) * Math.sin(currentRadian);
- let point1 = this.__rotatePoint__([x, y], [originX, originY], rotate);
+ if (config.gridLines) {
+ if (config.gridLines.vertical === false)
+ gridLines.vertical = false;
- rtn.start.push(point1);
+ if (config.gridLines.horizontal === false)
+ gridLines.horizontal = false;
+ }
- x = originX + ((radius - pointOffset) + currentEndPoint) * Math.cos(currentRadian);
- y = originY + ((radius - pointOffset) + currentEndPoint) * Math.sin(currentRadian);
- let point2 = this.__rotatePoint__([x, y], [originX, originY], rotate);
+ for (var i = 0; i < config.labels.length; i++) {
+ data.push({
+ X: config.labels[i],
+ Y: config.data[i]
+ });
+ }
- rtn.end.push(point2);
+ function getMaxY() {
+ var max = 0;
- }
+ for (var i = 0; i < data.length; i++) {
+ if (data[i].Y > max) {
+ max = data[i].Y;
+ }
+ }
- return rtn
- }
+ max += 10 - max % 10;
+ return max;
+ }
+
+ function getXPixel(val) {
+ return ((width - xPadding) / data.length) * val + xPadding;
+ }
+
+ function getYPixel(val) {
+ return height - (((height - yPadding) / getMaxY()) * val) - yPadding;
+ }
+
+ ctx.lineWidth = 0.8;
+ ctx.strokeStyle = '#999';
+ ctx.font = 'normal 12px Helvetica';
+ ctx.fillStyle = '#5e5e5e';
+ ctx.textAlign = "center";
+
+ ctx.beginPath();
+ ctx.moveTo(xPadding, yPadding / lineVariance);
+ ctx.lineTo(xPadding, height - yPadding);
+ ctx.lineTo(width - (xPadding / lineVariance), height - yPadding);
+ ctx.stroke();
+
+ // Data
+ ctx.textAlign = "right";
+ ctx.textBaseline = "middle";
+ for (var i = 0; i < getMaxY(); i += 10) {
+ if (gridLines.horizontal) {
+ ctx.beginPath();
+ ctx.lineWidth = 0.8;
+ ctx.strokeStyle = '#e7e7e7';
+ ctx.moveTo(xPadding - 5, getYPixel(i));
+ ctx.lineTo(width - (xPadding / lineVariance), getYPixel(i));
+ ctx.stroke();
+ }
- if (shape === "line") {
- let increment = size / pointCount;
+ ctx.fillText(i, xPadding - 10, getYPixel(i));
+ }
+
+ // Labels
+ ctx.textAlign = "left";
+ for (var i = 0; i < data.length; i++) {
+ if (gridLines.vertical) {
+ ctx.beginPath();
+ ctx.lineWidth = 0.8;
+ ctx.strokeStyle = '#e7e7e7';
+ ctx.moveTo(getXPixel(i), height - yPadding + 10);
+ ctx.lineTo(getXPixel(i), yPadding / lineVariance);
+ ctx.stroke();
+ }
- originX = customOrigin[0] || originX;
- originY = customOrigin[1] || originY;
+ ctx.fillText(data[i].X, getXPixel(i), height - yPadding + 20);
+ }
+
+ ctx.beginPath();
+ ctx.lineWidth = line.borderSize;
+ ctx.setLineDash(line.borderStyle);
+ ctx.strokeStyle = line.borderColor;
+ ctx.moveTo(getXPixel(0), getYPixel(data[0].Y));
+
+ for (var i = 1; i < data.length; i++) {
+ ctx.lineTo(getXPixel(i), getYPixel(data[i].Y));
+ }
+ ctx.stroke();
+ ctx.setLineDash([]);
+
+ if (config.points) {
+ ctx.fillStyle = (config.pointsColor) ? config.pointsColor : 'rgb(75,75,75)';
+ for (var i = 0; i < data.length; i++) {
+ ctx.beginPath();
+ ctx.arc(getXPixel(i), getYPixel(data[i].Y), 3, 0, Math.PI * 2, true);
+ ctx.fill();
+ }
+ }
+ }
- for (let i = 0; i <= pointCount; i++) {
- let degree = rotate;
- let pointOffset = endPoints[i] * (offset / 100);
+ Screen.prototype.chartLine = ChartLine;
- let startingPoint = this.__rotatePoint__([originX + (i * increment), originY - pointOffset],
- [originX, originY], degree);
- rtn.start.push(startingPoint);
+ Origami.chartLine = function(config) {
+ queue('chartLine', config);
+ return this;
+ };
+ // Resource.js
- let endingPoint = this.__rotatePoint__([originX + (i * increment), (originY + endPoints[i]) - pointOffset],
- [originX, originY], degree);
- rtn.end.push(endingPoint);
- }
+ Origami.background = function(color) {
+ queue('background', {
+ color: color
+ });
+ return this;
+ };
- return rtn
+ Origami.restore = function() {
+ queue('restore');
+ return this;
+ };
- }
+ Origami.save = function() {
+ queue('save');
+ return this;
+ };
- },
- drawCircle([x, y], diameter, options = {}) {
- let { color, lineColor = this.ctx.strokeStyle } = options;
-
- this.ctx.beginPath();
- this.ctx.arc(x, y, diameter / 2, 0, 2 * Math.PI);
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke();
- this.ctx.fillStyle = color;
- if (color) this.ctx.fill();
- },
- drawOval([x, y], height, width, options = {}) {
- let { rotation = 0, color, lineColor = this.ctx.strokeStyle } = options;
- if (rotation) rotation = this.__toRadians__(rotation);
-
- this.ctx.beginPath();
- this.ctx.ellipse(x, y, width, height, rotation, 0, 2 * Math.PI);
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke();
- this.ctx.fillStyle = color;
- if (color) this.ctx.fill();
- },
- drawSquare([x, y], diameter, options = {}) {
- this.drawRectangle([x, y], diameter, diameter, options);
- },
- drawRectangle([x, y], height, width, options = {}) {
- let { color, lineColor = this.ctx.strokeStyle, radius = 0, rotate = 0 } = options;
+ Origami.composition = function(globalComposite) {
+ queue('composition', {
+ globalComposite: globalComposite
+ });
+ return this;
+ };
- // if (width < 2 * radius) radius = width / 2;
- // if (height < 2 * radius) radius = height / 2;
+ Origami.translate = function(x, y) {
+ if (x === undefined || x === null) {
+ x = 'reset';
+ }
- this.ctx.beginPath();
- this.ctx.moveTo(x + radius, y);
- let p1 = this.__rotatePoint__([x + width, y], [x, y], rotate);
- let p2 = this.__rotatePoint__([x + width, y + height], [x, y], rotate);
- this.ctx.arcTo(p1[0], p1[1], p2[0], p2[1], radius);
+ if (typeof(x) === 'string') {
+ if (x === 'center') {
+ x = context.width / 2;
+ y = context.height / 2;
+ }
+ if (x === 'reset') {
+ x = -context.width / 2;
+ y = -context.height / 2;
+ }
+ }
- let p3 = this.__rotatePoint__([x + width, y + height], [x, y], rotate);
- let p4 = this.__rotatePoint__([x, y + height], [x, y], rotate);
- this.ctx.arcTo(p3[0], p3[1], p4[0], p4[1], radius);
+ queue('translate', {
+ x: x,
+ y: y
+ });
+ return this;
+ };
- let p5 = this.__rotatePoint__([x, y + height], [x, y], rotate);
- let p6 = this.__rotatePoint__([x, y], [x, y], rotate);
- this.ctx.arcTo(p5[0], p5[1], p6[0], p6[1], radius);
+ Origami.rotate = function(degrees) {
+ if (typeof(degrees) === 'undefined')
+ degrees = 'slow';
+
+ if (typeof(degrees) === 'string') {
+ // Slow
+ if (degrees === 'slow')
+ degrees = ((2 * Math.PI) / 60) * new Date().getSeconds() +
+ ((2 * Math.PI) / 60000) * new Date().getMilliseconds();
+
+ // Normal
+ else if (degrees === 'normal')
+ degrees = ((2 * Math.PI) / 30) * new Date().getSeconds() +
+ ((2 * Math.PI) / 30000) * new Date().getMilliseconds();
+
+ // Fast
+ else if (degrees === 'fast')
+ degrees = ((2 * Math.PI) / 6) * new Date().getSeconds() +
+ ((2 * Math.PI) / 6000) * new Date().getMilliseconds();
+ }
+
+ queue('rotate', {
+ degrees: degrees
+ });
+ return this;
+ };
- let p7 = this.__rotatePoint__([x, y], [x, y], rotate);
- let p8 = this.__rotatePoint__([x + width, y], [x, y], rotate);
- this.ctx.arcTo(p7[0], p7[1], p8[0], p8[1], radius);
- this.ctx.closePath();
+ Origami.stopRender = function() {
+ window.cancelAnimationFrame(this.paper.frame);
+ this.paper.frame = false;
+ };
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke();
- this.ctx.fillStyle = color;
- if (color) this.ctx.fill();
+ Origami.play = function() {
+ this.paper.frame = 1;
+ return this;
+ };
- },
- drawLine([fromX, fromY], [toX, toY], options = {}) {
- let { lineColor = this.ctx.strokeStyle } = options;
-
- this.ctx.beginPath();
- this.ctx.moveTo(fromX, fromY);
- this.ctx.lineTo(toX, toY);
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke();
- },
- drawPolygon(points, options = {}) {
- let { color, lineColor = this.ctx.strokeStyle, radius = 0, close = false } = options;
+ Origami.startRender = function(fn) {
+ var self = this;
+ if (self.paper.frame === false)
+ return;
- function getRoundedPoint(x1, y1, x2, y2, radius, first) {
- let total = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
- let idx = first ? radius / total : (total - radius) / total;
+ self.draw(function() {
+ self.paper.frame = window.requestAnimationFrame(fn.bind(this));
+ });
+ };
- return [x1 + (idx * (x2 - x1)), y1 + (idx * (y2 - y1))];
- }
+ Origami.scale = function(width, height) {
+ queue('scale', {
+ width: width,
+ height: height
+ });
+ return this;
+ };
- function getRoundedPoints(pts, radius) {
- let len = pts.length;
- let res = new Array(len);
+ Origami.flip = function(type) {
+ queue('flip', {
+ type: type
+ });
+ return this;
+ };
- for (let i2 = 0; i2 < len; i2++) {
- let i1 = i2 - 1;
- let i3 = i2 + 1;
+ Origami.flipEnd = function() {
+ queue('flipEnd');
+ return this;
+ };
- if (i1 < 0) i1 = len - 1;
- if (i3 == len) i3 = 0;
+ Origami.clear = function() {
+ queue('clear');
+ return this;
+ };
- let p1 = pts[i1];
- let p2 = pts[i2];
- let p3 = pts[i3];
+ Origami.on = function(ev, fn) {
+ this.paper.element.addEventListener(ev, fn);
+ return this;
+ };
- let prevPt = getRoundedPoint(p1[0], p1[1], p2[0], p2[1], radius, false);
- let nextPt = getRoundedPoint(p2[0], p2[1], p3[0], p3[1], radius, true);
- res[i2] = [prevPt[0], prevPt[1], p2[0], p2[1], nextPt[0], nextPt[1]];
- }
- return res;
- }
- if (radius > 0) {
- points = getRoundedPoints(points, radius);
- }
+ var factory = extend(Origami.init.bind(this), Origami);
- let i, pt, len = points.length;
- for (i = 0; i < len; i++) {
- pt = points[i];
- if (i == 0) {
- this.ctx.beginPath();
- this.ctx.moveTo(pt[0], pt[1]);
- } else {
- this.ctx.lineTo(pt[0], pt[1]);
- }
- if (radius > 0) {
- this.ctx.quadraticCurveTo(pt[2], pt[3], pt[4], pt[5]);
- }
- }
+ // For consistency with CommonJS environments' exports
+ if ( module && module.exports ){
+ module.exports = factory;
+ }
- if (close) this.ctx.closePath();
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke();
+ // For CommonJS with exports, but without module.exports, like Rhino
+ else if ( exports ) {
+ exports.origami = factory;
+ }
- this.ctx.fillStyle = color;
- if (color) this.ctx.fill();
- }
+ // For browser, export only select globals
+ else if ( typeof window === "object" ) {
+ window.origami = extend(Origami.init.bind(Origami), Origami);
+ }
+ // Get a reference to the global object
+ }( (function() {
+ return this;
+ })() ));
+ });
+ var origami_2 = origami_1.origami;
+
+ var drawRoundLayers = (functionContext) => {
+ let { data, options, ctx, h, w, Helper, canvasId } = functionContext;
+ let helper = new Helper(ctx);
+
+ let origamiContext = {};
+ let origami = origami_1.bind(origamiContext);
+
+ origami(ctx)
+ .rect(10, 10, 40, 40)
+ .draw();
+
+
};
- function Wave() {
- this.current_stream = {};
- this.sources = {};
- this.onFileLoad = null;
- this.activeElements = {};
- this.activated = false;
-
- window.AudioContext = window.AudioContext || window.webkitAudioContext;
+ //options:type,colors,stroke
+ function visualize(data, canvasId, options = {}, frame) {
+ //make a clone of options
+ options = { ...options };
+ //options
+ if (!options.stroke) options.stroke = 1;
+ if (!options.colors) options.colors = ["#d92027", "#ff9234", "#ffcd3c", "#35d0ba"];
+
+
+ let canvas = document.getElementById(canvasId);
+
+ if (!canvas) return;
+
+ let ctx = canvas.getContext("2d");
+ let h = canvas.height;
+ let w = canvas.width;
+
+
+
+ ctx.strokeStyle = options.colors[0];
+ ctx.lineWidth = options.stroke;
+
+ let typeMap = {
+ "bars": drawBars,
+ "bars blocks": drawBarsBlocks,
+ "big bars": drawBigBars,
+ "cubes": drawCubes,
+ "dualbars": drawDualbars,
+ "dualbars blocks": drawDualbarsBlocks,
+ "fireworks": drawFireworks,
+ "flower": drawFlower,
+ "flower blocks": drawFlowerBlocks,
+ "orbs": drawOrbs,
+ "ring": drawRing,
+ "rings": drawRings,
+ "round layers": drawRoundLayers,
+ "round wave": drawRoundWave,
+ "shine": drawShine,
+ "shine rings": drawShineRings,
+ "shockwave": drawShockwave,
+ "star": drawStar,
+ "static": drawStatic,
+ "stitches": drawStitches,
+ "wave": drawWave,
+ "web": drawWeb
+ };
+
+ let frameRateMap = {
+ "bars": 1,
+ "bars blocks": 1,
+ "big bars": 1,
+ "cubes": 1,
+ "dualbars": 1,
+ "dualbars blocks": 1,
+ "fireworks": 1,
+ "flower": 1,
+ "flower blocks": 1,
+ "ring": 1,
+ "rings": 1,
+ "round layers": 1,
+ "round wave": 1,
+ "orbs": 1,
+ "shine": 1,
+ "shine rings": 1,
+ "shockwave": 1,
+ "star": 1,
+ "static": 1,
+ "stitches": 1,
+ "wave": 1,
+ "web": 1
+ };
+
+ const functionContext = {
+ data, options, ctx, h, w, Helper: this.Helper, canvasId
+ };
+
+ if (typeof options.type == "string") options.type = [options.type];
+
+ options.type.forEach(type => {
+ //abide by the frame rate
+ if (frame % frameRateMap[type] === 0) {
+ //clear canvas
+ ctx.clearRect(0, 0, w, h);
+ ctx.beginPath();
+
+ typeMap[type](functionContext);
+ }
+ });
+
}
- Wave.prototype = {
- fromElement,
- fromFile,
- ...fromStream$1,
- visualize,
- Helper
+ function Helper(ctx) {
+ this.ctx = ctx;
+ this.mainColor = "black";
+ }
+
+ Helper.prototype = {
+ __toRadians__(degree) {
+ return (degree * Math.PI) / 180;
+ },
+ __rotatePoint__([pointX, pointY], [originX, originY], degree) {
+ //clockwise
+ let angle = this.__toRadians__(degree);
+ let rotatedX = Math.cos(angle) * (pointX - originX) - Math.sin(angle) * (pointY - originY) + originX;
+ let rotatedY = Math.sin(angle) * (pointX - originX) + Math.cos(angle) * (pointY - originY) + originY;
+
+ return [rotatedX, rotatedY]
+ },
+ mutateData(data, type, extra = null) {
+ if (type === "mirror") {
+ let rtn = [];
+
+ for (let i = 0; i < data.length; i += 2) {
+ rtn.push(data[i]);
+ }
+
+ rtn = [...rtn, ...rtn.reverse()];
+ return rtn
+ }
+
+ if (type === "shrink") {
+ //resize array by % of current array
+ if (extra < 1) {
+ extra = data.length * extra;
+ }
+
+ let rtn = [];
+ let splitAt = Math.floor(data.length / extra);
+
+ for (let i = 1; i <= extra; i++) {
+ let arraySection = data.slice(i * splitAt, (i * splitAt) + splitAt);
+ let middle = arraySection[Math.floor(arraySection.length / 2)];
+ rtn.push(middle);
+ }
+
+ return rtn
+ }
+
+ if (type === "split") {
+ let size = Math.floor(data.length / extra);
+ let rtn = [];
+ let temp = [];
+
+ let track = 0;
+ for (let i = 0; i <= size * extra; i++) {
+ if (track === size) {
+ rtn.push(temp);
+ temp = [];
+ track = 0;
+ }
+
+ temp.push(data[i]);
+ track++;
+ }
+
+ return rtn
+ }
+
+ if (type === "scale") {
+ let scalePercent = extra / 255;
+ if (extra <= 3 && extra >= 0) scalePercent = extra;
+ let rtn = data.map(value => value * scalePercent);
+ return rtn
+ }
+
+ if (type === "organize") {
+ let rtn = {};
+ rtn.base = data.slice(60, 120);
+ rtn.vocals = data.slice(120, 255);
+ rtn.mids = data.slice(255, 2000);
+ return rtn
+ }
+
+ if (type === "reverb") {
+ let rtn = [];
+ data.forEach((val, i) => {
+ rtn.push(val - (data[i + 1] || 0));
+ });
+ return rtn
+ }
+
+ if (type === "amp") {
+ let rtn = [];
+ data.forEach(val => {
+ rtn.push(val * (extra + 1));
+ });
+ return rtn
+ }
+
+ if (type === "min") {
+ let rtn = [];
+ data.forEach(value => {
+ if (value < extra) value = extra;
+ rtn.push(value);
+ });
+ return rtn
+ }
+ },
+ getPoints(shape, size, [originX, originY], pointCount, endPoints, options = {}) {
+ let { offset = 0, rotate = 0, customOrigin = [] } = options;
+ let rtn = {
+ start: [],
+ end: []
+ };
+
+ if (shape === "circle") {
+
+ let degreePerPoint = 360 / pointCount;
+ let radianPerPoint = this.__toRadians__(degreePerPoint);
+ let radius = size / 2;
+
+ for (let i = 1; i <= pointCount; i++) {
+ let currentRadian = radianPerPoint * i;
+ let currentEndPoint = endPoints[i - 1];
+ let pointOffset = endPoints[i - 1] * (offset / 100);
+
+ let x = originX + (radius - pointOffset) * Math.cos(currentRadian);
+ let y = originY + (radius - pointOffset) * Math.sin(currentRadian);
+ let point1 = this.__rotatePoint__([x, y], [originX, originY], rotate);
+
+ rtn.start.push(point1);
+
+ x = originX + ((radius - pointOffset) + currentEndPoint) * Math.cos(currentRadian);
+ y = originY + ((radius - pointOffset) + currentEndPoint) * Math.sin(currentRadian);
+ let point2 = this.__rotatePoint__([x, y], [originX, originY], rotate);
+
+ rtn.end.push(point2);
+
+ }
+
+ return rtn
+ }
+
+ if (shape === "line") {
+ let increment = size / pointCount;
+
+ originX = customOrigin[0] || originX;
+ originY = customOrigin[1] || originY;
+
+ for (let i = 0; i <= pointCount; i++) {
+ let degree = rotate;
+ let pointOffset = endPoints[i] * (offset / 100);
+
+ let startingPoint = this.__rotatePoint__([originX + (i * increment), originY - pointOffset],
+ [originX, originY], degree);
+ rtn.start.push(startingPoint);
+
+ let endingPoint = this.__rotatePoint__([originX + (i * increment), (originY + endPoints[i]) - pointOffset],
+ [originX, originY], degree);
+ rtn.end.push(endingPoint);
+ }
+
+ return rtn
+
+ }
+
+ },
+ drawCircle([x, y], diameter, options = {}) {
+ let { color, lineColor = this.ctx.strokeStyle } = options;
+
+ this.ctx.beginPath();
+ this.ctx.arc(x, y, diameter / 2, 0, 2 * Math.PI);
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke();
+ this.ctx.fillStyle = color;
+ if (color) this.ctx.fill();
+ },
+ drawOval([x, y], height, width, options = {}) {
+ let { rotation = 0, color, lineColor = this.ctx.strokeStyle } = options;
+ if (rotation) rotation = this.__toRadians__(rotation);
+
+ this.ctx.beginPath();
+ this.ctx.ellipse(x, y, width, height, rotation, 0, 2 * Math.PI);
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke();
+ this.ctx.fillStyle = color;
+ if (color) this.ctx.fill();
+ },
+ drawSquare([x, y], diameter, options = {}) {
+ this.drawRectangle([x, y], diameter, diameter, options);
+ },
+ drawRectangle([x, y], height, width, options = {}) {
+ let { color, lineColor = this.ctx.strokeStyle, radius = 0, rotate = 0 } = options;
+
+ // if (width < 2 * radius) radius = width / 2;
+ // if (height < 2 * radius) radius = height / 2;
+
+ this.ctx.beginPath();
+ this.ctx.moveTo(x + radius, y);
+ let p1 = this.__rotatePoint__([x + width, y], [x, y], rotate);
+ let p2 = this.__rotatePoint__([x + width, y + height], [x, y], rotate);
+ this.ctx.arcTo(p1[0], p1[1], p2[0], p2[1], radius);
+
+ let p3 = this.__rotatePoint__([x + width, y + height], [x, y], rotate);
+ let p4 = this.__rotatePoint__([x, y + height], [x, y], rotate);
+ this.ctx.arcTo(p3[0], p3[1], p4[0], p4[1], radius);
+
+ let p5 = this.__rotatePoint__([x, y + height], [x, y], rotate);
+ let p6 = this.__rotatePoint__([x, y], [x, y], rotate);
+ this.ctx.arcTo(p5[0], p5[1], p6[0], p6[1], radius);
+
+ let p7 = this.__rotatePoint__([x, y], [x, y], rotate);
+ let p8 = this.__rotatePoint__([x + width, y], [x, y], rotate);
+ this.ctx.arcTo(p7[0], p7[1], p8[0], p8[1], radius);
+ this.ctx.closePath();
+
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke();
+ this.ctx.fillStyle = color;
+ if (color) this.ctx.fill();
+
+ },
+ drawLine([fromX, fromY], [toX, toY], options = {}) {
+ let { lineColor = this.ctx.strokeStyle } = options;
+
+ this.ctx.beginPath();
+ this.ctx.moveTo(fromX, fromY);
+ this.ctx.lineTo(toX, toY);
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke();
+ },
+ drawPolygon(points, options = {}) {
+ let { color, lineColor = this.ctx.strokeStyle, radius = 0, close = false } = options;
+
+ function getRoundedPoint(x1, y1, x2, y2, radius, first) {
+ let total = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
+ let idx = first ? radius / total : (total - radius) / total;
+
+ return [x1 + (idx * (x2 - x1)), y1 + (idx * (y2 - y1))];
+ }
+
+ function getRoundedPoints(pts, radius) {
+ let len = pts.length;
+ let res = new Array(len);
+
+ for (let i2 = 0; i2 < len; i2++) {
+ let i1 = i2 - 1;
+ let i3 = i2 + 1;
+
+ if (i1 < 0) i1 = len - 1;
+ if (i3 == len) i3 = 0;
+
+ let p1 = pts[i1];
+ let p2 = pts[i2];
+ let p3 = pts[i3];
+
+ let prevPt = getRoundedPoint(p1[0], p1[1], p2[0], p2[1], radius, false);
+ let nextPt = getRoundedPoint(p2[0], p2[1], p3[0], p3[1], radius, true);
+ res[i2] = [prevPt[0], prevPt[1], p2[0], p2[1], nextPt[0], nextPt[1]];
+ }
+ return res;
+ }
+ if (radius > 0) {
+ points = getRoundedPoints(points, radius);
+ }
+
+ let i, pt, len = points.length;
+ for (i = 0; i < len; i++) {
+ pt = points[i];
+ if (i == 0) {
+ this.ctx.beginPath();
+ this.ctx.moveTo(pt[0], pt[1]);
+ } else {
+ this.ctx.lineTo(pt[0], pt[1]);
+ }
+ if (radius > 0) {
+ this.ctx.quadraticCurveTo(pt[2], pt[3], pt[4], pt[5]);
+ }
+ }
+
+ if (close) this.ctx.closePath();
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke();
+
+ this.ctx.fillStyle = color;
+ if (color) this.ctx.fill();
+ }
+
+ };
+
+ function Wave() {
+ this.current_stream = {};
+ this.sources = {};
+ this.onFileLoad = null;
+ this.activeElements = {};
+ this.activated = false;
+
+ window.AudioContext = window.AudioContext || window.webkitAudioContext;
+ }
+
+ Wave.prototype = {
+ fromElement,
+ fromFile,
+ ...fromStream$1,
+ visualize,
+ Helper
};
return Wave;
diff --git a/package-lock.json b/package-lock.json
index 82f4bf8..2d3935e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@foobar404/wave",
- "version": "1.2.2",
+ "version": "1.2.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1007,6 +1007,21 @@
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
"dev": true
},
+ "@types/node": {
+ "version": "14.0.23",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.23.tgz",
+ "integrity": "sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw==",
+ "dev": true
+ },
+ "@types/resolve": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
+ "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
@@ -1043,6 +1058,12 @@
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
+ "builtin-modules": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz",
+ "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==",
+ "dev": true
+ },
"caniuse-lite": {
"version": "1.0.30001091",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001091.tgz",
@@ -1168,6 +1189,7 @@
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz",
"integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==",
+ "dev": true,
"requires": {
"merge": "^1.2.0"
}
@@ -1211,6 +1233,21 @@
"loose-envify": "^1.0.0"
}
},
+ "is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
+ "dev": true
+ },
+ "is-reference": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
+ "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
+ "dev": true,
+ "requires": {
+ "@types/estree": "*"
+ }
+ },
"jest-worker": {
"version": "26.1.0",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.1.0.tgz",
@@ -1289,10 +1326,20 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
+ "magic-string": {
+ "version": "0.25.7",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
+ "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
+ "dev": true,
+ "requires": {
+ "sourcemap-codec": "^1.4.4"
+ }
+ },
"merge": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz",
- "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ=="
+ "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==",
+ "dev": true
},
"merge-stream": {
"version": "2.0.0",
@@ -1303,7 +1350,8 @@
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
},
"ms": {
"version": "2.1.2",
@@ -1335,6 +1383,12 @@
"object-keys": "^1.0.11"
}
},
+ "origamijs": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/origamijs/-/origamijs-0.5.1.tgz",
+ "integrity": "sha1-0d4acyPsWImZOr92latDGGueVcA=",
+ "dev": true
+ },
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
@@ -1432,6 +1486,40 @@
"path-parse": "^1.0.6"
}
},
+ "rollup-plugin-commonjs": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz",
+ "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==",
+ "dev": true,
+ "requires": {
+ "estree-walker": "^0.6.1",
+ "is-reference": "^1.1.2",
+ "magic-string": "^0.25.2",
+ "resolve": "^1.11.0",
+ "rollup-pluginutils": "^2.8.1"
+ },
+ "dependencies": {
+ "estree-walker": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
+ "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
+ "dev": true
+ }
+ }
+ },
+ "rollup-plugin-node-resolve": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz",
+ "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==",
+ "dev": true,
+ "requires": {
+ "@types/resolve": "0.0.8",
+ "builtin-modules": "^3.1.0",
+ "is-module": "^1.0.0",
+ "resolve": "^1.11.1",
+ "rollup-pluginutils": "^2.8.1"
+ }
+ },
"rollup-plugin-terser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-6.1.0.tgz",
@@ -1444,6 +1532,23 @@
"terser": "^4.7.0"
}
},
+ "rollup-pluginutils": {
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
+ "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
+ "dev": true,
+ "requires": {
+ "estree-walker": "^0.6.1"
+ },
+ "dependencies": {
+ "estree-walker": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
+ "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
+ "dev": true
+ }
+ }
+ },
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -1481,6 +1586,12 @@
"source-map": "^0.6.0"
}
},
+ "sourcemap-codec": {
+ "version": "1.4.8",
+ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+ "dev": true
+ },
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -1539,6 +1650,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/watch/-/watch-1.0.2.tgz",
"integrity": "sha1-NApxe952Vyb6CqB9ch4BR6VR3ww=",
+ "dev": true,
"requires": {
"exec-sh": "^0.2.0",
"minimist": "^1.2.0"
diff --git a/package.json b/package.json
index 02b3bfe..dbb55aa 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@foobar404/wave",
- "version": "1.2.4",
+ "version": "1.2.6",
"description": "Audio visualizer library for javascript (20+ designs).",
"main": "dist/bundle.cjs.js",
"directories": {
@@ -25,7 +25,7 @@
"files": [
"dist/bundle.cjs.js"
],
- "homepage": "https://github.com/foobar404/Wave.js",
+ "homepage": "https://foobar404.github.io/Wave.js/#/",
"repository": {
"type": "git",
"url": "https://github.com/foobar404/Wave.js.git"
@@ -37,9 +37,11 @@
"@babel/core": "^7.10.4",
"@babel/preset-env": "^7.10.4",
"@rollup/plugin-babel": "^5.0.4",
- "rollup-plugin-terser": "^6.1.0"
- },
- "dependencies": {
+ "origamijs": "^0.5.1",
+ "rollup-plugin-commonjs": "^10.1.0",
+ "rollup-plugin-node-resolve": "^5.2.0",
+ "rollup-plugin-terser": "^6.1.0",
"watch": "^1.0.2"
- }
+ },
+ "dependencies": {}
}
\ No newline at end of file
diff --git a/rollup.config.js b/rollup.config.js
index ef88b12..c6700fb 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -1,31 +1,24 @@
-// import { terser } from "rollup-plugin-terser";
-// import babel from '@rollup/plugin-babel';
-
-export default {
- input: "./src/index.js",
- output: [{
- file: './dist/bundle.iife.js',
- format: 'iife',
- name: 'Wave'
- }, {
- file: './dist/bundle.cjs.js',
- format: 'cjs'
- }],
- // plugins: [babel({
- // presets: [
- // [
- // "@babel/preset-env",
- // {
- // "targets": {
- // "browsers": [
- // "safari 6",
- // "cover 99.5%"
- // ]
- // },
- // debug: false
- // }
- // ]
- // ]
- // }), terser()]
-}
-
+// import { terser } from "rollup-plugin-terser";
+// import babel from '@rollup/plugin-babel';
+
+import resolve from 'rollup-plugin-node-resolve';
+import commonJS from 'rollup-plugin-commonjs'
+
+export default {
+ input: "./src/index.js",
+ output: [{
+ file: './dist/bundle.iife.js',
+ format: 'iife',
+ name: 'Wave'
+ }, {
+ file: './dist/bundle.cjs.js',
+ format: 'cjs'
+ }],
+ plugins: [
+ resolve(),
+ commonJS({
+ include: 'node_modules/**'
+ })
+ ]
+}
+
diff --git a/src/fromElement.js b/src/fromElement.js
index c20a724..3b1803d 100644
--- a/src/fromElement.js
+++ b/src/fromElement.js
@@ -1,112 +1,112 @@
-export default function fromElement(element_id, canvas_id, options) {
-
- const waveContext = this;
- let element = document.getElementById(element_id);
- if (!element) return
- element.crossOrigin = "anonymous";
-
- function run() {
- //user gesture has happened
- this.activated = true
-
- //track current wave for canvas
- this.activeCanvas = this.activeCanvas || {}
- this.activeCanvas[canvas_id] = JSON.stringify(options)
-
- //track elements used so multiple elements use the same data
- this.activeElements[element_id] = this.activeElements[element_id] || {}
- if (this.activeElements[element_id].count) this.activeElements[element_id].count += 1
- else this.activeElements[element_id].count = 1
-
- const currentCount = this.activeElements[element_id].count
-
- //fix "AudioContext already connected" error
- window.$wave = window.$wave || {}
- window.$wave[element.id] = window.$wave[element.id] || {}
-
- let audioCtx = window.$wave[element.id].audioCtx || new AudioContext();
- window.$wave[element.id].audioCtx = audioCtx
-
- let analyser = window.$wave[element.id].analyzer || audioCtx.createAnalyser();
- window.$wave[element.id].analyser = analyser
-
- //check if the element has a source already assigned and make sure they point to the same
- //reference because React will make a new element with a different reference
- let source = null;
- if (window.$wave[element.id].source)
- if (window.$wave[element.id].source.mediaElement === element)
- source = window.$wave[element.id].source
- else
- source = audioCtx.createMediaElementSource(element);
- else
- source = audioCtx.createMediaElementSource(element);
-
- window.$wave[element.id].source = source
-
- //beep test for ios
- let oscillator = audioCtx.createOscillator();
- oscillator.frequency.value = 1;
- oscillator.connect(audioCtx.destination);
- oscillator.start(0);
- oscillator.stop(0);
-
- source.connect(analyser)
- source.connect(audioCtx.destination)
-
- analyser.fftsize = 32768;
- let bufferLength = analyser.frequencyBinCount;
- let data = new Uint8Array(bufferLength);
- let frameCount = 1
-
- function renderFrame() {
- //only run one wave visual per canvas
- if (JSON.stringify(options) != this.activeCanvas[canvas_id]) {
- return
- }
-
- //if the element or canvas go out of scope, stop animation
- if (!document.getElementById(element_id) || !document.getElementById(canvas_id))
- return
-
- requestAnimationFrame(renderFrame);
- frameCount++
-
- //check if this element is the last to be called
- if (!(currentCount < this.activeElements[element_id].count)) {
- analyser.getByteFrequencyData(data);
- this.activeElements[element_id].data = data
- }
-
- this.visualize(this.activeElements[element_id].data, canvas_id, options, frameCount);
- }
-
- renderFrame = renderFrame.bind(this)
- renderFrame();
-
- }
-
-
- const create = () => {
- //remove all events
- ["touchstart", "touchmove", "touchend", "mouseup", "click", "play"].forEach(event => {
- element.removeEventListener(event, create, { once: true })
- })
-
- run.call(waveContext)
- }
-
- if (this.activated) {
- run.call(waveContext)
- } else {
- //wait for a valid user gesture
- document.body.addEventListener("touchstart", create, { once: true })
- document.body.addEventListener("touchmove", create, { once: true })
- document.body.addEventListener("touchend", create, { once: true })
- document.body.addEventListener("mouseup", create, { once: true })
- document.body.addEventListener("click", create, { once: true })
- element.addEventListener("play", create, { once: true })
- }
-
-
-
+export default function fromElement(element_id, canvas_id, options) {
+
+ const waveContext = this;
+ let element = document.getElementById(element_id);
+ if (!element) return
+ element.crossOrigin = "anonymous";
+
+ function run() {
+ //user gesture has happened
+ this.activated = true
+
+ //track current wave for canvas
+ this.activeCanvas = this.activeCanvas || {}
+ this.activeCanvas[canvas_id] = JSON.stringify(options)
+
+ //track elements used so multiple elements use the same data
+ this.activeElements[element_id] = this.activeElements[element_id] || {}
+ if (this.activeElements[element_id].count) this.activeElements[element_id].count += 1
+ else this.activeElements[element_id].count = 1
+
+ const currentCount = this.activeElements[element_id].count
+
+ //fix "AudioContext already connected" error
+ window.$wave = window.$wave || {}
+ window.$wave[element.id] = window.$wave[element.id] || {}
+
+ let audioCtx = window.$wave[element.id].audioCtx || new AudioContext();
+ window.$wave[element.id].audioCtx = audioCtx
+
+ let analyser = window.$wave[element.id].analyzer || audioCtx.createAnalyser();
+ window.$wave[element.id].analyser = analyser
+
+ //check if the element has a source already assigned and make sure they point to the same
+ //reference because React will make a new element with a different reference
+ let source = null;
+ if (window.$wave[element.id].source)
+ if (window.$wave[element.id].source.mediaElement === element)
+ source = window.$wave[element.id].source
+ else
+ source = audioCtx.createMediaElementSource(element);
+ else
+ source = audioCtx.createMediaElementSource(element);
+
+ window.$wave[element.id].source = source
+
+ //beep test for ios
+ let oscillator = audioCtx.createOscillator();
+ oscillator.frequency.value = 1;
+ oscillator.connect(audioCtx.destination);
+ oscillator.start(0);
+ oscillator.stop(0);
+
+ source.connect(analyser)
+ source.connect(audioCtx.destination)
+
+ analyser.fftsize = 32768;
+ let bufferLength = analyser.frequencyBinCount;
+ let data = new Uint8Array(bufferLength);
+ let frameCount = 1
+
+ function renderFrame() {
+ //only run one wave visual per canvas
+ if (JSON.stringify(options) != this.activeCanvas[canvas_id]) {
+ return
+ }
+
+ //if the element or canvas go out of scope, stop animation
+ if (!document.getElementById(element_id) || !document.getElementById(canvas_id))
+ return
+
+ requestAnimationFrame(renderFrame);
+ frameCount++
+
+ //check if this element is the last to be called
+ if (!(currentCount < this.activeElements[element_id].count)) {
+ analyser.getByteFrequencyData(data);
+ this.activeElements[element_id].data = data
+ }
+
+ this.visualize(this.activeElements[element_id].data, canvas_id, options, frameCount);
+ }
+
+ renderFrame = renderFrame.bind(this)
+ renderFrame();
+
+ }
+
+
+ const create = () => {
+ //remove all events
+ ["touchstart", "touchmove", "touchend", "mouseup", "click", "play"].forEach(event => {
+ element.removeEventListener(event, create, { once: true })
+ })
+
+ run.call(waveContext)
+ }
+
+ if (this.activated) {
+ run.call(waveContext)
+ } else {
+ //wait for a valid user gesture
+ document.body.addEventListener("touchstart", create, { once: true })
+ document.body.addEventListener("touchmove", create, { once: true })
+ document.body.addEventListener("touchend", create, { once: true })
+ document.body.addEventListener("mouseup", create, { once: true })
+ document.body.addEventListener("click", create, { once: true })
+ element.addEventListener("play", create, { once: true })
+ }
+
+
+
}
\ No newline at end of file
diff --git a/src/fromFile.js b/src/fromFile.js
index fcc5a85..ce27653 100644
--- a/src/fromFile.js
+++ b/src/fromFile.js
@@ -1,89 +1,89 @@
-export default function fromFile(file, options = {}) {
- //options
- if (!options.stroke) options.stroke = 10;
-
- let audio = new Audio();
- audio.src = file;
-
- let audioCtx = new AudioContext();
- let analyser = audioCtx.createAnalyser();
-
- let source = audioCtx.createMediaElementSource(audio);
- source.connect(analyser);
-
- analyser.fftSize = 64;
- let bufferLength = analyser.frequencyBinCount;
-
- let file_data;
- let temp_data = new Uint8Array(bufferLength);
- let getWave;
- let fdi = 0;
- let self = this;
-
- audio.addEventListener('loadedmetadata', async function () {
-
- while (audio.duration === Infinity) {
- await new Promise(r => setTimeout(r, 1000));
- audio.currentTime = 10000000 * Math.random();
- }
-
- audio.currentTime = 0;
- audio.play();
- })
-
- audio.onplay = function () {
- let findSize = (size) => {
-
- for (let range = 1; range <= 40; range++) {
- let power = 2 ** range;
-
- if (size <= power) return power;
- }
-
- }
- let d = audio.duration;
- audio.playbackRate = 16;
-
- d = d / audio.playbackRate;
-
- let drawRate = 20; //ms
-
- let size = ((d / (drawRate / 1000)) * (analyser.fftSize / 2));
- size = findSize(size);
- file_data = new Uint8Array(size);
-
-
- getWave = setInterval(function () {
- analyser.getByteFrequencyData(temp_data);
-
- for (let data in temp_data) {
- data = temp_data[data];
- file_data[fdi] = data;
- fdi++;
- }
-
- }, drawRate);
-
-
- }
-
- audio.onended = function () {
-
- if (audio.currentTime === audio.duration && file_data !== undefined) {
-
- clearInterval(getWave);
-
- let canvas = document.createElement("canvas");
- canvas.height = window.innerHeight;
- canvas.width = window.innerWidth;
-
- self.visualize(file_data, canvas, options);
- let image = canvas.toDataURL("image/jpg");
- self.onFileLoad(image);
-
- canvas.remove();
- }
-
- }
-
+export default function fromFile(file, options = {}) {
+ //options
+ if (!options.stroke) options.stroke = 10;
+
+ let audio = new Audio();
+ audio.src = file;
+
+ let audioCtx = new AudioContext();
+ let analyser = audioCtx.createAnalyser();
+
+ let source = audioCtx.createMediaElementSource(audio);
+ source.connect(analyser);
+
+ analyser.fftSize = 64;
+ let bufferLength = analyser.frequencyBinCount;
+
+ let file_data;
+ let temp_data = new Uint8Array(bufferLength);
+ let getWave;
+ let fdi = 0;
+ let self = this;
+
+ audio.addEventListener('loadedmetadata', async function () {
+
+ while (audio.duration === Infinity) {
+ await new Promise(r => setTimeout(r, 1000));
+ audio.currentTime = 10000000 * Math.random();
+ }
+
+ audio.currentTime = 0;
+ audio.play();
+ })
+
+ audio.onplay = function () {
+ let findSize = (size) => {
+
+ for (let range = 1; range <= 40; range++) {
+ let power = 2 ** range;
+
+ if (size <= power) return power;
+ }
+
+ }
+ let d = audio.duration;
+ audio.playbackRate = 16;
+
+ d = d / audio.playbackRate;
+
+ let drawRate = 20; //ms
+
+ let size = ((d / (drawRate / 1000)) * (analyser.fftSize / 2));
+ size = findSize(size);
+ file_data = new Uint8Array(size);
+
+
+ getWave = setInterval(function () {
+ analyser.getByteFrequencyData(temp_data);
+
+ for (let data in temp_data) {
+ data = temp_data[data];
+ file_data[fdi] = data;
+ fdi++;
+ }
+
+ }, drawRate);
+
+
+ }
+
+ audio.onended = function () {
+
+ if (audio.currentTime === audio.duration && file_data !== undefined) {
+
+ clearInterval(getWave);
+
+ let canvas = document.createElement("canvas");
+ canvas.height = window.innerHeight;
+ canvas.width = window.innerWidth;
+
+ self.visualize(file_data, canvas, options);
+ let image = canvas.toDataURL("image/jpg");
+ self.onFileLoad(image);
+
+ canvas.remove();
+ }
+
+ }
+
}
\ No newline at end of file
diff --git a/src/fromStream.js b/src/fromStream.js
index 7927f46..ad4c1ac 100644
--- a/src/fromStream.js
+++ b/src/fromStream.js
@@ -1,58 +1,58 @@
-function fromStream(stream, canvas_id, options = {}) {
-
- this.current_stream.id = canvas_id;
- this.current_stream.options = options;
-
- let audioCtx, analyser, source;
- if (!this.sources[stream.toString()]) {
- audioCtx = new AudioContext();
- analyser = audioCtx.createAnalyser();
-
- source = audioCtx.createMediaStreamSource(stream);
- source.connect(analyser);
- source.connect(audioCtx.destination); //playback audio
-
- this.sources[stream.toString()] = {
- "audioCtx": audioCtx,
- "analyser": analyser,
- "source": source
- }
- } else {
- cancelAnimationFrame(this.sources[stream.toString()].animation);
- audioCtx = this.sources[stream.toString()].audioCtx;
- analyser = this.sources[stream.toString()].analyser;
- source = this.sources[stream.toString()].source;
- }
-
- analyser.fftsize = 32768;
- let bufferLength = analyser.frequencyBinCount;
- this.current_stream.data = new Uint8Array(bufferLength);
-
- let self = this;
-
- function renderFrame() {
- self.current_stream.animation = requestAnimationFrame(self.current_stream.loop);
- self.sources[stream.toString()].animation = self.current_stream.animation;
- analyser.getByteFrequencyData(self.current_stream.data);
-
- self.visualize(self.current_stream.data, self.current_stream.id, self.current_stream.options);
- }
-
- this.current_stream.loop = renderFrame;
- renderFrame();
-
-}
-
-function stopStream() {
- cancelAnimationFrame(this.current_stream.animation);
-}
-
-function playStream() {
- this.current_stream.loop();
-}
-
-export default {
- fromStream,
- stopStream,
- playStream
+function fromStream(stream, canvas_id, options = {}) {
+
+ this.current_stream.id = canvas_id;
+ this.current_stream.options = options;
+
+ let audioCtx, analyser, source;
+ if (!this.sources[stream.toString()]) {
+ audioCtx = new AudioContext();
+ analyser = audioCtx.createAnalyser();
+
+ source = audioCtx.createMediaStreamSource(stream);
+ source.connect(analyser);
+ source.connect(audioCtx.destination); //playback audio
+
+ this.sources[stream.toString()] = {
+ "audioCtx": audioCtx,
+ "analyser": analyser,
+ "source": source
+ }
+ } else {
+ cancelAnimationFrame(this.sources[stream.toString()].animation);
+ audioCtx = this.sources[stream.toString()].audioCtx;
+ analyser = this.sources[stream.toString()].analyser;
+ source = this.sources[stream.toString()].source;
+ }
+
+ analyser.fftsize = 32768;
+ let bufferLength = analyser.frequencyBinCount;
+ this.current_stream.data = new Uint8Array(bufferLength);
+
+ let self = this;
+
+ function renderFrame() {
+ self.current_stream.animation = requestAnimationFrame(self.current_stream.loop);
+ self.sources[stream.toString()].animation = self.current_stream.animation;
+ analyser.getByteFrequencyData(self.current_stream.data);
+
+ self.visualize(self.current_stream.data, self.current_stream.id, self.current_stream.options);
+ }
+
+ this.current_stream.loop = renderFrame;
+ renderFrame();
+
+}
+
+function stopStream() {
+ cancelAnimationFrame(this.current_stream.animation);
+}
+
+function playStream() {
+ this.current_stream.loop();
+}
+
+export default {
+ fromStream,
+ stopStream,
+ playStream
}
\ No newline at end of file
diff --git a/src/helper.js b/src/helper.js
index 9046424..aca422a 100644
--- a/src/helper.js
+++ b/src/helper.js
@@ -1,292 +1,292 @@
-function Helper(ctx) {
- this.ctx = ctx
- this.mainColor = "black"
-}
-
-Helper.prototype = {
- __toRadians__(degree) {
- return (degree * Math.PI) / 180;
- },
- __rotatePoint__([pointX, pointY], [originX, originY], degree) {
- //clockwise
- let angle = this.__toRadians__(degree)
- let rotatedX = Math.cos(angle) * (pointX - originX) - Math.sin(angle) * (pointY - originY) + originX;
- let rotatedY = Math.sin(angle) * (pointX - originX) + Math.cos(angle) * (pointY - originY) + originY;
-
- return [rotatedX, rotatedY]
- },
- mutateData(data, type, extra = null) {
- if (type === "mirror") {
- let rtn = []
-
- for (let i = 0; i < data.length; i += 2) {
- rtn.push(data[i])
- }
-
- rtn = [...rtn, ...rtn.reverse()]
- return rtn
- }
-
- if (type === "shrink") {
- //resize array by % of current array
- if (extra < 1) {
- extra = data.length * extra
- }
-
- let rtn = []
- let splitAt = Math.floor(data.length / extra)
-
- for (let i = 1; i <= extra; i++) {
- let arraySection = data.slice(i * splitAt, (i * splitAt) + splitAt)
- let middle = arraySection[Math.floor(arraySection.length / 2)]
- rtn.push(middle)
- }
-
- return rtn
- }
-
- if (type === "split") {
- let size = Math.floor(data.length / extra)
- let rtn = []
- let temp = []
-
- let track = 0
- for (let i = 0; i <= size * extra; i++) {
- if (track === size) {
- rtn.push(temp)
- temp = []
- track = 0
- }
-
- temp.push(data[i])
- track++
- }
-
- return rtn
- }
-
- if (type === "scale") {
- let scalePercent = extra / 255
- if (extra <= 3 && extra >= 0) scalePercent = extra
- let rtn = data.map(value => value * scalePercent)
- return rtn
- }
-
- if (type === "organize") {
- let rtn = {}
- rtn.base = data.slice(60, 120)
- rtn.vocals = data.slice(120, 255)
- rtn.mids = data.slice(255, 2000)
- return rtn
- }
-
- if (type === "reverb") {
- let rtn = []
- data.forEach((val, i) => {
- rtn.push(val - (data[i + 1] || 0))
- })
- return rtn
- }
-
- if (type === "amp") {
- let rtn = []
- data.forEach(val => {
- rtn.push(val * (extra + 1))
- })
- return rtn
- }
-
- if (type === "min") {
- let rtn = []
- data.forEach(value => {
- if (value < extra) value = extra
- rtn.push(value)
- })
- return rtn
- }
- },
- getPoints(shape, size, [originX, originY], pointCount, endPoints, options = {}) {
- let { offset = 0, rotate = 0, customOrigin = [] } = options
- let rtn = {
- start: [],
- end: []
- }
-
- if (shape === "circle") {
-
- let degreePerPoint = 360 / pointCount
- let radianPerPoint = this.__toRadians__(degreePerPoint)
- let radius = size / 2
-
- for (let i = 1; i <= pointCount; i++) {
- let currentRadian = radianPerPoint * i
- let currentEndPoint = endPoints[i - 1]
- let pointOffset = endPoints[i - 1] * (offset / 100)
-
- let x = originX + (radius - pointOffset) * Math.cos(currentRadian)
- let y = originY + (radius - pointOffset) * Math.sin(currentRadian)
- let point1 = this.__rotatePoint__([x, y], [originX, originY], rotate)
-
- rtn.start.push(point1)
-
- x = originX + ((radius - pointOffset) + currentEndPoint) * Math.cos(currentRadian)
- y = originY + ((radius - pointOffset) + currentEndPoint) * Math.sin(currentRadian)
- let point2 = this.__rotatePoint__([x, y], [originX, originY], rotate)
-
- rtn.end.push(point2)
-
- }
-
- return rtn
- }
-
- if (shape === "line") {
- let increment = size / pointCount
-
- originX = customOrigin[0] || originX
- originY = customOrigin[1] || originY
-
- for (let i = 0; i <= pointCount; i++) {
- let degree = rotate
- let pointOffset = endPoints[i] * (offset / 100)
-
- let startingPoint = this.__rotatePoint__([originX + (i * increment), originY - pointOffset],
- [originX, originY], degree)
- rtn.start.push(startingPoint)
-
- let endingPoint = this.__rotatePoint__([originX + (i * increment), (originY + endPoints[i]) - pointOffset],
- [originX, originY], degree)
- rtn.end.push(endingPoint)
- }
-
- return rtn
-
- }
-
- },
- drawCircle([x, y], diameter, options = {}) {
- let { color, lineColor = this.ctx.strokeStyle } = options
-
- this.ctx.beginPath();
- this.ctx.arc(x, y, diameter / 2, 0, 2 * Math.PI);
- this.ctx.strokeStyle = lineColor
- this.ctx.stroke();
- this.ctx.fillStyle = color
- if (color) this.ctx.fill()
- },
- drawOval([x, y], height, width, options = {}) {
- let { rotation = 0, color, lineColor = this.ctx.strokeStyle } = options;
- if (rotation) rotation = this.__toRadians__(rotation);
-
- this.ctx.beginPath();
- this.ctx.ellipse(x, y, width, height, rotation, 0, 2 * Math.PI);
- this.ctx.strokeStyle = lineColor
- this.ctx.stroke();
- this.ctx.fillStyle = color
- if (color) this.ctx.fill()
- },
- drawSquare([x, y], diameter, options = {}) {
- this.drawRectangle([x, y], diameter, diameter, options)
- },
- drawRectangle([x, y], height, width, options = {}) {
- let { color, lineColor = this.ctx.strokeStyle, radius = 0, rotate = 0 } = options
-
- // if (width < 2 * radius) radius = width / 2;
- // if (height < 2 * radius) radius = height / 2;
-
- this.ctx.beginPath();
- this.ctx.moveTo(x + radius, y);
- let p1 = this.__rotatePoint__([x + width, y], [x, y], rotate)
- let p2 = this.__rotatePoint__([x + width, y + height], [x, y], rotate)
- this.ctx.arcTo(p1[0], p1[1], p2[0], p2[1], radius);
-
- let p3 = this.__rotatePoint__([x + width, y + height], [x, y], rotate)
- let p4 = this.__rotatePoint__([x, y + height], [x, y], rotate)
- this.ctx.arcTo(p3[0], p3[1], p4[0], p4[1], radius);
-
- let p5 = this.__rotatePoint__([x, y + height], [x, y], rotate)
- let p6 = this.__rotatePoint__([x, y], [x, y], rotate)
- this.ctx.arcTo(p5[0], p5[1], p6[0], p6[1], radius);
-
- let p7 = this.__rotatePoint__([x, y], [x, y], rotate)
- let p8 = this.__rotatePoint__([x + width, y], [x, y], rotate)
- this.ctx.arcTo(p7[0], p7[1], p8[0], p8[1], radius);
- this.ctx.closePath();
-
- this.ctx.strokeStyle = lineColor;
- this.ctx.stroke()
- this.ctx.fillStyle = color
- if (color) this.ctx.fill()
-
- },
- drawLine([fromX, fromY], [toX, toY], options = {}) {
- let { lineColor = this.ctx.strokeStyle } = options
-
- this.ctx.beginPath();
- this.ctx.moveTo(fromX, fromY);
- this.ctx.lineTo(toX, toY);
- this.ctx.strokeStyle = lineColor
- this.ctx.stroke();
- },
- drawPolygon(points, options = {}) {
- let { color, lineColor = this.ctx.strokeStyle, radius = 0, close = false } = options
-
- function getRoundedPoint(x1, y1, x2, y2, radius, first) {
- let total = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
- let idx = first ? radius / total : (total - radius) / total;
-
- return [x1 + (idx * (x2 - x1)), y1 + (idx * (y2 - y1))];
- }
-
- function getRoundedPoints(pts, radius) {
- let len = pts.length
- let res = new Array(len);
-
- for (let i2 = 0; i2 < len; i2++) {
- let i1 = i2 - 1;
- let i3 = i2 + 1;
-
- if (i1 < 0) i1 = len - 1;
- if (i3 == len) i3 = 0;
-
- let p1 = pts[i1];
- let p2 = pts[i2];
- let p3 = pts[i3];
-
- let prevPt = getRoundedPoint(p1[0], p1[1], p2[0], p2[1], radius, false);
- let nextPt = getRoundedPoint(p2[0], p2[1], p3[0], p3[1], radius, true);
- res[i2] = [prevPt[0], prevPt[1], p2[0], p2[1], nextPt[0], nextPt[1]];
- }
- return res;
- };
-
- if (radius > 0) {
- points = getRoundedPoints(points, radius);
- }
-
- let i, pt, len = points.length;
- for (i = 0; i < len; i++) {
- pt = points[i];
- if (i == 0) {
- this.ctx.beginPath();
- this.ctx.moveTo(pt[0], pt[1]);
- } else {
- this.ctx.lineTo(pt[0], pt[1]);
- }
- if (radius > 0) {
- this.ctx.quadraticCurveTo(pt[2], pt[3], pt[4], pt[5]);
- }
- }
-
- if (close) this.ctx.closePath();
- this.ctx.strokeStyle = lineColor
- this.ctx.stroke();
-
- this.ctx.fillStyle = color
- if (color) this.ctx.fill()
- }
-
-}
-
-
+function Helper(ctx) {
+ this.ctx = ctx
+ this.mainColor = "black"
+}
+
+Helper.prototype = {
+ __toRadians__(degree) {
+ return (degree * Math.PI) / 180;
+ },
+ __rotatePoint__([pointX, pointY], [originX, originY], degree) {
+ //clockwise
+ let angle = this.__toRadians__(degree)
+ let rotatedX = Math.cos(angle) * (pointX - originX) - Math.sin(angle) * (pointY - originY) + originX;
+ let rotatedY = Math.sin(angle) * (pointX - originX) + Math.cos(angle) * (pointY - originY) + originY;
+
+ return [rotatedX, rotatedY]
+ },
+ mutateData(data, type, extra = null) {
+ if (type === "mirror") {
+ let rtn = []
+
+ for (let i = 0; i < data.length; i += 2) {
+ rtn.push(data[i])
+ }
+
+ rtn = [...rtn, ...rtn.reverse()]
+ return rtn
+ }
+
+ if (type === "shrink") {
+ //resize array by % of current array
+ if (extra < 1) {
+ extra = data.length * extra
+ }
+
+ let rtn = []
+ let splitAt = Math.floor(data.length / extra)
+
+ for (let i = 1; i <= extra; i++) {
+ let arraySection = data.slice(i * splitAt, (i * splitAt) + splitAt)
+ let middle = arraySection[Math.floor(arraySection.length / 2)]
+ rtn.push(middle)
+ }
+
+ return rtn
+ }
+
+ if (type === "split") {
+ let size = Math.floor(data.length / extra)
+ let rtn = []
+ let temp = []
+
+ let track = 0
+ for (let i = 0; i <= size * extra; i++) {
+ if (track === size) {
+ rtn.push(temp)
+ temp = []
+ track = 0
+ }
+
+ temp.push(data[i])
+ track++
+ }
+
+ return rtn
+ }
+
+ if (type === "scale") {
+ let scalePercent = extra / 255
+ if (extra <= 3 && extra >= 0) scalePercent = extra
+ let rtn = data.map(value => value * scalePercent)
+ return rtn
+ }
+
+ if (type === "organize") {
+ let rtn = {}
+ rtn.base = data.slice(60, 120)
+ rtn.vocals = data.slice(120, 255)
+ rtn.mids = data.slice(255, 2000)
+ return rtn
+ }
+
+ if (type === "reverb") {
+ let rtn = []
+ data.forEach((val, i) => {
+ rtn.push(val - (data[i + 1] || 0))
+ })
+ return rtn
+ }
+
+ if (type === "amp") {
+ let rtn = []
+ data.forEach(val => {
+ rtn.push(val * (extra + 1))
+ })
+ return rtn
+ }
+
+ if (type === "min") {
+ let rtn = []
+ data.forEach(value => {
+ if (value < extra) value = extra
+ rtn.push(value)
+ })
+ return rtn
+ }
+ },
+ getPoints(shape, size, [originX, originY], pointCount, endPoints, options = {}) {
+ let { offset = 0, rotate = 0, customOrigin = [] } = options
+ let rtn = {
+ start: [],
+ end: []
+ }
+
+ if (shape === "circle") {
+
+ let degreePerPoint = 360 / pointCount
+ let radianPerPoint = this.__toRadians__(degreePerPoint)
+ let radius = size / 2
+
+ for (let i = 1; i <= pointCount; i++) {
+ let currentRadian = radianPerPoint * i
+ let currentEndPoint = endPoints[i - 1]
+ let pointOffset = endPoints[i - 1] * (offset / 100)
+
+ let x = originX + (radius - pointOffset) * Math.cos(currentRadian)
+ let y = originY + (radius - pointOffset) * Math.sin(currentRadian)
+ let point1 = this.__rotatePoint__([x, y], [originX, originY], rotate)
+
+ rtn.start.push(point1)
+
+ x = originX + ((radius - pointOffset) + currentEndPoint) * Math.cos(currentRadian)
+ y = originY + ((radius - pointOffset) + currentEndPoint) * Math.sin(currentRadian)
+ let point2 = this.__rotatePoint__([x, y], [originX, originY], rotate)
+
+ rtn.end.push(point2)
+
+ }
+
+ return rtn
+ }
+
+ if (shape === "line") {
+ let increment = size / pointCount
+
+ originX = customOrigin[0] || originX
+ originY = customOrigin[1] || originY
+
+ for (let i = 0; i <= pointCount; i++) {
+ let degree = rotate
+ let pointOffset = endPoints[i] * (offset / 100)
+
+ let startingPoint = this.__rotatePoint__([originX + (i * increment), originY - pointOffset],
+ [originX, originY], degree)
+ rtn.start.push(startingPoint)
+
+ let endingPoint = this.__rotatePoint__([originX + (i * increment), (originY + endPoints[i]) - pointOffset],
+ [originX, originY], degree)
+ rtn.end.push(endingPoint)
+ }
+
+ return rtn
+
+ }
+
+ },
+ drawCircle([x, y], diameter, options = {}) {
+ let { color, lineColor = this.ctx.strokeStyle } = options
+
+ this.ctx.beginPath();
+ this.ctx.arc(x, y, diameter / 2, 0, 2 * Math.PI);
+ this.ctx.strokeStyle = lineColor
+ this.ctx.stroke();
+ this.ctx.fillStyle = color
+ if (color) this.ctx.fill()
+ },
+ drawOval([x, y], height, width, options = {}) {
+ let { rotation = 0, color, lineColor = this.ctx.strokeStyle } = options;
+ if (rotation) rotation = this.__toRadians__(rotation);
+
+ this.ctx.beginPath();
+ this.ctx.ellipse(x, y, width, height, rotation, 0, 2 * Math.PI);
+ this.ctx.strokeStyle = lineColor
+ this.ctx.stroke();
+ this.ctx.fillStyle = color
+ if (color) this.ctx.fill()
+ },
+ drawSquare([x, y], diameter, options = {}) {
+ this.drawRectangle([x, y], diameter, diameter, options)
+ },
+ drawRectangle([x, y], height, width, options = {}) {
+ let { color, lineColor = this.ctx.strokeStyle, radius = 0, rotate = 0 } = options
+
+ // if (width < 2 * radius) radius = width / 2;
+ // if (height < 2 * radius) radius = height / 2;
+
+ this.ctx.beginPath();
+ this.ctx.moveTo(x + radius, y);
+ let p1 = this.__rotatePoint__([x + width, y], [x, y], rotate)
+ let p2 = this.__rotatePoint__([x + width, y + height], [x, y], rotate)
+ this.ctx.arcTo(p1[0], p1[1], p2[0], p2[1], radius);
+
+ let p3 = this.__rotatePoint__([x + width, y + height], [x, y], rotate)
+ let p4 = this.__rotatePoint__([x, y + height], [x, y], rotate)
+ this.ctx.arcTo(p3[0], p3[1], p4[0], p4[1], radius);
+
+ let p5 = this.__rotatePoint__([x, y + height], [x, y], rotate)
+ let p6 = this.__rotatePoint__([x, y], [x, y], rotate)
+ this.ctx.arcTo(p5[0], p5[1], p6[0], p6[1], radius);
+
+ let p7 = this.__rotatePoint__([x, y], [x, y], rotate)
+ let p8 = this.__rotatePoint__([x + width, y], [x, y], rotate)
+ this.ctx.arcTo(p7[0], p7[1], p8[0], p8[1], radius);
+ this.ctx.closePath();
+
+ this.ctx.strokeStyle = lineColor;
+ this.ctx.stroke()
+ this.ctx.fillStyle = color
+ if (color) this.ctx.fill()
+
+ },
+ drawLine([fromX, fromY], [toX, toY], options = {}) {
+ let { lineColor = this.ctx.strokeStyle } = options
+
+ this.ctx.beginPath();
+ this.ctx.moveTo(fromX, fromY);
+ this.ctx.lineTo(toX, toY);
+ this.ctx.strokeStyle = lineColor
+ this.ctx.stroke();
+ },
+ drawPolygon(points, options = {}) {
+ let { color, lineColor = this.ctx.strokeStyle, radius = 0, close = false } = options
+
+ function getRoundedPoint(x1, y1, x2, y2, radius, first) {
+ let total = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
+ let idx = first ? radius / total : (total - radius) / total;
+
+ return [x1 + (idx * (x2 - x1)), y1 + (idx * (y2 - y1))];
+ }
+
+ function getRoundedPoints(pts, radius) {
+ let len = pts.length
+ let res = new Array(len);
+
+ for (let i2 = 0; i2 < len; i2++) {
+ let i1 = i2 - 1;
+ let i3 = i2 + 1;
+
+ if (i1 < 0) i1 = len - 1;
+ if (i3 == len) i3 = 0;
+
+ let p1 = pts[i1];
+ let p2 = pts[i2];
+ let p3 = pts[i3];
+
+ let prevPt = getRoundedPoint(p1[0], p1[1], p2[0], p2[1], radius, false);
+ let nextPt = getRoundedPoint(p2[0], p2[1], p3[0], p3[1], radius, true);
+ res[i2] = [prevPt[0], prevPt[1], p2[0], p2[1], nextPt[0], nextPt[1]];
+ }
+ return res;
+ };
+
+ if (radius > 0) {
+ points = getRoundedPoints(points, radius);
+ }
+
+ let i, pt, len = points.length;
+ for (i = 0; i < len; i++) {
+ pt = points[i];
+ if (i == 0) {
+ this.ctx.beginPath();
+ this.ctx.moveTo(pt[0], pt[1]);
+ } else {
+ this.ctx.lineTo(pt[0], pt[1]);
+ }
+ if (radius > 0) {
+ this.ctx.quadraticCurveTo(pt[2], pt[3], pt[4], pt[5]);
+ }
+ }
+
+ if (close) this.ctx.closePath();
+ this.ctx.strokeStyle = lineColor
+ this.ctx.stroke();
+
+ this.ctx.fillStyle = color
+ if (color) this.ctx.fill()
+ }
+
+}
+
+
export default Helper
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 149c28b..c723b6b 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,30 +1,30 @@
-import fromElement from "./fromElement.js";
-import fromFile from "./fromFile.js";
-import fromStream from "./fromStream.js";
-import visualize from "./visualize.js";
-import Helper from "./helper.js";
-
-'use strict'
-
-function Wave() {
- this.current_stream = {};
- this.sources = {};
- this.onFileLoad = null;
- this.activeElements = {}
- this.activated = false
-
- window.AudioContext = window.AudioContext || window.webkitAudioContext;
-}
-
-Wave.prototype = {
- fromElement,
- fromFile,
- ...fromStream,
- visualize,
- Helper
-}
-
-export default Wave
-
-
-
+import fromElement from "./fromElement.js";
+import fromFile from "./fromFile.js";
+import fromStream from "./fromStream.js";
+import visualize from "./visualize.js";
+import Helper from "./helper.js";
+
+'use strict'
+
+function Wave() {
+ this.current_stream = {};
+ this.sources = {};
+ this.onFileLoad = null;
+ this.activeElements = {}
+ this.activated = false
+
+ window.AudioContext = window.AudioContext || window.webkitAudioContext;
+}
+
+Wave.prototype = {
+ fromElement,
+ fromFile,
+ ...fromStream,
+ visualize,
+ Helper
+}
+
+export default Wave
+
+
+
diff --git a/src/visualize.js b/src/visualize.js
index 5a3e21a..3b222dd 100644
--- a/src/visualize.js
+++ b/src/visualize.js
@@ -1,110 +1,113 @@
-import drawWave from "./visuals/drawWave.js"
-import drawShine from "./visuals/drawShine.js"
-import drawRing from "./visuals/drawRing.js"
-import drawBars from "./visuals/drawBars.js"
-import drawDualbars from "./visuals/drawDualbars.js"
-import drawOrbs from "./visuals/drawOrbs.js"
-import drawFlower from "./visuals/drawFlower.js"
-import drawFlowerBlocks from "./visuals/drawFlowerBlocks.js"
-import drawBarsBlocks from "./visuals/drawBarsBlocks.js"
-import drawDualbarsBlocks from "./visuals/drawDualbarsBlocks.js"
-import drawStar from "./visuals/drawStar.js"
-import drawRoundWave from "./visuals/drawRoundWave.js"
-import drawRings from "./visuals/drawRings.js"
-import drawShineRings from "./visuals/drawShineRings.js"
-import drawCubes from "./visuals/drawCubes.js"
-import drawBigBars from "./visuals/drawBigBars.js"
-import drawShockwave from "./visuals/drawShockwave.js"
-import drawFireworks from "./visuals/drawFireworks.js"
-import drawStatic from "./visuals/drawStatic.js"
-import drawWeb from "./visuals/drawWeb.js"
-import drawStitches from "./visuals/drawStitches.js"
-
-//options:type,colors,stroke
-export default function visualize(data, canvas, options = {}, frame) {
- //make a clone of options
- options = { ...options }
- //options
- if (!options.stroke) options.stroke = 1;
- if (!options.colors) options.colors = ["#d92027", "#ff9234", "#ffcd3c", "#35d0ba"];
-
- if (typeof canvas == "string") {
- canvas = document.getElementById(canvas);
- }
- if (!canvas) return;
-
- let ctx = canvas.getContext("2d");
- let h = canvas.height;
- let w = canvas.width;
-
-
-
- ctx.strokeStyle = options.colors[0];
- ctx.lineWidth = options.stroke;
-
- let typeMap = {
- "bars": drawBars,
- "bars blocks": drawBarsBlocks,
- "big bars": drawBigBars,
- "cubes": drawCubes,
- "dualbars": drawDualbars,
- "dualbars blocks": drawDualbarsBlocks,
- "fireworks": drawFireworks,
- "flower": drawFlower,
- "flower blocks": drawFlowerBlocks,
- "orbs": drawOrbs,
- "ring": drawRing,
- "rings": drawRings,
- "round wave": drawRoundWave,
- "shine": drawShine,
- "shine rings": drawShineRings,
- "shockwave": drawShockwave,
- "star": drawStar,
- "static": drawStatic,
- "stitches": drawStitches,
- "wave": drawWave,
- "web": drawWeb
- }
-
- let frameRateMap = {
- "bars": 1,
- "bars blocks": 1,
- "big bars": 1,
- "cubes": 1,
- "dualbars": 1,
- "dualbars blocks": 1,
- "fireworks": 1,
- "flower": 1,
- "flower blocks": 1,
- "ring": 1,
- "rings": 1,
- "round wave": 1,
- "orbs": 1,
- "shine": 1,
- "shine rings": 1,
- "shockwave": 1,
- "star": 1,
- "static": 1,
- "stitches": 1,
- "wave": 1,
- "web": 1
- }
-
- const functionContext = {
- data, options, ctx, h, w, Helper: this.Helper
- }
-
- if (typeof options.type == "string") options.type = [options.type]
-
- options.type.forEach(type => {
- //abide by the frame rate
- if (frame % frameRateMap[type] === 0) {
- //clear canvas
- ctx.clearRect(0, 0, w, h);
- ctx.beginPath();
-
- typeMap[type](functionContext)
- }
- })
-
+import drawWave from "./visuals/drawWave.js"
+import drawShine from "./visuals/drawShine.js"
+import drawRing from "./visuals/drawRing.js"
+import drawBars from "./visuals/drawBars.js"
+import drawDualbars from "./visuals/drawDualbars.js"
+import drawOrbs from "./visuals/drawOrbs.js"
+import drawFlower from "./visuals/drawFlower.js"
+import drawFlowerBlocks from "./visuals/drawFlowerBlocks.js"
+import drawBarsBlocks from "./visuals/drawBarsBlocks.js"
+import drawDualbarsBlocks from "./visuals/drawDualbarsBlocks.js"
+import drawStar from "./visuals/drawStar.js"
+import drawRoundWave from "./visuals/drawRoundWave.js"
+import drawRings from "./visuals/drawRings.js"
+import drawShineRings from "./visuals/drawShineRings.js"
+import drawCubes from "./visuals/drawCubes.js"
+import drawBigBars from "./visuals/drawBigBars.js"
+import drawShockwave from "./visuals/drawShockwave.js"
+import drawFireworks from "./visuals/drawFireworks.js"
+import drawStatic from "./visuals/drawStatic.js"
+import drawWeb from "./visuals/drawWeb.js"
+import drawStitches from "./visuals/drawStitches.js"
+import drawRoundLayers from "./visuals/drawRoundLayers.js"
+
+//options:type,colors,stroke
+export default function visualize(data, canvasId, options = {}, frame) {
+ //make a clone of options
+ options = { ...options }
+ //options
+ if (!options.stroke) options.stroke = 1;
+ if (!options.colors) options.colors = ["#d92027", "#ff9234", "#ffcd3c", "#35d0ba"];
+
+
+ let canvas = document.getElementById(canvasId);
+
+ if (!canvas) return;
+
+ let ctx = canvas.getContext("2d");
+ let h = canvas.height;
+ let w = canvas.width;
+
+
+
+ ctx.strokeStyle = options.colors[0];
+ ctx.lineWidth = options.stroke;
+
+ let typeMap = {
+ "bars": drawBars,
+ "bars blocks": drawBarsBlocks,
+ "big bars": drawBigBars,
+ "cubes": drawCubes,
+ "dualbars": drawDualbars,
+ "dualbars blocks": drawDualbarsBlocks,
+ "fireworks": drawFireworks,
+ "flower": drawFlower,
+ "flower blocks": drawFlowerBlocks,
+ "orbs": drawOrbs,
+ "ring": drawRing,
+ "rings": drawRings,
+ "round layers": drawRoundLayers,
+ "round wave": drawRoundWave,
+ "shine": drawShine,
+ "shine rings": drawShineRings,
+ "shockwave": drawShockwave,
+ "star": drawStar,
+ "static": drawStatic,
+ "stitches": drawStitches,
+ "wave": drawWave,
+ "web": drawWeb
+ }
+
+ let frameRateMap = {
+ "bars": 1,
+ "bars blocks": 1,
+ "big bars": 1,
+ "cubes": 1,
+ "dualbars": 1,
+ "dualbars blocks": 1,
+ "fireworks": 1,
+ "flower": 1,
+ "flower blocks": 1,
+ "ring": 1,
+ "rings": 1,
+ "round layers": 1,
+ "round wave": 1,
+ "orbs": 1,
+ "shine": 1,
+ "shine rings": 1,
+ "shockwave": 1,
+ "star": 1,
+ "static": 1,
+ "stitches": 1,
+ "wave": 1,
+ "web": 1
+ }
+
+ const functionContext = {
+ data, options, ctx, h, w, Helper: this.Helper, canvasId
+ }
+
+ if (typeof options.type == "string") options.type = [options.type]
+
+ options.type.forEach(type => {
+ //abide by the frame rate
+ if (frame % frameRateMap[type] === 0) {
+ //clear canvas
+ ctx.clearRect(0, 0, w, h);
+ ctx.beginPath();
+
+ typeMap[type](functionContext)
+ }
+ })
+
}
\ No newline at end of file
diff --git a/src/visuals/drawBars.js b/src/visuals/drawBars.js
index 15a624f..a78c1e6 100644
--- a/src/visuals/drawBars.js
+++ b/src/visuals/drawBars.js
@@ -1,26 +1,26 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let point_count = 64;
- let percent = h / 255;
- let increase = w / 64;
- let breakpoint = Math.floor(point_count / options.colors.length);
-
- for (let point = 1; point <= point_count; point++) {
- let p = data[point]; //get value
- p *= percent;
-
- let x = increase * point;
-
- ctx.moveTo(x, h);
- ctx.lineTo(x, h - p);
-
- if (point % breakpoint === 0) {
- let i = (point / breakpoint) - 1;
- ctx.strokeStyle = options.colors[i];
- ctx.stroke();
- ctx.beginPath();
- }
-
- }
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let point_count = 64;
+ let percent = h / 255;
+ let increase = w / 64;
+ let breakpoint = Math.floor(point_count / options.colors.length);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = data[point]; //get value
+ p *= percent;
+
+ let x = increase * point;
+
+ ctx.moveTo(x, h);
+ ctx.lineTo(x, h - p);
+
+ if (point % breakpoint === 0) {
+ let i = (point / breakpoint) - 1;
+ ctx.strokeStyle = options.colors[i];
+ ctx.stroke();
+ ctx.beginPath();
+ }
+
+ }
+}
diff --git a/src/visuals/drawBarsBlocks.js b/src/visuals/drawBarsBlocks.js
index ecf3e7a..891f622 100644
--- a/src/visuals/drawBarsBlocks.js
+++ b/src/visuals/drawBarsBlocks.js
@@ -1,18 +1,18 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let percent = h / 255;
- let width = w / 64;
-
- for (let point = 0; point < 64; point++) {
- let p = data[point]; //get value
- p *= percent;
- let x = width * point;
-
- ctx.rect(x, h, width, -(p));
- }
-
- ctx.fillStyle = options.colors[1] || options.colors[0];
- ctx.stroke();
- ctx.fill();
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let percent = h / 255;
+ let width = w / 64;
+
+ for (let point = 0; point < 64; point++) {
+ let p = data[point]; //get value
+ p *= percent;
+ let x = width * point;
+
+ ctx.rect(x, h, width, -(p));
+ }
+
+ ctx.fillStyle = options.colors[1] || options.colors[0];
+ ctx.stroke();
+ ctx.fill();
+}
diff --git a/src/visuals/drawBigBars.js b/src/visuals/drawBigBars.js
index b7c50bb..aaf8b8a 100644
--- a/src/visuals/drawBigBars.js
+++ b/src/visuals/drawBigBars.js
@@ -1,19 +1,19 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options
- const helper = new Helper(ctx)
-
- data = helper.mutateData(data, "organize").vocals
- data = helper.mutateData(data, "shrink", 10)
- data = helper.mutateData(data, "scale", h)
- data = helper.mutateData(data, "amp", 1)
- let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 })
-
- let colorIndex = 0
- let colorStop = Math.ceil(data.length / colors.length)
- points.start.forEach((start, i) => {
- if ((i + 1) % colorStop == 0) colorIndex++
- helper.drawRectangle(start, data[i], w / data.length, { color: colors[colorIndex] })
- })
-
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options
+ const helper = new Helper(ctx)
+
+ data = helper.mutateData(data, "organize").vocals
+ data = helper.mutateData(data, "shrink", 10)
+ data = helper.mutateData(data, "scale", h)
+ data = helper.mutateData(data, "amp", 1)
+ let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 })
+
+ let colorIndex = 0
+ let colorStop = Math.ceil(data.length / colors.length)
+ points.start.forEach((start, i) => {
+ if ((i + 1) % colorStop == 0) colorIndex++
+ helper.drawRectangle(start, data[i], w / data.length, { color: colors[colorIndex] })
+ })
+
+}
diff --git a/src/visuals/drawCubes.js b/src/visuals/drawCubes.js
index d660c56..16a914a 100644
--- a/src/visuals/drawCubes.js
+++ b/src/visuals/drawCubes.js
@@ -1,34 +1,34 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options;
- let helper = new Helper(ctx);
-
- data = helper.mutateData(data, "organize").base
-
- data = helper.mutateData(data, "shrink", 20).slice(0, 19)
- data = helper.mutateData(data, "scale", h)
-
- let points = helper.getPoints("line", w, [0, h], data.length, data)
-
- let spacing = 5;
- let squareSize = (w / 20) - spacing
- let colorIndex = 0
-
- points.start.forEach((start, i) => {
- let squareCount = Math.ceil(data[i] / squareSize)
-
- //find color stops from total possible squares in bar
- let totalSquares = (h - (spacing * (h / squareSize))) / squareSize
- let colorStop = Math.ceil(totalSquares / colors.length)
-
- for (let j = 1; j <= squareCount; j++) {
- let origin = [start[0], (start[1] - (squareSize * j) - (spacing * j))]
- helper.drawSquare(origin, squareSize, { color: colors[colorIndex], lineColor: "black" })
- if (j % colorStop == 0) {
- colorIndex++
- if (colorIndex >= colors.length) colorIndex = colors.length - 1
- }
- }
- colorIndex = 0
- })
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options;
+ let helper = new Helper(ctx);
+
+ data = helper.mutateData(data, "organize").base
+
+ data = helper.mutateData(data, "shrink", 20).slice(0, 19)
+ data = helper.mutateData(data, "scale", h)
+
+ let points = helper.getPoints("line", w, [0, h], data.length, data)
+
+ let spacing = 5;
+ let squareSize = (w / 20) - spacing
+ let colorIndex = 0
+
+ points.start.forEach((start, i) => {
+ let squareCount = Math.ceil(data[i] / squareSize)
+
+ //find color stops from total possible squares in bar
+ let totalSquares = (h - (spacing * (h / squareSize))) / squareSize
+ let colorStop = Math.ceil(totalSquares / colors.length)
+
+ for (let j = 1; j <= squareCount; j++) {
+ let origin = [start[0], (start[1] - (squareSize * j) - (spacing * j))]
+ helper.drawSquare(origin, squareSize, { color: colors[colorIndex], lineColor: "black" })
+ if (j % colorStop == 0) {
+ colorIndex++
+ if (colorIndex >= colors.length) colorIndex = colors.length - 1
+ }
+ }
+ colorIndex = 0
+ })
+}
diff --git a/src/visuals/drawDualbars.js b/src/visuals/drawDualbars.js
index efad9e6..27f5a90 100644
--- a/src/visuals/drawDualbars.js
+++ b/src/visuals/drawDualbars.js
@@ -1,30 +1,30 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let percent = h / 255;
- let increase = w / 128;
- let point_count = 128;
- let min = 5;
- let breakpoint = Math.floor(point_count / options.colors.length);
-
- for (let point = 1; point <= point_count; point++) {
- let p = data[point]; //get value
- p += min;
- p *= percent;
-
- let x = increase * point;
-
- let mid = (h / 2) + (p / 2);
-
- ctx.moveTo(x, mid);
- ctx.lineTo(x, mid - p);
-
- if (point % breakpoint === 0) {
- let i = (point / breakpoint) - 1;
- ctx.strokeStyle = options.colors[i];
- ctx.stroke();
- ctx.beginPath();
- }
-
- }
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let percent = h / 255;
+ let increase = w / 128;
+ let point_count = 128;
+ let min = 5;
+ let breakpoint = Math.floor(point_count / options.colors.length);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = data[point]; //get value
+ p += min;
+ p *= percent;
+
+ let x = increase * point;
+
+ let mid = (h / 2) + (p / 2);
+
+ ctx.moveTo(x, mid);
+ ctx.lineTo(x, mid - p);
+
+ if (point % breakpoint === 0) {
+ let i = (point / breakpoint) - 1;
+ ctx.strokeStyle = options.colors[i];
+ ctx.stroke();
+ ctx.beginPath();
+ }
+
+ }
+}
diff --git a/src/visuals/drawDualbarsBlocks.js b/src/visuals/drawDualbarsBlocks.js
index d2e2614..37af80d 100644
--- a/src/visuals/drawDualbarsBlocks.js
+++ b/src/visuals/drawDualbarsBlocks.js
@@ -1,21 +1,21 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let percent = h / 255;
- let width = w / 50;
-
- for (let point = 0; point <= 50; point++) {
- let p = data[point]; //get value
- p *= percent;
- let x = width * point;
-
- ctx.rect(x, (h / 2) + (p / 2), width, -(p));
- }
-
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
- }
-
- ctx.stroke();
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let percent = h / 255;
+ let width = w / 50;
+
+ for (let point = 0; point <= 50; point++) {
+ let p = data[point]; //get value
+ p *= percent;
+ let x = width * point;
+
+ ctx.rect(x, (h / 2) + (p / 2), width, -(p));
+ }
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+
+ ctx.stroke();
+}
diff --git a/src/visuals/drawFireworks.js b/src/visuals/drawFireworks.js
index df693c3..5eee440 100644
--- a/src/visuals/drawFireworks.js
+++ b/src/visuals/drawFireworks.js
@@ -1,21 +1,21 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options
- const helper = new Helper(ctx)
-
- data = helper.mutateData(data, "shrink", 200).slice(0, 120)
- data = helper.mutateData(data, "mirror")
- data = helper.mutateData(data, "scale", (h / 4) + ((h / 4) * .35))
-
- let points = helper.getPoints("circle", h / 2, [w / 2, h / 2], data.length, data, { offset: 35, rotate: 270 })
-
- points.start.forEach((start, i) => {
- helper.drawLine(start, points.end[i])
- })
-
- helper.drawPolygon(points.start, { close: true })
-
- points.end.forEach((end, i) => {
- helper.drawCircle(end, h * .01, { color: colors[0] })
- })
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options
+ const helper = new Helper(ctx)
+
+ data = helper.mutateData(data, "shrink", 200).slice(0, 120)
+ data = helper.mutateData(data, "mirror")
+ data = helper.mutateData(data, "scale", (h / 4) + ((h / 4) * .35))
+
+ let points = helper.getPoints("circle", h / 2, [w / 2, h / 2], data.length, data, { offset: 35, rotate: 270 })
+
+ points.start.forEach((start, i) => {
+ helper.drawLine(start, points.end[i])
+ })
+
+ helper.drawPolygon(points.start, { close: true })
+
+ points.end.forEach((end, i) => {
+ helper.drawCircle(end, h * .01, { color: colors[0] })
+ })
+}
diff --git a/src/visuals/drawFlower.js b/src/visuals/drawFlower.js
index e29b530..8198ee5 100644
--- a/src/visuals/drawFlower.js
+++ b/src/visuals/drawFlower.js
@@ -1,35 +1,35 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let min = 5;
- let r = h / 4;
- let offset = r / 2;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 128;
- let percent = (r - offset) / 255;
- let increase = (360 / point_count) * Math.PI / 180;
- let breakpoint = Math.floor(point_count / options.colors.length);
-
- for (let point = 1; point <= point_count; point++) {
- let p = (data[point] + min) * percent;
- let a = point * increase;
-
- let sx = cx + (r - (p - offset)) * Math.cos(a);
- let sy = cy + (r - (p - offset)) * Math.sin(a);
- ctx.moveTo(sx, sy);
-
- let dx = cx + (r + p) * Math.cos(a);
- let dy = cy + (r + p) * Math.sin(a);
- ctx.lineTo(dx, dy);
-
- if (point % breakpoint === 0) {
- let i = (point / breakpoint) - 1;
- ctx.strokeStyle = options.colors[i];
- ctx.stroke();
- ctx.beginPath();
- }
- }
-
- ctx.stroke();
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let min = 5;
+ let r = h / 4;
+ let offset = r / 2;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 128;
+ let percent = (r - offset) / 255;
+ let increase = (360 / point_count) * Math.PI / 180;
+ let breakpoint = Math.floor(point_count / options.colors.length);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = (data[point] + min) * percent;
+ let a = point * increase;
+
+ let sx = cx + (r - (p - offset)) * Math.cos(a);
+ let sy = cy + (r - (p - offset)) * Math.sin(a);
+ ctx.moveTo(sx, sy);
+
+ let dx = cx + (r + p) * Math.cos(a);
+ let dy = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+
+ if (point % breakpoint === 0) {
+ let i = (point / breakpoint) - 1;
+ ctx.strokeStyle = options.colors[i];
+ ctx.stroke();
+ ctx.beginPath();
+ }
+ }
+
+ ctx.stroke();
+}
diff --git a/src/visuals/drawFlowerBlocks.js b/src/visuals/drawFlowerBlocks.js
index 7c3ebb8..777badc 100644
--- a/src/visuals/drawFlowerBlocks.js
+++ b/src/visuals/drawFlowerBlocks.js
@@ -1,42 +1,42 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let min = 5;
- let r = h / 4;
- let offset = r / 2;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 56;
- let percent = r / 255;
- let increase = (360 / point_count) * Math.PI / 180;
-
- for (let point = 1; point <= point_count; point++) {
- let p = (data[point]) * percent;
- let a = point * increase;
-
- let ax = cx + (r - (p / 2)) * Math.cos(a);
- let ay = cy + (r - (p / 2)) * Math.sin(a);
- ctx.moveTo(ax, ay);
-
- let bx = cx + (r + p) * Math.cos(a);
- let by = cy + (r + p) * Math.sin(a);
- ctx.lineTo(bx, by);
-
- let dx = cx + (r + p) * Math.cos(a + increase);
- let dy = cy + (r + p) * Math.sin(a + increase);
- ctx.lineTo(dx, dy);
-
- let ex = cx + (r - (p / 2)) * Math.cos(a + increase);
- let ey = cy + (r - (p / 2)) * Math.sin(a + increase);
-
- ctx.lineTo(ex, ey);
- ctx.lineTo(ax, ay);
- }
-
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
- }
-
- ctx.stroke();
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let min = 5;
+ let r = h / 4;
+ let offset = r / 2;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 56;
+ let percent = r / 255;
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = (data[point]) * percent;
+ let a = point * increase;
+
+ let ax = cx + (r - (p / 2)) * Math.cos(a);
+ let ay = cy + (r - (p / 2)) * Math.sin(a);
+ ctx.moveTo(ax, ay);
+
+ let bx = cx + (r + p) * Math.cos(a);
+ let by = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(bx, by);
+
+ let dx = cx + (r + p) * Math.cos(a + increase);
+ let dy = cy + (r + p) * Math.sin(a + increase);
+ ctx.lineTo(dx, dy);
+
+ let ex = cx + (r - (p / 2)) * Math.cos(a + increase);
+ let ey = cy + (r - (p / 2)) * Math.sin(a + increase);
+
+ ctx.lineTo(ex, ey);
+ ctx.lineTo(ax, ay);
+ }
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+
+ ctx.stroke();
+}
diff --git a/src/visuals/drawOrbs.js b/src/visuals/drawOrbs.js
index 5f79491..85e0cd1 100644
--- a/src/visuals/drawOrbs.js
+++ b/src/visuals/drawOrbs.js
@@ -1,20 +1,20 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options
- const helper = new Helper(ctx)
-
- data = helper.mutateData(data, "organize").mids
- data = helper.mutateData(data, "split", 2)[0]
- data = helper.mutateData(data, "shrink", 100)
- data = helper.mutateData(data, "mirror")
- data = helper.mutateData(data, "scale", h)
- data = helper.mutateData(data, "amp", .75)
-
- let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 })
- points.start.forEach((start, i) => {
- helper.drawLine(start, points.end[i], { lineColor: colors[0] })
-
- helper.drawCircle(start, h * .01, { color: colors[1] || colors[0] })
- helper.drawCircle(points.end[i], h * .01, { color: colors[1] || colors[0] })
- })
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options
+ const helper = new Helper(ctx)
+
+ data = helper.mutateData(data, "organize").mids
+ data = helper.mutateData(data, "split", 2)[0]
+ data = helper.mutateData(data, "shrink", 100)
+ data = helper.mutateData(data, "mirror")
+ data = helper.mutateData(data, "scale", h)
+ data = helper.mutateData(data, "amp", .75)
+
+ let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 })
+ points.start.forEach((start, i) => {
+ helper.drawLine(start, points.end[i], { lineColor: colors[0] })
+
+ helper.drawCircle(start, h * .01, { color: colors[1] || colors[0] })
+ helper.drawCircle(points.end[i], h * .01, { color: colors[1] || colors[0] })
+ })
+}
diff --git a/src/visuals/drawRing.js b/src/visuals/drawRing.js
index 816f756..59a3239 100644
--- a/src/visuals/drawRing.js
+++ b/src/visuals/drawRing.js
@@ -1,42 +1,42 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let cx = w / 2;
- let cy = h / 2;
- let r = (h - 10) / 2;
- let offset = r / 5;
- let percent = (r - offset) / 255;
- let point_count = 150;
- let increase = (360 / point_count) * Math.PI / 180;
-
- ctx.arc(cx, cy, r, 0, 2 * Math.PI, true);
-
- let fa = 0;
- let fx = cx + (r - (data[0] * percent)) * Math.cos(fa);
- let fy = cy + (r - (data[0] * percent)) * Math.sin(fa);
- ctx.moveTo(fx, fy);
-
- let q = 0;
- for (let point = 0; point < point_count; point++) {
- q += 1
- if (point >= point_count / 2) {
- q -= 2;
- }
-
- let p = data[q]; //get value
- p *= percent;
-
- let a = point * increase;
- let x = cx + (r - p) * Math.cos(a);
- let y = cy + (r - p) * Math.sin(a);
-
- ctx.lineTo(x, y);
- ctx.arc(x, y, 2, 0, 2 * Math.PI);
-
- }
- ctx.lineTo(fx, fy);
-
- ctx.stroke();
- ctx.fillStyle = options.colors[1] || "#fff0";
- ctx.fill()
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let cx = w / 2;
+ let cy = h / 2;
+ let r = (h - 10) / 2;
+ let offset = r / 5;
+ let percent = (r - offset) / 255;
+ let point_count = 150;
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ ctx.arc(cx, cy, r, 0, 2 * Math.PI, true);
+
+ let fa = 0;
+ let fx = cx + (r - (data[0] * percent)) * Math.cos(fa);
+ let fy = cy + (r - (data[0] * percent)) * Math.sin(fa);
+ ctx.moveTo(fx, fy);
+
+ let q = 0;
+ for (let point = 0; point < point_count; point++) {
+ q += 1
+ if (point >= point_count / 2) {
+ q -= 2;
+ }
+
+ let p = data[q]; //get value
+ p *= percent;
+
+ let a = point * increase;
+ let x = cx + (r - p) * Math.cos(a);
+ let y = cy + (r - p) * Math.sin(a);
+
+ ctx.lineTo(x, y);
+ ctx.arc(x, y, 2, 0, 2 * Math.PI);
+
+ }
+ ctx.lineTo(fx, fy);
+
+ ctx.stroke();
+ ctx.fillStyle = options.colors[1] || "#fff0";
+ ctx.fill()
+}
diff --git a/src/visuals/drawRings.js b/src/visuals/drawRings.js
index 431a12b..9af1462 100644
--- a/src/visuals/drawRings.js
+++ b/src/visuals/drawRings.js
@@ -1,32 +1,32 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options
- let helper = new Helper(ctx)
- let minDimension = (h < w) ? h : w
-
- data = helper.mutateData(data, "organize")
- data = [data.mids, data.vocals]
-
- data[0] = helper.mutateData(data[0], "scale", minDimension / 4)
- data[1] = helper.mutateData(data[1], "scale", minDimension / 8)
-
- data[0] = helper.mutateData(data[0], "shrink", 1 / 5)
- data[0] = helper.mutateData(data[0], "split", 2)[0]
-
- data[0] = helper.mutateData(data[0], "reverb")
- data[1] = helper.mutateData(data[1], "reverb")
-
-
- let outerCircle = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data[0].length, data[0])
- let innerCircle = helper.getPoints("circle", minDimension / 4, [w / 2, h / 2], data[1].length, data[1])
-
- helper.drawPolygon(outerCircle.end, { close: true, radius: 4, lineColor: colors[0], color: colors[1] })
- helper.drawPolygon(innerCircle.end, { close: true, radius: 4, lineColor: colors[2], color: colors[3] })
-
- let middle = ((minDimension / 4) + (minDimension / 2)) / 2
- let largerInner = data[1] = helper.mutateData(data[1], "scale", ((minDimension / 4) - (minDimension / 2)))
- let innerBars = helper.getPoints("circle", middle, [w / 2, h / 2], data[1].length, largerInner)
- innerBars.start.forEach((start, i) => {
- helper.drawLine(start, innerBars.end[i], { lineColor: colors[4] || colors[2] })
- })
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options
+ let helper = new Helper(ctx)
+ let minDimension = (h < w) ? h : w
+
+ data = helper.mutateData(data, "organize")
+ data = [data.mids, data.vocals]
+
+ data[0] = helper.mutateData(data[0], "scale", minDimension / 4)
+ data[1] = helper.mutateData(data[1], "scale", minDimension / 8)
+
+ data[0] = helper.mutateData(data[0], "shrink", 1 / 5)
+ data[0] = helper.mutateData(data[0], "split", 2)[0]
+
+ data[0] = helper.mutateData(data[0], "reverb")
+ data[1] = helper.mutateData(data[1], "reverb")
+
+
+ let outerCircle = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data[0].length, data[0])
+ let innerCircle = helper.getPoints("circle", minDimension / 4, [w / 2, h / 2], data[1].length, data[1])
+
+ helper.drawPolygon(outerCircle.end, { close: true, radius: 4, lineColor: colors[0], color: colors[1] })
+ helper.drawPolygon(innerCircle.end, { close: true, radius: 4, lineColor: colors[2], color: colors[3] })
+
+ let middle = ((minDimension / 4) + (minDimension / 2)) / 2
+ let largerInner = data[1] = helper.mutateData(data[1], "scale", ((minDimension / 4) - (minDimension / 2)))
+ let innerBars = helper.getPoints("circle", middle, [w / 2, h / 2], data[1].length, largerInner)
+ innerBars.start.forEach((start, i) => {
+ helper.drawLine(start, innerBars.end[i], { lineColor: colors[4] || colors[2] })
+ })
+}
diff --git a/src/visuals/drawRoundLayers.js b/src/visuals/drawRoundLayers.js
new file mode 100644
index 0000000..0f56973
--- /dev/null
+++ b/src/visuals/drawRoundLayers.js
@@ -0,0 +1,16 @@
+import Origami from "origamijs";
+
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper, canvasId } = functionContext;
+ let { colors } = options
+ let helper = new Helper(ctx)
+
+ let origamiContext = {}
+ let origami = Origami.bind(origamiContext)
+
+ origami(ctx)
+ .rect(10, 10, 40, 40)
+ .draw()
+
+
+}
diff --git a/src/visuals/drawRoundWave.js b/src/visuals/drawRoundWave.js
index 34acc53..5a9d26c 100644
--- a/src/visuals/drawRoundWave.js
+++ b/src/visuals/drawRoundWave.js
@@ -1,35 +1,35 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let r = h / 4;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 100;
- let percent = r / 255;
- let increase = (360 / point_count) * Math.PI / 180;
- let min = 0;
- let offset = 0;
- let p = 0;
-
- // let z = (data[0] + min + offset) * percent;
- let sx = cx + (r + p) * Math.cos(0);
- let sy = cy + (r + p) * Math.sin(0);
- ctx.moveTo(sx, sy);
-
- for (let point = 1; point <= point_count; point++) {
- let p = (data[350 % point]) * percent;
- let a = point * increase;
-
- let dx = cx + (r + p) * Math.cos(a);
- let dy = cy + (r + p) * Math.sin(a);
- ctx.lineTo(dx, dy);
- }
-
- ctx.closePath();
- ctx.stroke();
-
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
- }
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let r = h / 4;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 100;
+ let percent = r / 255;
+ let increase = (360 / point_count) * Math.PI / 180;
+ let min = 0;
+ let offset = 0;
+ let p = 0;
+
+ // let z = (data[0] + min + offset) * percent;
+ let sx = cx + (r + p) * Math.cos(0);
+ let sy = cy + (r + p) * Math.sin(0);
+ ctx.moveTo(sx, sy);
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = (data[350 % point]) * percent;
+ let a = point * increase;
+
+ let dx = cx + (r + p) * Math.cos(a);
+ let dy = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+ }
+
+ ctx.closePath();
+ ctx.stroke();
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+}
diff --git a/src/visuals/drawShine.js b/src/visuals/drawShine.js
index 66dfc39..5829c4d 100644
--- a/src/visuals/drawShine.js
+++ b/src/visuals/drawShine.js
@@ -1,33 +1,33 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let cx = w / 2;
- let cy = h / 2;
- let r = h / 4;
- let percent = (h / 2 - r) / 255;
- let point_count = 512;
- let increase = (360 / point_count) * Math.PI / 180;
-
- for (let point = 1; point <= point_count; point++) {
- let p = data[600 % point]; //get value
- p *= percent;
- point++; //start at 1
- let a = point * increase;
-
- let sx = cx + r * Math.cos(a);
- let sy = cy + r * Math.sin(a);
- ctx.moveTo(sx, sy);
-
- let dx = cx + (r + p) * Math.cos(a);
- let dy = cy + (r + p) * Math.sin(a);
- ctx.lineTo(dx, dy);
-
- }
- ctx.stroke();
-
- if (options.colors[1]) {
- ctx.arc(cx, cy, r * .90, 0, 2 * Math.PI);
- ctx.fillStyle = options.colors[1];
- ctx.fill();
- }
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let cx = w / 2;
+ let cy = h / 2;
+ let r = h / 4;
+ let percent = (h / 2 - r) / 255;
+ let point_count = 512;
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = data[600 % point]; //get value
+ p *= percent;
+ point++; //start at 1
+ let a = point * increase;
+
+ let sx = cx + r * Math.cos(a);
+ let sy = cy + r * Math.sin(a);
+ ctx.moveTo(sx, sy);
+
+ let dx = cx + (r + p) * Math.cos(a);
+ let dy = cy + (r + p) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+
+ }
+ ctx.stroke();
+
+ if (options.colors[1]) {
+ ctx.arc(cx, cy, r * .90, 0, 2 * Math.PI);
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+}
diff --git a/src/visuals/drawShineRings.js b/src/visuals/drawShineRings.js
index 17ec48d..8fcee99 100644
--- a/src/visuals/drawShineRings.js
+++ b/src/visuals/drawShineRings.js
@@ -1,22 +1,22 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options
-
- let helper = new Helper(ctx)
- let minDimension = (h < w) ? h : w
-
- data = helper.mutateData(data, "organize")
- data.vocals = helper.mutateData(data.vocals, "scale", (minDimension / 2) / 2)
- data.base = helper.mutateData(data.base, "scale", (minDimension / 2) / 2)
-
- let outerBars = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals);
- let innerWave = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals, { offset: 100 });
- let thinLine = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.base.length, data.base, { offset: 100 });
-
- outerBars.start.forEach((start, i) => {
- helper.drawLine(start, outerBars.end[i], { lineColor: colors[0] })
- })
-
- helper.drawPolygon(innerWave.start, { close: true, lineColor: colors[1], color: colors[3], radius: 5 })
- helper.drawPolygon(thinLine.start, { close: true, lineColor: colors[2], color: colors[4], radius: 5 })
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options
+
+ let helper = new Helper(ctx)
+ let minDimension = (h < w) ? h : w
+
+ data = helper.mutateData(data, "organize")
+ data.vocals = helper.mutateData(data.vocals, "scale", (minDimension / 2) / 2)
+ data.base = helper.mutateData(data.base, "scale", (minDimension / 2) / 2)
+
+ let outerBars = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals);
+ let innerWave = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals, { offset: 100 });
+ let thinLine = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.base.length, data.base, { offset: 100 });
+
+ outerBars.start.forEach((start, i) => {
+ helper.drawLine(start, outerBars.end[i], { lineColor: colors[0] })
+ })
+
+ helper.drawPolygon(innerWave.start, { close: true, lineColor: colors[1], color: colors[3], radius: 5 })
+ helper.drawPolygon(thinLine.start, { close: true, lineColor: colors[2], color: colors[4], radius: 5 })
+}
diff --git a/src/visuals/drawShockwave.js b/src/visuals/drawShockwave.js
index 6a25a97..40ae2fb 100644
--- a/src/visuals/drawShockwave.js
+++ b/src/visuals/drawShockwave.js
@@ -1,20 +1,20 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options
-
- let helper = new Helper(ctx)
-
- data = helper.mutateData(data, "shrink", 300)
- data = helper.mutateData(data, "scale", h / 2)
- data = helper.mutateData(data, "split", 4).slice(0, 3)
-
- let colorIndex = 0;
- data.forEach((points) => {
- let wavePoints = helper.getPoints("line", w, [0, h / 2], points.length, points);
- helper.drawPolygon(wavePoints.end, { lineColor: colors[colorIndex], radius: (h * .015) })
-
- let invertedPoints = helper.getPoints("line", w, [0, h / 2], points.length, points, { offset: 100 });
- helper.drawPolygon(invertedPoints.start, { lineColor: colors[colorIndex], radius: (h * .015) })
- colorIndex++
- })
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options
+
+ let helper = new Helper(ctx)
+
+ data = helper.mutateData(data, "shrink", 300)
+ data = helper.mutateData(data, "scale", h / 2)
+ data = helper.mutateData(data, "split", 4).slice(0, 3)
+
+ let colorIndex = 0;
+ data.forEach((points) => {
+ let wavePoints = helper.getPoints("line", w, [0, h / 2], points.length, points);
+ helper.drawPolygon(wavePoints.end, { lineColor: colors[colorIndex], radius: (h * .015) })
+
+ let invertedPoints = helper.getPoints("line", w, [0, h / 2], points.length, points, { offset: 100 });
+ helper.drawPolygon(invertedPoints.start, { lineColor: colors[colorIndex], radius: (h * .015) })
+ colorIndex++
+ })
+}
diff --git a/src/visuals/drawStar.js b/src/visuals/drawStar.js
index 7be6dac..6e6d280 100644
--- a/src/visuals/drawStar.js
+++ b/src/visuals/drawStar.js
@@ -1,77 +1,77 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w } = functionContext;
-
- let r = h / 4;
- let offset = r / 4;
- let cx = w / 2;
- let cy = h / 2;
- let point_count = 120;
- let percent = (r - offset - 35) / (255);
- let increase = (360 / point_count) * Math.PI / 180;
-
- let top = [];
- let bottom = [];
-
- for (let point = 1; point <= point_count; point++) {
- let p = ((data[200 % point])) * percent;
- let a = point * increase;
-
- let sx = cx + ((r) - p + offset) * Math.cos(a);
- let sy = cy + ((r) - p + offset) * Math.sin(a);
- ctx.moveTo(sx, sy);
- bottom.push({
- x: sx,
- y: sy
- });
-
- let dx = cx + (r + p + offset) * Math.cos(a);
- let dy = cy + (r + p + offset) * Math.sin(a);
- ctx.lineTo(dx, dy);
- top.push({
- x: dx,
- y: dy
- });
-
- }
-
-
- ctx.moveTo(top[0].x, top[0].y)
- for (let t in top) {
- t = top[t];
-
- ctx.lineTo(t.x, t.y);
- }
- ctx.closePath();
-
- ctx.moveTo(bottom[0].x, bottom[0].y)
- for (let b = bottom.length - 1; b >= 0; b++) {
- b = bottom[b];
-
- ctx.lineTo(b.x, b.y);
- }
- ctx.closePath();
-
-
- if (options.colors[1]) {
- ctx.fillStyle = options.colors[1];
- ctx.fill();
- }
- ctx.stroke();
-
- //inner color
- ctx.beginPath();
- ctx.moveTo(bottom[0].x, bottom[0].y)
- for (let b in bottom) {
- b = bottom[b];
-
- ctx.lineTo(b.x, b.y);
- }
- ctx.closePath();
-
-
- if (options.colors[2]) {
- ctx.fillStyle = options.colors[2];
- ctx.fill();
- }
- ctx.stroke();
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w } = functionContext;
+
+ let r = h / 4;
+ let offset = r / 4;
+ let cx = w / 2;
+ let cy = h / 2;
+ let point_count = 120;
+ let percent = (r - offset - 35) / (255);
+ let increase = (360 / point_count) * Math.PI / 180;
+
+ let top = [];
+ let bottom = [];
+
+ for (let point = 1; point <= point_count; point++) {
+ let p = ((data[200 % point])) * percent;
+ let a = point * increase;
+
+ let sx = cx + ((r) - p + offset) * Math.cos(a);
+ let sy = cy + ((r) - p + offset) * Math.sin(a);
+ ctx.moveTo(sx, sy);
+ bottom.push({
+ x: sx,
+ y: sy
+ });
+
+ let dx = cx + (r + p + offset) * Math.cos(a);
+ let dy = cy + (r + p + offset) * Math.sin(a);
+ ctx.lineTo(dx, dy);
+ top.push({
+ x: dx,
+ y: dy
+ });
+
+ }
+
+
+ ctx.moveTo(top[0].x, top[0].y)
+ for (let t in top) {
+ t = top[t];
+
+ ctx.lineTo(t.x, t.y);
+ }
+ ctx.closePath();
+
+ ctx.moveTo(bottom[0].x, bottom[0].y)
+ for (let b = bottom.length - 1; b >= 0; b++) {
+ b = bottom[b];
+
+ ctx.lineTo(b.x, b.y);
+ }
+ ctx.closePath();
+
+
+ if (options.colors[1]) {
+ ctx.fillStyle = options.colors[1];
+ ctx.fill();
+ }
+ ctx.stroke();
+
+ //inner color
+ ctx.beginPath();
+ ctx.moveTo(bottom[0].x, bottom[0].y)
+ for (let b in bottom) {
+ b = bottom[b];
+
+ ctx.lineTo(b.x, b.y);
+ }
+ ctx.closePath();
+
+
+ if (options.colors[2]) {
+ ctx.fillStyle = options.colors[2];
+ ctx.fill();
+ }
+ ctx.stroke();
+}
diff --git a/src/visuals/drawStatic.js b/src/visuals/drawStatic.js
index 27dd81b..b592b95 100644
--- a/src/visuals/drawStatic.js
+++ b/src/visuals/drawStatic.js
@@ -1,25 +1,25 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options
- let helper = new Helper(ctx)
-
- data = helper.mutateData(data, "shrink", 1 / 8)
- data = helper.mutateData(data, "split", 2)[0]
- data = helper.mutateData(data, "scale", h)
-
- let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 })
-
- let index = 0
- let prevPoint = null
- points.start.forEach((start, i) => {
- if (prevPoint) {
- helper.drawLine(prevPoint, start)
- }
- helper.drawLine(start, points.end[i])
- prevPoint = points.end[i]
-
- index++
- })
-
-
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options
+ let helper = new Helper(ctx)
+
+ data = helper.mutateData(data, "shrink", 1 / 8)
+ data = helper.mutateData(data, "split", 2)[0]
+ data = helper.mutateData(data, "scale", h)
+
+ let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 })
+
+ let index = 0
+ let prevPoint = null
+ points.start.forEach((start, i) => {
+ if (prevPoint) {
+ helper.drawLine(prevPoint, start)
+ }
+ helper.drawLine(start, points.end[i])
+ prevPoint = points.end[i]
+
+ index++
+ })
+
+
+}
diff --git a/src/visuals/drawStitches.js b/src/visuals/drawStitches.js
index 66bf68f..a259181 100644
--- a/src/visuals/drawStitches.js
+++ b/src/visuals/drawStitches.js
@@ -1,24 +1,24 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options
- let helper = new Helper(ctx)
- let minDimension = (h < w) ? h : w
-
- data = helper.mutateData(data, "shrink", 200)
- data = helper.mutateData(data, "split", 2)[0]
- data = helper.mutateData(data, "scale", h / 2)
-
- let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data, { offset: 50 })
-
- helper.drawPolygon(points.end, { close: true })
- helper.drawPolygon(points.start, { close: true })
-
- for (let i = 0; i < points.start.length; i += 1) {
- let start = points.start[i]
- i++
- let end = points.end[i] || points.end[0]
-
- helper.drawLine(start, end)
- helper.drawLine(end, points.start[i + 1] || points.start[0])
- }
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options
+ let helper = new Helper(ctx)
+ let minDimension = (h < w) ? h : w
+
+ data = helper.mutateData(data, "shrink", 200)
+ data = helper.mutateData(data, "split", 2)[0]
+ data = helper.mutateData(data, "scale", h / 2)
+
+ let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data, { offset: 50 })
+
+ helper.drawPolygon(points.end, { close: true })
+ helper.drawPolygon(points.start, { close: true })
+
+ for (let i = 0; i < points.start.length; i += 1) {
+ let start = points.start[i]
+ i++
+ let end = points.end[i] || points.end[0]
+
+ helper.drawLine(start, end)
+ helper.drawLine(end, points.start[i + 1] || points.start[0])
+ }
+}
diff --git a/src/visuals/drawWave.js b/src/visuals/drawWave.js
index 8892599..ced5687 100644
--- a/src/visuals/drawWave.js
+++ b/src/visuals/drawWave.js
@@ -1,18 +1,18 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options
- const helper = new Helper(ctx)
-
- // data = helper.mutateData(data, "shrink", 200)
- data = helper.mutateData(data, "split", 4)[0]
- data = helper.mutateData(data, "scale", h)
-
- let points = helper.getPoints("line", w, [0, h], data.length, data, { offset: 100 })
- points.start = points.start.slice(0, points.end.length - 1)
- points.start.push([w, h])
- points.start.push([0, h])
-
- helper.drawPolygon(points.start, { lineColor: colors[0], color: colors[1], radius: (h * .008) })
-
-
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options
+ const helper = new Helper(ctx)
+
+ // data = helper.mutateData(data, "shrink", 200)
+ data = helper.mutateData(data, "split", 4)[0]
+ data = helper.mutateData(data, "scale", h)
+
+ let points = helper.getPoints("line", w, [0, h], data.length, data, { offset: 100 })
+ points.start = points.start.slice(0, points.end.length - 1)
+ points.start.push([w, h])
+ points.start.push([0, h])
+
+ helper.drawPolygon(points.start, { lineColor: colors[0], color: colors[1], radius: (h * .008) })
+
+
}
\ No newline at end of file
diff --git a/src/visuals/drawWeb.js b/src/visuals/drawWeb.js
index f0eb4ea..11f57e1 100644
--- a/src/visuals/drawWeb.js
+++ b/src/visuals/drawWeb.js
@@ -1,35 +1,35 @@
-export default (functionContext) => {
- let { data, options, ctx, h, w, Helper } = functionContext;
- let { colors } = options
- const helper = new Helper(ctx)
- let minDimension = (h < w) ? h : w
-
- data = helper.mutateData(data, "shrink", 100)
- data = helper.mutateData(data, "split", 2)[0]
- data = helper.mutateData(data, "scale", h / 4)
-
- let dataCopy = data
-
- let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data)
- helper.drawPolygon(points.end, { close: true })
-
- points.start.forEach((start, i) => {
- helper.drawLine(start, points.end[i])
- })
-
- data = helper.mutateData(data, "scale", .7)
- points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data)
- helper.drawPolygon(points.end, { close: true })
-
- data = helper.mutateData(data, "scale", .3)
- points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data)
- helper.drawPolygon(points.end, { close: true })
-
- helper.drawCircle([w / 2, h / 2], minDimension / 2, { color: colors[2] })
-
- dataCopy = helper.mutateData(dataCopy, "scale", 1.4)
- points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], dataCopy.length, dataCopy)
- points.end.forEach((end, i) => {
- helper.drawCircle(end, minDimension * .01, { color: colors[1], lineColor: colors[1] || colors[0] })
- })
-}
+export default (functionContext) => {
+ let { data, options, ctx, h, w, Helper } = functionContext;
+ let { colors } = options
+ const helper = new Helper(ctx)
+ let minDimension = (h < w) ? h : w
+
+ data = helper.mutateData(data, "shrink", 100)
+ data = helper.mutateData(data, "split", 2)[0]
+ data = helper.mutateData(data, "scale", h / 4)
+
+ let dataCopy = data
+
+ let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data)
+ helper.drawPolygon(points.end, { close: true })
+
+ points.start.forEach((start, i) => {
+ helper.drawLine(start, points.end[i])
+ })
+
+ data = helper.mutateData(data, "scale", .7)
+ points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data)
+ helper.drawPolygon(points.end, { close: true })
+
+ data = helper.mutateData(data, "scale", .3)
+ points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data)
+ helper.drawPolygon(points.end, { close: true })
+
+ helper.drawCircle([w / 2, h / 2], minDimension / 2, { color: colors[2] })
+
+ dataCopy = helper.mutateData(dataCopy, "scale", 1.4)
+ points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], dataCopy.length, dataCopy)
+ points.end.forEach((end, i) => {
+ helper.drawCircle(end, minDimension * .01, { color: colors[1], lineColor: colors[1] || colors[0] })
+ })
+}
diff --git a/test/index.html b/test/index.html
index 0f1d17e..5b77fd1 100644
--- a/test/index.html
+++ b/test/index.html
@@ -1,130 +1,131 @@
-
-
-
-
-
-
- Document
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/react-test/src/Wave.js b/test/react-test/src/Wave.js
index 8984a79..f27e074 100644
--- a/test/react-test/src/Wave.js
+++ b/test/react-test/src/Wave.js
@@ -1,20 +1,20 @@
-import React, { useEffect } from 'react'
-import Wave from "@foobar404/wave"
-
-export default () => {
- useEffect(() => {
- let audio = document.querySelector("audio")
- let canvas = document.querySelector("canvas")
-
- let wave = new Wave();
- wave.fromElement(audio, canvas, { type: "star" })
- }, [])
- return (
-
- )
-}
+import React, { useEffect } from 'react'
+import Wave from "@foobar404/wave"
+
+export default () => {
+ useEffect(() => {
+ let audio = document.querySelector("audio")
+ let canvas = document.querySelector("canvas")
+
+ let wave = new Wave();
+ wave.fromElement(audio, canvas, { type: "star" })
+ }, [])
+ return (
+
+ )
+}