You haven't chosen the sketch folder for the project yet.
} +diff --git a/.babelrc b/.babelrc
index 78fcb4c5..5a40860c 100644
--- a/.babelrc
+++ b/.babelrc
@@ -2,34 +2,35 @@
"env": {
"development": {
"presets": [
- [ "es2015", { "modules": false } ],
- "stage-2",
- "react"
+ "@babel/preset-env",
+ "@babel/preset-react"
],
"plugins": [
+ "styled-components",
"react-hot-loader/babel",
- "transform-object-rest-spread"
+ "@babel/plugin-proposal-object-rest-spread"
]
},
"production": {
"presets": [
- [ "es2015"],
- "stage-2",
- "react"
+ "@babel/preset-env",
+ "@babel/preset-react"
],
"plugins": [
- "transform-object-rest-spread"
+ "styled-components",
+ "@babel/plugin-proposal-object-rest-spread"
]
},
"test": {
"presets": [
- "es2015",
- "stage-2",
- "react"
+ "@babel/preset-env",
+ "@babel/preset-react"
],
"plugins": [
+ "styled-components",
"react-hot-loader/babel",
- "transform-object-rest-spread"
+ "@babel/plugin-proposal-object-rest-spread",
+ "@babel/plugin-transform-runtime"
]
}
}
diff --git a/.eslintignore b/.eslintignore
index e6211842..3c3629e6 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,4 +1 @@
-coverage/**
-node_modules/**
-dist/**
-src/index.html
+node_modules
diff --git a/.eslintrc b/.eslintrc
index 39302288..d2af44ec 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -4,27 +4,23 @@
"standard",
"standard-react"
],
- "plugins": [
- "babel",
- "react",
- "promise"
- ],
- "env": {
- "browser" : true
- },
"globals": {
- "__DEV__" : false,
- "__TEST__" : false,
- "__PROD__" : false,
- "__COVERAGE__" : false,
- "__DEFAULT_PROJECT__" : false,
- "nw" : false
+ "THREE": "readonly"
},
+ "env": {
+ "browser" : true,
+ "jest/globals": true
+ },
+ "plugins": [
+ "jest"
+ ],
"rules": {
"key-spacing" : 0,
"jsx-quotes" : [2, "prefer-single"],
"max-len" : [2, 120, 2],
"object-curly-spacing" : [2, "always"],
- "no-var" : 2
+ "no-var" : 2,
+ "comma-dangle" : [2, "always-multiline"],
+ "no-console" : [2, { "allow": ["warn", "error"] }]
}
}
diff --git a/build/icon.icns b/build/icon.icns
new file mode 100644
index 00000000..03167640
Binary files /dev/null and b/build/icon.icns differ
diff --git a/build/icon.ico b/build/icon.ico
new file mode 100644
index 00000000..667247ac
Binary files /dev/null and b/build/icon.ico differ
diff --git a/build/icon.png b/build/icon.png
new file mode 100644
index 00000000..3c43fecd
Binary files /dev/null and b/build/icon.png differ
diff --git a/config/webpack.custom.config.js b/config/webpack.custom.config.js
index d0090926..f423b692 100644
--- a/config/webpack.custom.config.js
+++ b/config/webpack.custom.config.js
@@ -1,33 +1,12 @@
-const tryRequire = require('try-require')
-
const config = {
module: {
rules: [
{
test: /\.icon\.txt$/,
- use: 'svg-inline-loader?classPrefix'
- }
- ]
- }
-}
-
-if (process.env.NODE_ENV === 'development') {
- const devConfig = tryRequire('./dev.config.js', require)
- let devServerOptions = {}
-
- if (devConfig && devConfig.defaultProject) {
- const defaultProject = require(devConfig.defaultProject)
- const sketchesPath = defaultProject.project.sketchesPath
-
- if (sketchesPath) {
- devServerOptions = {
- contentBase: sketchesPath,
- watchContentBase: true
- }
- }
- }
-
- config.devServer = devServerOptions
+ use: 'svg-inline-loader?classPrefix',
+ },
+ ],
+ },
}
module.exports = config
diff --git a/docs/dev/index.md b/docs/dev/index.md
index 8e382b66..3a250060 100644
--- a/docs/dev/index.md
+++ b/docs/dev/index.md
@@ -8,8 +8,11 @@ It is best practice to create a project folder outside of Hedron. This is advant
Inside the project folder, you'll want to have a "sketches" folder, this is what you'll point Hedron to.
+## Sketches Directory
+This directory contains sketch folders. Sketch folders can be grouped into directories to keep things neat, with as many levels of organisation as you need. However, you can't have a sketch folder inside another sketch folder.
+
## Sketch
-Sketches together in the sketches directory. A sketch is itself directory with two required files:
+Sketches live in the sketches directory. A sketch is itself a directory with two required files:
- config.js
- index.js
@@ -22,14 +25,20 @@ This is where the params and shots are defined.
module.exports = {
// Default title when sketch is loaded in (can be changed by user)
defaultTitle: 'Solid',
+ // Category and author can be used as a way to organise sketches based on the user's settings
+ category: 'Simple',
+ author: 'Laurence Ipsum',
// Params are values between 0 and 1 that can be manipulated by the user
// these values are sent to the sketch every frame
// e.g. Speed, scale, colour
params: [
{
key: 'rotSpeedX', // needs to be unique
- title: 'Rotation Speed X', // should be human
- defaultValue: 0 // must be between 0 and 1
+ defaultValue: 0, // must be between 0 and 1
+ title: 'Rotation Speed X', // optional, should be human, if not provided defaults to the key
+ defaultMin: 0, // optional, the value passed to the sketch when the param is at it's lowest value, if not provided defaults to 0
+ defaultMax: 1, // optional, the value passed to the sketch when the param is at it's highest value, if not provided defaults to 1
+ hidden: false, // optional, some params may want to be hidden in the UI, if they are controlled programatically by the sketch. Defaults to false.
},
],
// Shots are single functions that can fire, as opposed to values that change
@@ -45,14 +54,14 @@ module.exports = {
## index.js
-This is where the actual sketch is held. You can `require` other modules from here, so don't feel restricted to a single file.
+This is where the actual sketch is held. `THREE` is available as a global variable and it's strongly advised you use this rather than import the library yourself, to prevent unexpected behaviour. For convenience, `THREE.GLTFLoader` and `THREE.OrbitControls` are available too.
+
+You can `require` other modules from here, so don't feel restricted to a single file.
### Very basic example
This is the minimum you need to do in order to use Hedron.
```javascript
-const THREE = require('three')
-
class MyFirstSketch {
constructor () {
// Create a cube, add it to the root of the scene
@@ -82,11 +91,6 @@ A polyhedron that can spin on all axes. The user can change the speed of the rot
The user can change the scale. The user can also click on "shapeshift" and the geometry changes.
**/
-/** HEDRON TIP **
- Hedron uses three.js, so you'll need that :)
-**/
-const THREE = require('three')
-
/** HEDRON TIP **
Hedron sketches must be a class
**/
@@ -97,17 +101,17 @@ class Solid {
scene - This is the THREE object for the scene. You can also access the THREE renderer
using scene.renderer
+ params - The sketch params when the sketch first initialises
+
meta - This is an object with meta data that might be useful. It has the following properties:
sketchesFolder - The path to the sketches folder on your computer. Useful if you need to link to a resource such as an image.
-
- params - The sketch params when the sketch first initialises
**/
- constructor (scene, meta, params) {
+ constructor (scene, params, meta) {
/** HEDRON TIP **
Must define a "root" property as a THREE.Group or THREE.Object3D
Hedron looks for this and will add it to the scene.
**/
- this.root = new THREE.Group()
+ this.root = new THREE.Group() // THREE is a global var so no need to import
/** HEDRON TIP **
It's good practice to not manipulate the root object
@@ -235,6 +239,13 @@ class Solid {
module.exports = Solid
```
+## Reloading sketches / Auto reload
+If you have the "Watch sketches" setting enabled, Hedron will automatically refresh your sketches. However, if you don't have this enabled or something went wrong with the file watch (e.g. your sketch imports a file outside of its own folder) you'll need to click "Reload File" to see changes made to sketch files.
+
+This refresh will remove the sketch from the scene, import any new params or shots, remove and old params and shots, and then add the new sketch back into the scene.
+
+**Please note: File change detection may not work with all text editors. (e.g. Atom on OSX is reported to be inconsistent).**
+
## Hedron dev config
You can get extra functionality by adding `dev.config.js` to `/config` (from the root directory of the Hedron repo).
@@ -246,10 +257,4 @@ module.exports = {
}
```
-Setting `defaultProject` to the path of a saved project (e.g. `/Users/alex/Desktop/foo.json`) can help improve your workflow when developing:
-* The project will load automatically on load/restart
-* The project sketches folder will be watched for changes, triggering a restart
-
-## Reimporting
-
-If you've already got a project going with some sketches and then make edits to a sketch, Hedron automatically loads in the new content. However, if you've made changes to `config.js`, you'll need to "reimport" to see the new params and shots. Do this by clicking the button at the bottom of the view for that sketch.
+Setting `defaultProject` to the path of a saved project (e.g. `/Users/alex/Desktop/foo.json`) can help improve your workflow when developing by automatically loading that project when the app compiles. This is particularly useful when developing Hedron itself, so that you can test changes made to the app immediately, without having to manually load in a project each time.
\ No newline at end of file
diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md
index 62f01219..40bc6d3f 100644
--- a/docs/user-guide/index.md
+++ b/docs/user-guide/index.md
@@ -5,18 +5,19 @@ Here is a quick overview of how to use Hedron.
## Sketches
Sketches are created with [three.js](https://github.com/mrdoob/three.js/). They are a Javascript module that exports a single [THREE.Group](https://threejs.org/docs/#api/objects/Group), to be placed in the main scene. The different aspects of a sketch can be controlled using "params" and "shots".
-### Adding and removing sketches
Many sketches can be added to the same Hedron scene. These can be multiple instances of the same sketch, or different types of sketches.
In order to add sketches, click on the "+" in the right sidebar. If you're starting from scratch, you'll need to tell Hedron where your sketch folder is.
To remove a sketch, click the delete button at the bottom of the view for that sketch.
+Use the dropdown menu on the Add Sketch scene to organise your sketches. If the author of the sketch has provided the correct meta data, you'll be able to organise based on category or author. Otherwise you can organise based on the folder structure of your sketches.
+
### Switching between sketches
You can switch between different sketches that are already added to Hedron using the right sidebar.
## Params
-Params are the variables of a sketch. They are always a value between 0 and 1 (although more types of param are [planned](https://github.com/nudibranchrecords/hedron/issues/13)). The simplest way to control a param is to click and drag the value bar.
+Params are the variables of a sketch. They default to a value between 0 and 1 (although more types of param are [planned](https://github.com/nudibranchrecords/hedron/issues/13)). The simplest way to control a param is to click and drag the value bar.
### Adding an input to a param
The real power of Hedron is the ability to link different inputs to a param. This can be audio, LFO or MIDI.
@@ -35,6 +36,15 @@ Some things to note:
- Adding a MIDI input will involve a "MIDI learn" step
- MIDI inputs are always active, they do not have an active/disabled state
+
+### Editing the range of a param
+Params can have their range extended or decreased, this can be useful if you want to change the range for a particular instance of a sketch, but not affect all other instances of the sketch, or change the default range of the script
+
+To edit the range of a param:
+
+ 1. Open the param by clicking on the area below the value bar
+ 2. Open the advanced options by clicking "Advanced"
+ 3. Edit the minimum/maximum fields, the fields update when you press Enter or the field loses focus
## Shots
Shots are functions that the sketch has exposed for the user to have fun with. These could be things such as explosions, pre scripted animations, etc. The simplest way to control a shot is to click on the hit area for that shot.
@@ -46,8 +56,12 @@ Shots have a very similar system to adding inputs as params, so please refer to
- MIDI should be a "note on" type control
- Instead of LFO, shots have a "sequencer". The rows of the sequencer are **one beat** (quarter note) split into 8. Click on each step for when you want the shot to fire.
-## Reimporting shots and params
-If you've already got a project going with some sketches and then make edits to a sketch, Hedron automatically loads in the new content. However, if you've made changes to config.js, you'll need to "reimport" to see the new params and shots. Do this by clicking the button at the bottom of the view for that sketch.
+## Reloading sketches / Auto reload
+If you have the "Watch sketches" setting enabled, Hedron will automatically refresh your sketches. However, if you don't have this enabled or something went wrong with the file watch (e.g. your sketch imports a file outside of its own folder) you'll need to click "Reload File" to see changes made to sketch files.
+
+This refresh will remove the sketch from the scene, import any new params or shots, remove and old params and shots, and then add the new sketch back into the scene.
+
+**Please note: File change detection may not work with all text editors. (e.g. Atom on OSX is reported to be inconsistent).**
## Macros
Macros make it possible to control many params at once. To start using macros, click on "Macros" on the right sidebar.
@@ -68,9 +82,6 @@ Improvements to macros are [planned](https://github.com/nudibranchrecords/hedron
## MIDI Devices
Midi devices display on the left hand side, underneath the preview.
-### MIDI Banks
-You can change the current bank you are using for each device using the list of numbers next to that device. When assigning MIDI anywhere, it will default to the current bank you are on for that device.
-
## MIDI Clock
By default, MIDI clock is generated by Hedron.
@@ -79,6 +90,15 @@ By default, MIDI clock is generated by Hedron.
- You can manually edit the generated clock BPM, or disable it completely in the settings. (Project > Settings)
- If you have an external MIDI clock connected, Hedron will detect it automatically. You should disable the generated clock if you are using an external one.
+## Audio Parameters
+By clicking on the audio level bars left of the clock controls you can edit parameters to change the shaping of the incoming audio. The controls affect the audio as follows.
+
+- **Levels Falloff** - This is the amount that the value passed on to the parameters gets reduced by each frame, when this number is low the value will quickly jump up with a sound, but take time to come back down to zero.
+- **Levels Smoothing** - This is how much the prior frames value will be blended with the current incoming audio value, adding smoothing will cause quick changes in volume, up or down, to change more slowly. When this number is at 0 there is no smoothing, and at 1 it will lock the current value of the audio levels.
+- **Levels Power** - This value controls a power function with an exponent between .5 and 3. When this parameter is low it will cause low audio levels to get boosted higher when this parameter is high, low levels will be passed through even lower, causing only values that were high to begin with to remain high.
+- **Normalize Levels** - This causes each frequency band to be normalized based on it's highest and lowest recorded values, this will help the parameters connected to audio move within their full range, as often the low end tends to be louder while the high end is quieter.
+- **Normalized Range Falloff** - This is how much the recorded high and low of each frequency band decreases/increases respectively each frame.
+
## Other features
* Save or load using "Project > Save/Load/Save As..."
diff --git a/example-projects/logo/project.json b/example-projects/logo/project.json
new file mode 100644
index 00000000..cfc051d9
--- /dev/null
+++ b/example-projects/logo/project.json
@@ -0,0 +1 @@
+{"nodes":{"sceneCrossfader":{"id":"sceneCrossfader","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Scene Crossfader","type":"param"},"viewerMode":{"id":"viewerMode","value":"mix","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Viewer Mode","type":"select","options":[{"value":"mix","label":"Mix"},{"value":"A","label":"A"},{"value":"B","label":"B"}]},"sketchOrganization":{"id":"sketchOrganization","value":"category","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Sketch Organization","type":"select","options":[{"value":"folder","label":"Folder"},{"value":"category","label":"Category"},{"value":"author","label":"Author"}]},"audioLevelsFalloff":{"id":"audioLevelsFalloff","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Falloff","type":"param"},"audioLevelsPower":{"id":"audioLevelsPower","value":0.25,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Power","type":"param","min":0.5,"max":3},"audioLevelsSmoothing":{"id":"audioLevelsSmoothing","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Smoothing","type":"param"},"audioNormalizeLevels":{"id":"audioNormalizeLevels","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Normalize Levels","type":"param"},"audioNormalizeRangeFalloff":{"id":"audioNormalizeRangeFalloff","value":0.01,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Normalized Range Falloff","type":"param"},"rjqn7il":{"id":"rjqn7il","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"my3oidf","channel":"A"}},"title":"Add to A"},"m6ihkvn":{"id":"m6ihkvn","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"my3oidf","channel":"B"}},"title":"Add to B"},"kg3hs2g":{"id":"kg3hs2g","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"my3oidf","type":"active"}},"title":"Add to Active"},"l4woei9":{"id":"l4woei9","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"my3oidf","type":"opposite"}},"title":"Add to Opposite"},"d6eqgoc":{"id":"d6eqgoc","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"SCENE_CLEAR_CHANNEL","payload":{"id":"my3oidf"}},"title":"Clear"},"x70b7a7":{"id":"x70b7a7","value":0.984375,"inputLinkIds":["8d95yni"],"shotCount":0,"connectedMacroIds":[],"sketchId":"fba6j4h","title":"Color H","type":"param","key":"colorH","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1,"openedLinkId":"8d95yni","activeInputLinkId":"8d95yni"},"gqe9l6k":{"id":"gqe9l6k","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"fba6j4h","title":"Color S","type":"param","key":"colorS","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"t4fg79j":{"id":"t4fg79j","value":0.5333333333333334,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"fba6j4h","title":"Color L","type":"param","key":"colorL","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"l3l9rfx":{"id":"l3l9rfx","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"fba6j4h","title":"Ambient Light Intensity","type":"param","key":"aInt","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"akwo8gq":{"id":"akwo8gq","value":0.20435495535553758,"inputLinkIds":["j1aa7vr"],"shotCount":0,"connectedMacroIds":[],"sketchId":"fba6j4h","title":"Point Light Intensity","type":"param","key":"pInt","hidden":false,"min":0,"max":5,"defaultMin":0,"defaultMax":5,"openedLinkId":"j1aa7vr","activeInputLinkId":"j1aa7vr"},"1oalgep":{"id":"1oalgep","value":0.10674157303370786,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"fba6j4h","title":"Logo Rot Speed X","type":"param","key":"logoRotSpeedX","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"iuy1yvb":{"id":"iuy1yvb","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"fba6j4h","title":"Logo Rot Speed Y","type":"param","key":"logoRotSpeedY","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"d1d4b7a":{"id":"d1d4b7a","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"fba6j4h","title":"Logo Rot Speed Z","type":"param","key":"logoRotSpeedZ","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"wbueg73":{"id":"wbueg73","value":0.8015122861711951,"inputLinkIds":["qb3cv58"],"shotCount":0,"connectedMacroIds":[],"sketchId":"fba6j4h","title":"Logo Scale","type":"param","key":"logoScale","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1,"openedLinkId":"qb3cv58","activeInputLinkId":"qb3cv58"},"ek4e1ei":{"id":"ek4e1ei","value":0.35736361778716497,"inputLinkIds":["jljjpbq"],"shotCount":0,"connectedMacroIds":[],"sketchId":"fba6j4h","title":"Sphere Scale","type":"param","key":"sphereScale","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1,"openedLinkId":"jljjpbq","activeInputLinkId":"jljjpbq"},"4d0xd1q":{"id":"4d0xd1q","value":0,"inputLinkIds":[],"shotCount":8,"connectedMacroIds":[],"type":"shot","title":"Reset Logo Rot","method":"resetLogoRot","sketchId":"fba6j4h"},"5e531k6":{"id":"5e531k6","value":"noise","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}],"sketchId":"fba6j4h","parentNodeId":"cia76fe"},"f9j8sx8":{"id":"f9j8sx8","value":8,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}],"sketchId":"fba6j4h","parentNodeId":"cia76fe"},"glx9og4":{"id":"glx9og4","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true,"sketchId":"fba6j4h","parentNodeId":"cia76fe"},"5q2k1l9":{"id":"5q2k1l9","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Seed","key":"seed","type":"select","subNode":true,"options":[{"value":-1,"label":"auto"},{"value":0,"label":"0"},{"value":1,"label":"1"},{"value":2,"label":"2"},{"value":3,"label":"3"},{"value":4,"label":"4"},{"value":5,"label":"5"},{"value":6,"label":"6"},{"value":7,"label":"7"},{"value":8,"label":"8"},{"value":9,"label":"9"},{"value":10,"label":"10"},{"value":11,"label":"11"},{"value":12,"label":"12"},{"value":13,"label":"13"},{"value":14,"label":"14"},{"value":15,"label":"15"},{"value":16,"label":"16"},{"value":17,"label":"17"},{"value":18,"label":"18"},{"value":19,"label":"19"},{"value":20,"label":"20"},{"value":21,"label":"21"},{"value":22,"label":"22"},{"value":23,"label":"23"},{"value":24,"label":"24"}],"sketchId":"fba6j4h","parentNodeId":"cia76fe"},"00iur8p":{"id":"00iur8p","value":"noise","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}],"sketchId":"fba6j4h","parentNodeId":"80adxo4"},"u1fhvdr":{"id":"u1fhvdr","value":8,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}],"sketchId":"fba6j4h","parentNodeId":"80adxo4"},"gmud9yb":{"id":"gmud9yb","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true,"sketchId":"fba6j4h","parentNodeId":"80adxo4"},"h8dqnsw":{"id":"h8dqnsw","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Seed","key":"seed","type":"select","subNode":true,"options":[{"value":-1,"label":"auto"},{"value":0,"label":"0"},{"value":1,"label":"1"},{"value":2,"label":"2"},{"value":3,"label":"3"},{"value":4,"label":"4"},{"value":5,"label":"5"},{"value":6,"label":"6"},{"value":7,"label":"7"},{"value":8,"label":"8"},{"value":9,"label":"9"},{"value":10,"label":"10"},{"value":11,"label":"11"},{"value":12,"label":"12"},{"value":13,"label":"13"},{"value":14,"label":"14"},{"value":15,"label":"15"},{"value":16,"label":"16"},{"value":17,"label":"17"},{"value":18,"label":"18"},{"value":19,"label":"19"},{"value":20,"label":"20"},{"value":21,"label":"21"},{"value":22,"label":"22"},{"value":23,"label":"23"},{"value":24,"label":"24"}],"sketchId":"fba6j4h","parentNodeId":"80adxo4"},"hehj24t":{"id":"hehj24t","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}],"sketchId":"fba6j4h","parentNodeId":"y68xjvq"},"oaifano":{"id":"oaifano","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}],"sketchId":"fba6j4h","parentNodeId":"y68xjvq"},"vnvumqu":{"id":"vnvumqu","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true,"sketchId":"fba6j4h","parentNodeId":"y68xjvq"},"c55ub4q":{"id":"c55ub4q","value":-1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Seed","key":"seed","type":"select","subNode":true,"options":[{"value":-1,"label":"auto"},{"value":0,"label":"0"},{"value":1,"label":"1"},{"value":2,"label":"2"},{"value":3,"label":"3"},{"value":4,"label":"4"},{"value":5,"label":"5"},{"value":6,"label":"6"},{"value":7,"label":"7"},{"value":8,"label":"8"},{"value":9,"label":"9"},{"value":10,"label":"10"},{"value":11,"label":"11"},{"value":12,"label":"12"},{"value":13,"label":"13"},{"value":14,"label":"14"},{"value":15,"label":"15"},{"value":16,"label":"16"},{"value":17,"label":"17"},{"value":18,"label":"18"},{"value":19,"label":"19"},{"value":20,"label":"20"},{"value":21,"label":"21"},{"value":22,"label":"22"},{"value":23,"label":"23"},{"value":24,"label":"24"}],"sketchId":"fba6j4h","parentNodeId":"y68xjvq"},"ixxvkm9":{"id":"ixxvkm9","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"qb3cv58","sketchId":"fba6j4h","key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"85epqm4":{"id":"85epqm4","value":0.6384615384615384,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"qb3cv58","sketchId":"fba6j4h","key":"range","title":"Lower Range","passToNext":true,"subNode":true},"uq4ut6n":{"id":"uq4ut6n","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"qb3cv58","sketchId":"fba6j4h","key":"range","title":"Upper Range","passToNext":false,"subNode":true},"1qxoa7w":{"id":"1qxoa7w","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}],"sketchId":"fba6j4h","parentNodeId":"qb3cv58"},"2sbvovl":{"id":"2sbvovl","value":0.125,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}],"sketchId":"fba6j4h","parentNodeId":"qb3cv58"},"o4m5lcq":{"id":"o4m5lcq","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true,"sketchId":"fba6j4h","parentNodeId":"qb3cv58"},"6b82hew":{"id":"6b82hew","value":-1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Seed","key":"seed","type":"select","subNode":true,"options":[{"value":-1,"label":"auto"},{"value":0,"label":"0"},{"value":1,"label":"1"},{"value":2,"label":"2"},{"value":3,"label":"3"},{"value":4,"label":"4"},{"value":5,"label":"5"},{"value":6,"label":"6"},{"value":7,"label":"7"},{"value":8,"label":"8"},{"value":9,"label":"9"},{"value":10,"label":"10"},{"value":11,"label":"11"},{"value":12,"label":"12"},{"value":13,"label":"13"},{"value":14,"label":"14"},{"value":15,"label":"15"},{"value":16,"label":"16"},{"value":17,"label":"17"},{"value":18,"label":"18"},{"value":19,"label":"19"},{"value":20,"label":"20"},{"value":21,"label":"21"},{"value":22,"label":"22"},{"value":23,"label":"23"},{"value":24,"label":"24"}],"sketchId":"fba6j4h","parentNodeId":"qb3cv58"},"un0x0ew":{"id":"un0x0ew","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","title":"Toggle Activate","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"wbueg73","linkId":"qb3cv58"}},"sketchId":"fba6j4h","parentNodeId":"qb3cv58"},"qb3cv58":{"id":"qb3cv58","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"lfo","type":"inputLink","input":{"id":"lfo"},"nodeId":"wbueg73","sketchId":"fba6j4h","parentNodeId":"wbueg73","nodeType":"param","modifierIds":["ixxvkm9","85epqm4","uq4ut6n"],"lfoOptionIds":["1qxoa7w","2sbvovl","o4m5lcq","6b82hew"],"midiOptionIds":[],"audioOptionIds":[],"linkableActions":{"toggleActivate":"un0x0ew"},"linkType":"node","animOptionIds":[]},"xhhrpgq":{"id":"xhhrpgq","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"8d95yni","sketchId":"fba6j4h","key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"mqtidc3":{"id":"mqtidc3","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"8d95yni","sketchId":"fba6j4h","key":"range","title":"Lower Range","passToNext":true,"subNode":true},"7m9pnex":{"id":"7m9pnex","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"8d95yni","sketchId":"fba6j4h","key":"range","title":"Upper Range","passToNext":false,"subNode":true},"qvl42fo":{"id":"qvl42fo","value":"sawtooth","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}],"sketchId":"fba6j4h","parentNodeId":"8d95yni"},"qadv4kd":{"id":"qadv4kd","value":0.125,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}],"sketchId":"fba6j4h","parentNodeId":"8d95yni"},"rw4kc0t":{"id":"rw4kc0t","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true,"sketchId":"fba6j4h","parentNodeId":"8d95yni"},"yasaxhj":{"id":"yasaxhj","value":-1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Seed","key":"seed","type":"select","subNode":true,"options":[{"value":-1,"label":"auto"},{"value":0,"label":"0"},{"value":1,"label":"1"},{"value":2,"label":"2"},{"value":3,"label":"3"},{"value":4,"label":"4"},{"value":5,"label":"5"},{"value":6,"label":"6"},{"value":7,"label":"7"},{"value":8,"label":"8"},{"value":9,"label":"9"},{"value":10,"label":"10"},{"value":11,"label":"11"},{"value":12,"label":"12"},{"value":13,"label":"13"},{"value":14,"label":"14"},{"value":15,"label":"15"},{"value":16,"label":"16"},{"value":17,"label":"17"},{"value":18,"label":"18"},{"value":19,"label":"19"},{"value":20,"label":"20"},{"value":21,"label":"21"},{"value":22,"label":"22"},{"value":23,"label":"23"},{"value":24,"label":"24"}],"sketchId":"fba6j4h","parentNodeId":"8d95yni"},"6ojb4sj":{"id":"6ojb4sj","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","title":"Toggle Activate","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"x70b7a7","linkId":"8d95yni"}},"sketchId":"fba6j4h","parentNodeId":"8d95yni"},"8d95yni":{"id":"8d95yni","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"lfo","type":"inputLink","input":{"id":"lfo"},"nodeId":"x70b7a7","sketchId":"fba6j4h","parentNodeId":"x70b7a7","nodeType":"param","modifierIds":["xhhrpgq","mqtidc3","7m9pnex"],"lfoOptionIds":["qvl42fo","qadv4kd","rw4kc0t","yasaxhj"],"midiOptionIds":[],"audioOptionIds":[],"linkableActions":{"toggleActivate":"6ojb4sj"},"linkType":"node","animOptionIds":[]},"2rplgq1":{"id":"2rplgq1","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"j1aa7vr","sketchId":"fba6j4h","key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"c6gd8g6":{"id":"c6gd8g6","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"j1aa7vr","sketchId":"fba6j4h","key":"range","title":"Lower Range","passToNext":true,"subNode":true},"5kwbcea":{"id":"5kwbcea","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"j1aa7vr","sketchId":"fba6j4h","key":"range","title":"Upper Range","passToNext":false,"subNode":true},"tua0kl9":{"id":"tua0kl9","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Audio Band","key":"audioBand","type":"select","subNode":true,"options":[{"value":0,"label":"Low"},{"value":1,"label":"Low-Mid"},{"value":2,"label":"Mid"},{"value":3,"label":"High"}],"sketchId":"fba6j4h","parentNodeId":"j1aa7vr"},"s2k21pb":{"id":"s2k21pb","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","title":"Toggle Activate","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"akwo8gq","linkId":"j1aa7vr"}},"sketchId":"fba6j4h","parentNodeId":"j1aa7vr"},"j1aa7vr":{"id":"j1aa7vr","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"audio","type":"inputLink","input":{"id":"audio"},"nodeId":"akwo8gq","sketchId":"fba6j4h","parentNodeId":"akwo8gq","nodeType":"param","modifierIds":["2rplgq1","c6gd8g6","5kwbcea"],"lfoOptionIds":[],"midiOptionIds":[],"audioOptionIds":["tua0kl9"],"linkableActions":{"toggleActivate":"s2k21pb"},"linkType":"node","animOptionIds":[]},"lt26b9h":{"id":"lt26b9h","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"jljjpbq","sketchId":"fba6j4h","key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"vp9wpol":{"id":"vp9wpol","value":0.19230769230769232,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"jljjpbq","sketchId":"fba6j4h","key":"range","title":"Lower Range","passToNext":true,"subNode":true},"ndir5pi":{"id":"ndir5pi","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"jljjpbq","sketchId":"fba6j4h","key":"range","title":"Upper Range","passToNext":false,"subNode":true},"v80a9i2":{"id":"v80a9i2","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Audio Band","key":"audioBand","type":"select","subNode":true,"options":[{"value":0,"label":"Low"},{"value":1,"label":"Low-Mid"},{"value":2,"label":"Mid"},{"value":3,"label":"High"}],"sketchId":"fba6j4h","parentNodeId":"jljjpbq"},"fsgci77":{"id":"fsgci77","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","title":"Toggle Activate","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"ek4e1ei","linkId":"jljjpbq"}},"sketchId":"fba6j4h","parentNodeId":"jljjpbq"},"jljjpbq":{"id":"jljjpbq","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"audio","type":"inputLink","input":{"id":"audio"},"nodeId":"ek4e1ei","sketchId":"fba6j4h","parentNodeId":"ek4e1ei","nodeType":"param","modifierIds":["lt26b9h","vp9wpol","ndir5pi"],"lfoOptionIds":[],"midiOptionIds":[],"audioOptionIds":["v80a9i2"],"linkableActions":{"toggleActivate":"fsgci77"},"linkType":"node","animOptionIds":[]}},"scenes":{"items":{"my3oidf":{"id":"my3oidf","title":"New Scene","selectedSketchId":"fba6j4h","sketchIds":["fba6j4h"],"linkableActionIds":{"addToA":"rjqn7il","addToB":"m6ihkvn","addToActive":"kg3hs2g","addToOpposite":"l4woei9","clear":"d6eqgoc"}}},"currentSceneId":"my3oidf","channels":{"A":"my3oidf","B":false}},"sketches":{"fba6j4h":{"title":"Hedron Logo","moduleId":"logo","paramIds":["x70b7a7","gqe9l6k","t4fg79j","l3l9rfx","akwo8gq","1oalgep","iuy1yvb","d1d4b7a","wbueg73","ek4e1ei"],"shotIds":["4d0xd1q"],"openedNodeId":"akwo8gq"}},"project":{"errors":[],"errorPopup":false},"inputs":{"audio":{"value":[0.20435495535553758,0.04498548016230807,0.05956725196519405,0.15775958682669192],"assignedLinkIds":["j1aa7vr","jljjpbq"]},"lfo":{"value":311.875,"assignedLinkIds":["qb3cv58","8d95yni"]}},"inputLinks":{"nodeIds":[null,null]},"macros":{"learningId":false,"nodeIds":[]},"ui":{"panelWidths":{"left":55.92621526473667},"isEditing":false,"openedNode":false,"auxOpen":[],"addSketchOpen":{}},"router":{"location":{"pathname":"/scenes/view","search":"","hash":"","key":"n5ofl9"}},"settings":{"clockGenerated":true,"clockBpm":120,"aspectW":16,"aspectH":9,"antialias":true,"throttledFPS":60,"watchSketchesDir":true},"form":{}}
diff --git a/example-projects/logo/sketches/logo/config.js b/example-projects/logo/sketches/logo/config.js
new file mode 100644
index 00000000..579d9e9c
--- /dev/null
+++ b/example-projects/logo/sketches/logo/config.js
@@ -0,0 +1,64 @@
+module.exports = {
+ defaultTitle: 'Hedron Logo',
+ params: [
+ {
+ key: 'colorH',
+ title: 'Color H',
+ defaultValue: 0.5,
+ },
+ {
+ key: 'colorS',
+ title: 'Color S',
+ defaultValue: 0.5,
+ },
+ {
+ key: 'colorL',
+ title: 'Color L',
+ defaultValue: 0.5,
+ },
+ {
+ key: 'aInt',
+ title: 'Ambient Light Intensity',
+ defaultValue: 0.1,
+ },
+ {
+ key: 'pInt',
+ title: 'Point Light Intensity',
+ defaultValue: 0.5,
+ defaultMin: 0,
+ defaultMax: 5,
+ },
+ {
+ key: 'logoRotSpeedX',
+ title: 'Logo Rot Speed X',
+ defaultValue: 0,
+ },
+ {
+ key: 'logoRotSpeedY',
+ title: 'Logo Rot Speed Y',
+ defaultValue: 0,
+ },
+ {
+ key: 'logoRotSpeedZ',
+ title: 'Logo Rot Speed Z',
+ defaultValue: 0,
+ },
+ {
+ key: 'logoScale',
+ title: 'Logo Scale',
+ defaultValue: 0.7,
+ },
+ {
+ key: 'sphereScale',
+ title: 'Sphere Scale',
+ defaultValue: 1,
+ },
+ ],
+ shots: [
+ {
+ method: 'resetLogoRot',
+ title: 'Reset Logo Rot',
+ },
+ ],
+}
+
diff --git a/example-projects/logo/sketches/logo/hedron-logo.glb b/example-projects/logo/sketches/logo/hedron-logo.glb
new file mode 100644
index 00000000..480e782b
Binary files /dev/null and b/example-projects/logo/sketches/logo/hedron-logo.glb differ
diff --git a/example-projects/logo/sketches/logo/index.js b/example-projects/logo/sketches/logo/index.js
new file mode 100644
index 00000000..535fa88d
--- /dev/null
+++ b/example-projects/logo/sketches/logo/index.js
@@ -0,0 +1,65 @@
+const loader = new THREE.GLTFLoader()
+
+class Logo {
+ constructor (scene) {
+ this.root = new THREE.Group()
+
+ // Add lights
+ this.aLight = new THREE.AmbientLight(null, 0.2)
+ this.pLight = new THREE.PointLight(null, 3, 10)
+ this.root.add(this.pLight)
+ this.root.add(this.aLight)
+
+ // Add inner sphere
+ const sphereGeom = new THREE.IcosahedronBufferGeometry(1, 3)
+ const sphereMat = new THREE.MeshBasicMaterial()
+ this.sphere = new THREE.Mesh(sphereGeom, sphereMat)
+ this.root.add(this.sphere)
+
+ // Load logo model
+ loader.load(`${__dirname}/hedron-logo.glb`, obj => {
+ this.model = obj.scene.getObjectByName('Hedron')
+ this.root.add(this.model)
+
+ const s = 0.75
+ this.model.scale.set(s, s, s)
+ this.model.material = new THREE.MeshStandardMaterial({ color: 0xffffff })
+
+ this.resetLogoRot()
+ })
+ }
+
+ resetLogoRot () {
+ this.model.rotation.set(0.15, 0, 0)
+ }
+
+ update (p, t, f) {
+ if (!this.model) return
+
+ let s
+
+ // Adjust colour of sphere and lighting
+ this.pLight.color.setHSL(p.colorH, p.colorS, p.colorL)
+ this.aLight.color.setHSL(p.colorH, p.colorS, p.colorL)
+ this.sphere.material.color.setHSL(p.colorH, p.colorS, p.colorL)
+
+ // Intensity of lighting
+ this.aLight.intensity = p.aInt
+ this.pLight.intensity = p.pInt
+
+ // Logo Rotation
+ this.model.rotation.x += p.logoRotSpeedX * f * 0.3
+ this.model.rotation.y += p.logoRotSpeedY * f * 0.3
+ this.model.rotation.z += p.logoRotSpeedZ * f * 0.3
+
+ // Logo Scale
+ s = p.logoScale
+ this.model.scale.set(s, s, s)
+
+ // Inner sphere scale
+ s = p.sphereScale
+ this.sphere.scale.set(s, s, s)
+ }
+}
+
+module.exports = Logo
diff --git a/example-projects/package.json b/example-projects/package.json
deleted file mode 100644
index 46126345..00000000
--- a/example-projects/package.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "example-projects",
- "license": "MIT",
- "dependencies": {
- "@tweenjs/tween.js": "^17.2.0",
- "glslify": "^6.3.1",
- "lodash": "^4.17.11",
- "three": "^0.97.0",
- "three-addons": "^1.2.0"
- }
-}
diff --git a/example-projects/simple/project.json b/example-projects/simple/project.json
index 76241a19..15d08ab6 100644
--- a/example-projects/simple/project.json
+++ b/example-projects/simple/project.json
@@ -1 +1 @@
-{"nodes":{"sceneCrossfader":{"id":"sceneCrossfader","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Scene Crossfader","type":"param"},"viewerMode":{"id":"viewerMode","value":"mix","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Viewer Mode","type":"select","options":[{"value":"mix","label":"Mix"},{"value":"A","label":"A"},{"value":"B","label":"B"}]},"audioNormalizeLevels":{"id":"audioNormalizeLevels","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Normalize Levels","type":"param"},"audioLevelsFalloff":{"id":"audioLevelsFalloff","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Falloff","type":"param"},"45g3as2":{"id":"45g3as2","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Opacity","type":"param","key":"opacity"},"h7fpyqn":{"id":"h7fpyqn","value":0.4322033898305085,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Speed","type":"param","key":"speed"},"o8gbvq5":{"id":"o8gbvq5","value":0.9364406779661018,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"BG Color H","type":"param","key":"colorH"},"naxbdhq":{"id":"naxbdhq","value":0.5932203389830508,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"BG Color S","type":"param","key":"colorS"},"r8qk46i":{"id":"r8qk46i","value":0.3177966101694915,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"BG Color L","type":"param","key":"colorL"},"sbh5yrw":{"id":"sbh5yrw","value":0.07530120481927711,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rotation Speed X","type":"param","key":"rotSpeedX"},"9ng7lh7":{"id":"9ng7lh7","value":0.07228915662650602,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rotation Speed Y","type":"param","key":"rotSpeedY"},"xjm5dq4":{"id":"xjm5dq4","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rotation Speed Z","type":"param","key":"rotSpeedZ"},"sawiymq":{"id":"sawiymq","value":0.7259036144578314,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Scale","type":"param","key":"scale"},"icyqnmx":{"id":"icyqnmx","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Mesh Index","type":"param","key":"meshIndex"},"7uuhp0s":{"id":"7uuhp0s","value":0,"inputLinkIds":["tu8qxqi"],"shotCount":376,"connectedMacroIds":[],"type":"shot","title":"Shape Shift","method":"shapeShift","sketchId":"h92ajqd","openedLinkId":"tu8qxqi","activeInputLinkId":"tu8qxqi"},"7plnjjb":{"id":"7plnjjb","value":0.12349397590361445,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rotation Speed X","type":"param","key":"rotSpeedX"},"1wws3h0":{"id":"1wws3h0","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rotation Speed Y","type":"param","key":"rotSpeedY"},"i6hh1f7":{"id":"i6hh1f7","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rotation Speed Z","type":"param","key":"rotSpeedZ"},"1shut4q":{"id":"1shut4q","value":0.4080240748240045,"inputLinkIds":["5rc2e8o"],"shotCount":0,"connectedMacroIds":[],"title":"Scale","type":"param","key":"scale","openedLinkId":"5rc2e8o","activeInputLinkId":"5rc2e8o"},"76ngsl0":{"id":"76ngsl0","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Mesh Index","type":"param","key":"meshIndex"},"v8n5jhq":{"id":"v8n5jhq","value":0,"inputLinkIds":[],"shotCount":5,"connectedMacroIds":[],"type":"shot","title":"Shape Shift","method":"shapeShift","sketchId":"mfv9isa"},"1303jlf":{"id":"1303jlf","value":[1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[]},"iwv1pma":{"id":"iwv1pma","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"s9hm2yg":{"id":"s9hm2yg","value":0.3967254901960784,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"gain","title":"Gain","passToNext":false,"type":"audio","subNode":true},"29opahl":{"id":"29opahl","value":0.04901960784313725,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Lower Range","passToNext":true,"subNode":true},"07kdgfe":{"id":"07kdgfe","value":0.5294117647058824,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Upper Range","passToNext":false,"subNode":true}},"scenes":{"items":{"164edsk":{"id":"164edsk","title":"Solids","selectedSketchId":"mfv9isa","sketchIds":["gk1f9u4","h92ajqd","mfv9isa"],"linkableActionIds":{"addToA":"0dtydkk","addToB":"ocqrvbr","addToActive":"2ig94id","addToOpposite":"g70l9wa","clear":"9efnr9i"}},"1wm69ts":{"id":"1wm69ts","title":"Stars","selectedSketchId":"dy60hv7","sketchIds":["dy60hv7"],"linkableActionIds":{"addToA":"shpkh9g","addToB":"b6r2j19","addToActive":"gfly1ij","addToOpposite":"xd35dxw","clear":"897881h"}}},"currentSceneId":"164edsk","channels":{"A":"164edsk","B":"1wm69ts"}},"sketches":{"dy60hv7":{"title":"Stars","moduleId":"stars","paramIds":["45g3as2","h7fpyqn"],"shotIds":[],"openedNodes":{}},"gk1f9u4":{"title":"Env","moduleId":"env","paramIds":["o8gbvq5","naxbdhq","r8qk46i"],"shotIds":[],"openedNodes":{}},"h92ajqd":{"title":"Outer","moduleId":"solid","paramIds":["sbh5yrw","9ng7lh7","xjm5dq4","sawiymq","icyqnmx"],"shotIds":["7uuhp0s"],"openedNodes":{"shot":"7uuhp0s"}},"mfv9isa":{"title":"Inner","moduleId":"solid","paramIds":["7plnjjb","1wws3h0","i6hh1f7","1shut4q","76ngsl0"],"shotIds":["v8n5jhq"],"openedNodes":{"param":"1shut4q"}}},"project":{"filePath":"/Users/alex/Sites/GitHub/hedron/example-projects/simple/project.json","sketchesPath":"/Users/alex/Sites/GitHub/hedron/example-projects/simple/sketches","errors":["Sketches failed to load: Failed to load sketch folder: No sketches found","Failed to initiate sketches: Cannot read property 'Module' of undefined"],"errorPopup":false},"inputs":{"audio_0":{"value":0.7133311680963218,"assignedLinkIds":[]},"audio_1":{"value":0.6279030375158221,"assignedLinkIds":["5rc2e8o"]},"audio_2":{"value":0.2696383858655107,"assignedLinkIds":[]},"audio_3":{"value":0.1761536218916207,"assignedLinkIds":[]},"lfo":{"value":731.0833333333334,"assignedLinkIds":[]},"seq-step":{"assignedLinkIds":["tu8qxqi"],"value":24}},"inputLinks":{"tu8qxqi":{"title":"seq-step","input":{"id":"seq-step"},"id":"tu8qxqi","nodeId":"7uuhp0s","nodeType":"shot","modifierIds":[],"lfoOptionIds":[],"midiOptionIds":[],"linkableActions":{"toggleActivate":"jig7je8"},"sequencerGridId":"1303jlf","linkType":"node"},"5rc2e8o":{"title":"audio_1","input":{"id":"audio_1","type":"audio"},"id":"5rc2e8o","nodeId":"1shut4q","nodeType":"param","modifierIds":["iwv1pma","s9hm2yg","29opahl","07kdgfe"],"lfoOptionIds":[],"midiOptionIds":[],"linkableActions":{"toggleActivate":"nhkcid6"},"linkType":"node"}},"linkableActions":{"0dtydkk":{"id":"0dtydkk","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"164edsk","channel":"A"}},"inputLinkIds":[]},"ocqrvbr":{"id":"ocqrvbr","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"164edsk","channel":"B"}},"inputLinkIds":[]},"2ig94id":{"id":"2ig94id","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"164edsk","type":"active"}},"inputLinkIds":[]},"g70l9wa":{"id":"g70l9wa","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"164edsk","type":"opposite"}},"inputLinkIds":[]},"9efnr9i":{"id":"9efnr9i","action":{"type":"SCENE_CLEAR_CHANNEL","payload":{"id":"164edsk"}},"inputLinkIds":[]},"shpkh9g":{"id":"shpkh9g","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"1wm69ts","channel":"A"}},"inputLinkIds":[]},"b6r2j19":{"id":"b6r2j19","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"1wm69ts","channel":"B"}},"inputLinkIds":[]},"gfly1ij":{"id":"gfly1ij","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"1wm69ts","type":"active"}},"inputLinkIds":[]},"xd35dxw":{"id":"xd35dxw","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"1wm69ts","type":"opposite"}},"inputLinkIds":[]},"897881h":{"id":"897881h","action":{"type":"SCENE_CLEAR_CHANNEL","payload":{"id":"1wm69ts"}},"inputLinkIds":[]},"jig7je8":{"id":"jig7je8","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"7uuhp0s","linkId":"tu8qxqi"}},"inputLinkIds":[]},"nhkcid6":{"id":"nhkcid6","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"1shut4q","linkId":"5rc2e8o"}},"inputLinkIds":[]}},"macros":{"learningId":false,"items":{}},"ui":{"panelWidths":{"left":50},"isEditing":false,"openedNode":false},"router":{"location":{"pathname":"/scenes/view","search":"","hash":"","key":"90d7lh"}},"settings":{"clockGenerated":true,"clockBpm":120,"aspectW":16,"aspectH":9,"antialias":false,"throttledFPS":60},"form":{}}
+{"nodes":{"sceneCrossfader":{"id":"sceneCrossfader","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Scene Crossfader","type":"param"},"viewerMode":{"id":"viewerMode","value":"mix","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Viewer Mode","type":"select","options":[{"value":"mix","label":"Mix"},{"value":"A","label":"A"},{"value":"B","label":"B"}]},"sketchOrganization":{"id":"sketchOrganization","value":"category","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Sketch Organization","type":"select","options":[{"value":"folder","label":"Folder"},{"value":"category","label":"Category"},{"value":"author","label":"Author"}]},"audioLevelsFalloff":{"id":"audioLevelsFalloff","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Falloff","type":"param"},"audioLevelsPower":{"id":"audioLevelsPower","value":0.25,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Power","type":"param","min":0.5,"max":3},"audioLevelsSmoothing":{"id":"audioLevelsSmoothing","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Smoothing","type":"param"},"audioNormalizeLevels":{"id":"audioNormalizeLevels","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Normalize Levels","type":"param"},"audioNormalizeRangeFalloff":{"id":"audioNormalizeRangeFalloff","value":0.01,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Normalized Range Falloff","type":"param"},"h1n8xw8":{"id":"h1n8xw8","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"f1vwqkk","channel":"A"}},"title":"Add to A"},"wa2fvtb":{"id":"wa2fvtb","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"f1vwqkk","channel":"B"}},"title":"Add to B"},"n25blwi":{"id":"n25blwi","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"f1vwqkk","type":"active"}},"title":"Add to Active"},"817xlww":{"id":"817xlww","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"f1vwqkk","type":"opposite"}},"title":"Add to Opposite"},"2ag66pm":{"id":"2ag66pm","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"SCENE_CLEAR_CHANNEL","payload":{"id":"f1vwqkk"}},"title":"Clear"},"g7tllci":{"id":"g7tllci","value":0.546875,"inputLinkIds":["99r0oju"],"shotCount":0,"connectedMacroIds":[],"sketchId":"qpvup3p","title":"BG Color H","type":"param","key":"colorH","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1,"openedLinkId":"99r0oju","activeInputLinkId":"99r0oju"},"uh7mfhv":{"id":"uh7mfhv","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"qpvup3p","title":"BG Color S","type":"param","key":"colorS","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"sjwc7eq":{"id":"sjwc7eq","value":0.282258064516129,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"qpvup3p","title":"BG Color L","type":"param","key":"colorL","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"6besnyv":{"id":"6besnyv","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"et6x5w5","title":"Rotation Speed X","type":"param","key":"rotSpeedX","hidden":false,"min":-1,"max":1,"defaultMin":-1,"defaultMax":1},"cbo90q9":{"id":"cbo90q9","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"et6x5w5","title":"Rotation Speed Y","type":"param","key":"rotSpeedY","hidden":false,"min":-1,"max":1,"defaultMin":-1,"defaultMax":1},"51up7yl":{"id":"51up7yl","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"et6x5w5","title":"Rotation Speed Z","type":"param","key":"rotSpeedZ","hidden":false,"min":-1,"max":1,"defaultMin":-1,"defaultMax":1},"h11xydx":{"id":"h11xydx","value":0.17162741744380222,"inputLinkIds":["ocp36ke"],"shotCount":0,"connectedMacroIds":[],"sketchId":"et6x5w5","title":"Scale","type":"param","key":"scale","hidden":false,"min":0.00001,"max":4,"defaultMin":0.00001,"defaultMax":4,"openedLinkId":"ocp36ke","activeInputLinkId":"ocp36ke"},"ryf0wbv":{"id":"ryf0wbv","value":2,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"et6x5w5","title":"Mesh Index","type":"param","key":"meshIndex","hidden":true,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"l93f69i":{"id":"l93f69i","value":0,"inputLinkIds":[],"shotCount":2,"connectedMacroIds":[],"type":"shot","title":"Shape Shift","method":"shapeShift","sketchId":"et6x5w5"},"8du7bgf":{"id":"8du7bgf","value":0.5564516129032258,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"1r9rs1x","title":"Rotation Speed X","type":"param","key":"rotSpeedX","hidden":false,"min":-1,"max":1,"defaultMin":-1,"defaultMax":1},"339ae0r":{"id":"339ae0r","value":0.6451612903225806,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"1r9rs1x","title":"Rotation Speed Y","type":"param","key":"rotSpeedY","hidden":false,"min":-1,"max":1,"defaultMin":-1,"defaultMax":1},"ll3hb6r":{"id":"ll3hb6r","value":0.564516129032258,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"1r9rs1x","title":"Rotation Speed Z","type":"param","key":"rotSpeedZ","hidden":false,"min":-1,"max":1,"defaultMin":-1,"defaultMax":1},"e3gnt24":{"id":"e3gnt24","value":0.75,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"1r9rs1x","title":"Scale","type":"param","key":"scale","hidden":false,"min":0.00001,"max":4,"defaultMin":0.00001,"defaultMax":4},"xkxsl9s":{"id":"xkxsl9s","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"1r9rs1x","title":"Mesh Index","type":"param","key":"meshIndex","hidden":true,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"gl7anr9":{"id":"gl7anr9","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Shape Shift","method":"shapeShift","sketchId":"1r9rs1x"},"1lpiok9":{"id":"1lpiok9","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"99r0oju","sketchId":"qpvup3p","key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"9w03vvc":{"id":"9w03vvc","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"99r0oju","sketchId":"qpvup3p","key":"range","title":"Lower Range","passToNext":true,"subNode":true},"n5djtdo":{"id":"n5djtdo","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"99r0oju","sketchId":"qpvup3p","key":"range","title":"Upper Range","passToNext":false,"subNode":true},"up32bx4":{"id":"up32bx4","value":"sawtooth","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}],"sketchId":"qpvup3p","parentNodeId":"99r0oju"},"3jbdter":{"id":"3jbdter","value":0.03125,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}],"sketchId":"qpvup3p","parentNodeId":"99r0oju"},"yj1ralg":{"id":"yj1ralg","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true,"sketchId":"qpvup3p","parentNodeId":"99r0oju"},"buk5mgf":{"id":"buk5mgf","value":-1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Seed","key":"seed","type":"select","subNode":true,"options":[{"value":-1,"label":"auto"},{"value":0,"label":"0"},{"value":1,"label":"1"},{"value":2,"label":"2"},{"value":3,"label":"3"},{"value":4,"label":"4"},{"value":5,"label":"5"},{"value":6,"label":"6"},{"value":7,"label":"7"},{"value":8,"label":"8"},{"value":9,"label":"9"},{"value":10,"label":"10"},{"value":11,"label":"11"},{"value":12,"label":"12"},{"value":13,"label":"13"},{"value":14,"label":"14"},{"value":15,"label":"15"},{"value":16,"label":"16"},{"value":17,"label":"17"},{"value":18,"label":"18"},{"value":19,"label":"19"},{"value":20,"label":"20"},{"value":21,"label":"21"},{"value":22,"label":"22"},{"value":23,"label":"23"},{"value":24,"label":"24"}],"sketchId":"qpvup3p","parentNodeId":"99r0oju"},"we2weuw":{"id":"we2weuw","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","title":"Toggle Activate","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"g7tllci","linkId":"99r0oju"}},"sketchId":"qpvup3p","parentNodeId":"99r0oju"},"99r0oju":{"id":"99r0oju","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"lfo","type":"inputLink","input":{"id":"lfo"},"nodeId":"g7tllci","sketchId":"qpvup3p","parentNodeId":"g7tllci","nodeType":"param","modifierIds":["1lpiok9","9w03vvc","n5djtdo"],"lfoOptionIds":["up32bx4","3jbdter","yj1ralg","buk5mgf"],"midiOptionIds":[],"audioOptionIds":[],"linkableActions":{"toggleActivate":"we2weuw"},"linkType":"node","animOptionIds":[]},"ctirwnh":{"id":"ctirwnh","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"ocp36ke","sketchId":"et6x5w5","key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"oe77dmx":{"id":"oe77dmx","value":0.16304347826086957,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"ocp36ke","sketchId":"et6x5w5","key":"range","title":"Lower Range","passToNext":true,"subNode":true},"pe39gql":{"id":"pe39gql","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"ocp36ke","sketchId":"et6x5w5","key":"range","title":"Upper Range","passToNext":false,"subNode":true},"gtaq5hi":{"id":"gtaq5hi","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Audio Band","key":"audioBand","type":"select","subNode":true,"options":[{"value":0,"label":"Low"},{"value":1,"label":"Low-Mid"},{"value":2,"label":"Mid"},{"value":3,"label":"High"}],"sketchId":"et6x5w5","parentNodeId":"ocp36ke"},"kbgo5mx":{"id":"kbgo5mx","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","title":"Toggle Activate","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"h11xydx","linkId":"ocp36ke"}},"sketchId":"et6x5w5","parentNodeId":"ocp36ke"},"ocp36ke":{"id":"ocp36ke","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"audio","type":"inputLink","input":{"id":"audio"},"nodeId":"h11xydx","sketchId":"et6x5w5","parentNodeId":"h11xydx","nodeType":"param","modifierIds":["ctirwnh","oe77dmx","pe39gql"],"lfoOptionIds":[],"midiOptionIds":[],"audioOptionIds":["gtaq5hi"],"linkableActions":{"toggleActivate":"kbgo5mx"},"linkType":"node","animOptionIds":[]},"qf8hp3x":{"id":"qf8hp3x","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"p8bqii3","channel":"A"}},"title":"Add to A"},"xp62tyb":{"id":"xp62tyb","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"p8bqii3","channel":"B"}},"title":"Add to B"},"3agbd9u":{"id":"3agbd9u","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"p8bqii3","type":"active"}},"title":"Add to Active"},"cci8c70":{"id":"cci8c70","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"p8bqii3","type":"opposite"}},"title":"Add to Opposite"},"uloot60":{"id":"uloot60","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"SCENE_CLEAR_CHANNEL","payload":{"id":"p8bqii3"}},"title":"Clear"},"tlx02j4":{"id":"tlx02j4","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"tahpywu","title":"Opacity","type":"param","key":"opacity","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"re1ihmk":{"id":"re1ihmk","value":0.1015625,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"tahpywu","title":"Speed","type":"param","key":"speed","hidden":false,"min":-1,"max":1,"defaultMin":-1,"defaultMax":1}},"scenes":{"items":{"f1vwqkk":{"id":"f1vwqkk","title":"Geoms","selectedSketchId":"qpvup3p","sketchIds":["qpvup3p","et6x5w5","1r9rs1x"],"linkableActionIds":{"addToA":"h1n8xw8","addToB":"wa2fvtb","addToActive":"n25blwi","addToOpposite":"817xlww","clear":"2ag66pm"}},"p8bqii3":{"id":"p8bqii3","title":"Stars","selectedSketchId":"tahpywu","sketchIds":["tahpywu"],"linkableActionIds":{"addToA":"qf8hp3x","addToB":"xp62tyb","addToActive":"3agbd9u","addToOpposite":"cci8c70","clear":"uloot60"}}},"currentSceneId":"f1vwqkk","channels":{"A":"f1vwqkk","B":"p8bqii3"}},"sketches":{"qpvup3p":{"title":"Env","moduleId":"env","paramIds":["g7tllci","uh7mfhv","sjwc7eq"],"shotIds":[],"openedNodeId":"g7tllci"},"et6x5w5":{"title":"Inner","moduleId":"solid","paramIds":["6besnyv","cbo90q9","51up7yl","h11xydx","ryf0wbv"],"shotIds":["l93f69i"]},"1r9rs1x":{"title":"Outer","moduleId":"solid","paramIds":["8du7bgf","339ae0r","ll3hb6r","e3gnt24","xkxsl9s"],"shotIds":["gl7anr9"],"openedNodeId":"339ae0r"},"tahpywu":{"title":"Stars","moduleId":"stars","paramIds":["tlx02j4","re1ihmk"],"shotIds":[]}},"project":{"errors":[],"errorPopup":false},"inputs":{"audio":{"value":[0.18182960663259443,0.01025613512765978,0,0],"assignedLinkIds":["ocp36ke"]},"lfo":{"value":305.5,"assignedLinkIds":["99r0oju"]}},"inputLinks":{"nodeIds":[null]},"macros":{"learningId":false,"nodeIds":[]},"ui":{"panelWidths":{"left":50},"isEditing":false,"openedNode":false,"auxOpen":["sketchcat_simple"],"addSketchOpen":{}},"router":{"location":{"pathname":"/scenes/view","search":"","hash":"","key":"klskb5"}},"settings":{"clockGenerated":true,"clockBpm":120,"aspectW":16,"aspectH":9,"antialias":false,"throttledFPS":60,"watchSketchesDir":true},"form":{}}
diff --git a/example-projects/simple/sketches/env/config.js b/example-projects/simple/sketches/env/config.js
index 2750142a..a58994b0 100644
--- a/example-projects/simple/sketches/env/config.js
+++ b/example-projects/simple/sketches/env/config.js
@@ -1,20 +1,21 @@
module.exports = {
defaultTitle: 'Env',
+ category:'simple',
params: [
{
key: 'colorH',
title: 'BG Color H',
- defaultValue: 0
+ defaultValue: 0,
},
{
key: 'colorS',
title: 'BG Color S',
- defaultValue: 0
+ defaultValue: 0,
},
{
key: 'colorL',
title: 'BG Color L',
- defaultValue: 0
- }
- ]
+ defaultValue: 0,
+ },
+ ],
}
diff --git a/example-projects/simple/sketches/env/index.js b/example-projects/simple/sketches/env/index.js
index 545cd17b..9e98f445 100644
--- a/example-projects/simple/sketches/env/index.js
+++ b/example-projects/simple/sketches/env/index.js
@@ -1,5 +1,3 @@
-const THREE = require('three')
-
class Env {
constructor (scene) {
this.scene = scene.scene
diff --git a/example-projects/simple/sketches/solid/config.js b/example-projects/simple/sketches/solid/config.js
index 983de09f..3ec61cf2 100644
--- a/example-projects/simple/sketches/solid/config.js
+++ b/example-projects/simple/sketches/solid/config.js
@@ -5,6 +5,8 @@
module.exports = {
// Default title when sketch is loaded in (can be changed by user)
defaultTitle: 'Solid',
+ // Collapsable category for this sketch to be grouped under
+ category:'simple',
// Params are values between 0 and 1 that can be manipulated by the user
// these values are sent to the sketch every frame
// e.g. Speed, scale, colour
@@ -12,35 +14,46 @@ module.exports = {
{
key: 'rotSpeedX', // needs to be unique
title: 'Rotation Speed X', // should be human
- defaultValue: 0 // must be between 0 and 1
+ defaultValue: 0.5, // must be between 0 and 1
+ defaultMin: -1,
+ defaultMax: 1,
},
{
key: 'rotSpeedY',
title: 'Rotation Speed Y',
- defaultValue: 0
+ defaultValue: 0.5,
+ defaultMin: -1,
+ defaultMax: 1,
},
{
key: 'rotSpeedZ',
title: 'Rotation Speed Z',
- defaultValue: 0
+ defaultValue: 0.5,
+ defaultMin: -1,
+ defaultMax: 1,
},
{
key: 'scale',
title: 'Scale',
- defaultValue: 0.5
+ defaultValue: 0.5,
+ defaultMin: 0.00001,
+ defaultMax: 4,
},
{
key: 'meshIndex',
title: 'Mesh Index',
- defaultValue: 0
- }
+ defaultValue: 0,
+ // meshIndex is changed by the shapeShift shot and not something
+ // the user needs to view/edit, so we set hidden:true
+ hidden: true,
+ },
],
// Shots are single functions that can fire, as opposed to values that change
// e.g. Explosions, Pre-defined animations
shots: [
{
method: 'shapeShift', // needs to be unique
- title: 'Shape Shift' // should be human
- }
- ]
+ title: 'Shape Shift', // should be human
+ },
+ ],
}
diff --git a/example-projects/simple/sketches/solid/index.js b/example-projects/simple/sketches/solid/index.js
index eec0143d..14bc5230 100644
--- a/example-projects/simple/sketches/solid/index.js
+++ b/example-projects/simple/sketches/solid/index.js
@@ -4,11 +4,6 @@ A polyhedron that can spin on all axes. The user can change the speed of the rot
The user can change the scale. The user can also click on "shapeshift" and the geometry changes.
**/
-/** HEDRON TIP **
- Hedron uses three.js, so you'll need that :)
-**/
-const THREE = require('three')
-
/** HEDRON TIP **
Hedron sketches must be a class
**/
@@ -25,12 +20,12 @@ class Solid {
params - The sketch params when the sketch first initialises
**/
- constructor (scene, meta, params) {
+ constructor (scene, params, meta) {
/** HEDRON TIP **
Must define a "root" property as a THREE.Group or THREE.Object3D
Hedron looks for this and will add it to the scene.
**/
- this.root = new THREE.Group()
+ this.root = new THREE.Group() // THREE is a global var, so no need to import
/** HEDRON TIP **
It's good practice to not manipulate the root object
@@ -47,7 +42,7 @@ class Solid {
const mat = new THREE.MeshBasicMaterial(
{ wireframe: true, color: 0xffffff }
)
- const size = 300
+ const size = 1
// Array geometries (the platonic solids!)
const geoms = [
@@ -55,7 +50,7 @@ class Solid {
new THREE.BoxGeometry(size, size, size),
new THREE.OctahedronGeometry(size),
new THREE.TetrahedronGeometry(size),
- new THREE.DodecahedronGeometry(size)
+ new THREE.DodecahedronGeometry(size),
]
// Loop through meshes
@@ -104,7 +99,6 @@ class Solid {
this.group.rotation.z += params.rotSpeedZ * baseSpeed * frameDiff
// Change scale using params.scale
- params.scale = Math.max(params.scale * 4, 0.00001)
this.group.scale.set(params.scale, params.scale, params.scale)
}
@@ -148,6 +142,7 @@ class Solid {
Use the destructor method to do anything when the sketch is deleted
**/
destructor () {
+ // eslint-disable-next-line no-console
console.log('Solid sketch deleted!')
}
}
diff --git a/example-projects/simple/sketches/stars/config.js b/example-projects/simple/sketches/stars/config.js
index 6959d4a8..8203134d 100644
--- a/example-projects/simple/sketches/stars/config.js
+++ b/example-projects/simple/sketches/stars/config.js
@@ -1,17 +1,20 @@
module.exports = {
defaultTitle: 'Stars',
+ category:'simple',
params: [
{
title: 'Opacity',
key: 'opacity',
- defaultValue: 1
+ defaultValue: 1,
},
{
title: 'Speed',
key: 'speed',
- defaultValue: 0.5
- }
+ defaultValue: 0.5,
+ defaultMin: -1,
+ defaultMax: 1,
+ },
],
shots: [
- ]
+ ],
}
diff --git a/example-projects/simple/sketches/stars/index.js b/example-projects/simple/sketches/stars/index.js
index fa062c44..ba6f6c4b 100644
--- a/example-projects/simple/sketches/stars/index.js
+++ b/example-projects/simple/sketches/stars/index.js
@@ -1,8 +1,6 @@
/** HEDRON TIP **
Look in "example-projects/simple/sketches/solid" for info on how to create sketches
**/
-const THREE = require('three')
-
const range = 10000
const particleCount = 1800
@@ -17,11 +15,11 @@ class Stars {
this.material = new THREE.PointsMaterial({
color: 0xFFFFFF,
size: 10,
- transparent: true
+ transparent: true,
})
// now create the individual particles
- for (var p = 0; p < particleCount; p++) {
+ for (let p = 0; p < particleCount; p++) {
// create a particle with random position
const pX = randomInRange()
const pY = randomInRange()
@@ -35,9 +33,9 @@ class Stars {
// create the particle system
this.particleSystem = new THREE.Points(
- this.particles,
- this.material
- )
+ this.particles,
+ this.material
+ )
// add it to the scene
this.root.add(this.particleSystem)
@@ -63,7 +61,7 @@ class Stars {
}
// and the position
- particle.z += particle.velocity.z * ((p.speed * 2) - 1)
+ particle.z += particle.velocity.z * p.speed
// flag to the particle system
// that we've changed its vertices.
diff --git a/example-projects/trig/project.json b/example-projects/trig/project.json
index 7e2a6419..519309a7 100644
--- a/example-projects/trig/project.json
+++ b/example-projects/trig/project.json
@@ -1 +1 @@
-{"nodes":{"sceneCrossfader":{"id":"sceneCrossfader","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Scene Crossfader","type":"param"},"viewerMode":{"id":"viewerMode","value":"mix","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Viewer Mode","type":"select","options":[{"value":"mix","label":"Mix"},{"value":"A","label":"A"},{"value":"B","label":"B"}]},"audioNormalizeLevels":{"id":"audioNormalizeLevels","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Normalize Levels","type":"param"},"audioLevelsFalloff":{"id":"audioLevelsFalloff","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Falloff","type":"param"},"4127fmo":{"id":"4127fmo","value":0.004277569313096086,"inputLinkIds":["26gjlp1"],"shotCount":0,"connectedMacroIds":[],"title":"Pos X","type":"param","key":"posX","openedLinkId":"26gjlp1","activeInputLinkId":"26gjlp1"},"1tuv4x5":{"id":"1tuv4x5","value":0.4369348682670615,"inputLinkIds":["iv80n1l"],"shotCount":0,"connectedMacroIds":[],"title":"Pos Y","type":"param","key":"posY","openedLinkId":"iv80n1l","activeInputLinkId":"iv80n1l"},"wdhgvg2":{"id":"wdhgvg2","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Pos Z","type":"param","key":"posZ"},"71ftemb":{"id":"71ftemb","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"grm7m9i":{"id":"grm7m9i","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Lower Range","passToNext":true,"subNode":true},"fsdfv7n":{"id":"fsdfv7n","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Upper Range","passToNext":false,"subNode":true},"3meb0s9":{"id":"3meb0s9","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}]},"e0tqe94":{"id":"e0tqe94","value":0.25,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}]},"8ku58x7":{"id":"8ku58x7","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true},"acbon8j":{"id":"acbon8j","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"b8yb2ym":{"id":"b8yb2ym","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Lower Range","passToNext":true,"subNode":true},"abb5anj":{"id":"abb5anj","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Upper Range","passToNext":false,"subNode":true},"6e1mta6":{"id":"6e1mta6","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}]},"72p8iov":{"id":"72p8iov","value":0.25,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}]},"3dpgn03":{"id":"3dpgn03","value":0.25,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true}},"scenes":{"items":{"doajdmy":{"id":"doajdmy","title":"Circle","selectedSketchId":"v66udcf","sketchIds":["v66udcf"],"linkableActionIds":{"addToA":"bxrvwbs","addToB":"lh468lq","addToActive":"4uw4m8l","addToOpposite":"j27mose","clear":"u566l3e"}}},"currentSceneId":"doajdmy","channels":{"A":"doajdmy","B":false}},"sketches":{"v66udcf":{"title":"Point","moduleId":"point","paramIds":["4127fmo","1tuv4x5","wdhgvg2"],"shotIds":[],"openedNodes":{"param":"1tuv4x5"}}},"project":{"filePath":"/Users/alex/Sites/GitHub/hedron/example-projects/trig/project.json","sketchesPath":"/Users/alex/Sites/GitHub/hedron/example-projects/trig/sketches","errors":[],"errorPopup":false},"inputs":{"audio_0":{"value":0.09192983671719823,"assignedLinkIds":[]},"audio_1":{"value":0.3920417479652838,"assignedLinkIds":[]},"audio_2":{"value":0.2800157346788512,"assignedLinkIds":[]},"audio_3":{"value":0.31956442755083536,"assignedLinkIds":[]},"lfo":{"value":218.91666666666666,"assignedLinkIds":["26gjlp1","iv80n1l"]}},"inputLinks":{"26gjlp1":{"title":"lfo","input":{"id":"lfo"},"id":"26gjlp1","nodeId":"4127fmo","nodeType":"param","modifierIds":["71ftemb","grm7m9i","fsdfv7n"],"lfoOptionIds":["3meb0s9","e0tqe94","8ku58x7"],"midiOptionIds":[],"linkableActions":{"toggleActivate":"27wt27g"},"linkType":"node"},"iv80n1l":{"title":"lfo","input":{"id":"lfo"},"id":"iv80n1l","nodeId":"1tuv4x5","nodeType":"param","modifierIds":["acbon8j","b8yb2ym","abb5anj"],"lfoOptionIds":["6e1mta6","72p8iov","3dpgn03"],"midiOptionIds":[],"linkableActions":{"toggleActivate":"p95mpjp"},"linkType":"node"}},"linkableActions":{"bxrvwbs":{"id":"bxrvwbs","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"doajdmy","channel":"A"}},"inputLinkIds":[]},"lh468lq":{"id":"lh468lq","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"doajdmy","channel":"B"}},"inputLinkIds":[]},"4uw4m8l":{"id":"4uw4m8l","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"doajdmy","type":"active"}},"inputLinkIds":[]},"j27mose":{"id":"j27mose","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"doajdmy","type":"opposite"}},"inputLinkIds":[]},"u566l3e":{"id":"u566l3e","action":{"type":"SCENE_CLEAR_CHANNEL","payload":{"id":"doajdmy"}},"inputLinkIds":[]},"27wt27g":{"id":"27wt27g","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"4127fmo","linkId":"26gjlp1"}},"inputLinkIds":[]},"p95mpjp":{"id":"p95mpjp","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"1tuv4x5","linkId":"iv80n1l"}},"inputLinkIds":[]}},"macros":{"learningId":false,"items":{}},"ui":{"panelWidths":{"left":39.47906026557712},"isEditing":false,"openedNode":false},"router":{"location":{"pathname":"/scenes/view/doajdmy","search":"","hash":"","key":"le4hx2"}},"settings":{"clockGenerated":true,"clockBpm":120,"aspectW":16,"aspectH":9,"antialias":false,"throttledFPS":60},"form":{}}
+{"nodes":{"sceneCrossfader":{"id":"sceneCrossfader","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Scene Crossfader","type":"param"},"viewerMode":{"id":"viewerMode","value":"mix","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Viewer Mode","type":"select","options":[{"value":"mix","label":"Mix"},{"value":"A","label":"A"},{"value":"B","label":"B"}]},"sketchOrganization":{"id":"sketchOrganization","value":"category","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Sketch Organization","type":"select","options":[{"value":"folder","label":"Folder"},{"value":"category","label":"Category"},{"value":"author","label":"Author"}]},"audioLevelsFalloff":{"id":"audioLevelsFalloff","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Falloff","type":"param"},"audioLevelsPower":{"id":"audioLevelsPower","value":0.25,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Power","type":"param","min":0.5,"max":3},"audioLevelsSmoothing":{"id":"audioLevelsSmoothing","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Smoothing","type":"param"},"audioNormalizeLevels":{"id":"audioNormalizeLevels","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Normalize Levels","type":"param"},"audioNormalizeRangeFalloff":{"id":"audioNormalizeRangeFalloff","value":0.01,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Normalized Range Falloff","type":"param"},"0q5g8o9":{"id":"0q5g8o9","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"03i6pnt","channel":"A"}},"title":"Add to A"},"5ordnaq":{"id":"5ordnaq","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"03i6pnt","channel":"B"}},"title":"Add to B"},"w77snsi":{"id":"w77snsi","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"03i6pnt","type":"active"}},"title":"Add to Active"},"ewg6lsv":{"id":"ewg6lsv","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"03i6pnt","type":"opposite"}},"title":"Add to Opposite"},"eotcf9u":{"id":"eotcf9u","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","action":{"type":"SCENE_CLEAR_CHANNEL","payload":{"id":"03i6pnt"}},"title":"Clear"},"4u8v39a":{"id":"4u8v39a","value":0.6913417161825233,"inputLinkIds":["3uqd8y8"],"shotCount":0,"connectedMacroIds":[],"sketchId":"twtate1","title":"Pos X","type":"param","key":"posX","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1,"openedLinkId":"3uqd8y8","activeInputLinkId":"3uqd8y8"},"6hsv6jb":{"id":"6hsv6jb","value":0.9619397662556425,"inputLinkIds":["1xl746m"],"shotCount":0,"connectedMacroIds":[],"sketchId":"twtate1","title":"Pos Y","type":"param","key":"posY","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1,"openedLinkId":"1xl746m","activeInputLinkId":"1xl746m"},"coqi875":{"id":"coqi875","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"sketchId":"twtate1","title":"Pos Z","type":"param","key":"posZ","hidden":false,"min":0,"max":1,"defaultMin":0,"defaultMax":1},"wq22umi":{"id":"wq22umi","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"3uqd8y8","sketchId":"twtate1","key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"vdm6b2i":{"id":"vdm6b2i","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"3uqd8y8","sketchId":"twtate1","key":"range","title":"Lower Range","passToNext":true,"subNode":true},"kki76ro":{"id":"kki76ro","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"3uqd8y8","sketchId":"twtate1","key":"range","title":"Upper Range","passToNext":false,"subNode":true},"s2lgnmd":{"id":"s2lgnmd","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}],"sketchId":"twtate1","parentNodeId":"3uqd8y8"},"xirv410":{"id":"xirv410","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}],"sketchId":"twtate1","parentNodeId":"3uqd8y8"},"f8rh73k":{"id":"f8rh73k","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true,"sketchId":"twtate1","parentNodeId":"3uqd8y8"},"1u5nbvy":{"id":"1u5nbvy","value":-1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Seed","key":"seed","type":"select","subNode":true,"options":[{"value":-1,"label":"auto"},{"value":0,"label":"0"},{"value":1,"label":"1"},{"value":2,"label":"2"},{"value":3,"label":"3"},{"value":4,"label":"4"},{"value":5,"label":"5"},{"value":6,"label":"6"},{"value":7,"label":"7"},{"value":8,"label":"8"},{"value":9,"label":"9"},{"value":10,"label":"10"},{"value":11,"label":"11"},{"value":12,"label":"12"},{"value":13,"label":"13"},{"value":14,"label":"14"},{"value":15,"label":"15"},{"value":16,"label":"16"},{"value":17,"label":"17"},{"value":18,"label":"18"},{"value":19,"label":"19"},{"value":20,"label":"20"},{"value":21,"label":"21"},{"value":22,"label":"22"},{"value":23,"label":"23"},{"value":24,"label":"24"}],"sketchId":"twtate1","parentNodeId":"3uqd8y8"},"bbwdc3b":{"id":"bbwdc3b","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","title":"Toggle Activate","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"4u8v39a","linkId":"3uqd8y8"}},"sketchId":"twtate1","parentNodeId":"3uqd8y8"},"3uqd8y8":{"id":"3uqd8y8","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"lfo","type":"inputLink","input":{"id":"lfo"},"nodeId":"4u8v39a","sketchId":"twtate1","parentNodeId":"4u8v39a","nodeType":"param","modifierIds":["wq22umi","vdm6b2i","kki76ro"],"lfoOptionIds":["s2lgnmd","xirv410","f8rh73k","1u5nbvy"],"midiOptionIds":[],"audioOptionIds":[],"linkableActions":{"toggleActivate":"bbwdc3b"},"linkType":"node","animOptionIds":[]},"e59hju5":{"id":"e59hju5","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"1xl746m","sketchId":"twtate1","key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"0pjakm3":{"id":"0pjakm3","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"1xl746m","sketchId":"twtate1","key":"range","title":"Lower Range","passToNext":true,"subNode":true},"qthetc4":{"id":"qthetc4","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"parentNodeId":"1xl746m","sketchId":"twtate1","key":"range","title":"Upper Range","passToNext":false,"subNode":true},"3w69bw9":{"id":"3w69bw9","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}],"sketchId":"twtate1","parentNodeId":"1xl746m"},"vovli0y":{"id":"vovli0y","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}],"sketchId":"twtate1","parentNodeId":"1xl746m"},"nf5g5vi":{"id":"nf5g5vi","value":0.25,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true,"sketchId":"twtate1","parentNodeId":"1xl746m"},"e95kvg8":{"id":"e95kvg8","value":-1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Seed","key":"seed","type":"select","subNode":true,"options":[{"value":-1,"label":"auto"},{"value":0,"label":"0"},{"value":1,"label":"1"},{"value":2,"label":"2"},{"value":3,"label":"3"},{"value":4,"label":"4"},{"value":5,"label":"5"},{"value":6,"label":"6"},{"value":7,"label":"7"},{"value":8,"label":"8"},{"value":9,"label":"9"},{"value":10,"label":"10"},{"value":11,"label":"11"},{"value":12,"label":"12"},{"value":13,"label":"13"},{"value":14,"label":"14"},{"value":15,"label":"15"},{"value":16,"label":"16"},{"value":17,"label":"17"},{"value":18,"label":"18"},{"value":19,"label":"19"},{"value":20,"label":"20"},{"value":21,"label":"21"},{"value":22,"label":"22"},{"value":23,"label":"23"},{"value":24,"label":"24"}],"sketchId":"twtate1","parentNodeId":"1xl746m"},"3wac4ru":{"id":"3wac4ru","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"linkableAction","title":"Toggle Activate","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"6hsv6jb","linkId":"1xl746m"}},"sketchId":"twtate1","parentNodeId":"1xl746m"},"1xl746m":{"id":"1xl746m","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"lfo","type":"inputLink","input":{"id":"lfo"},"nodeId":"6hsv6jb","sketchId":"twtate1","parentNodeId":"6hsv6jb","nodeType":"param","modifierIds":["e59hju5","0pjakm3","qthetc4"],"lfoOptionIds":["3w69bw9","vovli0y","nf5g5vi","e95kvg8"],"midiOptionIds":[],"audioOptionIds":[],"linkableActions":{"toggleActivate":"3wac4ru"},"linkType":"node","animOptionIds":[]}},"scenes":{"items":{"03i6pnt":{"id":"03i6pnt","title":"Point","selectedSketchId":"twtate1","sketchIds":["twtate1"],"linkableActionIds":{"addToA":"0q5g8o9","addToB":"5ordnaq","addToActive":"w77snsi","addToOpposite":"ewg6lsv","clear":"eotcf9u"}}},"currentSceneId":"03i6pnt","channels":{"A":"03i6pnt","B":false}},"sketches":{"twtate1":{"title":"Point","moduleId":"point","paramIds":["4u8v39a","6hsv6jb","coqi875"],"shotIds":[]}},"project":{"errors":[],"errorPopup":false},"inputs":{"audio":{"value":[0.2792073732718575,0.18485977384321212,0.22962028748828678,0.21285002514756501],"assignedLinkIds":[]},"lfo":{"value":198.125,"assignedLinkIds":["3uqd8y8","1xl746m"]}},"inputLinks":{"nodeIds":[null]},"macros":{"learningId":false,"nodeIds":[]},"ui":{"panelWidths":{"left":50},"isEditing":false,"openedNode":false,"auxOpen":[],"addSketchOpen":{}},"router":{"location":{"pathname":"/scenes/view/03i6pnt","search":"","hash":"","key":"ndr5ru"}},"settings":{"clockGenerated":true,"clockBpm":120,"aspectW":16,"aspectH":9,"antialias":false,"throttledFPS":60,"watchSketchesDir":true},"form":{}}
diff --git a/example-projects/trig/sketches/point/config.js b/example-projects/trig/sketches/point/config.js
index 010c4ed3..21b4adb2 100644
--- a/example-projects/trig/sketches/point/config.js
+++ b/example-projects/trig/sketches/point/config.js
@@ -12,19 +12,19 @@ module.exports = {
{
key: 'posX', // needs to be unique
title: 'Pos X', // should be human
- defaultValue: 0.5 // must be between 0 and 1
+ defaultValue: 0.5, // must be between 0 and 1
},
{
key: 'posY',
title: 'Pos Y',
- defaultValue: 0.5
+ defaultValue: 0.5,
},
{
key: 'posZ',
title: 'Pos Z',
- defaultValue: 0.5
- }
+ defaultValue: 0.5,
+ },
],
shots: [
- ]
+ ],
}
diff --git a/example-projects/trig/sketches/point/index.js b/example-projects/trig/sketches/point/index.js
index 364ecb38..9b96a0c9 100644
--- a/example-projects/trig/sketches/point/index.js
+++ b/example-projects/trig/sketches/point/index.js
@@ -1,10 +1,7 @@
-const THREE = require('three')
-
class Point {
-
- constructor (scene, meta, params) {
+ constructor () {
this.root = new THREE.Group()
- const geom = new THREE.IcosahedronGeometry(100)
+ const geom = new THREE.IcosahedronGeometry(0.5)
const mat = new THREE.MeshNormalMaterial()
this.mesh = new THREE.Mesh(geom, mat)
@@ -12,13 +9,12 @@ class Point {
}
update (params, time, frameDiff, allParams) {
- const rad = 1500
+ const rad = 5
this.mesh.position.x = (rad * params.posX) - rad / 2
this.mesh.position.y = (rad * params.posY) - rad / 2
this.mesh.position.z = (rad * params.posZ) - rad / 2
}
-
}
module.exports = Point
diff --git a/example-projects/trippy/project.json b/example-projects/trippy/project.json
deleted file mode 100644
index 7912f433..00000000
--- a/example-projects/trippy/project.json
+++ /dev/null
@@ -1 +0,0 @@
-{"nodes":{"sceneCrossfader":{"id":"sceneCrossfader","value":0.01366120218579231,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Scene Crossfader","type":"param"},"viewerMode":{"id":"viewerMode","value":"mix","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Viewer Mode","type":"select","options":[{"value":"mix","label":"Mix"},{"value":"A","label":"A"},{"value":"B","label":"B"}]},"audioNormalizeLevels":{"id":"audioNormalizeLevels","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Normalize Levels","type":"param"},"audioLevelsFalloff":{"id":"audioLevelsFalloff","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Levels Falloff","type":"param"},"0s6lvul":{"id":"0s6lvul","value":0.5778388278388278,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Z Speed","type":"param","key":"zSpeed"},"vei9jws":{"id":"vei9jws","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Tunnel Scale","type":"param","key":"tunnelScale"},"usb304w":{"id":"usb304w","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rot Speed","type":"param","key":"rotSpeed"},"hdp7xd1":{"id":"hdp7xd1","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rot Tween Speed","type":"param","key":"rotTweenSpeed"},"7cuaqas":{"id":"7cuaqas","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Block Shift Speed","type":"param","key":"blockShiftSpeed"},"ypj20pn":{"id":"ypj20pn","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Block Spin Speed","type":"param","key":"blockSpinSpeed"},"ftuvkhp":{"id":"ftuvkhp","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Perlin Speed","type":"param","key":"perlinSpeed"},"928kfik":{"id":"928kfik","value":0.9997322937381838,"inputLinkIds":["mdqy0x9"],"shotCount":0,"connectedMacroIds":[],"title":"color H","type":"param","key":"colorH","openedLinkId":"mdqy0x9","activeInputLinkId":"mdqy0x9"},"oekq70k":{"id":"oekq70k","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"color S","type":"param","key":"colorS"},"kb2byt3":{"id":"kb2byt3","value":0.5192307692307692,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"color L","type":"param","key":"colorL"},"2rkglfv":{"id":"2rkglfv","value":0,"inputLinkIds":["y91yr74"],"shotCount":343,"connectedMacroIds":[],"type":"shot","title":"Quarter Turn","method":"quarterTurn","sketchId":"4mipx19","openedLinkId":"y91yr74","activeInputLinkId":"y91yr74"},"utd7ext":{"id":"utd7ext","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Remove Blocks","method":"removeBlocks","sketchId":"4mipx19"},"covtc3r":{"id":"covtc3r","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Add Blocks","method":"addBlocks","sketchId":"4mipx19"},"tcyawv3":{"id":"tcyawv3","value":0,"inputLinkIds":["pqbp3yc"],"shotCount":336,"connectedMacroIds":[],"type":"shot","title":"Shift Blocks","method":"shiftBlocks","sketchId":"4mipx19","openedLinkId":"pqbp3yc","activeInputLinkId":"pqbp3yc"},"n6u2rgu":{"id":"n6u2rgu","value":0,"inputLinkIds":["oglnu99"],"shotCount":328,"connectedMacroIds":[],"type":"shot","title":"Spin Blocks","method":"spinBlocks","sketchId":"4mipx19","openedLinkId":"oglnu99","activeInputLinkId":"oglnu99"},"6bcuie8":{"id":"6bcuie8","value":0,"inputLinkIds":["ngb783x"],"shotCount":625,"connectedMacroIds":[],"type":"shot","title":"Flash Blocks","method":"flashBlocks","sketchId":"4mipx19","openedLinkId":"ngb783x","activeInputLinkId":"ngb783x"},"9h704ki":{"id":"9h704ki","value":0,"inputLinkIds":[],"shotCount":6,"connectedMacroIds":[],"type":"shot","title":"Boosted Flash Blocks","method":"boostedFlashBlocks","sketchId":"4mipx19","activeInputLinkId":"yydl896"},"a4dx8hv":{"id":"a4dx8hv","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Flash All On","method":"flashAllBlocksOn","sketchId":"4mipx19"},"yx0bq36":{"id":"yx0bq36","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Flash All Off","method":"flashAllBlocksOff","sketchId":"4mipx19"},"cl04jaf":{"id":"cl04jaf","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Pipes On","method":"pipesOn","sketchId":"4mipx19"},"fq7lx8b":{"id":"fq7lx8b","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Pipes Off","method":"pipesOff","sketchId":"4mipx19"},"1e6sq5r":{"id":"1e6sq5r","value":0.5935977586707601,"inputLinkIds":["har1p3h"],"shotCount":4369,"connectedMacroIds":[],"type":"shot","title":"Pipes Swap","method":"pipesSwap","sketchId":"4mipx19","openedLinkId":"har1p3h","activeInputLinkId":"har1p3h"},"913i7q9":{"id":"913i7q9","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Pipes All On","method":"pipesAllOn","sketchId":"4mipx19"},"di0yss4":{"id":"di0yss4","value":0.0269429365814908,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Fog Density","type":"param","key":"fogDensity"},"j5obnao":{"id":"j5obnao","value":0.29120879120879106,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"BG Color H","type":"param","key":"colorH"},"1ic3j5e":{"id":"1ic3j5e","value":0.19230769230769232,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"BG Color S","type":"param","key":"colorS"},"b52kkui":{"id":"b52kkui","value":0.2032967032967033,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"BG Color L","type":"param","key":"colorL"},"0gbvtty":{"id":"0gbvtty","value":0.027472527472527472,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Main Light Intensity","type":"param","key":"mainLightIntensity"},"j52vm6n":{"id":"j52vm6n","value":0.43131868131868134,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Central Point Light Distance","type":"param","key":"centralPointLightDistance"},"fg8t2s1":{"id":"fg8t2s1","value":0.07967032967032969,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Central Point Light Intensity","type":"param","key":"centralPointLightIntensity"},"rfs0r6r":{"id":"rfs0r6r","value":0.5934065934065934,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Central Point Light Color H","type":"param","key":"centralPointLightH"},"pvrhqxy":{"id":"pvrhqxy","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Central Point Light Color S","type":"param","key":"centralPointLightS"},"p30aooi":{"id":"p30aooi","value":0.510989010989011,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Central Point Light Color L","type":"param","key":"centralPointLightL"},"qgb5nue":{"id":"qgb5nue","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Camera 1","method":"camera1","sketchId":"ocqps2s"},"nn10yhi":{"id":"nn10yhi","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Camera 2","method":"camera2","sketchId":"ocqps2s"},"484bbb6":{"id":"484bbb6","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Camera 3","method":"camera3","sketchId":"ocqps2s"},"l7hv666":{"id":"l7hv666","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Camera Random","method":"cameraRandom","sketchId":"ocqps2s"},"nap0vp4":{"id":"nap0vp4","value":0.07967032967032966,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Pos Z","type":"param","key":"posZ"},"5a03ptw":{"id":"5a03ptw","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rot Speed X","type":"param","key":"rotSpeedX"},"9sqssm7":{"id":"9sqssm7","value":0.4606227106227106,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rot Speed Y","type":"param","key":"rotSpeedY"},"y45y8v3":{"id":"y45y8v3","value":0.5164835164835165,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rot Speed Z","type":"param","key":"rotSpeedZ"},"kvcndvn":{"id":"kvcndvn","value":0.5141941391941391,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Blob Speed","type":"param","key":"blobSpeed"},"5xblfei":{"id":"5xblfei","value":0.1291208791208791,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Num Blobs","type":"param","key":"numBlobs"},"pyam4a5":{"id":"pyam4a5","value":0.7454212454212454,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Blob Strength","type":"param","key":"blobStrength"},"vh3fvwa":{"id":"vh3fvwa","value":0,"inputLinkIds":[],"shotCount":3,"connectedMacroIds":[],"type":"shot","title":"Spin","method":"spin","sketchId":"ur1s211"},"t57i74c":{"id":"t57i74c","value":0,"inputLinkIds":["8rqkjit"],"shotCount":1115,"connectedMacroIds":[],"type":"shot","title":"Update Reflection","method":"updateReflection","sketchId":"ur1s211","openedLinkId":"8rqkjit","activeInputLinkId":"8rqkjit"},"sxkn122":{"id":"sxkn122","value":0.10000000000000003,"inputLinkIds":["efw1t57"],"shotCount":0,"connectedMacroIds":[],"title":"Pos Z","type":"param","key":"posZ","openedLinkId":"efw1t57","activeInputLinkId":"efw1t57"},"59iwl0f":{"id":"59iwl0f","value":0.5224358974358975,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rot Speed X","type":"param","key":"rotSpeedX"},"h79kdes":{"id":"h79kdes","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rot Speed Y","type":"param","key":"rotSpeedY"},"inr1ca9":{"id":"inr1ca9","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rot Speed Z","type":"param","key":"rotSpeedZ"},"y82phdn":{"id":"y82phdn","value":0.5512820512820513,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Blob Speed","type":"param","key":"blobSpeed"},"wysadp0":{"id":"wysadp0","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Num Blobs","type":"param","key":"numBlobs"},"yf31edd":{"id":"yf31edd","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Blob Strength","type":"param","key":"blobStrength"},"59sl06n":{"id":"59sl06n","value":0,"inputLinkIds":["8ciljw6"],"shotCount":1585,"connectedMacroIds":[],"type":"shot","title":"Spin","method":"spin","sketchId":"scpeype","openedLinkId":"8ciljw6","activeInputLinkId":"8ciljw6"},"o2y3foc":{"id":"o2y3foc","value":0,"inputLinkIds":["yicpwlx"],"shotCount":1572,"connectedMacroIds":[],"type":"shot","title":"Update Reflection","method":"updateReflection","sketchId":"scpeype","openedLinkId":"yicpwlx","activeInputLinkId":"yicpwlx"},"kvrxcg0":{"id":"kvrxcg0","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Fog Density","type":"param","key":"fogDensity"},"k8v9w13":{"id":"k8v9w13","value":0.4672984353849878,"inputLinkIds":["4cd69xv"],"shotCount":0,"connectedMacroIds":[],"title":"BG Color H","type":"param","key":"colorH","openedLinkId":"4cd69xv","activeInputLinkId":"4cd69xv"},"qp1gg1m":{"id":"qp1gg1m","value":0.6217948717948718,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"BG Color S","type":"param","key":"colorS"},"ck7fo50":{"id":"ck7fo50","value":0.5082417582417582,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"BG Color L","type":"param","key":"colorL"},"yy8kmye":{"id":"yy8kmye","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Main Light Intensity","type":"param","key":"mainLightIntensity"},"jfe9qam":{"id":"jfe9qam","value":0.5,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Central Point Light Distance","type":"param","key":"centralPointLightDistance"},"kgxq8f6":{"id":"kgxq8f6","value":0.5384615384615384,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Central Point Light Intensity","type":"param","key":"centralPointLightIntensity"},"sbv7x5e":{"id":"sbv7x5e","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Central Point Light Color H","type":"param","key":"centralPointLightH"},"e79i3yp":{"id":"e79i3yp","value":0.625,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Central Point Light Color S","type":"param","key":"centralPointLightS"},"wf1iwh0":{"id":"wf1iwh0","value":0.02564102564102566,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Central Point Light Color L","type":"param","key":"centralPointLightL"},"jv28hwm":{"id":"jv28hwm","value":0,"inputLinkIds":[],"shotCount":3,"connectedMacroIds":[],"type":"shot","title":"Camera 1","method":"camera1","sketchId":"t9k44bf"},"98uw21m":{"id":"98uw21m","value":0,"inputLinkIds":[],"shotCount":2,"connectedMacroIds":[],"type":"shot","title":"Camera 2","method":"camera2","sketchId":"t9k44bf"},"yn73iwy":{"id":"yn73iwy","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"type":"shot","title":"Camera 3","method":"camera3","sketchId":"t9k44bf"},"c7ol1m3":{"id":"c7ol1m3","value":0,"inputLinkIds":[],"shotCount":5,"connectedMacroIds":[],"type":"shot","title":"Camera Random","method":"cameraRandom","sketchId":"t9k44bf"},"46oelft":{"id":"46oelft","value":[0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[]},"3qvmm8l":{"id":"3qvmm8l","value":[0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[]},"m8huxne":{"id":"m8huxne","value":"triangle","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"}]},"316tj0s":{"id":"316tj0s","value":0.0625,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}]},"vyhlvqd":{"id":"vyhlvqd","value":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[]},"6dn9dvu":{"id":"6dn9dvu","value":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[]},"o3w2eld":{"id":"o3w2eld","value":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[]},"s7bmq4p":{"id":"s7bmq4p","value":[0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[]},"jwq6wgd":{"id":"jwq6wgd","value":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[]},"uomtkk7":{"id":"uomtkk7","value":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[]},"koeh596":{"id":"koeh596","value":[1,0,0,1,1,0,0,0,1,1,1,0,0,0,1,0,1,1,1,0,0,0,1,1,1,0,1,0,0,1,0,0],"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[]},"hc2qon7":{"id":"hc2qon7","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"qsf8bda":{"id":"qsf8bda","value":0.10000000000000003,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Lower Range","passToNext":true,"subNode":true},"i69mg9x":{"id":"i69mg9x","value":0.7434782608695651,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Upper Range","passToNext":false,"subNode":true},"ih4jeua":{"id":"ih4jeua","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"}]},"f7ot6i4":{"id":"f7ot6i4","value":0.125,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}]},"0lvbofx":{"id":"0lvbofx","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"}]},"ouwxsec":{"id":"ouwxsec","value":0.0625,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}]},"2h25rkg":{"id":"2h25rkg","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"}]},"3accxww":{"id":"3accxww","value":0.125,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}]},"oo0ko1w":{"id":"oo0ko1w","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"bu2jkow":{"id":"bu2jkow","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Lower Range","passToNext":true,"subNode":true},"1qsnupi":{"id":"1qsnupi","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Upper Range","passToNext":false,"subNode":true},"ude3fuj":{"id":"ude3fuj","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}]},"0n4v4nm":{"id":"0n4v4nm","value":0.125,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}]},"ey7arcm":{"id":"ey7arcm","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true},"2bnabgm":{"id":"2bnabgm","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"threshold","title":"Threshold","passToNext":false,"subNode":true},"rgpg4uv":{"id":"rgpg4uv","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Lower Range","passToNext":true,"subNode":true},"xn071mc":{"id":"xn071mc","value":1,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"key":"range","title":"Upper Range","passToNext":false,"subNode":true},"dcid9y7":{"id":"dcid9y7","value":"sine","inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Shape","key":"shape","type":"select","subNode":true,"options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"sawtooth","label":"Sawtooth"},{"value":"rSawtooth","label":"Revese Sawtooth"},{"value":"triangle","label":"Triangle"},{"value":"noise","label":"Noise"}]},"ptl3gkx":{"id":"ptl3gkx","value":0.25,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Rate","key":"rate","type":"select","subNode":true,"options":[{"value":32,"label":"32"},{"value":16,"label":"16"},{"value":8,"label":"8"},{"value":4,"label":"4"},{"value":2,"label":"2"},{"value":1,"label":"1"},{"value":0.5,"label":"1/2"},{"value":0.25,"label":"1/4"},{"value":0.125,"label":"1/8"},{"value":0.0625,"label":"1/16"},{"value":0.03125,"label":"1/32"}]},"0gjaa69":{"id":"0gjaa69","value":0,"inputLinkIds":[],"shotCount":0,"connectedMacroIds":[],"title":"Phase","key":"phase","subNode":true}},"scenes":{"items":{"o4imxh1":{"id":"o4imxh1","title":"Scene 1","selectedSketchId":"4mipx19","sketchIds":["4mipx19","ocqps2s","scpeype"],"linkableActionIds":{"addToA":"jcyapan","addToB":"pcur2h9","addToActive":"1mcpry9","addToOpposite":"akqhown","clear":"pnisikj"}},"bwcbhnc":{"id":"bwcbhnc","title":"Scene 2","selectedSketchId":"ur1s211","sketchIds":["ur1s211","t9k44bf"],"linkableActionIds":{"addToA":"7joltm2","addToB":"o77wdca","addToActive":"hbo3m24","addToOpposite":"1m10ph8","clear":"kreswpj"}}},"currentSceneId":"o4imxh1","channels":{"A":"o4imxh1","B":"bwcbhnc"}},"sketches":{"4mipx19":{"title":"Tunnel","moduleId":"tunnel","paramIds":["0s6lvul","vei9jws","usb304w","hdp7xd1","7cuaqas","ypj20pn","ftuvkhp","928kfik","oekq70k","kb2byt3"],"shotIds":["2rkglfv","utd7ext","covtc3r","tcyawv3","n6u2rgu","6bcuie8","9h704ki","a4dx8hv","yx0bq36","cl04jaf","fq7lx8b","1e6sq5r","913i7q9"],"openedNodes":{}},"ocqps2s":{"title":"Env","moduleId":"env","paramIds":["di0yss4","j5obnao","1ic3j5e","b52kkui","0gbvtty","j52vm6n","fg8t2s1","rfs0r6r","pvrhqxy","p30aooi"],"shotIds":["qgb5nue","nn10yhi","484bbb6","l7hv666"],"openedNodes":{}},"ur1s211":{"title":"Blobs","moduleId":"blobs","paramIds":["nap0vp4","5a03ptw","9sqssm7","y45y8v3","kvcndvn","5xblfei","pyam4a5"],"shotIds":["vh3fvwa","t57i74c"],"openedNodes":{"shot":"t57i74c"}},"scpeype":{"title":"Blobs","moduleId":"blobs","paramIds":["sxkn122","59iwl0f","h79kdes","inr1ca9","y82phdn","wysadp0","yf31edd"],"shotIds":["59sl06n","o2y3foc"],"openedNodes":{"shot":"o2y3foc"}},"t9k44bf":{"title":"Env","moduleId":"env","paramIds":["kvrxcg0","k8v9w13","qp1gg1m","ck7fo50","yy8kmye","jfe9qam","kgxq8f6","sbv7x5e","e79i3yp","wf1iwh0"],"shotIds":["jv28hwm","98uw21m","yn73iwy","c7ol1m3"],"openedNodes":{}}},"project":{"filePath":"/Users/alex/Sites/GitHub/hedron/example-projects/trippy/project.json","sketchesPath":"/Users/alex/Sites/GitHub/hedron/example-projects/trippy/sketches","errors":[],"errorPopup":false},"inputs":{"audio_0":{"value":0.004992596511431009,"assignedLinkIds":[]},"audio_1":{"value":0,"assignedLinkIds":[]},"audio_2":{"value":0,"assignedLinkIds":[]},"audio_3":{"value":0,"assignedLinkIds":[]},"lfo":{"value":642.0416666666666,"assignedLinkIds":["efw1t57","mdqy0x9","4cd69xv"]},"seq-step":{"assignedLinkIds":["8ciljw6","yicpwlx","8rqkjit","y91yr74","pqbp3yc","oglnu99","ngb783x","har1p3h"],"value":16}},"inputLinks":{"8ciljw6":{"title":"seq-step","input":{"id":"seq-step"},"id":"8ciljw6","nodeId":"59sl06n","nodeType":"shot","modifierIds":[],"lfoOptionIds":[],"midiOptionIds":[],"linkableActions":{"toggleActivate":"mngwmxq"},"sequencerGridId":"46oelft","linkType":"node"},"yicpwlx":{"title":"seq-step","input":{"id":"seq-step"},"id":"yicpwlx","nodeId":"o2y3foc","nodeType":"shot","modifierIds":[],"lfoOptionIds":[],"midiOptionIds":[],"linkableActions":{"toggleActivate":"naps24x"},"sequencerGridId":"3qvmm8l","linkType":"node"},"8rqkjit":{"title":"seq-step","input":{"id":"seq-step"},"id":"8rqkjit","nodeId":"t57i74c","nodeType":"shot","modifierIds":[],"lfoOptionIds":[],"midiOptionIds":[],"linkableActions":{"toggleActivate":"pl8p2ge"},"sequencerGridId":"vyhlvqd","linkType":"node"},"y91yr74":{"title":"seq-step","input":{"id":"seq-step"},"id":"y91yr74","nodeId":"2rkglfv","nodeType":"shot","modifierIds":[],"lfoOptionIds":[],"midiOptionIds":[],"linkableActions":{"toggleActivate":"a4rfv47"},"sequencerGridId":"6dn9dvu","linkType":"node"},"pqbp3yc":{"title":"seq-step","input":{"id":"seq-step"},"id":"pqbp3yc","nodeId":"tcyawv3","nodeType":"shot","modifierIds":[],"lfoOptionIds":[],"midiOptionIds":[],"linkableActions":{"toggleActivate":"tykfg94"},"sequencerGridId":"o3w2eld","linkType":"node"},"oglnu99":{"title":"seq-step","input":{"id":"seq-step"},"id":"oglnu99","nodeId":"n6u2rgu","nodeType":"shot","modifierIds":[],"lfoOptionIds":[],"midiOptionIds":[],"linkableActions":{"toggleActivate":"53cehe3"},"sequencerGridId":"s7bmq4p","linkType":"node"},"ngb783x":{"title":"seq-step","input":{"id":"seq-step"},"id":"ngb783x","nodeId":"6bcuie8","nodeType":"shot","modifierIds":[],"lfoOptionIds":[],"midiOptionIds":[],"linkableActions":{"toggleActivate":"9heiqdi"},"sequencerGridId":"uomtkk7","linkType":"node"},"har1p3h":{"title":"seq-step","input":{"id":"seq-step"},"id":"har1p3h","nodeId":"1e6sq5r","nodeType":"shot","modifierIds":[],"lfoOptionIds":[],"midiOptionIds":[],"linkableActions":{"toggleActivate":"c66i99c"},"sequencerGridId":"koeh596","linkType":"node"},"efw1t57":{"title":"lfo","input":{"id":"lfo"},"id":"efw1t57","nodeId":"sxkn122","nodeType":"param","modifierIds":["hc2qon7","qsf8bda","i69mg9x"],"lfoOptionIds":["ih4jeua","f7ot6i4"],"midiOptionIds":[],"linkableActions":{"toggleActivate":"jw3yfb0"},"linkType":"node"},"mdqy0x9":{"title":"lfo","input":{"id":"lfo"},"id":"mdqy0x9","nodeId":"928kfik","nodeType":"param","modifierIds":["oo0ko1w","bu2jkow","1qsnupi"],"lfoOptionIds":["ude3fuj","0n4v4nm","ey7arcm"],"midiOptionIds":[],"linkableActions":{"toggleActivate":"jreqw2t"},"linkType":"node"},"4cd69xv":{"title":"lfo","input":{"id":"lfo"},"id":"4cd69xv","nodeId":"k8v9w13","nodeType":"param","modifierIds":["2bnabgm","rgpg4uv","xn071mc"],"lfoOptionIds":["dcid9y7","ptl3gkx","0gjaa69"],"midiOptionIds":[],"linkableActions":{"toggleActivate":"95yti2d"},"linkType":"node"}},"linkableActions":{"jcyapan":{"id":"jcyapan","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"o4imxh1","channel":"A"}},"inputLinkIds":[]},"pcur2h9":{"id":"pcur2h9","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"o4imxh1","channel":"B"}},"inputLinkIds":[]},"1mcpry9":{"id":"1mcpry9","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"o4imxh1","type":"active"}},"inputLinkIds":[]},"akqhown":{"id":"akqhown","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"o4imxh1","type":"opposite"}},"inputLinkIds":[]},"pnisikj":{"id":"pnisikj","action":{"type":"SCENE_CLEAR_CHANNEL","payload":{"id":"o4imxh1"}},"inputLinkIds":[]},"7joltm2":{"id":"7joltm2","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"bwcbhnc","channel":"A"}},"inputLinkIds":[]},"o77wdca":{"id":"o77wdca","action":{"type":"R_SCENE_SELECT_CHANNEL","payload":{"id":"bwcbhnc","channel":"B"}},"inputLinkIds":[]},"hbo3m24":{"id":"hbo3m24","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"bwcbhnc","type":"active"}},"inputLinkIds":[]},"1m10ph8":{"id":"1m10ph8","action":{"type":"U_SCENE_SELECT_CHANNEL","payload":{"id":"bwcbhnc","type":"opposite"}},"inputLinkIds":[]},"kreswpj":{"id":"kreswpj","action":{"type":"SCENE_CLEAR_CHANNEL","payload":{"id":"bwcbhnc"}},"inputLinkIds":[]},"mngwmxq":{"id":"mngwmxq","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"59sl06n","linkId":"8ciljw6"}},"inputLinkIds":[]},"naps24x":{"id":"naps24x","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"o2y3foc","linkId":"yicpwlx"}},"inputLinkIds":[]},"pl8p2ge":{"id":"pl8p2ge","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"t57i74c","linkId":"8rqkjit"}},"inputLinkIds":[]},"a4rfv47":{"id":"a4rfv47","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"2rkglfv","linkId":"y91yr74"}},"inputLinkIds":[]},"tykfg94":{"id":"tykfg94","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"tcyawv3","linkId":"pqbp3yc"}},"inputLinkIds":[]},"53cehe3":{"id":"53cehe3","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"n6u2rgu","linkId":"oglnu99"}},"inputLinkIds":[]},"9heiqdi":{"id":"9heiqdi","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"6bcuie8","linkId":"ngb783x"}},"inputLinkIds":[]},"c66i99c":{"id":"c66i99c","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"1e6sq5r","linkId":"har1p3h"}},"inputLinkIds":[]},"jw3yfb0":{"id":"jw3yfb0","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"sxkn122","linkId":"efw1t57"}},"inputLinkIds":[]},"jreqw2t":{"id":"jreqw2t","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"928kfik","linkId":"mdqy0x9"}},"inputLinkIds":[]},"95yti2d":{"id":"95yti2d","action":{"type":"NODE_ACTIVE_INPUT_LINK_TOGGLE","payload":{"nodeId":"k8v9w13","linkId":"4cd69xv"}},"inputLinkIds":[]}},"macros":{"learningId":false,"items":{}},"ui":{"panelWidths":{"left":50},"isEditing":false,"openedNode":"sceneCrossfader"},"router":{"location":{"pathname":"/scenes/view","search":"","hash":"","key":"i4qf6b"}},"settings":{"clockGenerated":true,"clockBpm":120,"aspectW":16,"aspectH":9,"antialias":false,"throttledFPS":60},"form":{}}
diff --git a/example-projects/trippy/sketches/blobs/config.js b/example-projects/trippy/sketches/blobs/config.js
deleted file mode 100644
index 2c15721d..00000000
--- a/example-projects/trippy/sketches/blobs/config.js
+++ /dev/null
@@ -1,50 +0,0 @@
-module.exports = {
- defaultTitle: 'Blobs',
- params: [
- {
- key: 'posZ',
- title: 'Pos Z',
- defaultValue: 0.5
- },
- {
- key: 'rotSpeedX',
- title: 'Rot Speed X',
- defaultValue: 0.5
- },
- {
- key: 'rotSpeedY',
- title: 'Rot Speed Y',
- defaultValue: 0.5
- },
- {
- key: 'rotSpeedZ',
- title: 'Rot Speed Z',
- defaultValue: 0.5
- },
- {
- key: 'blobSpeed',
- title: 'Blob Speed',
- defaultValue: 0.5
- },
- {
- key: 'numBlobs',
- title: 'Num Blobs',
- defaultValue: 0.5
- },
- {
- key: 'blobStrength',
- title: 'Blob Strength',
- defaultValue: 0.5
- }
- ],
- shots: [
- {
- method: 'spin',
- title: 'Spin'
- },
- {
- method: 'updateReflection',
- title: 'Update Reflection'
- }
- ]
-}
diff --git a/example-projects/trippy/sketches/blobs/index.js b/example-projects/trippy/sketches/blobs/index.js
deleted file mode 100644
index 174a77b0..00000000
--- a/example-projects/trippy/sketches/blobs/index.js
+++ /dev/null
@@ -1,88 +0,0 @@
-const { MeshStandardMaterial, CubeCamera, Object3D } = require('three')
-const { MarchingCubes } = require('three-addons')
-const TWEEN = require('@tweenjs/tween.js')
-
-class Blobs {
- constructor (injectedScene) {
- const { scene, renderer } = injectedScene
-
- this.root = new Object3D()
- const scale = 1000
- this.scene = scene
- this.renderer = renderer
- this.cubeCamera = new CubeCamera(1, 3000, 32)
-
- setTimeout(() => {
- this.cubeCamera.update(this.renderer, this.scene)
- }, 100)
-
- const mat = new MeshStandardMaterial(
- { color: 0xFFFFFF, envMap: this.cubeCamera.renderTarget, roughness: 0.1, metalness: 1.0 }
- )
- this.object = new MarchingCubes(32, mat, true, true)
- this.object.position.set(0, 0, 0)
- this.object.scale.set(scale, scale, scale)
-
- this.object.enableUvs = false
- this.object.enableColors = false
-
- this.group = new Object3D()
- this.group.add(this.cubeCamera)
- this.group.add(this.object)
- this.root.add(this.group)
-
- this.blobTime = 0
-
- this.props = {
- spinSpeed: 0
- }
- }
-
- spin () {
- this.isAnimating = true
- this.props.spinSpeed = 0.15
-
- new TWEEN.Tween(this.props)
- .to({ spinSpeed: 0 }, 1000)
- .easing(TWEEN.Easing.Quadratic.Out)
- .start()
- .onComplete(() => {
- this.isAnimating = false
- })
- }
-
- updateReflection () {
- this.cubeCamera.update(this.renderer, this.scene)
- }
-
- update (params, time, frameDiff) {
- this.blobTime += ((params.blobSpeed * 2) - 1) * frameDiff / 7
- const object = this.object
- const numblobs = params.numBlobs * 50
- const rotSpeedZ = params.rotSpeedZ + this.props.spinSpeed
-
- object.reset()
-
- this.group.rotation.x += ((params.rotSpeedX * 2) - 1) * frameDiff
- this.group.rotation.y += ((params.rotSpeedY * 2) - 1) * frameDiff
- this.group.rotation.z += ((rotSpeedZ * 2) - 1) * frameDiff
-
- this.group.position.z = params.posZ * -10000
-
- // fill the field with some metaballs
- var i, ballx, bally, ballz, subtract, strength
-
- subtract = 12
- strength = (params.blobStrength * 3) / ((Math.sqrt(numblobs) - 1) / 4 + 1)
-
- for (i = 0; i < numblobs; i++) {
- ballx = Math.sin(i + 1.26 * this.blobTime * (1.03 + 0.5 * Math.cos(0.21 * i))) * 0.27 + 0.5
- bally = Math.abs(Math.cos(i + 1.12 * this.blobTime * Math.cos(1.22 + 0.1424 * i))) * 0.27 + 0.5
- ballz = Math.cos(i + 1.32 * this.blobTime * 0.1 * Math.sin((0.92 + 0.53 * i))) * 0.27 + 0.5
-
- object.addBall(ballx, bally, ballz, strength, subtract)
- }
- }
-}
-
-module.exports = Blobs
diff --git a/example-projects/trippy/sketches/env/config.js b/example-projects/trippy/sketches/env/config.js
deleted file mode 100644
index 6f15f138..00000000
--- a/example-projects/trippy/sketches/env/config.js
+++ /dev/null
@@ -1,73 +0,0 @@
-module.exports = {
- defaultTitle: 'Env',
- params: [
- {
- key: 'fogDensity',
- title: 'Fog Density',
- defaultValue: 0
- },
- {
- key: 'colorH',
- title: 'BG Color H',
- defaultValue: 0
- },
- {
- key: 'colorS',
- title: 'BG Color S',
- defaultValue: 0
- },
- {
- key: 'colorL',
- title: 'BG Color L',
- defaultValue: 0
- },
- {
- key: 'mainLightIntensity',
- title: 'Main Light Intensity',
- defaultValue: 1
- },
- {
- key: 'centralPointLightDistance',
- title: 'Central Point Light Distance',
- defaultValue: 0.5
- },
- {
- key: 'centralPointLightIntensity',
- title: 'Central Point Light Intensity',
- defaultValue: 0.5
- },
- {
- key: 'centralPointLightH',
- title: 'Central Point Light Color H',
- defaultValue: 1
- },
- {
- key: 'centralPointLightS',
- title: 'Central Point Light Color S',
- defaultValue: 1
- },
- {
- key: 'centralPointLightL',
- title: 'Central Point Light Color L',
- defaultValue: 1
- }
- ],
- shots: [
- {
- title: 'Camera 1',
- method: 'camera1'
- },
- {
- title: 'Camera 2',
- method: 'camera2'
- },
- {
- title: 'Camera 3',
- method: 'camera3'
- },
- {
- title: 'Camera Random',
- method: 'cameraRandom'
- }
- ]
-}
diff --git a/example-projects/trippy/sketches/env/index.js b/example-projects/trippy/sketches/env/index.js
deleted file mode 100644
index 6a176599..00000000
--- a/example-projects/trippy/sketches/env/index.js
+++ /dev/null
@@ -1,73 +0,0 @@
-const THREE = require('three')
-
-class Env {
- constructor (scene) {
- this.root = new THREE.Object3D()
- this.scene = scene
-
- this.clearColor = new THREE.Color()
- this.scene.scene.fog = new THREE.FogExp2()
-
- this.ambientLight = new THREE.AmbientLight(0xffffff, 0.3)
- this.directionalLight1 = new THREE.DirectionalLight(0xffffff, 0.7)
- this.directionalLight2 = new THREE.DirectionalLight(0x256351, 0.7)
- this.directionalLight1.position.set(1, 1, 1)
- this.directionalLight1.position.set(-0.5, 0.5, 0.5)
-
- this.centralPointLight = new THREE.PointLight(0xffffff, 1, 10000)
- // this.centralPointLight.position.z = -1000
- this.scene.scene.add(this.centralPointLight)
-
- this.scene.scene.add(this.directionalLight1)
- this.scene.scene.add(this.directionalLight2)
- this.scene.scene.add(this.ambientLight)
-
- this.props = {}
-
- this.pointLightTick = 0
-
- this.camera1()
- }
-
- cameraMove (x, y, z) {
- this.scene.camera.position.x = x
- this.scene.camera.position.y = y
- this.scene.camera.position.z = z
- this.scene.camera.lookAt(new THREE.Vector3(0, 0, 0))
- }
-
- camera1 () {
- this.cameraMove(0, 0, 1000)
- }
-
- camera2 () {
- this.cameraMove(500, -500, 1000)
- }
-
- camera3 () {
- this.cameraMove(-500, 500, 500)
- }
-
- cameraRandom () {
- const a = [500, -500, 800, -800, 1000, -1000]
- const r = () => Math.floor(Math.random() * a.length)
- this.cameraMove(a[r()], a[r()], a[r()])
- }
-
- update (p, t) {
- this.clearColor.setHSL(p.colorH, p.colorS, p.colorL)
- this.scene.scene.fog.density = p.fogDensity * 0.01
- this.scene.scene.fog.color = this.clearColor
- this.scene.scene.background = this.clearColor
-
- this.directionalLight1.intensity = 0.7 * p.mainLightIntensity
- this.directionalLight2.intensity = 0.7 * p.mainLightIntensity
- this.ambientLight.intensity = 0.3 * p.mainLightIntensity
-
- this.centralPointLight.color.setHSL(p.centralPointLightH, p.centralPointLightS, p.centralPointLightL)
- this.centralPointLight.distance = Math.max(p.centralPointLightDistance * 30000, 0.001)
- this.centralPointLight.intensity = p.centralPointLightIntensity * 10
- }
-}
-
-module.exports = Env
diff --git a/example-projects/trippy/sketches/tunnel/Block.js b/example-projects/trippy/sketches/tunnel/Block.js
deleted file mode 100644
index 7f93bcf9..00000000
--- a/example-projects/trippy/sketches/tunnel/Block.js
+++ /dev/null
@@ -1,350 +0,0 @@
-const { Object3D, MeshLambertMaterial, Mesh } = require('three')
-const TWEEN = require('@tweenjs/tween.js')
-const PI_HALF = Math.PI / 2
-
-const roundRot = rot => {
- const diff = rot % PI_HALF
-
- if (diff === 0) {
- return rot
- } else {
- return rot + (PI_HALF - diff)
- }
-}
-
-class Block {
- constructor (x, y, z, blockSize, colors, towerWidth, towerHeight, wavyMats, cubeGeom) {
- this.blockSize = blockSize
- this.towerHeight = towerHeight
- this.towerWidth = towerWidth
- this.wavyMatSide = false
-
- this.shiftTween = false
-
- // Tweenable properties
- this.props = {
- scale: 1,
- rotX: 0,
- rotY: 0,
- rotZ: 0,
- cubeScale: 1,
- xPos: x,
- yPos: y,
- zPos: z
- }
- this.nextProps = {}
-
- const wavyMatIndex = Math.floor(Math.random() * wavyMats.length)
-
- this.wavyMat = wavyMats[wavyMatIndex]
-
- this.defaultMats = [
- new MeshLambertMaterial({
- color: 0x000000
- }),
- new MeshLambertMaterial({
- color: 0x555555
- }),
- new MeshLambertMaterial({
- color: 0xffffff
- }),
- new MeshLambertMaterial({
- color: 0x222222
- }),
- new MeshLambertMaterial({
- color: 0x444444
- }),
- new MeshLambertMaterial({
- color: 0x999999
- })
- ]
-
- this.mats = this.defaultMats.slice(0)
-
- this.cube = new Mesh(cubeGeom, this.mats)
- this.group = new Object3D()
- this.group.add(this.cube)
- }
-
- change () {
- if (Math.random() > 0.5) {
- this.toggle()
- }
- }
-
- flash (boosted) {
- this.cube.material = this.defaultMats.slice(0)
- this.wavyMatSide = false
-
- if (boosted || Math.random() > 0.5) {
- this.wavyMatSide = Math.floor(Math.random() * 4)
- this.cube.material[this.wavyMatSide] = this.wavyMat
-
- if (boosted) {
- this.wavyMatSide = 'force'
- this.cube.material[Math.floor(Math.random() * 4)] = this.wavyMat
- this.cube.material[Math.floor(Math.random() * 4)] = this.wavyMat
- this.cube.material[Math.floor(Math.random() * 4)] = this.wavyMat
- }
- }
- }
-
- flashAllOn () {
- this.wavyMatSide = 'force'
- this.cube.material = this.wavyMat
- }
-
- flashAllOff () {
- this.wavyMatSide = false
- this.cube.material = this.defaultMats.slice(0)
- }
-
- spin () {
- const axis = ['X', 'Y', 'Z']
- const nextRot = {
- rotX: roundRot(this.props.rotX),
- rotY: roundRot(this.props.rotY),
- rotZ: roundRot(this.props.rotZ)
- }
- const i = Math.floor(Math.random() * 3)
- nextRot[`rot${axis[i]}`] += Math.PI / 2
-
- new TWEEN.Tween(this.props)
- .to(nextRot, this.blockSpinSpeed)
- .easing(TWEEN.Easing.Quadratic.Out)
- .start()
- }
-
- flicker (hide, cb) {
- const numFlicks = 5
- let i = 0
- const flick = () => {
- if (i > numFlicks) {
- this.group.visible = !hide
- if (cb) cb()
- } else {
- this.group.visible = !this.group.visible
- setTimeout(flick, Math.random() * 100)
- i++
- }
- }
-
- flick()
- }
-
- toggle () {
- if (this.visible) {
- this.visible = false
- } else {
- this.visible = true
- }
-
- const s = this.visible ? 1 : 0.001
- const r = this.visible ? 0 : Math.PI
-
- new TWEEN.Tween(this.props)
- .to({ scale: s, rot: r }, 500)
- .easing(TWEEN.Easing.Quadratic.Out)
- .start()
- }
-
- move (blocks) {
- const numBlocks = this.towerWidth - 1
-
- let nextMove = {}
- let doTween
-
- let moves = {
- up: {
- prop: 'yPos',
- val: Math.round(this.props.yPos) + 1,
- enabled: true
- },
- down: {
- prop: 'yPos',
- val: Math.round(this.props.yPos) - 1,
- enabled: true
- },
- left: {
- prop: 'xPos',
- val: Math.round(this.props.xPos) + 1,
- enabled: true
- },
- right: {
- prop: 'xPos',
- val: Math.round(this.props.xPos) - 1,
- enabled: true
- },
- forward: {
- prop: 'zPos',
- val: Math.round(this.props.zPos) + 1,
- enabled: true
- },
- backward: {
- prop: 'zPos',
- val: Math.round(this.props.zPos) - 1,
- enabled: true
- }
- }
-
- for (let i = 0; i < blocks.length; i++) {
- const props = blocks[i].props
- const nextProps = blocks[i].nextProps
-
- if (
- (
- props.xPos === this.props.xPos &&
- props.yPos === this.props.yPos &&
- props.zPos === moves.forward.val ||
- moves.forward.val > this.towerHeight - 1
- ) ||
- (
- nextProps.xPos === this.props.xPos &&
- nextProps.yPos === this.props.yPos &&
- nextProps.zPos === moves.forward.val
- )
- ) {
- moves.forward.enabled = false
- }
-
- if (
- (
- props.xPos === this.props.xPos &&
- props.yPos === this.props.yPos &&
- props.zPos === moves.backward.val ||
- moves.forward.val < 0
- ) ||
- (
- nextProps.xPos === this.props.xPos &&
- nextProps.yPos === this.props.yPos &&
- nextProps.zPos === moves.backward.val
- )
- ) {
- moves.backward.enabled = false
- }
-
- if (
- (
- props.xPos === this.props.xPos &&
- props.yPos === moves.up.val &&
- props.zPos === this.props.zPos ||
- moves.up.val > numBlocks
- ) ||
- (
- nextProps.xPos === this.props.xPos &&
- nextProps.yPos === moves.up.val &&
- nextProps.zPos === this.props.zPos
- )
- ) {
- moves.up.enabled = false
- }
-
- if (
- (
- props.xPos === this.props.xPos &&
- props.yPos === moves.down.val &&
- props.zPos === this.props.zPos ||
- moves.down.val < 0
- ) ||
- (
- nextProps.xPos === this.props.xPos &&
- nextProps.yPos === moves.down.val &&
- nextProps.zPos === this.props.zPos
- )
- ) {
- moves.down.enabled = false
- }
-
- if (
- (
- props.xPos === moves.left.val &&
- props.yPos === this.props.yPos &&
- props.zPos === this.props.zPos ||
- moves.left.val > numBlocks
- ) ||
- (
- nextProps.xPos === moves.left.val &&
- nextProps.yPos === this.props.yPos &&
- nextProps.zPos === this.props.zPos
- )
- ) {
- moves.left.enabled = false
- }
-
- if (
- (
- props.xPos === moves.right.val &&
- props.yPos === this.props.yPos &&
- props.zPos === this.props.zPos ||
- moves.right.val < 0
- ) ||
- (
- nextProps.xPos === moves.right.val &&
- nextProps.yPos === this.props.yPos &&
- nextProps.zPos === this.props.zPos
- )
- ) {
- moves.right.enabled = false
- }
- }
-
- if (this.props.yPos === 2) {
- if (moves.right.val === 2) moves.right.enabled = false
- if (moves.left.val === 2) moves.left.enabled = false
- }
-
- if (this.props.xPos === 2) {
- if (moves.up.val === 2) moves.up.enabled = false
- if (moves.down.val === 2) moves.down.enabled = false
- }
-
- const permittedMoves =
- Object.keys(moves).filter(key =>
- moves[key].enabled
- )
-
- if (permittedMoves.length) {
- const roundMoves = {
- xPos: Math.round(this.props.xPos),
- yPos: Math.round(this.props.yPos),
- zPos: Math.round(this.props.zPos)
- }
-
- const i = Math.floor(Math.random() * permittedMoves.length)
- const move = moves[permittedMoves[i]]
-
- nextMove = Object.assign({}, roundMoves, { [move.prop]: move.val })
-
- doTween = true
- }
-
- if (doTween) {
- this.nextProps = Object.assign({}, this.props, nextMove)
-
- this.shiftTween = new TWEEN.Tween(this.props)
- .to(nextMove, this.blockShiftSpeed)
- .easing(TWEEN.Easing.Bounce.Out)
- .start()
- }
- }
-
- update (p, t, f, color) {
- const blockSize = this.blockSize
- const towerHeight = this.towerHeight
-
- const { blockShiftSpeed, blockSpinSpeed } = p
-
- this.blockShiftSpeed = 1000 - (1000 * blockShiftSpeed)
- this.blockSpinSpeed = 1000 - (1000 * blockSpinSpeed)
-
- this.group.rotation.x = this.props.rotX
- this.group.rotation.y = this.props.rotY
- this.group.rotation.z = this.props.rotZ
-
- this.group.position.x = this.props.xPos * blockSize - blockSize * 2
- this.group.position.y = this.props.yPos * blockSize - blockSize * 2
- this.group.position.z = this.props.zPos * blockSize - blockSize * towerHeight / 2
- }
-}
-
-module.exports = Block
diff --git a/example-projects/trippy/sketches/tunnel/Pipe.js b/example-projects/trippy/sketches/tunnel/Pipe.js
deleted file mode 100644
index bf822307..00000000
--- a/example-projects/trippy/sketches/tunnel/Pipe.js
+++ /dev/null
@@ -1,94 +0,0 @@
-const { TubeGeometry, Mesh, Vector3, CubicBezierCurve3, Geometry } = require('three')
-const _ = require('lodash')
-
-class Pipe {
- constructor (blockSize, towerHeight, material) {
- const boundry = [2, 2]
-
- // const cubeGeom = new BoxGeometry(blockSize, blockSize, blockSize)
- // const cubeMaterial = new MeshBasicMaterial({ wireframe: true })
- // const blockHelper = new Mesh(cubeGeom, cubeMaterial)
- this.geom = new Geometry()
-
- const createBend = (prevDir, nextDir) => {
- const bendCurve = new CubicBezierCurve3(
- new Vector3(-prevDir[0] * blockSize / 2, -prevDir[1] * blockSize / 2, -prevDir[2] * blockSize / 2),
- new Vector3(0, 0, 0),
- new Vector3(0, 0, 0),
- new Vector3(nextDir[0] * blockSize / 2, nextDir[1] * blockSize / 2, nextDir[2] * blockSize / 2)
- )
- const bendGeom = new TubeGeometry(bendCurve, 10, 10, 8, false)
- // bend.add(blockHelper.clone())
- return bendGeom
- }
-
- const positions = []
- let nextPos = [1, 0, 0]
- let failCount = 0
- const failLimit = 50
- let z = 0
- let i = 0
- while (z > -towerHeight && failCount < failLimit) {
- const calc = () => {
- let rp
- if (Math.random() > 0.5) {
- // Encourage twisty pipes by only allowing
- // them to go forwards 50% of the time
- rp = Math.floor(Math.random() * 3)
- } else {
- rp = Math.floor(Math.random() * 2)
- }
- if (rp === 2) {
- z--
- }
- const r = rp === 2 ? -1 : Math.random() > 0.5 ? 1 : -1
- const dir = [0, 0, 0]
- dir[rp] = r
-
- nextPos = [pos[0] + dir[0], pos[1] + dir[1], pos[2] + dir[2]]
- let allowNextPos = true
-
- if (nextPos[0] > boundry[0] || nextPos[0] < -boundry[0] ||
- nextPos[1] > boundry[1] || nextPos[1] < -boundry[1] ||
- (nextPos[0] === 0 && nextPos[1] === 0)
- ) {
- allowNextPos = false
- } else {
- for (let j = 0; j < i; j++) {
- const p = positions[j]
- if (_.isEqual(nextPos, p.pos)) {
- allowNextPos = false
- }
- }
- }
-
- if (allowNextPos) {
- failCount = 0
- positions[i] = { dir, pos }
- i++
- } else if (failCount < failLimit) {
- failCount++
- calc()
- }
- }
- const pos = nextPos
-
- calc()
- }
-
- for (let i = 0; i < positions.length; i++) {
- const p = positions[i].pos
- const d = positions[i].dir
- const prevDir = i > 0 ? positions[i - 1].dir : [1, 0, 0]
-
- const s = createBend(prevDir, d)
- s.translate(p[0] * blockSize, p[1] * blockSize, p[2] * blockSize)
-
- this.geom.merge(s)
- }
-
- this.group = new Mesh(this.geom, material)
- }
-}
-
-module.exports = Pipe
diff --git a/example-projects/trippy/sketches/tunnel/Pipes.js b/example-projects/trippy/sketches/tunnel/Pipes.js
deleted file mode 100644
index 510af015..00000000
--- a/example-projects/trippy/sketches/tunnel/Pipes.js
+++ /dev/null
@@ -1,75 +0,0 @@
-const { Object3D, MeshBasicMaterial } = require('three')
-const Pipe = require('./Pipe')
-
-class Pipes {
- constructor (blockSize, towerHeight) {
- this.pipes = []
- this.numPipes = 3
- this.group = new Object3D()
- this.group.visible = true
- this.material = new MeshBasicMaterial({ wireframe: true, color: 0x2EFFFD, fog: false })
-
- for (let i = 0; i < this.numPipes; i++) {
- const pipe = new Pipe(blockSize, towerHeight, this.material)
- this.pipes.push(pipe)
- this.group.add(pipe.group)
- }
-
- this.isRotating = false
- }
-
- randomPipeIndex () {
- return Math.floor(Math.random() * this.numPipes)
- }
-
- flicker (hide, cb) {
- const numFlicks = 5
- let i = 0
- const flick = () => {
- if (i > numFlicks) {
- this.group.visible = !hide
- if (cb) cb()
- } else {
- this.group.visible = !this.group.visible
- setTimeout(flick, Math.random() * 100)
- i++
- }
- }
-
- flick()
- }
-
- swap () {
- let randomIndex
- const r = () => {
- randomIndex = this.randomPipeIndex()
- if (randomIndex === this.visiblePipe) r()
- }
- r()
- this.visiblePipe = randomIndex
- for (let i = 0; i < this.numPipes; i++) {
- const pipe = this.pipes[i]
- if (randomIndex === i) {
- pipe.group.visible = true
- } else {
- pipe.group.visible = false
- }
- }
- }
-
- allOn () {
- for (let i = 0; i < this.numPipes; i++) {
- this.pipes[i].group.visible = true
- }
- }
-
- update (color) {
- if (this.isRotating) {
- this.group.rotation.z -= 0.015
- }
-
- this.material.color = color
- }
-}
-
-module.exports = Pipes
diff --git a/example-projects/trippy/sketches/tunnel/Tower.js b/example-projects/trippy/sketches/tunnel/Tower.js
deleted file mode 100644
index 8dc05831..00000000
--- a/example-projects/trippy/sketches/tunnel/Tower.js
+++ /dev/null
@@ -1,198 +0,0 @@
-const { Object3D, ShaderMaterial, Color, BoxBufferGeometry, UniformsUtils, UniformsLib } = require('three')
-const Block = require('./Block')
-const Pipes = require('./Pipes')
-const glsl = require('glslify')
-const vertShader = glsl.file('./vert.glsl')
-const fragShader = glsl.file('./frag.glsl')
-
-class Tower {
- constructor (blockSize, colors, towerWidth, towerHeight, startPos) {
- const now = Date.now()
- this.pipes = new Pipes(blockSize, towerHeight)
- const numWavyMats = 5
- this.delta = now
- this.gamma = now
- this.beta = now
- this.alpha = now + 500
- this.blocks = []
- this.group = new Object3D()
- this.group.position.z = startPos
- this.maxZ = towerHeight * blockSize
- this.minZ = -this.maxZ
- this.tower = new Object3D()
- this.group.add(this.tower)
- this.group.add(this.pipes.group)
- this.isFlickering = false
-
- this.props = {
- perlinTime: 0
- }
-
- this.wavyMats = []
-
- for (let i = 0; i < numWavyMats; i++) {
- const uniforms = UniformsUtils.merge([
- UniformsLib[ 'fog' ],
- {
- iTime: { value: Date.now(), type: 'f' },
- seed: { value: Math.random() * 100 },
- color1: { value: new Color(colors[0]) },
- color2: { value: new Color(0x2EFFFD) }
- }
- ])
- const mat = new ShaderMaterial({
- vertexShader: vertShader,
- fragmentShader: fragShader,
- fog: false,
- uniforms
- })
-
- this.wavyMats.push(mat)
- }
-
- const cubeGeom = new BoxBufferGeometry(blockSize, blockSize, blockSize)
-
- for (let x = 0; x < towerWidth; x++) {
- for (let y = 0; y < towerWidth; y++) {
- for (let z = 0; z < towerHeight - 2; z++) {
- if (!(x === 2 && y === 2) && Math.random() > 0.5) {
- const newBlock = new Block(
- x, y, z, blockSize, colors, towerWidth, towerHeight, this.wavyMats, cubeGeom
- )
- this.tower.add(newBlock.group)
- this.blocks.push(newBlock)
- }
- }
- }
- }
-
- this.flashBlocks()
- }
-
- removeBlocks () {
- for (let i = 0; i < this.blocks.length; i++) {
- if (Math.random() > 0.8) {
- this.blocks[i].flicker(true)
- }
- }
- }
-
- addBlocks () {
- for (let i = 0; i < this.blocks.length; i++) {
- if (Math.random() > 0.8) {
- this.blocks[i].flicker()
- }
- }
- }
-
- shiftBlocks () {
- for (let i = 0; i < this.blocks.length; i++) {
- this.blocks[i].move(this.blocks)
- }
- }
-
- spinBlocks () {
- for (let i = 0; i < this.blocks.length; i++) {
- if (Math.random() > 0.5) {
- this.blocks[i].spin()
- }
- }
- }
-
- flashBlocks () {
- for (let i = 0; i < this.blocks.length; i++) {
- this.blocks[i].flash()
- }
- }
-
- flashAllBlocksOn () {
- for (let i = 0; i < this.blocks.length; i++) {
- this.blocks[i].flashAllOn()
- }
- }
-
- flashAllBlocksOff () {
- for (let i = 0; i < this.blocks.length; i++) {
- this.blocks[i].flashAllOff()
- }
- }
-
- boostedFlashBlocks () {
- for (let i = 0; i < this.blocks.length; i++) {
- this.blocks[i].flash(true)
- }
- }
-
- pipesOn () {
- this.pipes.flicker()
- }
-
- pipesOff () {
- this.pipes.flicker(true)
- }
-
- pipesSwap () {
- this.pipes.group.visible = true
- this.pipes.swap()
- }
-
- pipesAllOn () {
- this.pipes.flicker()
- this.pipes.allOn()
- }
-
- flicker (cb) {
- const numFlicks = 5
- let i = 0
- const flick = () => {
- if (i > numFlicks) {
- this.group.visible = true
- cb()
- } else {
- this.group.visible = !this.group.visible
- setTimeout(flick, Math.random() * 50)
- i++
- }
- }
-
- flick()
- }
-
- update (p, t, f, color) {
- const blocks = this.blocks
- let { tunnelScale, zSpeed, perlinSpeed } = p
- const speed = ((zSpeed * 2) - 1) * f * 20
- const scale = 1 + (10 * tunnelScale)
-
- this.props.perlinTime += perlinSpeed * f / 10
-
- this.group.position.z += speed
-
- if (this.group.position.z < this.minZ && !this.isFlickering) {
- this.isFlickering = true
- this.flicker(() => {
- this.isFlickering = false
- const diff = Math.abs(this.group.position.z) - Math.abs(this.minZ)
- this.group.position.z = this.maxZ - diff
- })
- } else if (this.group.position.z > this.maxZ && !this.isFlickering) {
- const diff = this.group.position.z - this.maxZ
- this.group.position.z = this.minZ + diff
- }
-
- this.tower.scale.set(scale, scale, 1)
-
- this.pipes.update(color)
-
- for (let i = 0; i < blocks.length; i++) {
- blocks[i].update(p, t, f, color)
- }
-
- for (let i = 0; i < this.wavyMats.length; i++) {
- this.wavyMats[i].uniforms.iTime.value = this.props.perlinTime
- this.wavyMats[i].uniforms.color2.value = color
- }
- }
-}
-
-module.exports = Tower
diff --git a/example-projects/trippy/sketches/tunnel/chunks/common.glsl b/example-projects/trippy/sketches/tunnel/chunks/common.glsl
deleted file mode 100644
index 2ed7888d..00000000
--- a/example-projects/trippy/sketches/tunnel/chunks/common.glsl
+++ /dev/null
@@ -1,95 +0,0 @@
-#define PI 3.14159265359
-#define PI2 6.28318530718
-#define PI_HALF 1.5707963267949
-#define RECIPROCAL_PI 0.31830988618
-#define RECIPROCAL_PI2 0.15915494
-#define LOG2 1.442695
-#define EPSILON 1e-6
-
-#define saturate(a) clamp( a, 0.0, 1.0 )
-#define whiteCompliment(a) ( 1.0 - saturate( a ) )
-
-float pow2( const in float x ) { return x*x; }
-float pow3( const in float x ) { return x*x*x; }
-float pow4( const in float x ) { float x2 = x*x; return x2*x2; }
-float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
-// expects values in the range of [0,1]x[0,1], returns values in the [0,1] range.
-// do not collapse into a single function per: http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
-highp float rand( const in vec2 uv ) {
- const highp float a = 12.9898, b = 78.233, c = 43758.5453;
- highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );
- return fract(sin(sn) * c);
-}
-
-struct IncidentLight {
- vec3 color;
- vec3 direction;
- bool visible;
-};
-
-struct ReflectedLight {
- vec3 directDiffuse;
- vec3 directSpecular;
- vec3 indirectDiffuse;
- vec3 indirectSpecular;
-};
-
-struct GeometricContext {
- vec3 position;
- vec3 normal;
- vec3 viewDir;
-};
-
-vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
-
- return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
-
-}
-
-// http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations
-vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
-
- return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
-
-}
-
-vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
-
- float distance = dot( planeNormal, point - pointOnPlane );
-
- return - distance * planeNormal + point;
-
-}
-
-float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
-
- return sign( dot( point - pointOnPlane, planeNormal ) );
-
-}
-
-vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {
-
- return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
-
-}
-
-mat3 transposeMat3( const in mat3 m ) {
-
- mat3 tmp;
-
- tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );
- tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );
- tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );
-
- return tmp;
-
-}
-
-// https://en.wikipedia.org/wiki/Relative_luminance
-float linearToRelativeLuminance( const in vec3 color ) {
-
- vec3 weights = vec3( 0.2126, 0.7152, 0.0722 );
-
- return dot( weights, color.rgb );
-
-}
diff --git a/example-projects/trippy/sketches/tunnel/chunks/fog_fragment.glsl b/example-projects/trippy/sketches/tunnel/chunks/fog_fragment.glsl
deleted file mode 100644
index 8307a324..00000000
--- a/example-projects/trippy/sketches/tunnel/chunks/fog_fragment.glsl
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifdef USE_FOG
-
- #ifdef FOG_EXP2
-
- float fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );
-
- #else
-
- float fogFactor = smoothstep( fogNear, fogFar, fogDepth );
-
- #endif
-
- gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );
-
-#endif
diff --git a/example-projects/trippy/sketches/tunnel/chunks/fog_pars_fragment.glsl b/example-projects/trippy/sketches/tunnel/chunks/fog_pars_fragment.glsl
deleted file mode 100644
index 26c4093c..00000000
--- a/example-projects/trippy/sketches/tunnel/chunks/fog_pars_fragment.glsl
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifdef USE_FOG
-
- uniform vec3 fogColor;
- varying float fogDepth;
-
- #ifdef FOG_EXP2
-
- uniform float fogDensity;
-
- #else
-
- uniform float fogNear;
- uniform float fogFar;
-
- #endif
-
-#endif
diff --git a/example-projects/trippy/sketches/tunnel/chunks/fog_pars_vertex.glsl b/example-projects/trippy/sketches/tunnel/chunks/fog_pars_vertex.glsl
deleted file mode 100644
index d27a1a1e..00000000
--- a/example-projects/trippy/sketches/tunnel/chunks/fog_pars_vertex.glsl
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifdef USE_FOG
-
- varying float fogDepth;
-
-#endif
diff --git a/example-projects/trippy/sketches/tunnel/chunks/fog_vertex.glsl b/example-projects/trippy/sketches/tunnel/chunks/fog_vertex.glsl
deleted file mode 100644
index 549ea8d2..00000000
--- a/example-projects/trippy/sketches/tunnel/chunks/fog_vertex.glsl
+++ /dev/null
@@ -1,5 +0,0 @@
-vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
-
-#ifdef USE_FOG
-fogDepth = -mvPosition.z;
-#endif
diff --git a/example-projects/trippy/sketches/tunnel/config.js b/example-projects/trippy/sketches/tunnel/config.js
deleted file mode 100644
index 96c811e6..00000000
--- a/example-projects/trippy/sketches/tunnel/config.js
+++ /dev/null
@@ -1,109 +0,0 @@
-module.exports = {
- defaultTitle: 'Tunnel',
- params: [
- {
- key: 'zSpeed',
- title: 'Z Speed',
- defaultValue: 0.5
- },
- {
- key: 'tunnelScale',
- title: 'Tunnel Scale',
- defaultValue: 0
- },
- {
- key: 'rotSpeed',
- title: 'Rot Speed',
- defaultValue: 0
- },
- {
- key: 'rotTweenSpeed',
- title: 'Rot Tween Speed',
- defaultValue: 0.5
- },
- {
- key: 'blockShiftSpeed',
- title: 'Block Shift Speed',
- defaultValue: 0.5
- },
- {
- key: 'blockSpinSpeed',
- title: 'Block Spin Speed',
- defaultValue: 0.5
- },
- {
- key: 'perlinSpeed',
- title: 'Perlin Speed',
- defaultValue: 0.5
- },
- {
- key: 'colorH',
- title: 'color H',
- defaultValue: 0.5
- },
- {
- key: 'colorS',
- title: 'color S',
- defaultValue: 0.5
- },
- {
- key: 'colorL',
- title: 'color L',
- defaultValue: 0.5
- }
- ],
- shots: [
- {
- method: 'quarterTurn',
- title: 'Quarter Turn'
- },
- {
- method: 'removeBlocks',
- title: 'Remove Blocks'
- },
- {
- method: 'addBlocks',
- title: 'Add Blocks'
- },
- {
- method: 'shiftBlocks',
- title: 'Shift Blocks'
- },
- {
- method: 'spinBlocks',
- title: 'Spin Blocks'
- },
- {
- method: 'flashBlocks',
- title: 'Flash Blocks'
- },
- {
- method: 'boostedFlashBlocks',
- title: 'Boosted Flash Blocks'
- },
- {
- method: 'flashAllBlocksOn',
- title: 'Flash All On'
- },
- {
- method: 'flashAllBlocksOff',
- title: 'Flash All Off'
- },
- {
- method: 'pipesOn',
- title: 'Pipes On'
- },
- {
- method: 'pipesOff',
- title: 'Pipes Off'
- },
- {
- method: 'pipesSwap',
- title: 'Pipes Swap'
- },
- {
- method: 'pipesAllOn',
- title: 'Pipes All On'
- }
- ]
-}
diff --git a/example-projects/trippy/sketches/tunnel/frag.glsl b/example-projects/trippy/sketches/tunnel/frag.glsl
deleted file mode 100644
index 644f018b..00000000
--- a/example-projects/trippy/sketches/tunnel/frag.glsl
+++ /dev/null
@@ -1,48 +0,0 @@
-varying vec2 vUv;
-varying vec3 vWorldPosition;
-
-uniform vec2 iResolution;
-uniform float iTime;
-uniform float seed;
-uniform vec3 color1;
-uniform vec3 color2;
-
-#pragma glslify: import('./chunks/common.glsl')
-#pragma glslify: import('./chunks/fog_pars_fragment.glsl')
-
-vec2 GetGradient(vec2 intPos, float t) {
- float rand = fract(sin(dot(intPos, vec2(12.9898, 78.233))) * seed);;
- float angle = 6.283185 * rand + 4.0 * t * rand;
- return vec2(cos(angle), sin(angle));
-}
-
-
-float Pseudo3dNoise(vec3 pos) {
- vec2 i = floor(pos.xy);
- vec2 f = pos.xy - i;
- vec2 blend = f * f * (3.0 - 2.0 * f);
- float noiseVal =
- mix(
- mix(
- dot(GetGradient(i + vec2(0, 0), pos.z), f - vec2(0, 0)),
- dot(GetGradient(i + vec2(1, 0), pos.z), f - vec2(1, 0)),
- blend.x),
- mix(
- dot(GetGradient(i + vec2(0, 1), pos.z), f - vec2(0, 1)),
- dot(GetGradient(i + vec2(1, 1), pos.z), f - vec2(1, 1)),
- blend.x),
- blend.y
- );
- return noiseVal / 0.7; // normalize to about [-1..1]
-}
-
-
-void main() {
-
-
- vec2 uv = vUv.xy;
- float noiseVal = 0.5 + 0.5 * Pseudo3dNoise(vec3(uv * 1.0, iTime / 2.));
- noiseVal = mod(noiseVal, 0.1) * 10.;
- gl_FragColor = vec4(mix(color1, color2, noiseVal), 1.);
- #pragma glslify: import('./chunks/fog_fragment.glsl')
-}
diff --git a/example-projects/trippy/sketches/tunnel/index.js b/example-projects/trippy/sketches/tunnel/index.js
deleted file mode 100644
index 29ebb8fd..00000000
--- a/example-projects/trippy/sketches/tunnel/index.js
+++ /dev/null
@@ -1,117 +0,0 @@
-const THREE = require('three')
-const TWEEN = require('@tweenjs/tween.js')
-const Tower = require('./Tower')
-
-class Tunnel {
- constructor (scene) {
- scene.scene.fog = new THREE.FogExp2()
- this.root = new THREE.Group()
- const groupSize = 500
- const towerHeight = 10
- const towerWidth = 5
- const blockSize = groupSize / towerWidth
-
- this.isRotating = false
- this.colors = [0x004C48, 0x962515]
-
- this.rotator = new THREE.Object3D()
- this.rotator.position.z = 1000
- this.root.add(this.rotator)
-
- this.tower1 = new Tower(blockSize, this.colors, towerWidth, towerHeight, -towerHeight * blockSize / 2)
- this.tower2 = new Tower(blockSize, this.colors, towerWidth, towerHeight, towerHeight * blockSize / 2)
- this.rotator.add(this.tower1.group)
- this.rotator.add(this.tower2.group)
-
- this.rotatorProps = {
- rotZ: 0
- }
- }
-
- quarterTurn () {
- let diff = Math.round(this.rotatorProps.rotZ % (Math.PI / 4) * 1000) / 1000
-
- new TWEEN.Tween(this.rotatorProps)
- .to({ rotZ: this.rotatorProps.rotZ + ((Math.PI / 4) - diff) }, this.rotTweenSpeed)
- .easing(TWEEN.Easing.Quadratic.Out)
- .start()
- }
-
- removeBlocks () {
- this.tower1.removeBlocks()
- this.tower2.removeBlocks()
- }
-
- addBlocks () {
- this.tower1.addBlocks()
- this.tower2.addBlocks()
- }
-
- shiftBlocks () {
- this.tower1.shiftBlocks()
- this.tower2.shiftBlocks()
- }
-
- spinBlocks () {
- this.tower1.spinBlocks()
- this.tower2.spinBlocks()
- }
-
- flashBlocks () {
- this.tower1.flashBlocks()
- this.tower2.flashBlocks()
- }
-
- flashAllBlocksOn () {
- this.tower1.flashAllBlocksOn()
- this.tower2.flashAllBlocksOn()
- }
-
- flashAllBlocksOff () {
- this.tower1.flashAllBlocksOff()
- this.tower2.flashAllBlocksOff()
- }
-
- boostedFlashBlocks () {
- this.tower1.boostedFlashBlocks()
- this.tower2.boostedFlashBlocks()
- }
-
- pipesOn () {
- this.tower1.pipesOn()
- this.tower2.pipesOn()
- }
-
- pipesOff () {
- this.tower1.pipesOff()
- this.tower2.pipesOff()
- }
-
- pipesSwap () {
- this.tower1.pipesSwap()
- this.tower2.pipesSwap()
- }
-
- pipesAllOn () {
- this.tower1.pipesAllOn()
- this.tower2.pipesAllOn()
- }
-
- update (p, t, f) {
- const { rotSpeed, rotTweenSpeed, colorH, colorS, colorL } = p
- const color = new THREE.Color().setHSL(colorH, colorS, colorL)
- this.tower1.update(p, t, f, color)
- this.tower2.update(p, t, f, color)
-
- this.rotTweenSpeed = 1000 - (rotTweenSpeed * 1000)
-
- this.rotatorProps.rotZ += rotSpeed * 0.5
-
- this.rotator.rotation.z = this.rotatorProps.rotZ
- this.rotator.scale.set(25, 25, 25)
-
- TWEEN.update()
- }
-}
-
-module.exports = Tunnel
diff --git a/example-projects/trippy/sketches/tunnel/vert.glsl b/example-projects/trippy/sketches/tunnel/vert.glsl
deleted file mode 100644
index 72d85f61..00000000
--- a/example-projects/trippy/sketches/tunnel/vert.glsl
+++ /dev/null
@@ -1,17 +0,0 @@
-varying vec3 vWorldPosition;
-varying vec2 vUv;
-
-#pragma glslify: import('./chunks/fog_pars_vertex.glsl')
-
-void main() {
-
- vUv = uv;
-
- vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
- vWorldPosition = worldPosition.xyz;
-
- #pragma glslify: import('./chunks/fog_vertex.glsl')
-
- gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
-}
diff --git a/example-projects/yarn.lock b/example-projects/yarn.lock
deleted file mode 100644
index 5cad8fb9..00000000
--- a/example-projects/yarn.lock
+++ /dev/null
@@ -1,598 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@choojs/findup@^0.2.0":
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/@choojs/findup/-/findup-0.2.1.tgz#ac13c59ae7be6e1da64de0779a0a7f03d75615a3"
- dependencies:
- commander "^2.15.1"
-
-"@tweenjs/tween.js@^17.2.0":
- version "17.2.0"
- resolved "https://registry.yarnpkg.com/@tweenjs/tween.js/-/tween.js-17.2.0.tgz#21f89b709bafc4b303adae7a83b4f35a0d9e4796"
-
-acorn@^5.0.0:
- version "5.7.3"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
-
-balanced-match@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
-
-bl@^1.0.0:
- version "1.2.2"
- resolved "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
- dependencies:
- readable-stream "^2.3.5"
- safe-buffer "^5.1.1"
-
-brace-expansion@^1.1.7:
- version "1.1.11"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
- dependencies:
- balanced-match "^1.0.0"
- concat-map "0.0.1"
-
-buffer-from@^1.0.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
-
-commander@^2.15.1:
- version "2.19.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
-
-concat-map@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
-
-concat-stream@^1.5.2:
- version "1.6.2"
- resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
- dependencies:
- buffer-from "^1.0.0"
- inherits "^2.0.3"
- readable-stream "^2.2.2"
- typedarray "^0.0.6"
-
-core-util-is@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
-
-deep-equal@~1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
-
-deep-is@~0.1.3:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
-
-define-properties@^1.1.2:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
- dependencies:
- object-keys "^1.0.12"
-
-defined@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
-
-duplexify@^3.4.5:
- version "3.6.1"
- resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.1.tgz#b1a7a29c4abfd639585efaecce80d666b1e34125"
- dependencies:
- end-of-stream "^1.0.0"
- inherits "^2.0.1"
- readable-stream "^2.0.0"
- stream-shift "^1.0.0"
-
-end-of-stream@^1.0.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
- dependencies:
- once "^1.4.0"
-
-es-abstract@^1.5.0:
- version "1.12.0"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
- dependencies:
- es-to-primitive "^1.1.1"
- function-bind "^1.1.1"
- has "^1.0.1"
- is-callable "^1.1.3"
- is-regex "^1.0.4"
-
-es-to-primitive@^1.1.1:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
- dependencies:
- is-callable "^1.1.4"
- is-date-object "^1.0.1"
- is-symbol "^1.0.2"
-
-escodegen@^1.8.1:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589"
- dependencies:
- esprima "^3.1.3"
- estraverse "^4.2.0"
- esutils "^2.0.2"
- optionator "^0.8.1"
- optionalDependencies:
- source-map "~0.6.1"
-
-esprima@^3.1.3:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
-
-estraverse@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
-
-esutils@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
-
-events@^1.0.2:
- version "1.1.1"
- resolved "http://registry.npmjs.org/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
-
-falafel@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/falafel/-/falafel-2.1.0.tgz#96bb17761daba94f46d001738b3cedf3a67fe06c"
- dependencies:
- acorn "^5.0.0"
- foreach "^2.0.5"
- isarray "0.0.1"
- object-keys "^1.0.6"
-
-fast-levenshtein@~2.0.4:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
-
-for-each@~0.3.3:
- version "0.3.3"
- resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
- dependencies:
- is-callable "^1.1.3"
-
-foreach@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
-
-from2@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
- dependencies:
- inherits "^2.0.1"
- readable-stream "^2.0.0"
-
-fs.realpath@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
-
-function-bind@^1.0.2, function-bind@^1.1.1, function-bind@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
-
-glob@~7.1.2:
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
- dependencies:
- fs.realpath "^1.0.0"
- inflight "^1.0.4"
- inherits "2"
- minimatch "^3.0.4"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
-glsl-inject-defines@^1.0.1:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/glsl-inject-defines/-/glsl-inject-defines-1.0.3.tgz#dd1aacc2c17fcb2bd3fc32411c6633d0d7b60fd4"
- dependencies:
- glsl-token-inject-block "^1.0.0"
- glsl-token-string "^1.0.1"
- glsl-tokenizer "^2.0.2"
-
-glsl-resolve@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/glsl-resolve/-/glsl-resolve-0.0.1.tgz#894bef73910d792c81b5143180035d0a78af76d3"
- dependencies:
- resolve "^0.6.1"
- xtend "^2.1.2"
-
-glsl-token-assignments@^2.0.0:
- version "2.0.2"
- resolved "http://registry.npmjs.org/glsl-token-assignments/-/glsl-token-assignments-2.0.2.tgz#a5d82ab78499c2e8a6b83cb69495e6e665ce019f"
-
-glsl-token-defines@^1.0.0:
- version "1.0.0"
- resolved "http://registry.npmjs.org/glsl-token-defines/-/glsl-token-defines-1.0.0.tgz#cb892aa959936231728470d4f74032489697fa9d"
- dependencies:
- glsl-tokenizer "^2.0.0"
-
-glsl-token-depth@^1.1.0, glsl-token-depth@^1.1.1:
- version "1.1.2"
- resolved "http://registry.npmjs.org/glsl-token-depth/-/glsl-token-depth-1.1.2.tgz#23c5e30ee2bd255884b4a28bc850b8f791e95d84"
-
-glsl-token-descope@^1.0.2:
- version "1.0.2"
- resolved "http://registry.npmjs.org/glsl-token-descope/-/glsl-token-descope-1.0.2.tgz#0fc90ab326186b82f597b2e77dc9e21efcd32076"
- dependencies:
- glsl-token-assignments "^2.0.0"
- glsl-token-depth "^1.1.0"
- glsl-token-properties "^1.0.0"
- glsl-token-scope "^1.1.0"
-
-glsl-token-inject-block@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/glsl-token-inject-block/-/glsl-token-inject-block-1.1.0.tgz#e1015f5980c1091824adaa2625f1dfde8bd00034"
-
-glsl-token-properties@^1.0.0:
- version "1.0.1"
- resolved "http://registry.npmjs.org/glsl-token-properties/-/glsl-token-properties-1.0.1.tgz#483dc3d839f0d4b5c6171d1591f249be53c28a9e"
-
-glsl-token-scope@^1.1.0, glsl-token-scope@^1.1.1:
- version "1.1.2"
- resolved "http://registry.npmjs.org/glsl-token-scope/-/glsl-token-scope-1.1.2.tgz#a1728e78df24444f9cb93fd18ef0f75503a643b1"
-
-glsl-token-string@^1.0.1:
- version "1.0.1"
- resolved "http://registry.npmjs.org/glsl-token-string/-/glsl-token-string-1.0.1.tgz#59441d2f857de7c3449c945666021ece358e48ec"
-
-glsl-token-whitespace-trim@^1.0.0:
- version "1.0.0"
- resolved "http://registry.npmjs.org/glsl-token-whitespace-trim/-/glsl-token-whitespace-trim-1.0.0.tgz#46d1dfe98c75bd7d504c05d7d11b1b3e9cc93b10"
-
-glsl-tokenizer@^2.0.0, glsl-tokenizer@^2.0.2:
- version "2.1.5"
- resolved "https://registry.yarnpkg.com/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz#1c2e78c16589933c274ba278d0a63b370c5fee1a"
- dependencies:
- through2 "^0.6.3"
-
-glslify-bundle@^5.0.0:
- version "5.0.0"
- resolved "http://registry.npmjs.org/glslify-bundle/-/glslify-bundle-5.0.0.tgz#0252ada1ef9df30b660006e0bb21fd130b486e42"
- dependencies:
- glsl-inject-defines "^1.0.1"
- glsl-token-defines "^1.0.0"
- glsl-token-depth "^1.1.1"
- glsl-token-descope "^1.0.2"
- glsl-token-scope "^1.1.1"
- glsl-token-string "^1.0.1"
- glsl-token-whitespace-trim "^1.0.0"
- glsl-tokenizer "^2.0.2"
- murmurhash-js "^1.0.0"
- shallow-copy "0.0.1"
-
-glslify-deps@^1.2.5:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/glslify-deps/-/glslify-deps-1.3.1.tgz#dfa6962322454a91ecc4de25b5e710415b0c89ad"
- dependencies:
- "@choojs/findup" "^0.2.0"
- events "^1.0.2"
- glsl-resolve "0.0.1"
- glsl-tokenizer "^2.0.0"
- graceful-fs "^4.1.2"
- inherits "^2.0.1"
- map-limit "0.0.1"
- resolve "^1.0.0"
-
-glslify@^6.3.1:
- version "6.3.1"
- resolved "https://registry.yarnpkg.com/glslify/-/glslify-6.3.1.tgz#af74f4a47497603f21498ad14172396cddc8062f"
- dependencies:
- bl "^1.0.0"
- concat-stream "^1.5.2"
- duplexify "^3.4.5"
- falafel "^2.1.0"
- from2 "^2.3.0"
- glsl-resolve "0.0.1"
- glsl-token-whitespace-trim "^1.0.0"
- glslify-bundle "^5.0.0"
- glslify-deps "^1.2.5"
- minimist "^1.2.0"
- resolve "^1.1.5"
- stack-trace "0.0.9"
- static-eval "^2.0.0"
- tape "^4.6.0"
- through2 "^2.0.1"
- xtend "^4.0.0"
-
-graceful-fs@^4.1.2:
- version "4.1.11"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
-
-has-symbols@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
-
-has@^1.0.1, has@~1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
- dependencies:
- function-bind "^1.1.1"
-
-inflight@^1.0.4:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
- dependencies:
- once "^1.3.0"
- wrappy "1"
-
-inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
-
-is-callable@^1.1.3, is-callable@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
-
-is-date-object@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
-
-is-regex@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
- dependencies:
- has "^1.0.1"
-
-is-symbol@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38"
- dependencies:
- has-symbols "^1.0.0"
-
-isarray@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
-
-isarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
-
-levn@~0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
- dependencies:
- prelude-ls "~1.1.2"
- type-check "~0.3.2"
-
-lodash@^4.17.11:
- version "4.17.11"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
-
-map-limit@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/map-limit/-/map-limit-0.0.1.tgz#eb7961031c0f0e8d001bf2d56fab685d58822f38"
- dependencies:
- once "~1.3.0"
-
-minimatch@^3.0.4:
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
- dependencies:
- brace-expansion "^1.1.7"
-
-minimist@^1.2.0, minimist@~1.2.0:
- version "1.2.0"
- resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
-
-murmurhash-js@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51"
-
-object-inspect@~1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
-
-object-keys@^1.0.12, object-keys@^1.0.6:
- version "1.0.12"
- resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2"
-
-once@^1.3.0, once@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
- dependencies:
- wrappy "1"
-
-once@~1.3.0:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20"
- dependencies:
- wrappy "1"
-
-optionator@^0.8.1:
- version "0.8.2"
- resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
- dependencies:
- deep-is "~0.1.3"
- fast-levenshtein "~2.0.4"
- levn "~0.3.0"
- prelude-ls "~1.1.2"
- type-check "~0.3.2"
- wordwrap "~1.0.0"
-
-path-is-absolute@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
-
-path-parse@^1.0.5:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
-
-prelude-ls@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
-
-process-nextick-args@~2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
-
-"readable-stream@>=1.0.33-1 <1.1.0-0":
- version "1.0.34"
- resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.1"
- isarray "0.0.1"
- string_decoder "~0.10.x"
-
-readable-stream@^2.0.0, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.5:
- version "2.3.6"
- resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~2.0.0"
- safe-buffer "~5.1.1"
- string_decoder "~1.1.1"
- util-deprecate "~1.0.1"
-
-resolve@^0.6.1:
- version "0.6.3"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46"
-
-resolve@^1.0.0, resolve@^1.1.5:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
- dependencies:
- path-parse "^1.0.5"
-
-resolve@~1.7.1:
- version "1.7.1"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3"
- dependencies:
- path-parse "^1.0.5"
-
-resumer@~0.0.0:
- version "0.0.0"
- resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759"
- dependencies:
- through "~2.3.4"
-
-safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
-
-shallow-copy@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170"
-
-source-map@~0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
-
-stack-trace@0.0.9:
- version "0.0.9"
- resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695"
-
-static-eval@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.0.0.tgz#0e821f8926847def7b4b50cda5d55c04a9b13864"
- dependencies:
- escodegen "^1.8.1"
-
-stream-shift@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952"
-
-string.prototype.trim@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
- dependencies:
- define-properties "^1.1.2"
- es-abstract "^1.5.0"
- function-bind "^1.0.2"
-
-string_decoder@~0.10.x:
- version "0.10.31"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
-
-string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
- dependencies:
- safe-buffer "~5.1.0"
-
-tape@^4.6.0:
- version "4.9.1"
- resolved "https://registry.yarnpkg.com/tape/-/tape-4.9.1.tgz#1173d7337e040c76fbf42ec86fcabedc9b3805c9"
- dependencies:
- deep-equal "~1.0.1"
- defined "~1.0.0"
- for-each "~0.3.3"
- function-bind "~1.1.1"
- glob "~7.1.2"
- has "~1.0.3"
- inherits "~2.0.3"
- minimist "~1.2.0"
- object-inspect "~1.6.0"
- resolve "~1.7.1"
- resumer "~0.0.0"
- string.prototype.trim "~1.1.2"
- through "~2.3.8"
-
-three-addons@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/three-addons/-/three-addons-1.2.0.tgz#a36293e2489bdda08be8efc31291485b41de1560"
- dependencies:
- three "^0.92.0"
-
-three@^0.92.0:
- version "0.92.0"
- resolved "https://registry.yarnpkg.com/three/-/three-0.92.0.tgz#8d3d1f5af890e62da7f4cb45d20c09fa51057dcd"
-
-three@^0.97.0:
- version "0.97.0"
- resolved "https://registry.yarnpkg.com/three/-/three-0.97.0.tgz#76141e1b0ace14246fe9198a458fefddc98a4e30"
-
-through2@^0.6.3:
- version "0.6.5"
- resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48"
- dependencies:
- readable-stream ">=1.0.33-1 <1.1.0-0"
- xtend ">=4.0.0 <4.1.0-0"
-
-through2@^2.0.1:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
- dependencies:
- readable-stream "^2.1.5"
- xtend "~4.0.1"
-
-through@~2.3.4, through@~2.3.8:
- version "2.3.8"
- resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
-
-type-check@~0.3.2:
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
- dependencies:
- prelude-ls "~1.1.2"
-
-typedarray@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
-
-util-deprecate@~1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
-
-wordwrap@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
-
-wrappy@1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
-
-"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
-
-xtend@^2.1.2:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.2.0.tgz#eef6b1f198c1c8deafad8b1765a04dad4a01c5a9"
diff --git a/external-assets/hedron.blend b/external-assets/hedron.blend
new file mode 100644
index 00000000..93235e98
Binary files /dev/null and b/external-assets/hedron.blend differ
diff --git a/external-assets/icon.svg b/external-assets/icon.svg
new file mode 100644
index 00000000..34e4cab7
--- /dev/null
+++ b/external-assets/icon.svg
@@ -0,0 +1,140 @@
+
+
+
+
diff --git a/mockTests/inputLinks.test.js b/mockTests/inputLinks.test.js
new file mode 100644
index 00000000..df546a67
--- /dev/null
+++ b/mockTests/inputLinks.test.js
@@ -0,0 +1,108 @@
+/** * SETUP ***/
+
+import proxyquire from 'proxyquire'
+import listen from 'redux-action-listeners'
+import { createStore, applyMiddleware, combineReducers } from 'redux'
+
+import inputsReducer from '../src/store/inputs/reducer'
+import nodesReducer from '../src/store/nodes/reducer'
+import inputLinksReducer from '../src/store/inputLinks/reducer'
+
+import { constructMidiId } from '../src/utils/midiMessage'
+
+import { uInputLinkUpdateMidiInput } from '../src/store/inputLinks/actions'
+
+const rootReducer = combineReducers(
+ {
+ nodes: nodesReducer,
+ inputs: inputsReducer,
+ inputLinks: inputLinksReducer,
+ }
+)
+
+let uniqueId
+const uid = () => {
+ uniqueId++
+ return 'id_' + uniqueId
+}
+
+const inputLinksListener = proxyquire('../src/store/inputLinks/listener', {
+ 'uid': uid,
+}).default
+
+const rootListener = {
+ types: 'all',
+
+ handleAction (action, dispatched, store) {
+ inputLinksListener(action, store)
+ },
+}
+
+/** * TEST ***/
+
+test('(mock) Input Links - Update link midi input', () => {
+ uniqueId = 0
+ const messageType = 'controlChange'
+ const noteNum = 100
+ const channel = 13
+
+ // State starts assuming some dropdown value have changed
+ const startState = {
+ nodes: {
+ option_a: {
+ key: 'channel',
+ value: channel,
+ },
+ option_b: {
+ key: 'messageType',
+ value: messageType,
+ },
+ option_c: {
+ key: 'noteNum',
+ value: noteNum,
+ },
+ option_x: {
+ key: 'foo',
+ value: 1,
+ },
+ link_a: {
+ id: 'link_a',
+ midiOptionIds: [
+ 'option_a', 'option_b', 'option_c',
+ ],
+ input: {
+ id: 'midi_0_0',
+ type: 'midi',
+ },
+ },
+ },
+ inputs: {
+ midi_0_0: {
+ assignedLinkIds: [
+ 'link_a',
+ ],
+ },
+ },
+ inputLinks: {
+ nodeIds: ['link_a'],
+ },
+ }
+
+ const store = createStore(rootReducer, startState, applyMiddleware(listen(rootListener)))
+
+ let state
+
+ // The dropdown value has changed and so this action would be dispatched
+ store.dispatch(uInputLinkUpdateMidiInput('link_a'))
+ state = store.getState()
+
+ const oldInput = state.inputs.midi_0_0
+ expect(oldInput.assignedLinkIds.length).toBe(0)
+
+ const newInputId = constructMidiId(messageType, noteNum, channel)
+ const newInput = state.inputs[newInputId]
+ expect(newInput.assignedLinkIds[0]).toBe('link_a')
+
+ const link = state.nodes.link_a
+ expect(link.input.id).toBe(newInputId)
+})
diff --git a/mockTests/scenes.spec.js b/mockTests/scenes.spec.js
index 718c4c6d..61deed47 100644
--- a/mockTests/scenes.spec.js
+++ b/mockTests/scenes.spec.js
@@ -1,424 +1,426 @@
-import test from 'tape'
-import proxyquire from 'proxyquire'
-import listen from 'redux-action-listeners'
-import { createStore, applyMiddleware, combineReducers } from 'redux'
-import createSagaMiddleware from 'redux-saga'
-const sagaMiddleware = createSagaMiddleware()
-import { uSceneCreate, uSceneDelete, sceneSketchSelect, sceneRename } from '../src/store/scenes/actions'
-
-import { fork } from 'redux-saga/effects'
-import { watchNodes } from '../src/store/nodes/sagas'
-import sketchesReducer from '../src/store/sketches/reducer'
-import scenesReducer from '../src/store/scenes/reducer'
-import nodesReducer from '../src/store/nodes/reducer'
-import uiReducer from '../src/store/ui/reducer'
-import linkableActionsReducer from '../src/store/linkableActions/reducer'
-import linkableActionsListener from '../src/store/linkableActions/listener'
-
-const rootReducer = combineReducers(
- {
- nodes: nodesReducer,
- sketches: sketchesReducer,
- scenes: scenesReducer,
- linkableActions: linkableActionsReducer
- }
-)
-
-let uniqueId
-const uid = () => {
- uniqueId++
- return 'id_' + uniqueId
-}
-
-const sceneUtils = {
- generateSceneLinkableActionIds: id => ({
- foo: {
- id: 'f01',
- action: { type: 'FOO', payload: { id } }
- },
- bar: {
- id: 'b01',
- action: { type: 'BAR', payload: { id } }
- }
- })
-}
-
-const sketchesListener = proxyquire('../src/store/sketches/listener', {
- 'uid': uid
-}).default
-
-const scenesListener = proxyquire('../src/store/scenes/listener', {
- 'uid': uid,
- './utils': sceneUtils
-}).default
-
-function* rootSaga (dispatch) {
- yield [
- fork(watchNodes)
- ]
-}
-
-const rootListener = {
- types: 'all',
-
- handleAction (action, dispatched, store) {
- scenesListener(action, store)
- sketchesListener(action, store)
- linkableActionsListener(action, store)
- }
-}
-
-test('(mock) Scenes - Add Scene', (t) => {
- uniqueId = 0
-
- const rootReducer = combineReducers(
- {
- nodes: nodesReducer,
- sketches: sketchesReducer,
- scenes: scenesReducer,
- ui: uiReducer,
- linkableActions: linkableActionsReducer
- }
- )
-
- const store = createStore(rootReducer, {
- nodes: {},
- sketches: {}
- }, applyMiddleware(sagaMiddleware, listen(rootListener)))
- sagaMiddleware.run(rootSaga, store.dispatch)
-
- let state
-
- state = store.getState()
- t.deepEqual(state.scenes.items, {},
- 'scenes start with empty items')
-
- store.dispatch(uSceneCreate())
- state = store.getState()
- t.deepEqual(state.scenes.items,
- {
- id_1: {
- id: 'id_1',
- title: 'New Scene',
- selectedSketchId: false,
- sketchIds: [],
- linkableActionIds: {
- foo: 'f01',
- bar: 'b01'
- }
- }
- },
- 'scene is added to items list when sceneCreate is dispatched')
-
- t.equal(state.scenes.currentSceneId, 'id_1',
- 'scene just created is made current'
- )
-
- t.deepEqual(state.scenes.channels, {
- A: 'id_1',
- B: false
- },
- 'because is first scene, id_1 added to channel A'
- )
-
- t.deepEqual(state.linkableActions, {
- f01: {
- id: 'f01',
- action: { type: 'FOO', payload: { 'id': 'id_1' } },
- inputLinkIds: []
- },
- b01: {
- id: 'b01',
- action: { type: 'BAR', payload: { 'id': 'id_1' } },
- inputLinkIds: []
- }
- },
- 'linkable actions created'
- )
-
- t.deepEqual(state.ui.isEditing,
- {
- id: 'id_1',
- type: 'sceneTitle'
- }
- , 'UI opens to editing scene')
-
- store.dispatch(uSceneCreate())
- state = store.getState()
- t.deepEqual(state.scenes.items,
- {
- id_1: {
- id: 'id_1',
- title: 'New Scene',
- selectedSketchId: false,
- sketchIds: [],
- linkableActionIds: {
- foo: 'f01',
- bar: 'b01'
- }
- },
- id_2: {
- id: 'id_2',
- title: 'New Scene',
- selectedSketchId: false,
- sketchIds: [],
- linkableActionIds: {
- foo: 'f01',
- bar: 'b01'
- }
- }
- },
- 'scene is added to items list when sceneCreate is dispatched')
- t.equal(state.scenes.currentSceneId, 'id_2',
- 'scene just created is made current'
- )
-
- t.deepEqual(state.scenes.channels, {
- A: 'id_1',
- B: false
- },
- 'because is NOT first scene, channels remain untouched'
- )
-
- t.deepEqual(state.ui.isEditing,
- {
- id: 'id_2',
- type: 'sceneTitle'
- }
- , 'UI opens to editing scene')
-
- t.end()
-})
-
-test('(mock) Scenes - Delete Scene', (t) => {
- const store = createStore(rootReducer, {
- nodes: {
- node_01: {},
- node_02: {},
- node_03: {}
- },
- sketches: {
- sketch_01: {
- title: 'Foo',
- moduleId: 'foo',
- paramIds: [],
- shotIds: [],
- openedNodes: {}
- },
- sketch_02: {
- title: 'Bar',
- moduleId: 'bar',
- paramIds: ['node_01', 'node_02'],
- shotIds: ['node_03'],
- openedNodes: {}
- }
- },
- scenes: {
- currentSceneId: 'id_1',
- channels: {
- A: 'id_1',
- B: 'id_2'
- },
- items: {
- id_1: {
- id: 'id_1',
- sketchIds: [],
- linkableActionIds: {}
- },
- id_2: {
- id: 'id_2',
- sketchIds: ['sketch_01', 'sketch_02'],
- linkableActionIds: {
- foo: 'f01',
- bar: 'b01'
- }
- }
- }
- },
- linkableActions: {
- f01: {
- id: 'f01',
- inputLinkIds: []
- },
- b01: {
- id: 'b01',
- inputLinkIds: ['i01']
- }
- }
- }, applyMiddleware(sagaMiddleware, listen(rootListener)))
- sagaMiddleware.run(rootSaga, store.dispatch)
-
- let state
-
- store.dispatch(uSceneDelete('id_1'))
- state = store.getState()
- t.deepEqual(state.scenes.items,
- {
- id_2: {
- id: 'id_2',
- sketchIds: ['sketch_01', 'sketch_02'],
- linkableActionIds: {
- foo: 'f01',
- bar: 'b01'
- }
- }
- },
- 'Scene deleted with no sketches just removes that scene')
- t.equal(state.scenes.currentSceneId, 'id_2',
- 'currentSceneId is changed to last item in list'
- )
-
- t.deepEqual(state.scenes.channels, {
- A: false,
- B: 'id_2'
- },
- 'Scene id is removed from channel'
- )
-
- t.equal(Object.keys(state.nodes).length, 3, 'Nodes kept the same')
- t.equal(Object.keys(state.sketches).length, 2, 'Sketches kept the same')
- t.equal(Object.keys(state.linkableActions).length, 2, 'linkableActions kept the same')
-
- store.dispatch(uSceneDelete('id_2'))
- state = store.getState()
-
- t.equal(Object.keys(state.scenes.items).length, 0, 'Last scene deleted, scenes are now 0')
- t.equal(state.scenes.currentSceneId, false, 'Last scene deleted, currentSceneId is now false')
- t.equal(Object.keys(state.nodes).length, 0, 'Last scene deleted, nodes are now 0')
- t.equal(Object.keys(state.sketches).length, 0, 'Last scene deleted, sketches are now 0')
- t.equal(Object.keys(state.linkableActions).length, 0, 'Last scene deleted, linkableActions are now 0')
- t.deepEqual(state.scenes.channels, {
- A: false,
- B: false
- },
- 'Scene id is removed from channel'
- )
-
- t.end()
-})
-
-test('(mock) Scenes - Select Sketch', (t) => {
- const store = createStore(rootReducer, {
- nodes: {
- },
- sketches: {
- },
- scenes: {
- items: {
- id_1: {
- id: 'id_1',
- selectedSketchId: false,
- sketchIds: ['sketch_03']
- },
- id_2: {
- id: 'id_2',
- selectedSketchId: 'sketch_01',
- sketchIds: ['sketch_01', 'sketch_02']
- }
- }
- }
- }, applyMiddleware(sagaMiddleware, listen(rootListener)))
- sagaMiddleware.run(rootSaga, store.dispatch)
-
- let state
-
- store.dispatch(sceneSketchSelect('id_1', 'sketch_03'))
- state = store.getState()
- t.deepEqual(state.scenes,
- {
- items: {
- id_1: {
- id: 'id_1',
- selectedSketchId: 'sketch_03',
- sketchIds: ['sketch_03']
- },
- id_2: {
- id: 'id_2',
- selectedSketchId: 'sketch_01',
- sketchIds: ['sketch_01', 'sketch_02']
- }
- }
- },
- 'Sketch id updated when sketch selected')
-
- store.dispatch(sceneSketchSelect('id_2', 'sketch_01'))
- state = store.getState()
- t.deepEqual(state.scenes,
- {
- items: {
- id_1: {
- id: 'id_1',
- selectedSketchId: 'sketch_03',
- sketchIds: ['sketch_03']
- },
- id_2: {
- id: 'id_2',
- selectedSketchId: 'sketch_01',
- sketchIds: ['sketch_01', 'sketch_02']
- }
- }
- },
- 'Sketch id updated when sketch selected')
-
- t.end()
-})
-
-test('(mock) Scenes - Rename', (t) => {
- const store = createStore(rootReducer, {
- nodes: {
- },
- sketches: {
- },
- scenes: {
- items: {
- id_1: {
- title: 'Foo Title',
- id: 'id_1'
- },
- id_2: {
- title: 'Bar Title',
- id: 'id_2'
- }
- }
- }
- }, applyMiddleware(sagaMiddleware, listen(rootListener)))
- sagaMiddleware.run(rootSaga, store.dispatch)
-
- let state
-
- store.dispatch(sceneRename('id_1', 'Lorem Ipsum'))
- state = store.getState()
- t.deepEqual(state.scenes,
- {
- items: {
- id_1: {
- title: 'Lorem Ipsum',
- id: 'id_1'
- },
- id_2: {
- title: 'Bar Title',
- id: 'id_2'
- }
- }
- },
- 'Scene title updated')
-
- store.dispatch(sceneRename('id_2', 'Ipsum Dollor'))
- state = store.getState()
- t.deepEqual(state.scenes,
- {
- items: {
- id_1: {
- title: 'Lorem Ipsum',
- id: 'id_1'
- },
- id_2: {
- title: 'Ipsum Dollor',
- id: 'id_2'
- }
- }
- },
- 'Scene title updated')
-
- t.end()
-})
+// DISABLED. Need to move over to jest to allow "window" global
+
+// import test from 'tape'
+// import proxyquire from 'proxyquire'
+// import listen from 'redux-action-listeners'
+// import { createStore, applyMiddleware, combineReducers } from 'redux'
+// import createSagaMiddleware from 'redux-saga'
+// const sagaMiddleware = createSagaMiddleware()
+// import { uSceneCreate, uSceneDelete, sceneSketchSelect, sceneRename } from '../src/store/scenes/actions'
+
+// import { fork } from 'redux-saga/effects'
+// import { watchNodes } from '../src/store/nodes/sagas'
+// import sketchesReducer from '../src/store/sketches/reducer'
+// import scenesReducer from '../src/store/scenes/reducer'
+// import nodesReducer from '../src/store/nodes/reducer'
+// import uiReducer from '../src/store/ui/reducer'
+// import linkableActionsReducer from '../src/store/linkableActions/reducer'
+// import linkableActionsListener from '../src/store/linkableActions/listener'
+
+// const rootReducer = combineReducers(
+// {
+// nodes: nodesReducer,
+// sketches: sketchesReducer,
+// scenes: scenesReducer,
+// linkableActions: linkableActionsReducer,
+// }
+// )
+
+// let uniqueId
+// const uid = () => {
+// uniqueId++
+// return 'id_' + uniqueId
+// }
+
+// const sceneUtils = {
+// generateSceneLinkableActionIds: id => ({
+// foo: {
+// id: 'f01',
+// action: { type: 'FOO', payload: { id } },
+// },
+// bar: {
+// id: 'b01',
+// action: { type: 'BAR', payload: { id } },
+// },
+// }),
+// }
+
+// const sketchesListener = proxyquire('../src/store/sketches/listener', {
+// 'uid': uid,
+// }).default
+
+// const scenesListener = proxyquire('../src/store/scenes/listener', {
+// 'uid': uid,
+// './utils': sceneUtils,
+// }).default
+
+// function* rootSaga (dispatch) {
+// yield [
+// fork(watchNodes),
+// ]
+// }
+
+// const rootListener = {
+// types: 'all',
+
+// handleAction (action, dispatched, store) {
+// scenesListener(action, store)
+// sketchesListener(action, store)
+// linkableActionsListener(action, store)
+// },
+// }
+
+// test('(mock) Scenes - Add Scene', (t) => {
+// uniqueId = 0
+
+// const rootReducer = combineReducers(
+// {
+// nodes: nodesReducer,
+// sketches: sketchesReducer,
+// scenes: scenesReducer,
+// ui: uiReducer,
+// linkableActions: linkableActionsReducer,
+// }
+// )
+
+// const store = createStore(rootReducer, {
+// nodes: {},
+// sketches: {},
+// }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+// sagaMiddleware.run(rootSaga, store.dispatch)
+
+// let state
+
+// state = store.getState()
+// t.deepEqual(state.scenes.items, {},
+// 'scenes start with empty items')
+
+// store.dispatch(uSceneCreate())
+// state = store.getState()
+// t.deepEqual(state.scenes.items,
+// {
+// id_1: {
+// id: 'id_1',
+// title: 'New Scene',
+// selectedSketchId: false,
+// sketchIds: [],
+// linkableActionIds: {
+// foo: 'f01',
+// bar: 'b01',
+// },
+// },
+// },
+// 'scene is added to items list when sceneCreate is dispatched')
+
+// t.equal(state.scenes.currentSceneId, 'id_1',
+// 'scene just created is made current'
+// )
+
+// t.deepEqual(state.scenes.channels, {
+// A: 'id_1',
+// B: false,
+// },
+// 'because is first scene, id_1 added to channel A'
+// )
+
+// t.deepEqual(state.linkableActions, {
+// f01: {
+// id: 'f01',
+// action: { type: 'FOO', payload: { 'id': 'id_1' } },
+// inputLinkIds: [],
+// },
+// b01: {
+// id: 'b01',
+// action: { type: 'BAR', payload: { 'id': 'id_1' } },
+// inputLinkIds: [],
+// },
+// },
+// 'linkable actions created'
+// )
+
+// t.deepEqual(state.ui.isEditing,
+// {
+// id: 'id_1',
+// type: 'sceneTitle',
+// }
+// , 'UI opens to editing scene')
+
+// store.dispatch(uSceneCreate())
+// state = store.getState()
+// t.deepEqual(state.scenes.items,
+// {
+// id_1: {
+// id: 'id_1',
+// title: 'New Scene',
+// selectedSketchId: false,
+// sketchIds: [],
+// linkableActionIds: {
+// foo: 'f01',
+// bar: 'b01',
+// },
+// },
+// id_2: {
+// id: 'id_2',
+// title: 'New Scene',
+// selectedSketchId: false,
+// sketchIds: [],
+// linkableActionIds: {
+// foo: 'f01',
+// bar: 'b01',
+// },
+// },
+// },
+// 'scene is added to items list when sceneCreate is dispatched')
+// t.equal(state.scenes.currentSceneId, 'id_2',
+// 'scene just created is made current'
+// )
+
+// t.deepEqual(state.scenes.channels, {
+// A: 'id_1',
+// B: false,
+// },
+// 'because is NOT first scene, channels remain untouched'
+// )
+
+// t.deepEqual(state.ui.isEditing,
+// {
+// id: 'id_2',
+// type: 'sceneTitle',
+// }
+// , 'UI opens to editing scene')
+
+// t.end()
+// })
+
+// test('(mock) Scenes - Delete Scene', (t) => {
+// const store = createStore(rootReducer, {
+// nodes: {
+// node_01: {},
+// node_02: {},
+// node_03: {},
+// },
+// sketches: {
+// sketch_01: {
+// title: 'Foo',
+// moduleId: 'foo',
+// paramIds: [],
+// shotIds: [],
+// openedNodes: {},
+// },
+// sketch_02: {
+// title: 'Bar',
+// moduleId: 'bar',
+// paramIds: ['node_01', 'node_02'],
+// shotIds: ['node_03'],
+// openedNodes: {},
+// },
+// },
+// scenes: {
+// currentSceneId: 'id_1',
+// channels: {
+// A: 'id_1',
+// B: 'id_2',
+// },
+// items: {
+// id_1: {
+// id: 'id_1',
+// sketchIds: [],
+// linkableActionIds: {},
+// },
+// id_2: {
+// id: 'id_2',
+// sketchIds: ['sketch_01', 'sketch_02'],
+// linkableActionIds: {
+// foo: 'f01',
+// bar: 'b01',
+// },
+// },
+// },
+// },
+// linkableActions: {
+// f01: {
+// id: 'f01',
+// inputLinkIds: [],
+// },
+// b01: {
+// id: 'b01',
+// inputLinkIds: ['i01'],
+// },
+// },
+// }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+// sagaMiddleware.run(rootSaga, store.dispatch)
+
+// let state
+
+// store.dispatch(uSceneDelete('id_1'))
+// state = store.getState()
+// t.deepEqual(state.scenes.items,
+// {
+// id_2: {
+// id: 'id_2',
+// sketchIds: ['sketch_01', 'sketch_02'],
+// linkableActionIds: {
+// foo: 'f01',
+// bar: 'b01',
+// },
+// },
+// },
+// 'Scene deleted with no sketches just removes that scene')
+// t.equal(state.scenes.currentSceneId, 'id_2',
+// 'currentSceneId is changed to last item in list'
+// )
+
+// t.deepEqual(state.scenes.channels, {
+// A: false,
+// B: 'id_2',
+// },
+// 'Scene id is removed from channel'
+// )
+
+// t.equal(Object.keys(state.nodes).length, 3, 'Nodes kept the same')
+// t.equal(Object.keys(state.sketches).length, 2, 'Sketches kept the same')
+// t.equal(Object.keys(state.linkableActions).length, 2, 'linkableActions kept the same')
+
+// store.dispatch(uSceneDelete('id_2'))
+// state = store.getState()
+
+// t.equal(Object.keys(state.scenes.items).length, 0, 'Last scene deleted, scenes are now 0')
+// t.equal(state.scenes.currentSceneId, false, 'Last scene deleted, currentSceneId is now false')
+// t.equal(Object.keys(state.nodes).length, 0, 'Last scene deleted, nodes are now 0')
+// t.equal(Object.keys(state.sketches).length, 0, 'Last scene deleted, sketches are now 0')
+// t.equal(Object.keys(state.linkableActions).length, 0, 'Last scene deleted, linkableActions are now 0')
+// t.deepEqual(state.scenes.channels, {
+// A: false,
+// B: false,
+// },
+// 'Scene id is removed from channel'
+// )
+
+// t.end()
+// })
+
+// test('(mock) Scenes - Select Sketch', (t) => {
+// const store = createStore(rootReducer, {
+// nodes: {
+// },
+// sketches: {
+// },
+// scenes: {
+// items: {
+// id_1: {
+// id: 'id_1',
+// selectedSketchId: false,
+// sketchIds: ['sketch_03'],
+// },
+// id_2: {
+// id: 'id_2',
+// selectedSketchId: 'sketch_01',
+// sketchIds: ['sketch_01', 'sketch_02'],
+// },
+// },
+// },
+// }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+// sagaMiddleware.run(rootSaga, store.dispatch)
+
+// let state
+
+// store.dispatch(sceneSketchSelect('id_1', 'sketch_03'))
+// state = store.getState()
+// t.deepEqual(state.scenes,
+// {
+// items: {
+// id_1: {
+// id: 'id_1',
+// selectedSketchId: 'sketch_03',
+// sketchIds: ['sketch_03'],
+// },
+// id_2: {
+// id: 'id_2',
+// selectedSketchId: 'sketch_01',
+// sketchIds: ['sketch_01', 'sketch_02'],
+// },
+// },
+// },
+// 'Sketch id updated when sketch selected')
+
+// store.dispatch(sceneSketchSelect('id_2', 'sketch_01'))
+// state = store.getState()
+// t.deepEqual(state.scenes,
+// {
+// items: {
+// id_1: {
+// id: 'id_1',
+// selectedSketchId: 'sketch_03',
+// sketchIds: ['sketch_03'],
+// },
+// id_2: {
+// id: 'id_2',
+// selectedSketchId: 'sketch_01',
+// sketchIds: ['sketch_01', 'sketch_02'],
+// },
+// },
+// },
+// 'Sketch id updated when sketch selected')
+
+// t.end()
+// })
+
+// test('(mock) Scenes - Rename', (t) => {
+// const store = createStore(rootReducer, {
+// nodes: {
+// },
+// sketches: {
+// },
+// scenes: {
+// items: {
+// id_1: {
+// title: 'Foo Title',
+// id: 'id_1',
+// },
+// id_2: {
+// title: 'Bar Title',
+// id: 'id_2',
+// },
+// },
+// },
+// }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+// sagaMiddleware.run(rootSaga, store.dispatch)
+
+// let state
+
+// store.dispatch(sceneRename('id_1', 'Lorem Ipsum'))
+// state = store.getState()
+// t.deepEqual(state.scenes,
+// {
+// items: {
+// id_1: {
+// title: 'Lorem Ipsum',
+// id: 'id_1',
+// },
+// id_2: {
+// title: 'Bar Title',
+// id: 'id_2',
+// },
+// },
+// },
+// 'Scene title updated')
+
+// store.dispatch(sceneRename('id_2', 'Ipsum Dollor'))
+// state = store.getState()
+// t.deepEqual(state.scenes,
+// {
+// items: {
+// id_1: {
+// title: 'Lorem Ipsum',
+// id: 'id_1',
+// },
+// id_2: {
+// title: 'Ipsum Dollor',
+// id: 'id_2',
+// },
+// },
+// },
+// 'Scene title updated')
+
+// t.end()
+// })
diff --git a/mockTests/sketches.spec.js b/mockTests/sketches.spec.js
deleted file mode 100644
index acf23ce2..00000000
--- a/mockTests/sketches.spec.js
+++ /dev/null
@@ -1,884 +0,0 @@
-import test from 'tape'
-import proxyquire from 'proxyquire'
-import listen from 'redux-action-listeners'
-import { createStore, applyMiddleware, combineReducers } from 'redux'
-import createSagaMiddleware from 'redux-saga'
-const sagaMiddleware = createSagaMiddleware()
-import { uSketchCreate, uSketchDelete, uSketchReimport } from '../src/store/sketches/actions'
-
-import { fork } from 'redux-saga/effects'
-import { watchNodes } from '../src/store/nodes/sagas'
-import sketchesReducer from '../src/store/sketches/reducer'
-import availableModulesReducer from '../src/store/availableModules/reducer'
-import nodesReducer from '../src/store/nodes/reducer'
-import scenesReducer from '../src/store/scenes/reducer'
-
-const rootReducer = combineReducers(
- {
- nodes: nodesReducer,
- availableModules: availableModulesReducer,
- sketches: sketchesReducer,
- scenes: scenesReducer
- }
-)
-
-let uniqueId
-const uid = () => {
- uniqueId++
- return 'id_' + uniqueId
-}
-
-const sketchesListener = proxyquire('../src/store/sketches/listener', {
- 'uid': uid
-}).default
-
-const scenesListener = proxyquire('../src/store/scenes/listener', {
- 'uid': uid
-}).default
-
-const rootListener = {
- types: 'all',
-
- handleAction (action, dispatched, store) {
- sketchesListener(action, store)
- scenesListener(action, store)
- }
-}
-
-function* rootSaga (dispatch) {
- yield [
- fork(watchNodes)
- ]
-}
-
-test('(mock) Sketches - Add/Delete Sketch', (t) => {
- uniqueId = 0
-
- const rootReducer = combineReducers(
- {
- nodes: nodesReducer,
- availableModules: availableModulesReducer,
- sketches: sketchesReducer,
- scenes: scenesReducer,
- router: () => ({
- location: {
- pathname: 'scenes/addSketch/scene_02'
- }
- })
- }
- )
-
- const store = createStore(rootReducer, {
- availableModules: {
- foo: {
- defaultTitle: 'Foo',
- params: [
- {
- key: 'speed',
- title: 'Speed',
- defaultValue: 0.5
- }
- ],
- shots: []
- },
- bar: {
- defaultTitle: 'Bar',
- params: [
- {
- key: 'scale',
- title: 'Scale',
- defaultValue: 0.2
- },
- {
- key: 'color',
- title: 'Color',
- defaultValue: 0.1
- }
- ],
- shots: [
- {
- method: 'explode',
- title: 'Explode'
- }
- ]
- },
- boring: {
- defaultTitle: 'Boring'
- }
- },
- nodes: {},
- sketches: {},
- scenes: {
- currentSceneId: 'scene_02',
- items: {
- scene_01: {
- id: 'scene_01',
- selectedSketchId: false,
- sketchIds: []
- },
- scene_02: {
- id: 'scene_02',
- selectedSketchId: false,
- sketchIds: []
- }
- }
- }
- }, applyMiddleware(sagaMiddleware, listen(rootListener)))
- sagaMiddleware.run(rootSaga, store.dispatch)
-
- let state
-
- state = store.getState()
- t.deepEqual(state.nodes, {}, 'nodes start empty')
-
- store.dispatch(uSketchCreate('foo', 'scene_01'))
- state = store.getState()
-
- t.deepEqual(state.scenes.items, {
- scene_01: {
- id: 'scene_01',
- selectedSketchId: 'id_1',
- sketchIds: ['id_1']
- },
- scene_02: {
- id: 'scene_02',
- selectedSketchId: false,
- sketchIds: []
- }
- }, 'After creating sketch, sketch id is added to scene, selectedSketchId is set')
-
- t.deepEqual(state.sketches, {
- id_1: {
- title: 'Foo',
- moduleId: 'foo',
- paramIds: ['id_2'],
- shotIds: [],
- openedNodes: {}
- }
- }, 'After creating sketch, sketch item is created')
-
- t.deepEqual(state.nodes, {
- id_2: {
- id: 'id_2',
- title: 'Speed',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- }
- }, 'After creating sketch, node item is created for param')
-
- store.dispatch(uSketchCreate('bar', 'scene_01'))
- state = store.getState()
-
- t.deepEqual(state.scenes.items, {
- scene_01: {
- id: 'scene_01',
- sketchIds: ['id_1', 'id_3'],
- selectedSketchId: 'id_3'
- },
- scene_02: {
- id: 'scene_02',
- selectedSketchId: false,
- sketchIds: []
- }
- }, 'After creating sketch, sketch id is added to scene')
-
- t.deepEqual(state.sketches, {
- id_1: {
- title: 'Foo',
- moduleId: 'foo',
- paramIds: ['id_2'],
- shotIds: [],
- openedNodes: {}
- },
- id_3: {
- title: 'Bar',
- moduleId: 'bar',
- paramIds: ['id_4', 'id_5'],
- shotIds: ['id_6'],
- openedNodes: {}
- }
- }, 'After creating sketch, sketch item is created')
-
- t.deepEqual(state.nodes, {
- id_2: {
- id: 'id_2',
- title: 'Speed',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- },
- id_4: {
- id: 'id_4',
- title: 'Scale',
- value: 0.2,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'scale'
- },
- id_5: {
- id: 'id_5',
- title: 'Color',
- value: 0.1,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'color'
- },
- id_6: {
- id: 'id_6',
- title: 'Explode',
- value: 0,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'shot',
- method: 'explode',
- sketchId: 'id_3'
- }
- }, 'After creating sketch, node items are created for params and shot')
-
- store.dispatch(uSketchDelete('id_1', 'scene_01'))
- state = store.getState()
-
- t.deepEqual(state.scenes.items, {
- scene_01: {
- id: 'scene_01',
- sketchIds: ['id_3'],
- selectedSketchId: 'id_3'
- },
- scene_02: {
- id: 'scene_02',
- sketchIds: [],
- selectedSketchId: false
- }
- }, 'After deleting sketch, sketch id is removed from scene, selectedSketchId becomes last in list')
-
- t.deepEqual(state.sketches, {
- id_3: {
- title: 'Bar',
- moduleId: 'bar',
- paramIds: ['id_4', 'id_5'],
- shotIds: ['id_6'],
- openedNodes: {}
- }
- }, 'After deleting sketch, sketch item is removed')
-
- t.deepEqual(state.nodes, {
- id_4: {
- id: 'id_4',
- title: 'Scale',
- value: 0.2,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'scale'
- },
- id_5: {
- id: 'id_5',
- title: 'Color',
- value: 0.1,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'color'
- },
- id_6: {
- id: 'id_6',
- title: 'Explode',
- value: 0,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'shot',
- method: 'explode',
- sketchId: 'id_3'
- }
- }, 'After deleting sketch, node items are removed')
-
- store.dispatch(uSketchDelete('id_3', 'scene_01'))
- state = store.getState()
-
- t.deepEqual(state.scenes.items, {
- scene_01: {
- id: 'scene_01',
- sketchIds: [],
- selectedSketchId: false
- },
- scene_02: {
- id: 'scene_02',
- sketchIds: [],
- selectedSketchId: false
- }
- }, 'After deleting sketch, sketch id is removed from scene, selected sketchId becomes false (none left)')
-
- t.deepEqual(state.sketches, {}, 'After deleting sketch, sketch item is removed')
- t.deepEqual(state.nodes, {}, 'After deleting sketch, node items are removed')
-
- store.dispatch(uSketchCreate('boring'))
- state = store.getState()
-
- t.deepEqual(state.scenes.items, {
- scene_01: {
- id: 'scene_01',
- sketchIds: [],
- selectedSketchId: false
- },
- scene_02: {
- id: 'scene_02',
- sketchIds: ['id_7'],
- selectedSketchId: 'id_7'
- }
- }, 'After creating sketch with no specified scene id, sketch id is added to scene using currentSceneId')
-
- t.deepEqual(state.sketches, {
- id_7: {
- title: 'Boring',
- moduleId: 'boring',
- paramIds: [],
- shotIds: [],
- openedNodes: {}
- }
- }, 'After creating sketch, sketch item is created')
-
- t.deepEqual(state.nodes, {}, 'After creating sketch, no nodes created (because sketch has no params/shots)')
-
- store.dispatch(uSketchDelete('id_7'))
- state = store.getState()
-
- t.deepEqual(state.scenes.items, {
- scene_01: {
- id: 'scene_01',
- sketchIds: [],
- selectedSketchId: false
- },
- scene_02: {
- id: 'scene_02',
- sketchIds: [],
- selectedSketchId: false
- }
- }, 'After deleting sketch with no specified scene id, uses currentSceneId to determine which scene')
-
- t.deepEqual(state.sketches, {}, 'After deleting sketch, sketch item is removed')
-
- t.end()
-})
-
-test('(mock) Sketches - Reimport Sketch (Unedited sketch)', (t) => {
- uniqueId = 2
-
- const defaultState = {
- availableModules: {
- foo: {
- defaultTitle: 'Foo',
- params: [
- {
- key: 'speed',
- title: 'Speed',
- defaultValue: 0.5
- }
- ],
- shots: []
- }
- },
- nodes: {
- id_2: {
- id: 'id_2',
- title: 'Speed',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- }
- },
- sketches: {
- id_1: {
- title: 'Foo',
- moduleId: 'foo',
- paramIds: ['id_2'],
- shotIds: [],
- openedNodes: {}
- }
- },
- scenes: {
- items: {}
- }
- }
-
- const store = createStore(rootReducer, defaultState,
- applyMiddleware(sagaMiddleware, listen(rootListener)))
- sagaMiddleware.run(rootSaga, store.dispatch)
-
- let state
-
- store.dispatch(uSketchReimport('id_1'))
-
- state = store.getState()
-
- t.deepEqual(
- state, defaultState,
- 'After reimporting undedited sketch, state has not changed'
- )
-
- t.end()
-})
-
-test('(mock) Sketches - Reimport Sketch (simple)', (t) => {
- uniqueId = 2
-
- const store = createStore(rootReducer, {
- availableModules: {
- foo: {
- defaultTitle: 'Foo',
- params: [
- {
- key: 'speed',
- title: 'Speed',
- defaultValue: 0.5
- },
- {
- key: 'scale',
- title: 'Scale',
- defaultValue: 0.2
- }
- ],
- shots: []
- }
- },
- nodes: {
- id_2: {
- id: 'id_2',
- title: 'Speed',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- }
- },
- sketches: {
- id_1: {
- title: 'Foo',
- moduleId: 'foo',
- paramIds: ['id_2'],
- shotIds: [],
- openedNodes: {}
- }
- }
- }, applyMiddleware(sagaMiddleware, listen(rootListener)))
- sagaMiddleware.run(rootSaga, store.dispatch)
-
- let state
-
- store.dispatch(uSketchReimport('id_1'))
-
- state = store.getState()
-
- t.deepEqual(
- state.sketches['id_1'].paramIds, ['id_2', 'id_3'],
- 'After reimporting, sketch has new paramId'
- )
-
- t.deepEqual(
- state.nodes,
- {
- id_2: {
- id: 'id_2',
- title: 'Speed',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- },
- id_3: {
- id: 'id_3',
- title: 'Scale',
- value: 0.2,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'scale'
- }
- },
- 'After reimporting, new node exists'
- )
-
- t.end()
-})
-
-test('(mock) Sketches - Reimport Sketch (params and shots)', (t) => {
- uniqueId = 3
-
- const store = createStore(rootReducer, {
- availableModules: {
- foo: {
- defaultTitle: 'Foo',
- params: [
- {
- key: 'speed',
- title: 'Speed',
- defaultValue: 0.5
- },
- {
- key: 'scale',
- title: 'Scale',
- defaultValue: 0.2
- }
- ],
- shots: [
- {
- method: 'explode',
- title: 'Explode'
- },
- {
- method: 'spin',
- title: 'Spin'
- }
- ]
- }
- },
- nodes: {
- id_2: {
- id: 'id_2',
- title: 'Speed',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- },
- id_3: {
- id: 'id_3',
- title: 'Explode',
- value: 0,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'shot',
- method: 'explode',
- sketchId: 'id_1'
- }
- },
- sketches: {
- id_1: {
- title: 'Foo',
- moduleId: 'foo',
- paramIds: ['id_2'],
- shotIds: ['id_3'],
- openedNodes: {}
- }
- }
- }, applyMiddleware(sagaMiddleware, listen(rootListener)))
- sagaMiddleware.run(rootSaga, store.dispatch)
-
- let state
-
- store.dispatch(uSketchReimport('id_1'))
-
- state = store.getState()
-
- t.deepEqual(
- state.sketches['id_1'].paramIds, ['id_2', 'id_4'],
- 'After reimporting, sketch has new paramId'
- )
-
- t.deepEqual(
- state.sketches['id_1'].shotIds, ['id_3', 'id_5'],
- 'After reimporting, sketch has new shotId'
- )
-
- t.deepEqual(
- state.nodes,
- {
- id_2: {
- id: 'id_2',
- title: 'Speed',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- },
- id_3: {
- id: 'id_3',
- title: 'Explode',
- value: 0,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'shot',
- method: 'explode',
- sketchId: 'id_1'
- },
- id_4: {
- id: 'id_4',
- title: 'Scale',
- value: 0.2,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'scale'
- },
- id_5: {
- id: 'id_5',
- title: 'Spin',
- value: 0,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'shot',
- method: 'spin',
- sketchId: 'id_1'
- }
- },
- 'After reimporting, new nodes exist'
- )
-
- t.end()
-})
-
-test('(mock) Sketches - Reimport Sketch (with shot and param title changes)', (t) => {
- uniqueId = 3
-
- const store = createStore(rootReducer, {
- availableModules: {
- foo: {
- defaultTitle: 'Foo',
- params: [
- {
- key: 'speed',
- title: 'Speed New',
- defaultValue: 0.5
- },
- {
- key: 'scale',
- title: 'Scale',
- defaultValue: 0.2
- }
- ],
- shots: [
- {
- method: 'explode',
- title: 'Explode New'
- }
- ]
- }
- },
- nodes: {
- id_2: {
- id: 'id_2',
- title: 'Speed',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- },
- id_3: {
- id: 'id_3',
- title: 'Explode New',
- value: 0,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'shot',
- method: 'explode',
- sketchId: 'id_1'
- }
- },
- sketches: {
- id_1: {
- title: 'Foo',
- moduleId: 'foo',
- paramIds: ['id_2'],
- shotIds: ['id_3'],
- openedNodes: {}
- }
- }
- }, applyMiddleware(sagaMiddleware, listen(rootListener)))
- sagaMiddleware.run(rootSaga, store.dispatch)
-
- let state
-
- store.dispatch(uSketchReimport('id_1'))
-
- state = store.getState()
-
- t.deepEqual(
- state.sketches['id_1'].paramIds, ['id_2', 'id_4'],
- 'After reimporting, sketch has new paramId'
- )
-
- t.deepEqual(
- state.nodes,
- {
- id_2: {
- id: 'id_2',
- title: 'Speed New',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- },
- id_3: {
- id: 'id_3',
- title: 'Explode New',
- value: 0,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'shot',
- method: 'explode',
- sketchId: 'id_1'
- },
- id_4: {
- id: 'id_4',
- title: 'Scale',
- value: 0.2,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'scale'
- }
- },
- 'After reimporting, new node exists, old nodes titles have changed'
- )
-
- t.end()
-})
-
-test('(mock) Sketches - Reimport Sketch (Different order)', (t) => {
- uniqueId = 3
-
- const store = createStore(rootReducer, {
- availableModules: {
- foo: {
- defaultTitle: 'Foo',
- params: [
- {
- key: 'speed',
- title: 'Speed',
- defaultValue: 0.5
- },
- {
- key: 'bar',
- title: 'Bar',
- defaultValue: 0.5
- },
- {
- key: 'scale',
- title: 'Scale',
- defaultValue: 0.2
- }
- ],
- shots: []
- }
- },
- nodes: {
- id_2: {
- id: 'id_2',
- title: 'Speed',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- },
- id_3: {
- id: 'id_3',
- title: 'Scale',
- value: 0.2,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'scale'
- }
- },
- sketches: {
- id_1: {
- title: 'Foo',
- moduleId: 'foo',
- paramIds: ['id_2', 'id_3'],
- shotIds: [],
- openedNodes: {}
- }
- }
- }, applyMiddleware(sagaMiddleware, listen(rootListener)))
- sagaMiddleware.run(rootSaga, store.dispatch)
-
- let state
-
- store.dispatch(uSketchReimport('id_1'))
-
- state = store.getState()
-
- t.deepEqual(
- state.sketches['id_1'].paramIds, ['id_2', 'id_4', 'id_3'],
- 'After reimporting, sketch has new paramId in middle of array'
- )
-
- t.deepEqual(
- state.nodes,
- {
- id_2: {
- id: 'id_2',
- title: 'Speed',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'speed'
- },
- id_3: {
- id: 'id_3',
- title: 'Scale',
- value: 0.2,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'scale'
- },
- id_4: {
- id: 'id_4',
- title: 'Bar',
- value: 0.5,
- inputLinkIds: [],
- shotCount: 0,
- connectedMacroIds: [],
- type: 'param',
- key: 'bar'
- }
- },
- 'After reimporting, new node exists'
- )
-
- t.end()
-})
diff --git a/mockTests/sketches.test.js b/mockTests/sketches.test.js
new file mode 100644
index 00000000..1bf42d1c
--- /dev/null
+++ b/mockTests/sketches.test.js
@@ -0,0 +1,1159 @@
+import listen from 'redux-action-listeners'
+import { createStore, applyMiddleware, combineReducers } from 'redux'
+import createSagaMiddleware from 'redux-saga'
+const sagaMiddleware = createSagaMiddleware()
+import { uSketchCreate, uSketchDelete } from '../src/store/sketches/actions'
+
+import { fork } from 'redux-saga/effects'
+import { watchNodes } from '../src/store/nodes/sagas'
+import { watchMacros } from '../src/store/macros/sagas'
+import sketchesReducer from '../src/store/sketches/reducer'
+import availableModulesReducer from '../src/store/availableModules/reducer'
+import nodesReducer from '../src/store/nodes/reducer'
+import scenesReducer from '../src/store/scenes/reducer'
+import macrosReducer from '../src/store/macros/reducer'
+
+import sketchesListener from '../src/store/sketches/listener'
+import scenesListener from '../src/store/scenes/listener'
+
+let mockUniqueId = 0
+
+jest.mock('uid', () => () => {
+ mockUniqueId++
+ return 'id_' + mockUniqueId
+})
+
+const rootListener = {
+ types: 'all',
+
+ handleAction (action, dispatched, store) {
+ sketchesListener(action, store)
+ scenesListener(action, store)
+ },
+}
+
+function* rootSaga (dispatch) {
+ yield [
+ fork(watchNodes),
+ fork(watchMacros),
+ ]
+}
+
+test('(mock) Sketches - Add/Delete Sketch', () => {
+ const rootReducer = combineReducers(
+ {
+ nodes: nodesReducer,
+ availableModules: availableModulesReducer,
+ sketches: sketchesReducer,
+ scenes: scenesReducer,
+ router: () => ({
+ location: {
+ pathname: 'scenes/addSketch/scene_02',
+ },
+ }),
+ }
+ )
+
+ const store = createStore(rootReducer, {
+ availableModules: {
+ foo: {
+ defaultTitle: 'Foo',
+ params: [
+ {
+ key: 'speed',
+ title: 'Speed',
+ defaultValue: 0.5,
+ defaultMin: -1,
+ defaultMax: 1,
+ },
+ ],
+ shots: [],
+ },
+ bar: {
+ defaultTitle: 'Bar',
+ params: [
+ {
+ key: 'scale',
+ title: 'Scale',
+ defaultValue: 0.2,
+ },
+ {
+ key: 'color',
+ title: 'Color',
+ defaultValue: 0.1,
+ },
+ ],
+ shots: [
+ {
+ method: 'explode',
+ title: 'Explode',
+ },
+ ],
+ },
+ boring: {
+ defaultTitle: 'Boring',
+ },
+ },
+ nodes: {},
+ sketches: {},
+ scenes: {
+ currentSceneId: 'scene_02',
+ items: {
+ scene_01: {
+ id: 'scene_01',
+ selectedSketchId: false,
+ sketchIds: [],
+ },
+ scene_02: {
+ id: 'scene_02',
+ selectedSketchId: false,
+ sketchIds: [],
+ },
+ },
+ },
+ }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+ sagaMiddleware.run(rootSaga, store.dispatch)
+
+ let state
+
+ state = store.getState()
+
+ // 'nodes start empty'
+ expect(state.nodes).toEqual({})
+
+ store.dispatch(uSketchCreate('foo', 'scene_01'))
+ state = store.getState()
+
+ // 'After creating sketch, sketch id is added to scene, selectedSketchId is set'
+ expect(state.scenes.items).toEqual({
+ scene_01: {
+ id: 'scene_01',
+ selectedSketchId: 'id_1',
+ sketchIds: ['id_1'],
+ },
+ scene_02: {
+ id: 'scene_02',
+ selectedSketchId: false,
+ sketchIds: [],
+ },
+ })
+
+ // 'After creating sketch, sketch item is created'
+ expect(state.sketches).toEqual({
+ id_1: {
+ title: 'Foo',
+ moduleId: 'foo',
+ paramIds: ['id_2'],
+ shotIds: [],
+ },
+ })
+
+ // 'After creating sketch, node item is created for param'
+ expect(state.nodes).toEqual({
+ id_2: {
+ id: 'id_2',
+ title: 'Speed',
+ value: 0.5,
+ inputLinkIds: [],
+ shotCount: 0,
+ sketchId: 'id_1',
+ connectedMacroIds: [],
+ type: 'param',
+ key: 'speed',
+ hidden: false,
+ min: -1,
+ max: 1,
+ defaultMin: -1,
+ defaultMax: 1,
+ },
+ })
+
+ store.dispatch(uSketchCreate('bar', 'scene_01'))
+ state = store.getState()
+
+ // 'After creating sketch, sketch id is added to scene'
+ expect(state.scenes.items).toEqual({
+ scene_01: {
+ id: 'scene_01',
+ sketchIds: ['id_1', 'id_3'],
+ selectedSketchId: 'id_3',
+ },
+ scene_02: {
+ id: 'scene_02',
+ selectedSketchId: false,
+ sketchIds: [],
+ },
+ })
+
+ // 'After creating sketch, sketch item is created'
+ expect(state.sketches).toEqual({
+ id_1: {
+ title: 'Foo',
+ moduleId: 'foo',
+ paramIds: ['id_2'],
+ shotIds: [],
+ },
+ id_3: {
+ title: 'Bar',
+ moduleId: 'bar',
+ paramIds: ['id_4', 'id_5'],
+ shotIds: ['id_6'],
+ },
+ })
+
+ // 'After creating sketch, node items are created for params and shot'
+ expect(state.nodes).toEqual({
+ id_2: {
+ id: 'id_2',
+ title: 'Speed',
+ value: 0.5,
+ inputLinkIds: [],
+ shotCount: 0,
+ sketchId: 'id_1',
+ connectedMacroIds: [],
+ type: 'param',
+ key: 'speed',
+ hidden: false,
+ min: -1,
+ max: 1,
+ defaultMin: -1,
+ defaultMax: 1,
+ },
+ id_4: {
+ id: 'id_4',
+ title: 'Scale',
+ value: 0.2,
+ inputLinkIds: [],
+ shotCount: 0,
+ sketchId: 'id_3',
+ connectedMacroIds: [],
+ type: 'param',
+ key: 'scale',
+ hidden: false,
+ min: 0,
+ max: 1,
+ defaultMin: 0,
+ defaultMax: 1,
+ },
+ id_5: {
+ id: 'id_5',
+ title: 'Color',
+ value: 0.1,
+ inputLinkIds: [],
+ shotCount: 0,
+ sketchId: 'id_3',
+ connectedMacroIds: [],
+ type: 'param',
+ key: 'color',
+ hidden: false,
+ min: 0,
+ max: 1,
+ defaultMin: 0,
+ defaultMax: 1,
+ },
+ id_6: {
+ id: 'id_6',
+ title: 'Explode',
+ value: 0,
+ inputLinkIds: [],
+ shotCount: 0,
+ connectedMacroIds: [],
+ type: 'shot',
+ method: 'explode',
+ sketchId: 'id_3',
+ },
+ })
+
+ store.dispatch(uSketchDelete('id_1', 'scene_01'))
+ state = store.getState()
+
+ // 'After deleting sketch, sketch id is removed from scene, selectedSketchId becomes last in list'
+ expect(state.scenes.items).toEqual({
+ scene_01: {
+ id: 'scene_01',
+ sketchIds: ['id_3'],
+ selectedSketchId: 'id_3',
+ },
+ scene_02: {
+ id: 'scene_02',
+ sketchIds: [],
+ selectedSketchId: false,
+ },
+ })
+
+ // 'After deleting sketch, sketch item is removed'
+ expect(state.sketches).toEqual({
+ id_3: {
+ title: 'Bar',
+ moduleId: 'bar',
+ paramIds: ['id_4', 'id_5'],
+ shotIds: ['id_6'],
+ },
+ })
+
+ // 'After deleting sketch, node items are removed'
+ expect(state.nodes).toEqual({
+ id_4: {
+ id: 'id_4',
+ title: 'Scale',
+ value: 0.2,
+ inputLinkIds: [],
+ shotCount: 0,
+ sketchId: 'id_3',
+ connectedMacroIds: [],
+ type: 'param',
+ key: 'scale',
+ hidden: false,
+ min: 0,
+ max: 1,
+ defaultMin: 0,
+ defaultMax: 1,
+ },
+ id_5: {
+ id: 'id_5',
+ title: 'Color',
+ value: 0.1,
+ inputLinkIds: [],
+ shotCount: 0,
+ sketchId: 'id_3',
+ connectedMacroIds: [],
+ type: 'param',
+ key: 'color',
+ hidden: false,
+ min: 0,
+ max: 1,
+ defaultMin: 0,
+ defaultMax: 1,
+ },
+ id_6: {
+ id: 'id_6',
+ title: 'Explode',
+ value: 0,
+ inputLinkIds: [],
+ shotCount: 0,
+ connectedMacroIds: [],
+ type: 'shot',
+ method: 'explode',
+ sketchId: 'id_3',
+ },
+ })
+
+ store.dispatch(uSketchDelete('id_3', 'scene_01'))
+ state = store.getState()
+
+ expect(state.scenes.items).toEqual({
+ scene_01: {
+ id: 'scene_01',
+ sketchIds: [],
+ selectedSketchId: false,
+ },
+ scene_02: {
+ id: 'scene_02',
+ sketchIds: [],
+ selectedSketchId: false,
+ },
+ }, 'After deleting sketch, sketch id is removed from scene, selected sketchId becomes false (none left)')
+
+ // 'After deleting sketch, sketch item is removed'
+ expect(state.sketches).toEqual({})
+ // 'After deleting sketch, node items are removed'
+ expect(state.nodes).toEqual({})
+
+ store.dispatch(uSketchCreate('boring'))
+ state = store.getState()
+
+ // 'After creating sketch with no specified scene id, sketch id is added to scene using currentSceneId'
+ expect(state.scenes.items).toEqual({
+ scene_01: {
+ id: 'scene_01',
+ sketchIds: [],
+ selectedSketchId: false,
+ },
+ scene_02: {
+ id: 'scene_02',
+ sketchIds: ['id_7'],
+ selectedSketchId: 'id_7',
+ },
+ })
+
+ // 'After creating sketch, sketch item is created'
+ expect(state.sketches).toEqual({
+ id_7: {
+ title: 'Boring',
+ moduleId: 'boring',
+ paramIds: [],
+ shotIds: [],
+ },
+ })
+
+ // 'After creating sketch, no nodes created (because sketch has no params/shots)'
+ expect(state.nodes).toEqual({})
+
+ store.dispatch(uSketchDelete('id_7'))
+ state = store.getState()
+
+ // 'After deleting sketch with no specified scene id, uses currentSceneId to determine which scene'
+ expect(state.scenes.items).toEqual({
+ scene_01: {
+ id: 'scene_01',
+ sketchIds: [],
+ selectedSketchId: false,
+ },
+ scene_02: {
+ id: 'scene_02',
+ sketchIds: [],
+ selectedSketchId: false,
+ },
+ })
+
+ // 'After deleting sketch, sketch item is removed'
+ expect(state.sketches).toEqual({})
+})
+
+test('(mock) Sketches - Delete sketch with macro associated to params', () => {
+ const rootReducer = combineReducers(
+ {
+ nodes: nodesReducer,
+ availableModules: availableModulesReducer,
+ sketches: sketchesReducer,
+ scenes: scenesReducer,
+ macros: macrosReducer,
+ router: () => ({
+ location: {
+ pathname: 'scenes/addSketch/scene_02',
+ },
+ }),
+ }
+ )
+
+ const store = createStore(rootReducer, {
+ nodes: {
+ param_a: {
+ id: 'param_a',
+ connectedMacroIds: ['macro_a'],
+ },
+ macro_a: {
+ targetParamLinks: {
+ param_a: {
+ paramId: 'param_a',
+ nodeId: 'macro_link_a',
+ },
+ },
+ },
+ macro_link_a: {
+
+ },
+ },
+ sketches: {
+ sketch_a: {
+ paramIds: ['param_a'],
+ shotIds: [],
+ },
+ },
+ scenes: {
+ currentSceneId: 'scene_01',
+ items: {
+ scene_01: {
+ id: 'scene_01',
+ selectedSketchId: false,
+ sketchIds: ['sketch_a'],
+ },
+ },
+ },
+ macros: {
+ nodeIds: ['macro_a'],
+ },
+ }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+ sagaMiddleware.run(rootSaga, store.dispatch)
+
+ store.dispatch(uSketchDelete('sketch_a', 'scene_01'))
+
+ let state = store.getState()
+
+ const nodes = state.nodes
+ const macros = state.macros
+
+ expect(nodes.param_a).toBe(undefined)
+ expect(nodes.macro_link_a).toBe(undefined)
+ expect(nodes.macro_a.targetParamLinks.param_a).toBe(undefined)
+ expect(macros.nodeIds).toHaveLength(1) // Macro not deleted
+})
+
+// TODO: Below tests disabled because since changes made to reimporting sketches, this is now harder to mock
+
+// test('(mock) Sketches - Reimport Sketch (Unedited sketch)', (t) => {
+// mockUniqueId = 2
+
+// const defaultState = {
+// nodes: {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'speed',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// },
+// availableModules: {
+// foo: {
+// defaultTitle: 'Foo',
+// filePathArray: [],
+// params: [
+// {
+// key: 'speed',
+// title: 'Speed',
+// defaultValue: 0.5,
+// },
+// ],
+// shots: [],
+// },
+// },
+// sketches: {
+// id_1: {
+// title: 'Foo',
+// moduleId: 'foo',
+// paramIds: ['id_2'],
+// shotIds: [],
+// },
+// },
+// scenes: {
+// items: {},
+// },
+// project: {
+// sketchesPath: '',
+// },
+// }
+
+// const store = createStore(rootReducer, defaultState,
+// applyMiddleware(sagaMiddleware, listen(rootListener)))
+// sagaMiddleware.run(rootSaga, store.dispatch)
+
+// let state
+
+// store.dispatch(uSketchReloadFile('id_1'))
+
+// state = store.getState()
+
+// // 'After reimporting undedited sketch, state has not changed'
+// expect(state).toEqual(defaultState)
+// })
+
+// test('(mock) Sketches - Reimport Sketch (simple)', (t) => {
+// mockUniqueId = 2
+
+// const store = createStore(rootReducer, {
+// availableModules: {
+// foo: {
+// defaultTitle: 'Foo',
+// params: [
+// {
+// key: 'speed',
+// title: 'Speed',
+// defaultValue: 0.5,
+// },
+// {
+// key: 'scale',
+// title: 'Scale',
+// defaultValue: 0.2,
+// },
+// ],
+// shots: [],
+// },
+// },
+// nodes: {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'speed',
+// hidden: false,
+// min: 0,
+// max: 1,
+// },
+// },
+// sketches: {
+// id_1: {
+// title: 'Foo',
+// moduleId: 'foo',
+// paramIds: ['id_2'],
+// shotIds: [],
+// },
+// },
+// }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+// sagaMiddleware.run(rootSaga, store.dispatch)
+
+// let state
+
+// store.dispatch(uSketchReloadFile('id_1'))
+
+// state = store.getState()
+
+// // 'After reimporting, sketch has new paramId'
+// expect(state.sketches['id_1'].paramIds).toEqual(['id_2', 'id_3'])
+
+// // 'After reimporting, new node exists'
+// expect(state.nodes).toEqual(
+// {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'speed',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// id_3: {
+// id: 'id_3',
+// title: 'Scale',
+// value: 0.2,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'scale',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// },
+// )
+// })
+
+// test('(mock) Sketches - Reimport Sketch (params and shots)', (t) => {
+// mockUniqueId = 2
+
+// const store = createStore(rootReducer, {
+// availableModules: {
+// foo: {
+// defaultTitle: 'Foo',
+// params: [
+// {
+// key: 'speed',
+// title: 'Speed',
+// defaultValue: 0.5,
+// },
+// {
+// key: 'scale',
+// title: 'Scale',
+// defaultValue: 0.2,
+// },
+// ],
+// shots: [
+// {
+// method: 'explode',
+// title: 'Explode',
+// },
+// {
+// method: 'spin',
+// title: 'Spin',
+// },
+// ],
+// },
+// },
+// nodes: {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'speed',
+// hidden: false,
+// min: 0,
+// max: 1,
+// },
+// id_3: {
+// id: 'id_3',
+// title: 'Explode',
+// value: 0,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'shot',
+// method: 'explode',
+// sketchId: 'id_1',
+// },
+// },
+// sketches: {
+// id_1: {
+// title: 'Foo',
+// moduleId: 'foo',
+// paramIds: ['id_2'],
+// shotIds: ['id_3'],
+// },
+// },
+// }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+// sagaMiddleware.run(rootSaga, store.dispatch)
+
+// let state
+
+// store.dispatch(uSketchReloadFile('id_1'))
+
+// state = store.getState()
+
+// // 'After reimporting, sketch has new paramId'
+// expect(state.sketches['id_1'].paramIds).toEqual(['id_2', 'id_4'])
+
+// // 'After reimporting, sketch has new shotId'
+// expect(state.sketches['id_1'].shotIds).toEqual(['id_3', 'id_5'])
+
+// // 'After reimporting, new nodes exist'
+// expect(state.nodes).toEqual(
+// {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'speed',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// id_3: {
+// id: 'id_3',
+// title: 'Explode',
+// value: 0,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'shot',
+// method: 'explode',
+// sketchId: 'id_1',
+// },
+// id_4: {
+// id: 'id_4',
+// title: 'Scale',
+// value: 0.2,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'scale',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// id_5: {
+// id: 'id_5',
+// title: 'Spin',
+// value: 0,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'shot',
+// method: 'spin',
+// sketchId: 'id_1',
+// },
+// }
+// )
+// })
+
+// test('(mock) Sketches - Reimport Sketch (with shot and param title changes)', (t) => {
+// mockUniqueId = 2
+
+// const store = createStore(rootReducer, {
+// availableModules: {
+// foo: {
+// defaultTitle: 'Foo',
+// params: [
+// {
+// key: 'speed',
+// title: 'Speed New',
+// defaultValue: 0.5,
+// },
+// {
+// key: 'scale',
+// title: 'Scale',
+// defaultValue: 0.2,
+// },
+// ],
+// shots: [
+// {
+// method: 'explode',
+// title: 'Explode New',
+// },
+// ],
+// },
+// },
+// nodes: {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// hidden: false,
+// min: 0,
+// max: 1,
+// type: 'param',
+// key: 'speed',
+// },
+// id_3: {
+// id: 'id_3',
+// title: 'Explode New',
+// value: 0,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'shot',
+// method: 'explode',
+// sketchId: 'id_1',
+// },
+// },
+// sketches: {
+// id_1: {
+// title: 'Foo',
+// moduleId: 'foo',
+// paramIds: ['id_2'],
+// shotIds: ['id_3'],
+// },
+// },
+// }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+// sagaMiddleware.run(rootSaga, store.dispatch)
+
+// let state
+
+// store.dispatch(uSketchReloadFile('id_1'))
+
+// state = store.getState()
+
+// // 'After reimporting, sketch has new paramId'
+// expect(state.sketches['id_1'].paramIds).toEqual(['id_2', 'id_4'])
+
+// // 'After reimporting, new node exists, old nodes titles have changed'
+// expect(state.nodes).toEqual(
+// {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed New',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'speed',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// id_3: {
+// id: 'id_3',
+// title: 'Explode New',
+// value: 0,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'shot',
+// method: 'explode',
+// sketchId: 'id_1',
+// },
+// id_4: {
+// id: 'id_4',
+// title: 'Scale',
+// value: 0.2,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'scale',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// }
+// )
+// })
+
+// test('(mock) Sketches - Reimport Sketch (Different order)', (t) => {
+// mockUniqueId = 2
+
+// const store = createStore(rootReducer, {
+// availableModules: {
+// foo: {
+// defaultTitle: 'Foo',
+// params: [
+// {
+// key: 'speed',
+// title: 'Speed',
+// defaultValue: 0.5,
+// },
+// {
+// key: 'bar',
+// title: 'Bar',
+// defaultValue: 0.5,
+// },
+// {
+// key: 'scale',
+// title: 'Scale',
+// defaultValue: 0.2,
+// },
+// ],
+// shots: [],
+// },
+// },
+// nodes: {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'speed',
+// hidden: false,
+// min: 0,
+// max: 1,
+// },
+// id_3: {
+// id: 'id_3',
+// title: 'Scale',
+// value: 0.2,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'scale',
+// hidden: false,
+// min: 0,
+// max: 1,
+// },
+// },
+// sketches: {
+// id_1: {
+// title: 'Foo',
+// moduleId: 'foo',
+// paramIds: ['id_2', 'id_3'],
+// shotIds: [],
+// },
+// },
+// }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+// sagaMiddleware.run(rootSaga, store.dispatch)
+
+// let state
+
+// store.dispatch(uSketchReloadFile('id_1'))
+
+// state = store.getState()
+
+// // 'After reimporting, sketch has new paramId in middle of array'
+// expect(state.sketches['id_1'].paramIds).toEqual(['id_2', 'id_4', 'id_3'])
+
+// // 'After reimporting, new node exists'
+// expect(state.nodes).toEqual(
+// {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'speed',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// id_3: {
+// id: 'id_3',
+// title: 'Scale',
+// value: 0.2,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'scale',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// id_4: {
+// id: 'id_4',
+// title: 'Bar',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'bar',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// }
+// )
+// })
+
+// test('(mock) Sketches - Reimport Sketch (remove old nodes)', (t) => {
+// mockUniqueId = 2
+
+// const store = createStore(rootReducer, {
+// availableModules: {
+// foo: {
+// defaultTitle: 'Foo',
+// params: [
+// {
+// key: 'speed',
+// title: 'Speed',
+// defaultValue: 0.5,
+// },
+// ],
+// shots: [
+// {
+// method: 'spin',
+// title: 'Spin',
+// },
+// ],
+// },
+// },
+// nodes: {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'speed',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// id_3: {
+// id: 'id_3',
+// title: 'Explode',
+// value: 0,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'shot',
+// method: 'explode',
+// sketchId: 'id_1',
+// },
+// id_4: {
+// id: 'id_4',
+// title: 'Scale',
+// value: 0.2,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'scale',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// id_5: {
+// id: 'id_5',
+// title: 'Spin',
+// value: 0,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'shot',
+// method: 'spin',
+// sketchId: 'id_1',
+// },
+// },
+// sketches: {
+// id_1: {
+// title: 'Foo',
+// moduleId: 'foo',
+// paramIds: ['id_2', 'id_4'],
+// shotIds: ['id_3', 'id_5'],
+// },
+// },
+// }, applyMiddleware(sagaMiddleware, listen(rootListener)))
+// sagaMiddleware.run(rootSaga, store.dispatch)
+
+// let state
+
+// store.dispatch(uSketchReloadFile('id_1'))
+
+// state = store.getState()
+
+// // 'After reimporting, sketch has removed paramId'
+// expect(state.sketches['id_1'].paramIds).toEqual(['id_2'])
+
+// // 'After reimporting, sketch has removed shotId'
+// expect(state.sketches['id_1'].shotIds).toEqual(['id_5'])
+
+// // 'After reimporting, old nodes removed'
+// expect(state.nodes).toEqual(
+// {
+// id_2: {
+// id: 'id_2',
+// title: 'Speed',
+// value: 0.5,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'param',
+// key: 'speed',
+// hidden: false,
+// min: 0,
+// max: 1,
+// defaultMin: 0,
+// defaultMax: 1,
+// },
+// id_5: {
+// id: 'id_5',
+// title: 'Spin',
+// value: 0,
+// inputLinkIds: [],
+// shotCount: 0,
+// connectedMacroIds: [],
+// type: 'shot',
+// method: 'spin',
+// sketchId: 'id_1',
+// },
+// })
+// })
diff --git a/package.json b/package.json
index a0254553..e013c820 100644
--- a/package.json
+++ b/package.json
@@ -1,18 +1,20 @@
{
- "name": "hedron",
- "version": "0.4.1",
+ "name": "Hedron",
+ "author": "Nudibranch Records",
+ "description": "Perform live shows with your three.js creations",
+ "version": "0.5.0",
+ "homepage": "https://github.com/nudibranchrecords/hedron",
"repository": {},
"license": "AGPL-3.0+",
"scripts": {
- "lint": "eslint bin build config server src tests",
+ "lint": "eslint src config example-projects mockTests",
"lint:css": "stylelint \"src/components/**/*.js\"",
"lint:fix": "yarn lint -- --fix",
- "test": "yarn lint && NODE_ENV=test tape-watch --once -r babel-register src/**/*.spec.js mockTests/**/*.spec.js -p tap-diff",
- "test:dev": "NODE_ENV=test tape-watch -r babel-register src/**/*.spec.js mockTests/**/*.spec.js -p tap-diff",
+ "test": "yarn lint && yarn jest && cross-env NODE_ENV=test tape-watch --once -r @babel/register src/**/*.spec.js mockTests/**/*.spec.js -p tap-diff",
+ "test:dev": "cross-env NODE_ENV=test tape-watch -r @babel/register src/**/*.spec.js mockTests/**/*.spec.js -p tap-diff",
+ "test-jest": "yarn jest --watch",
"compile": "electron-webpack",
"dist": "yarn compile && electron-builder",
- "dist:dev": "yarn dist -- --dir -c.compression=store -c.mac.identity=null && open dist/mac/hedron.app/ --args --distDev",
- "dist:example-projects": "yarn --cwd ./example-projects && zip dist/example-projects.zip ./example-projects -r",
"start": "yarn electron-webpack dev"
},
"electronWebpack": {
@@ -32,33 +34,39 @@
"glslify-import"
]
},
+ "jest": {
+ "testMatch": [
+ "**/?(*.)+(test).[jt]s?(x)"
+ ]
+ },
"dependencies": {
- "babel-loader": "^6.3.2",
- "babel-plugin-transform-object-rest-spread": "^6.22.0",
- "babel-polyfill": "^6.23.0",
- "babel-preset-es2015": "^6.22.0",
- "babel-register": "^6.22.0",
+ "@babel/core": "^7.2.2",
+ "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
+ "@babel/polyfill": "^7.0.0",
+ "@babel/preset-env": "^7.3.1",
+ "@babel/register": "^7.0.0",
+ "@tweenjs/tween.js": "^17.2.0",
+ "babel-loader": "^8.0.5",
+ "chokidar": "^3.0.0",
"create-react-class": "^15.5.2",
- "electron-debug": "^1.4.0",
- "electron-log": "^2.2.14",
"err-code": "^1.1.2",
"eventemitter3": "^3.0.1",
"glslify-import": "^3.1.0",
"history": "^4.6.1",
"jsonfile": "^2.4.0",
- "lodash": "^4.17.4",
+ "lodash": "^4.17.15",
"performance-now": "^2.1.0",
"proxyquire": "^1.7.11",
- "react": "^16.2.0",
+ "react": "^16.7.0",
"react-addons-perf": "^15.4.2",
"react-create-class": "^1.0.0",
- "react-dom": "16",
+ "react-dom": "^16.7.0",
"react-hot-loader": "next",
"react-input-autosize": "^1.1.3",
+ "react-popper": "^1.3.3",
"react-redux": "^5.0.2",
"react-router-dom": "next",
"react-router-redux": "^5.0.0-alpha.9",
- "react-select": "^1.0.0-rc.3",
"recompose": "^0.26.0",
"redux": "^3.6.0",
"redux-action-listeners": "^1.0.2",
@@ -68,39 +76,55 @@
"redux-ignore": "^1.2.4",
"redux-saga": "^0.16.0",
"stats.js": "^0.17.0",
- "styled-components": "^2.2.3",
+ "styled-components": "^4.1.3",
"tap-diff": "^0.1.1",
"tap-tempo": "^0.1.1",
- "three": "^0.92.0",
+ "three": "^0.107.0",
"tinycolor2": "^1.4.1",
"try-require": "^1.2.1",
"uid": "^0.0.2"
},
"devDependencies": {
- "babel-eslint": "^7.1.1",
- "babel-preset-react": "^6.24.1",
- "babel-preset-stage-2": "^6.22.0",
+ "@babel/core": "^7.2.2",
+ "@babel/plugin-proposal-class-properties": "^7.0.0",
+ "@babel/plugin-proposal-export-namespace-from": "^7.0.0",
+ "@babel/plugin-proposal-function-sent": "^7.0.0",
+ "@babel/plugin-proposal-json-strings": "^7.0.0",
+ "@babel/plugin-proposal-numeric-separator": "^7.0.0",
+ "@babel/plugin-proposal-throw-expressions": "^7.0.0",
+ "@babel/plugin-syntax-dynamic-import": "^7.0.0",
+ "@babel/plugin-syntax-import-meta": "^7.0.0",
+ "@babel/plugin-transform-runtime": "^7.2.0",
+ "@babel/preset-react": "^7.0.0",
+ "@babel/runtime": "^7.3.1",
+ "babel-eslint": "8.2.6",
+ "babel-plugin-styled-components": "^1.10.0",
"clean-webpack-plugin": "^0.1.16",
"concurrently": "^3.4.0",
"copy-webpack-plugin": "^4.0.1",
+ "cross-env": "^5.2.0",
"css-loader": "^0.28.7",
"deep-freeze": "^0.0.1",
- "electron": "^1.8.2-beta.2",
- "electron-builder": "^19.43.0",
+ "electron": "3",
+ "electron-builder": "^20.38.5",
+ "electron-debug": "^1.4.0",
"electron-devtools-installer": "^2.2.1",
- "electron-webpack": "^1.11.0",
- "eslint": "^3.15.0",
+ "electron-log": "^2.2.14",
+ "electron-webpack": "^2.6.1",
+ "eslint": "^6.1.0",
"eslint-config-standard": "^6.2.1",
"eslint-config-standard-react": "^4.2.0",
"eslint-plugin-babel": "^4.0.1",
+ "eslint-plugin-jest": "^22.3.0",
"eslint-plugin-promise": "^3.4.1",
"eslint-plugin-react": "^6.10.0",
"eslint-plugin-standard": "^2.0.1",
+ "jest": "^24.1.0",
"jsdom": "^11.5.1",
"jsdom-global": "^3.0.2",
"minimist": "^1.2.0",
"redux-debounced": "^0.4.0",
- "redux-devtools-extension": "^2.13.2",
+ "redux-devtools-extension": "^2.13.7",
"sinon": "^2.1.0",
"style-loader": "^0.16.1",
"stylelint": "^7.9.0",
@@ -110,7 +134,8 @@
"tap-colorize": "^1.2.0",
"tape": "^4.6.3",
"tape-watch": "^2.3.0",
- "webpack": "^3.8.1",
- "webpack-dev-server": "^2.4.1"
+ "webpack": "^4.29.1",
+ "webpack-cli": "^3.2.3",
+ "webpack-dev-server": "^3.1.14"
}
}
diff --git a/readme.md b/readme.md
index 9ffb4dad..a5ae8de0 100644
--- a/readme.md
+++ b/readme.md
@@ -1,4 +1,4 @@
-# Hedron
+#
Perform live shows with your three.js creations.
@@ -14,26 +14,27 @@ Perform live shows with your three.js creations.
- ⏲️ Use MIDI clock input or tap tempo to get BPM
- 🌇🎚️🌋 Create many scenes and crossfade between them
- 🔍 Preview and compose scenes before displaying them to the audience
-- 🎛️ Use virtual MIDI banks to get the most out of your controllers
- 💡 Use MIDI Learn to quickly assign controls
+- 🔥 Hot reload your sketches on code changes, without affecting the rest of the scene
- ⚙️ Support for multiple MIDI control modes (abs, rel1, rel2, rel3)
- 📽️ Easily send output picture to external display
- 💾 Save / load using JSON project files
+## Hedron in action
+[![Polyop](http://nudibranchrecords.github.io/hedron/polyop-creator.jpg)](https://vimeo.com/310779808)
+[![Netgrind @ Halifax Pride](http://nudibranchrecords.github.io/hedron/netgrind-halifax-pride.jpg)](https://www.netgrindgames.com/)
+
## Getting Started
### Install
Download the latest [release](https://github.com/nudibranchrecords/hedron/releases) or
[build from source](#build-from-source).
-### Load trippy example project
-1. If you haven't got the source code, download the latest example projects zip from the [releases](https://github.com/nudibranchrecords/hedron/releases) page.
-2. Choose "Load Existing Project". Locate the repo directory. Open `example-projects/trippy/project.json`
-3. An alert will appear. Choose "Locate Sketch Folder" and open `/example-projects/trippy/sketches`
+### Load example project
+1. Download the latest example projects zip from the [releases](https://github.com/nudibranchrecords/hedron/releases) page. If you've compiled from source, you'll already have the example projects, found in `/example-projects`.
+2. In Hedron, choose "Load Existing Project". Choose a folder from the example projects (`Logo` is a good start!) and open `project.json`.
4. Play it some music, tap BPM, experiment with the controls
-5. 😎
-
-Please note that if you're trying to do this from the source code, you'll want to run `yarn` from inside the `example-projects` directory to install dependencies.
+5. 👽
## User Guide
Head to the [User Guide](docs/user-guide/index.md) to learn how to use Hedron.
@@ -63,7 +64,7 @@ If you are having fun with Hedron, we'd love you to help with development. See t
Don't worry too much if the tests aren't passing, we can work on that together. :)
### Build From Source
-If you're making your own sketches, you'll probably want to build Hedron from source. You'll get lots of extra development benefits this way, such as auto refreshing on save.
+Building from source gives you some extra development features such as setting a default project that will always load on start.
1. Make sure [Node.js](https://nodejs.org/en/) and [Yarn](https://yarnpkg.com/en/docs/install) are installed on your machine.
2. Open terminal and run the commands below.
@@ -85,8 +86,6 @@ Run `yarn dist` to package up the app for best performance and no dev tools. Onc
|--|--|
| `yarn start` | Run in dev mode |
| `yarn dist` | Package the app |
-| `yarn dist:dev` | Run a production build without packaging. Behaves similarly to `yarn start` in that it will look for a default project and open Chrome DevTools automatically. However it will not do any sort of live refreshing. |
-| `yarn dist:example-projects`| Install dependencies for example projects, zip them and move them to the `dist` folder |
| `yarn lint` | Run linting |
| `yarn test` | Run pre deployment tests (including linting) |
| `yarn test:dev` | Run tests on file changes (does not include linting) |
diff --git a/src/assets/icons/down.icon.txt b/src/assets/icons/down.icon.txt
index 4fb1a169..2c5035b5 100644
--- a/src/assets/icons/down.icon.txt
+++ b/src/assets/icons/down.icon.txt
@@ -3,8 +3,6 @@
diff --git a/src/components/AboutOverlay/index.js b/src/components/AboutOverlay/index.js
new file mode 100644
index 00000000..4508b204
--- /dev/null
+++ b/src/components/AboutOverlay/index.js
@@ -0,0 +1,64 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import OverlayModal from '../OverlayModal'
+import styled from 'styled-components'
+import logo from '../../../build/icon.png'
+
+const { app } = require('electron').remote
+const isDevelopment = process.env.NODE_ENV !== 'production'
+const vNum = app.getVersion()
+
+// Version number comes out wrong in dev mode so we only display for production
+const modalTitle = isDevelopment ? 'Dev Mode' : `v${vNum}`
+
+const Wrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ img {
+ max-width: 15rem;
+ margin-bottom: 1rem;
+ }
+
+ p:last-child {
+ margin: 0;
+ }
+`
+
+const Credits = styled.div`
+ border-top: 1px solid rgba(255,255,255,0.5);
+ width: 100%;
+ padding-top: 1rem;
+
+ p {
+ font-size: 0.8rem;
+ }
+`
+
+const AboutOverlay = ({ isVisible, onCancelClick }) => (
+ Hedron is an open-source project brought to you
+ by Nudibranch Give feedback, report bugs or improve the software
+ on Github Logo created by Cale Bradbury
You haven't chosen the sketch folder for the project yet.
} +You haven't chosen the sketch folder for the project yet.
}