diff --git a/.babelrc.js b/.babelrc.js deleted file mode 100644 index 38bedc4d..00000000 --- a/.babelrc.js +++ /dev/null @@ -1,34 +0,0 @@ -module.exports = function (api) { - api.cache(true); - - const ENV = process.env.BABEL_ENV || process.env.NODE_ENV; - - const presets = [ - [ - '@babel/env', - { - targets: { - electron: '15.3.0', - }, - }, - ], - '@babel/react', - ]; - - const plugins = [ - '@babel/proposal-class-properties', - '@babel/proposal-object-rest-spread', - '@babel/proposal-optional-chaining', - '@babel/proposal-nullish-coalescing-operator', - '@babel/proposal-export-default-from', - ]; - - if (ENV === 'development') { - plugins.push('react-refresh/babel'); - } - - return { - presets, - plugins, - }; -}; diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 1217b18e..00000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -/app/ \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 1af09d66..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "env": { - "browser": true, - "commonjs": true, - "es6": true, - "node": true, - "jest/globals": true - }, - - "parser": "@babel/eslint-parser", - "parserOptions": { - "requireConfigFile": false, - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": 11, - "sourceType": "module" - }, - "extends": [ - "eslint:recommended", - "plugin:prettier/recommended", - "plugin:react/recommended", - "plugin:import/errors", - "plugin:css-modules/recommended", - "plugin:jest/recommended" - ], - "plugins": ["prettier", "promise", "css-modules", "react", "react-hooks", "jest"], - "rules": { - "class-methods-use-this": "off", - "consistent-return": "off", - "default-case": "off", - "linebreak-style": ["error", "unix"], - "max-len": [ - "error", - { - "code": 100, - "ignoreComments": true - } - ], - "no-await-in-loop": "off", - "no-bitwise": "off", - "no-return-assign": ["error", "except-parens"], - "no-unused-expressions": [ - "error", - { - "allowShortCircuit": true - } - ], - "no-param-reassign": "off", - "no-plusplus": "off", - "no-shadow": "off", - "no-underscore-dangle": "off", - "one-var-declaration-per-line": ["error", "initializations"], - "quotes": ["error", "single"], - "semi": ["error", "always"], - "strict": "off", - "css-modules/no-unused-class": "off", - "import/extensions": "off", - "import/no-extraneous-dependencies": "off", - "import/no-unresolved": "off", - "import/prefer-default-export": "off", - "no-restricted-syntax": "off", - "prettier/prettier": "error", - "react/destructuring-assignment": "off", - "react/forbid-prop-types": "off", - "react/jsx-filename-extension": "off", - "react/jsx-props-no-spreading": "off", - "react/state-in-constructor": "off", - "react/static-property-placement": ["error", "static public field"], - "react/no-array-index-key": "off", - "react/no-multi-comp": "off", - "react/prop-types": "off", - "react/require-default-props": "off", - "react/sort-comp": "off" - } -} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 215bc1b8..00000000 --- a/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -# Common -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -Thumbs.db -*.swp -*.log - -# Environment -.idea -.env -*.iml -*.bat -*.map - -# Project -node_modules -bin -coverage -dist -/app/ -/plugins/ -/resources/ diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100644 index 36af2198..00000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -npx lint-staged diff --git a/.npmignore b/.npmignore deleted file mode 100644 index f59ec20a..00000000 --- a/.npmignore +++ /dev/null @@ -1 +0,0 @@ -* \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 1193784d..00000000 --- a/.prettierrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "arrowParens": "avoid", - "endOfLine": "lf", - "printWidth": 100, - "singleQuote": true, - "trailingComma": "all" -} diff --git a/.stylelintrc.json b/.stylelintrc.json deleted file mode 100644 index 117fac2a..00000000 --- a/.stylelintrc.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends": [ - "stylelint-config-recommended", - "stylelint-config-css-modules", - "stylelint-config-prettier" - ], - "rules": { - "no-descending-specificity": null, - "selector-pseudo-class-no-unknown": [ - true, - { - "ignorePseudoClasses": ["global", "horizontal", "vertical"] - } - ] - }, - "ignoreFiles": ["**/*.js"] -} diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 6112fdc1..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Build: yarn build", - "type": "node", - "request": "launch", - "cwd": "${workspaceFolder}", - "runtimeExecutable": "yarn", - "runtimeArgs": [ "run", "build" ], - }, - { - "name": "Build: yarn dev", - "type": "node", - "request": "launch", - "cwd": "${workspaceFolder}", - "runtimeExecutable": "yarn", - "runtimeArgs": [ "run", "dev" ], - }, - { - "name": "Build: yarn test", - "type": "node", - "request": "launch", - "cwd": "${workspaceFolder}", - "runtimeExecutable": "yarn", - "runtimeArgs": [ "run", "test" ], - }, - { - "name": "React: DevServer", - "type": "node", - "request": "launch", - "cwd": "${workspaceFolder}", - "env": { "PORT": "3001" }, - "runtimeExecutable": "yarn", - "runtimeArgs": [ "run", "dev" ], - }, - { - "name": "Electron: Main", - "type": "node", - "request": "launch", - "cwd": "${workspaceFolder}", - "protocol": "inspector", - "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron", - "runtimeArgs": [ "--remote-debugging-port=9223", "." ], - "windows": { - "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd" - } - }, - { - "name": "Electron: Renderer", - "type": "chrome", - "request": "attach", - "port": 9223, - "webRoot": "${workspaceFolder}", - "timeout": 15000 - } - ], - "compounds": [ - { - "name": "Astrofox: Debug", - "configurations": [ - "React: DevServer", - "Electron: Main", - "Electron: Renderer", - ] - } - ] -} \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 51277655..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Mike Cao - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index d1ed6924..00000000 --- a/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# Astrofox - -## What is it? - -Astrofox is a motion graphics program that lets turn audio into amazing videos. - - - -## Quick links - -- Demo video: https://www.youtube.com/watch?v=IbvuniqNPPw -- Website: https://astrofox.io -- Discord chat: https://discord.gg/wJ6pyMZ -- Reddit forum: https://www.reddit.com/r/astrofox/ -- Bug tracker: https://github.com/astrofox-io/astrofox/issues - -## Running Astrofox - -### Get the source - -``` -git clone https://github.com/astrofox-io/astrofox.git -``` - -### Install FFmpeg - -``` -yarn install-ffmpeg -``` - -### Install dependencies - -``` -yarn install -``` - -### Build the application - -``` -yarn build -``` - -### Start the application - -``` -yarn start -``` - -## Running for development - -Instead of `yarn build` above, run `yarn dev`. This will start up a development server -in the current console window. - -Then, in a separate console window, run `yarn start`. - -## License - -MIT diff --git a/__tests__/core/ArrayList.spec.js b/__tests__/core/ArrayList.spec.js deleted file mode 100644 index 843eff55..00000000 --- a/__tests__/core/ArrayList.spec.js +++ /dev/null @@ -1,48 +0,0 @@ -import ArrayList from 'core/ArrayList'; - -let a; - -beforeEach(() => { - a = new ArrayList(1, 2, 3); -}); - -test('arraylist is instance of array', () => { - expect(a).toBeInstanceOf(Array); -}); - -describe('isEmpty method working properly', () => { - test('empty arraylist', () => { - expect(new ArrayList().isEmpty()).toBe(true); - }); - - test('non-empty arraylist', () => { - expect(a.isEmpty()).toBe(false); - }); -}); - -test('insert method working properly', () => { - a.insert(5, 1); - expect(a).toEqual([1, 5, 2, 3]); -}); - -test('remove method working properly', () => { - a.remove(0); - expect(a).toEqual([2, 3]); -}); - -describe('swap method working properly', () => { - test('different indexes', () => { - a.swap(0, 2); - expect(a).toEqual([3, 2, 1]); - }); - - test('same indexes', () => { - a.swap(0, 0); - expect(a).toEqual([1, 2, 3]); - }); -}); - -test('clear method working properly', () => { - a.clear(); - expect(a).toEqual([]); -}); diff --git a/__tests__/core/Entity.spec.js b/__tests__/core/Entity.spec.js deleted file mode 100644 index 3fa1db72..00000000 --- a/__tests__/core/Entity.spec.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @jest-environment jsdom - */ -import Entity from 'core/Entity'; - -let e; - -beforeEach(() => { - e = new Entity('NewEntity', { speed: '100' }); -}); - -test('create works properly', () => { - const a = Entity.create(Entity, { id: "321321", properties: {} }); - expect(a.id).toEqual('321321'); - expect(a.properties).toStrictEqual({}); -}); - -describe('constructor works properly', () => { - test('with properties', () => { - const a = new Entity('Name', { speed: '100' }); - expect(a.name).toStrictEqual('Name'); - expect(a.properties).toStrictEqual({ speed: '100' }); - }); - - test('without properties', () => { - const a = new Entity('Name'); - expect(a.name).toStrictEqual('Name'); - expect(a.properties).toStrictEqual({}); - }); -}); - -describe('update works properly', () => { - test('no properties provided', () => { - expect(e.update()).toBe(false); - }); - - test('properties is typeof function', () => { - const speedUp = props => { - return { ...props, speed: '200' }; - }; - expect(e.update(speedUp)).toBe(true); - }); - - test('properties is not typeof function', () => { - expect(e.update({ speed: '200' })).toBe(true); - }); -}); - -test('toString works provided', () => { - expect(e.toString()).toEqual(`[NewEntity ${e.id}]`); -}); - -test('toJSON works property', () => { - expect(e.toJSON()).toEqual({ id: `${e.id}`, name: 'NewEntity', properties: { speed: '100' } }); -}); diff --git a/__tests__/core/EntityList.spec.js b/__tests__/core/EntityList.spec.js deleted file mode 100644 index 97fc8861..00000000 --- a/__tests__/core/EntityList.spec.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @jest-environment jsdom - */ -import EntityList from 'core/EntityList'; -import Entity from 'core/Entity'; - -let e; -let obj1; -let obj2; -let obj3; - -beforeEach(() => { - obj1 = new Entity('Object1'); - obj2 = new Entity('Object2'); - obj3 = new Entity('Object3'); - - e = new EntityList(obj1, obj2); -}); - -describe('getElementById method works properly', () => { - test('valid id', () => { - expect(e.getElementById(obj1.id)).toEqual(obj1); - }); - - test('invalid id', () => { - expect(e.getElementById(3)).toBeUndefined(); - }); -}); - -describe('hasElement method works properly', () => { - test('valid object', () => { - expect(e.hasElement(obj1)).toBe(true); - }); - - test('invalid object', () => { - expect(e.hasElement(obj3)).toBe(false); - }); -}); - -describe('addElement method works properly', () => { - test('no object provided', () => { - expect(e.addElement()).toBeUndefined(); - }); - - test('index provided', () => { - expect(e.addElement(obj3, 1)).toEqual(obj3); - }); - - test('no index provided', () => { - expect(e.addElement(obj3)).toEqual(obj3); - }); -}); - -describe('removeElement method works properly', () => { - test('element exists', () => { - expect(e.removeElement(obj2)).toBe(true); - }); - - test('element does not exist', () => { - expect(e.removeElement({ id: 3 })).toBe(false); - }); -}); - -describe('shiftElement method works properly', () => { - test('element exists', () => { - expect(e.shiftElement(obj2, 1)).toBe(false); - }); - - test('element does not exist', () => { - expect(e.shiftElement(obj3, 1)).toBe(false); - }); -}); - -test('toJSON method works properly', () => { - expect(e.toJSON()).toEqual([ - { id: `${e[0].id}`, name: 'Object1', properties: {} }, - { id: `${e[1].id}`, name: 'Object2', properties: {} }, - ]); -}); - -// Extra EntityList tests -describe('isEmpty method working properly', () => { - test('empty EntityList', () => { - expect(new EntityList().isEmpty()).toBe(true); - }); - - test('non-empty EntityList', () => { - expect(e.isEmpty()).toBe(false); - }); -}); - -test('clear method working properly', () => { - e.clear(); - expect(e).toEqual([]); -}); diff --git a/__tests__/utils/array.spec.js b/__tests__/utils/array.spec.js deleted file mode 100644 index 6b8050c7..00000000 --- a/__tests__/utils/array.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -import { isDefined, contains, reverse } from 'utils/array'; - -test('check if array is defined', () => { - expect(isDefined([1, 2, 3])).toBe(true); -}); - -test('check if arr1 contains arr2', () => { - expect(contains([1, 2, 4], [1, 2, 3])).toBe(true); - expect(contains([1, 2, 3], [4, 5, 6])).toBe(false); -}); - -test('reverse an array properly', () => { - expect(reverse([1, 2, 3])).toEqual([3, 2, 1]); - expect(reverse([1, 2, 3])).not.toBe([1, 2, 3]); -}); diff --git a/__tests__/utils/crypto.spec.js b/__tests__/utils/crypto.spec.js deleted file mode 100644 index b919f215..00000000 --- a/__tests__/utils/crypto.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @jest-environment jsdom - */ - -import { uniqueId } from 'utils/crypto'; - -test('uniqueId functions exists', () => { - expect(uniqueId()).toBeDefined(); -}); - -test('unique id has a length of 40 characters', () => { - expect(uniqueId()).toHaveLength(40); -}); diff --git a/__tests__/utils/easing.spec.js b/__tests__/utils/easing.spec.js deleted file mode 100644 index e8570ad1..00000000 --- a/__tests__/utils/easing.spec.js +++ /dev/null @@ -1,71 +0,0 @@ -import { - linear, - easeInQuad, - easeOutQuad, - easeInOutQuad, - easeInCubic, - easeOutCubic, - easeInOutCubic, - easeInQuart, - easeOutQuart, - easeInOutQuart, - easeInQuint, - easeOutQuint, - easeInOutQuint, -} from 'utils/easing'; - -test('linear constant', () => { - expect(linear(10)).toBe(10); -}); - -test('accelerating from zero velocity properly', () => { - expect(easeInQuad(10)).toBe(100); -}); - -test('decelerating to zero velocity properly', () => { - expect(easeOutQuad(10)).toBe(-80); -}); - -test('acceleration until halfway, then deceleration properly', () => { - expect(easeInOutQuad(0)).toBe(0); - expect(easeInOutQuad(10)).toBe(-161); -}); - -test('accelerating from zero velocity properly', () => { - expect(easeInCubic(10)).toBe(1000); -}); - -test('decelerating to zero velocity properly', () => { - expect(easeOutCubic(10)).toBe(730); -}); - -test('acceleration until halfway, then deceleration properly', () => { - expect(easeInOutCubic(0.3)).toBe(0.108); - expect(easeInOutCubic(10)).toBe(2917); -}); - -test('accelerating from zero velocity properly', () => { - expect(easeInQuart(10)).toBe(10000); -}); - -test('decelerating to zero velocity properly', () => { - expect(easeOutQuart(10)).toBe(-6560); -}); - -test('acceleration until halfway, then deceleration properly', () => { - expect(easeInOutQuart(0.3)).toBe(0.0648); - expect(easeInOutQuart(10)).toBe(-52487); -}); - -test('accelerating from zero velocity properly', () => { - expect(easeInQuint(10)).toBe(100000); -}); - -test('decelerating to zero velocity properly', () => { - expect(easeOutQuint(10)).toBe(59050); -}); - -test('acceleration until halfway, then deceleration properly', () => { - expect(easeInOutQuint(0.3)).toBe(0.03888); - expect(easeInOutQuint(10)).toBe(944785); -}); diff --git a/__tests__/utils/format.spec.js b/__tests__/utils/format.spec.js deleted file mode 100644 index 79e53434..00000000 --- a/__tests__/utils/format.spec.js +++ /dev/null @@ -1,116 +0,0 @@ -import { - formatSize, - parseTime, - formatTime, - formatShortTime, - parseSeekTime, - formatSeekTime, -} from 'utils/format'; - -describe('formatSize is working properly', () => { - test('formatSize exists', () => { - expect(formatSize()).toBeDefined(); - }); - - test('value is zero', () => { - expect(formatSize(0, 2)).toEqual('N/A'); - }); - - test('value is not zero', () => { - expect(formatSize(16540654, 2)).toEqual('15.77 MB'); - }); -}); - -describe('parseTime is working properly', () => { - test('parseTime exists', () => { - expect(parseTime()).toBeDefined(); - }); - - test('returns properly', () => { - expect(parseTime(254511)).toEqual({ days: 2, hours: 22, minutes: 41, ms: 0, seconds: 51 }); - }); -}); - -describe('formatTime is working properly', () => { - test('formatTime exists', () => { - expect(parseTime()).toBeDefined(); - }); - - test('hours is less than than zero', () => { - expect(formatTime(264)).toEqual('4:24'); - }); - - test('hours is greater than than zero', () => { - expect(formatTime(25451)).toEqual('7:04:11'); - }); -}); - -describe('formatShortTime is working properly', () => { - test('formatShortTime exists', () => { - expect(formatShortTime()).toBeDefined(); - }); - - test('val is equal to zero', () => { - expect(formatShortTime(0)).toEqual('0s'); - }); - - test('days is greater than than zero & format = d', () => { - expect(formatShortTime(254511, ['d'])).toEqual('2d'); - }); - - test('hours is greater than than zero & format = h', () => { - expect(formatShortTime(25451, ['h'])).toEqual('7h'); - }); - - test('minutes is greater than than zero & format = m', () => { - expect(formatShortTime(25451, ['m'])).toEqual('4m'); - }); - - test('seconds is greater than than zero & format = s', () => { - expect(formatShortTime(25451, ['s'])).toEqual('11s'); - }); - - test('ms is greater than than zero & format = ms', () => { - expect(formatShortTime(250.25, ['ms'])).toEqual('250ms'); - }); - - test('correct output with default format', () => { - expect(formatShortTime(254511)).toEqual('41m51s'); - }); - - test('correct output with format', () => { - expect(formatShortTime(254500.25, ['d', 'h', 'm', 's', 'ms'])).toEqual('2d22h41m40s250ms'); - }); - - test('correct output with double spaces', () => { - expect(formatShortTime(254511, ['m', 's'], ' ')).toEqual('41m 51s '); - }); -}); - -describe('parseSeekTime is working properly', () => { - test('parseSeekTime exists', () => { - expect(parseSeekTime('')).toBeDefined(); - }); - - test('val does not match regex', () => { - expect(parseSeekTime('060')).toBeNull(); - }); - - test('has hours', () => { - expect(parseSeekTime('5:51:60')).toEqual(21120); - }); - - test('has no hours', () => { - expect(parseSeekTime('51:60')).toEqual(3120); - }); -}); - -describe('formatSeekTime is working properly', () => { - test('formatSeekTime exists', () => { - expect(formatSeekTime()).toBeDefined(); - }); - - test('formats seek time properly', () => { - expect(formatSeekTime(65489)).toEqual('18:11:29'); - }); -}); diff --git a/__tests__/utils/math.spec.js b/__tests__/utils/math.spec.js deleted file mode 100644 index 21c2cc4e..00000000 --- a/__tests__/utils/math.spec.js +++ /dev/null @@ -1,78 +0,0 @@ -import { - round, - ceil, - floor, - clamp, - decimals, - roundTo, - normalize, - log10, - db2mag, - mag2db, - deg2rad, - rad2deg, - hash, -} from 'utils/math'; - -test('rounding number properly', () => { - expect(round(5.1)).toBe(5); - expect(round(5.9)).toBe(6); -}); - -test('ceiling number properly', () => { - expect(ceil(5.2)).toBe(6); - expect(ceil(5)).toBe(5); -}); - -test('floor operation working properly', () => { - expect(floor(5.2)).toBe(5); -}); - -test('clamps value between min and max properly', () => { - expect(clamp(1, 2, 8)).toBe(2); - expect(clamp(10, 2, 8)).toBe(8); - expect(clamp(8, 2, 8)).toBe(8); -}); - -test('count decimal places in a number properly', () => { - expect(decimals(5)).toBe(0); - expect(decimals(5.298)).toBe(3); -}); - -test('round to nearest given interval properly', () => { - expect(roundTo(5.6, 10)).toBe(10); - expect(roundTo(11, -5)).toBe(5); - expect(roundTo(10, 5.55)).toBe(11.1); -}); - -test('find percent value of a number in a range properly', () => { - expect(normalize(50, 20, 20)).toBe(1); - expect(normalize(500, 20, 30)).toBe(1); - expect(normalize(0, 20, 30)).toBe(0); - expect(normalize(50, 20, 80)).toBe(0.5); -}); - -test('calculate log base 10 properly', () => { - expect(log10(100)).toBe(2); -}); - -test('calculate decibels to magnitude properly', () => { - expect(db2mag(20)).toBe(10.000000000000002); -}); - -test('calculate magnitude to decibels properly', () => { - expect(mag2db(20)).toBe(26.02059991327962); -}); - -test('convert degrees to radians properly', () => { - expect(deg2rad(180)).toBe(3.141592653589793); -}); - -test('convert radians to degrees properly', () => { - expect(rad2deg(3.141592653589793)).toBe(180); -}); - -test('find hash code of a string properly', () => { - expect(hash('')).toBe(0); - expect(hash('astrofox')).toBe(-332709840); -}); diff --git a/__tests__/utils/object.spec.js b/__tests__/utils/object.spec.js deleted file mode 100644 index 15e4d69a..00000000 --- a/__tests__/utils/object.spec.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @jest-environment jsdom - */ -import { updateExistingProps } from 'utils/object'; -import cloneDeep from 'lodash/cloneDeep'; - -describe('updateExistingProps works properly', () => { - test('oldProps !== newProps', () => { - const oldProps = { speed: "100", theta: 75, acceleration: "2m/s", undefined: null }; - const newProps = { speed: "200", direction: 75, acceleration: 4.2, undefined: undefined }; - const result = updateExistingProps(oldProps, newProps); - expect(result).toBeTruthy(); - expect(oldProps).toStrictEqual({ speed: "200", theta: 75, acceleration: 4.2, undefined: undefined }); - }); - - test('oldProps === newProps', () => { - const oldProps = { speed: "100", theta: 75, acceleration: "2m/s", undefined: undefined }; - const newProps = { speed: "100", theta: 75, direction: 75, acceleration: "2m/s", undefined: undefined }; - const oldPropsDup = cloneDeep(oldProps); - const result = updateExistingProps(oldProps, newProps); - expect(result).toBeFalsy(); - expect(oldProps).toStrictEqual(oldPropsDup); - }); -}); diff --git a/__tests__/utils/string.spec.js b/__tests__/utils/string.spec.js deleted file mode 100644 index 5a46f671..00000000 --- a/__tests__/utils/string.spec.js +++ /dev/null @@ -1,5 +0,0 @@ -import { trimChars } from 'utils/string'; - -test('trim chars from string properly', () => { - expect(trimChars("hello there\v")).toBe("hello there"); -}); diff --git a/build/background.tiff b/build/background.tiff deleted file mode 100644 index ccb90cd1..00000000 Binary files a/build/background.tiff and /dev/null differ diff --git a/build/entitlements.mac.plist b/build/entitlements.mac.plist deleted file mode 100644 index bb87459e..00000000 --- a/build/entitlements.mac.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.security.cs.allow-unsigned-executable-memory - - - \ No newline at end of file diff --git a/build/icon.icns b/build/icon.icns deleted file mode 100644 index c3cec0f4..00000000 Binary files a/build/icon.icns and /dev/null differ diff --git a/build/icon.ico b/build/icon.ico deleted file mode 100644 index ff8b2627..00000000 Binary files a/build/icon.ico and /dev/null differ diff --git a/build/icons/512x512.png b/build/icons/512x512.png deleted file mode 100644 index d83e6752..00000000 Binary files a/build/icons/512x512.png and /dev/null differ diff --git a/build/install-spinner.gif b/build/install-spinner.gif deleted file mode 100644 index 8a8d0fef..00000000 Binary files a/build/install-spinner.gif and /dev/null differ diff --git a/ds b/ds new file mode 100644 index 00000000..72f7f1e8 --- /dev/null +++ b/ds @@ -0,0 +1 @@ +dfadsf diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index bf8b8360..00000000 --- a/jest.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - moduleDirectories: ['node_modules', 'src'], - setupFiles: ['./test/crypto.mock.js'], -}; diff --git a/package.json b/package.json deleted file mode 100644 index 2163c5c1..00000000 --- a/package.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "name": "astrofox", - "version": "1.4.0", - "productName": "Astrofox", - "description": "Audio reactive motion graphics program", - "author": "Mike Cao ", - "license": "MIT", - "homepage": "https://astrofox.io", - "repository": { - "type": "git", - "url": "https://github.com/astrofox-io/astrofox" - }, - "main": "app/main.js", - "scripts": { - "start": "dotenv electron ./app", - "dev": "npm-run-all bootstrap dev-all", - "build": "npm-run-all bootstrap build-prod", - "test": "jest --coverage", - "dev-all": "npm-run-all --parallel dev-electron dev-view", - "dev-view": "dotenv webpack serve --progress --config webpack.config.view.js", - "dev-electron": "webpack --progress --watch --config webpack.config.electron.js", - "build-dev": "webpack --progress --config webpack.config.js", - "build-prod": "cross-env NODE_ENV=production webpack --progress --config webpack.config.js", - "build-electron": "npm-run-all init-app build-main build-preload", - "build-main": "webpack --config webpack.config.main.js", - "build-preload": "webpack --config webpack.config.preload.js", - "build-win": "dotenv electron-builder --x64 --win", - "build-mac": "dotenv electron-builder --x64 --mac", - "build-linux": "dotenv electron-builder --x64 --linux", - "lint": "eslint src || exit 0", - "lint-fix": "eslint --fix src || exit 0", - "lint-check": "eslint --print-config . | eslint-config-prettier-check", - "stylelint": "stylelint src/view/components", - "notarize": "node ./scripts/notarize.js", - "bootstrap": "node scripts/bootstrap.js", - "install-ffmpeg": "node ./scripts/install-ffmpeg.js" - }, - "build": { - "appId": "io.astrofox.app", - "productName": "Astrofox", - "asar": true, - "files": [ - "**/*", - "!*.yml", - "!*.lock" - ], - "extraResources": [ - { - "from": "bin", - "to": "bin" - } - ], - "publish": { - "provider": "generic", - "url": "https://files.astrofox.io/download", - "channel": "latest" - }, - "dmg": { - "sign": false - }, - "nsis": { - "oneClick": true - }, - "mac": { - "category": "public.app-category.video", - "hardenedRuntime": true, - "gatekeeperAssess": false, - "entitlements": "build/entitlements.mac.plist", - "entitlementsInherit": "build/entitlements.mac.plist" - }, - "win": { - "target": [ - "nsis" - ] - }, - "linux": { - "target": [ - "AppImage" - ], - "icon": "build/icons/512x512.png", - "category": "AudioVideo" - } - }, - "lint-staged": { - "src/**/*.js": [ - "prettier --write", - "eslint" - ], - "src/**/*.{css,less}": [ - "stylelint --fix", - "prettier --write" - ] - }, - "dependencies": { - "classnames": "^2.3.1", - "debug": "^4.3.1", - "del": "^6.0.0", - "electron-localshortcut": "^3.2.1", - "fourier-transform": "^1.1.2", - "glob": "^7.1.6", - "id3js": "2.1.1", - "immer": "^9.0.6", - "lodash": "^4.17.21", - "mime": "^2.5.2", - "path-browserify": "^1.0.1", - "prop-types": "^15.7.2", - "react": "^18.1.0", - "react-dom": "^18.1.0", - "react-spring": "^9.0.0", - "react-window": "^1.8.6", - "reselect": "^4.0.0", - "semver": "^7.3.5", - "three": "0.139.2", - "tinycolor2": "^1.4.2", - "window-function": "^2.1.0", - "yauzl": "^2.10.0", - "zustand": "^3.4.0" - }, - "devDependencies": { - "@babel/core": "^7.13.14", - "@babel/eslint-parser": "^7.16.3", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-export-default-from": "^7.12.13", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/preset-env": "^7.13.12", - "@babel/preset-react": "^7.12.13", - "@hot-loader/react-dom": "^17.0.1", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.1", - "babel-loader": "^8.2.2", - "copy-webpack-plugin": "^9.0.1", - "cross-env": "^7.0.3", - "css-loader": "^6.4.0", - "css-minimizer-webpack-plugin": "^3.1.1", - "dotenv": "^10.0.0", - "dotenv-cli": "^4.0.0", - "electron": "18.3.7", - "electron-builder": "^23.0.3", - "electron-notarize": "^1.0.0", - "electron-updater": "^5.0.1", - "eslint": "^8.0.1", - "eslint-config-airbnb": "^18.2.1", - "eslint-config-prettier": "^8.1.0", - "eslint-plugin-css-modules": "^2.11.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jest": "^25.2.2", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-promise": "^5.1.0", - "eslint-plugin-react": "^7.23.1", - "eslint-plugin-react-hooks": "^4.2.0", - "express": "^4.17.1", - "file-loader": "^6.2.0", - "glsl-man": "^1.1.14", - "glslx": "^0.2.13", - "husky": "^7.0.2", - "jest": "^27.2.5", - "less": "^4.1.1", - "less-loader": "^10.1.0", - "lint-staged": "^11.2.3", - "mini-css-extract-plugin": "^2.4.2", - "npm-run-all": "^4.1.5", - "prettier": "^2.2.1", - "prettier-eslint": "^13.0.0", - "react-refresh": "^0.13.0", - "style-loader": "^3.3.0", - "stylelint": "^14.0.1", - "stylelint-config-css-modules": "^2.2.0", - "stylelint-config-prettier": "^9.0.3", - "stylelint-config-recommended": "^6.0.0", - "svg-sprite-loader": "6.0.11", - "terser-webpack-plugin": "^5.1.1", - "url-loader": "^4.1.1", - "webpack": "^5.30.0", - "webpack-cli": "^4.6.0", - "webpack-dev-server": "^4.3.1" - } -} diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js deleted file mode 100644 index ccf1ca0b..00000000 --- a/scripts/bootstrap.js +++ /dev/null @@ -1,35 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const prettier = require('prettier'); -const pkg = require('../package.json'); - -const appFolder = path.resolve(__dirname, '../app'); - -if (!fs.existsSync(appFolder)) { - fs.mkdirSync(appFolder); -} - -const { name, version, productName, description, author, license, homepage, repository } = pkg; - -// Create package.json file in app directory -const json = prettier.format( - JSON.stringify({ - name, - version, - productName, - description, - author, - license, - homepage, - repository, - main: 'main.js', - dependencies: {}, - }), - { parser: 'json' }, -); - -fs.writeFileSync(path.join(appFolder, 'package.json'), json); - -// Create app-update.yml files -const srcFile = path.resolve(__dirname, '../src/build/app/dev-app-update.yml'); -fs.copyFileSync(srcFile, path.resolve(appFolder, 'dev-app-update.yml')); diff --git a/scripts/install-ffmpeg.js b/scripts/install-ffmpeg.js deleted file mode 100644 index d67f3a67..00000000 --- a/scripts/install-ffmpeg.js +++ /dev/null @@ -1,39 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const os = require('os'); -const https = require('https'); - -const dest = path.resolve(__dirname, '../bin'); - -if (!fs.existsSync(dest)) { - fs.mkdirSync(dest); -} - -const platform = os.platform(); - -if (!['win32', 'darwin', 'linux'].includes(platform)) { - throw new Error('Unsupported platform'); -} - -const files = { - win32: ['win', 'ffmpeg.exe'], - darwin: ['mac', 'ffmpeg'], - linux: ['linux', 'ffmpeg'], -}; - -const download = async (url, file) => { - const filename = path.join(dest, file); - - console.log(`Downloading ${url} -> ${filename}`); - - await new Promise(resolve => { - https.get(url, res => { - resolve(res.pipe(fs.createWriteStream(filename))); - }); - }); -}; - -const [dir, file] = files[platform]; -const url = `https://files.astrofox.io/ffmpeg/${dir}/${file}`; - -download(url, file); diff --git a/scripts/notarize.js b/scripts/notarize.js deleted file mode 100644 index c6a5082b..00000000 --- a/scripts/notarize.js +++ /dev/null @@ -1,17 +0,0 @@ -require('dotenv').config(); -const { notarize } = require('electron-notarize'); - -const { APPLEID, APPLEIDPASS } = process.env; - -(async () => { - console.log('Staring notarize...'); - - await notarize({ - appBundleId: 'io.astrofox.app', - appPath: 'dist/mac/Astrofox.app', - appleId: APPLEID, - appleIdPassword: APPLEIDPASS, - }); - - console.log('Notarization complete.'); -})(); diff --git a/src/audio/Audio.js b/src/audio/Audio.js deleted file mode 100644 index e46f6d1b..00000000 --- a/src/audio/Audio.js +++ /dev/null @@ -1,171 +0,0 @@ -export default class Audio { - constructor(context) { - this.audioContext = context; - this.source = null; - this.buffer = null; - this.startTime = 0; - this.stopTime = 0; - this.nodes = []; - this.playing = false; - this.paused = false; - this.repeat = false; - } - - load(src) { - if (typeof src === 'string') { - return this.loadUrl(src); - } else if (src instanceof ArrayBuffer) { - return this.loadData(src); - } else if (src instanceof AudioBuffer) { - return this.loadBuffer(src); - } - - throw new Error(`Invalid source: ${typeof src}`); - } - - unload() { - if (this.source) { - this.stop(); - this.source = null; - this.buffer = null; - } - } - - // Loads a url via AJAX - async loadUrl(url) { - const response = await fetch(url); - return this.loadData(response); - } - - // Decodes an ArrayBuffer into an AudioBuffer - async loadData(data) { - const buffer = await this.audioContext.decodeAudioData(data); - return this.loadBuffer(buffer); - } - - // Loads an AudioBuffer - loadBuffer(buffer) { - this.buffer = buffer; - } - - addNode(node) { - if (this.nodes.indexOf(node) < 0) { - this.nodes.push(node); - } - } - - removeNode(node) { - const index = this.nodes.indexOf(node); - - if (index > -1) { - this.nodes.splice(index, 1); - } - } - - reconnectNodes() { - this.nodes.forEach(node => { - this.source.connect(node); - }); - } - - disconnectNodes() { - this.nodes.forEach(node => { - node.disconnect(); - }); - } - - initBuffer() { - this.source = this.audioContext.createBufferSource(); - this.source.buffer = this.buffer; - - this.reconnectNodes(); - } - - play() { - if (this.buffer) { - this.initBuffer(); - - this.startTime = this.audioContext.currentTime; - this.source.start(0, this.getCurrentTime()); - this.playing = true; - this.paused = false; - } - } - - pause() { - if (this.source) { - this.source.stop(); - this.source = null; - } - - this.stopTime += this.audioContext.currentTime - this.startTime; - this.playing = false; - this.paused = true; - } - - stop() { - if (this.source) { - if (this.playing) this.source.stop(); - this.source.disconnect(); - this.source = null; - } - - this.stopTime = 0; - this.playing = false; - this.paused = false; - } - - seek(pos) { - if (this.playing) { - this.stop(); - this.updatePosition(pos); - this.play(); - } else { - this.updatePosition(pos); - } - } - - getCurrentTime() { - return this.playing - ? this.stopTime + (this.audioContext.currentTime - this.startTime) - : this.stopTime; - } - - getDuration() { - return this.buffer ? this.buffer.duration : 0; - } - - getBufferLength() { - return this.buffer ? this.buffer.length : 0; - } - - getPosition() { - return this.getCurrentTime() / this.getDuration() || 0; - } - - getBufferPosition(time) { - const position = time ? time / this.getDuration() : this.getPosition(); - return ~~(position * this.buffer.length); - } - - getAudioSlice(start, end) { - const channels = this.buffer.numberOfChannels; - const length = end - start; - const output = this.audioContext.createBuffer(channels, length, this.audioContext.sampleRate); - - for (let i = 0; i < channels; i++) { - const ch = output.getChannelData(i); - const buffer = this.buffer.getChannelData(i); - - for (let j = start; j < end; j++) { - ch[j - start] = buffer[j]; - } - } - - return output; - } - - updatePosition(pos) { - this.stopTime = ~~(pos * this.buffer.duration); - } -} diff --git a/src/audio/AudioReactor.js b/src/audio/AudioReactor.js deleted file mode 100644 index 38a33f74..00000000 --- a/src/audio/AudioReactor.js +++ /dev/null @@ -1,199 +0,0 @@ -import cloneDeep from 'lodash/cloneDeep'; -import Entity from 'core/Entity'; -import FFTParser from 'audio/FFTParser'; -import { normalize, floor, ceil } from 'utils/math'; -import { - FFT_SIZE, - SAMPLE_RATE, - REACTOR_BARS, - REACTOR_BAR_WIDTH, - REACTOR_BAR_HEIGHT, - REACTOR_BAR_SPACING, -} from 'view/constants'; -import { isDefined } from 'utils/array'; -import { getDisplayName } from 'utils/controls'; - -const REACTOR_BINS = 64; -const CYCLE_MODIFIER = 0.1; - -const outputOptions = ['Subtract', 'Add', 'Reverse', 'Forward', 'Cycle']; - -const spectrumProperties = { - maxDecibels: -20, - smoothingTimeConstant: 0.5, - maxFrequency: ceil((SAMPLE_RATE / FFT_SIZE) * REACTOR_BINS), - normalize: true, - bins: REACTOR_BINS, -}; - -export default class AudioReactor extends Entity { - static config = { - name: 'AudioReactor', - description: 'Audio reactor.', - type: 'reactor', - label: 'Reactor', - defaultProperties: { - outputMode: 'Add', - selection: { - x: 0, - y: 0, - width: 100, - height: 100, - }, - range: { - x1: 0, - x2: 1, - y1: 0, - y2: 1, - }, - maxDecibels: -20, - smoothingTimeConstant: 0.5, - }, - controls: { - outputMode: { - label: 'Output Mode', - type: 'select', - items: outputOptions, - }, - maxDecibels: { - label: 'Max dB', - type: 'number', - min: -40, - max: 0, - withRange: true, - }, - smoothingTimeConstant: { - label: 'Smoothing', - type: 'number', - min: 0, - max: 0.99, - step: 0.01, - withRange: true, - }, - }, - }; - - constructor(properties) { - const { - config: { name, label, defaultProperties }, - } = AudioReactor; - - super(name, { ...defaultProperties, ...properties }); - - this.parser = new FFTParser({ ...spectrumProperties, ...properties }); - this.type = 'reactor'; - this.displayName = getDisplayName(label); - this.enabled = true; - this.result = { fft: [], output: 0 }; - this.direction = 1; - } - - update(properties = {}) { - const { selection, maxDecibels, smoothingTimeConstant } = properties; - - if (isDefined(maxDecibels, smoothingTimeConstant)) { - this.parser.update(properties); - } - - if (selection) { - const { x, y, width, height } = selection; - const maxWidth = REACTOR_BARS * (REACTOR_BAR_WIDTH + REACTOR_BAR_SPACING); - const maxHeight = REACTOR_BAR_HEIGHT; - - properties.range = { - x1: x / maxWidth, - x2: (x + width) / maxWidth, - y1: y / maxHeight, - y2: (y + height) / maxHeight, - }; - } - - return super.update(properties); - } - - getResult() { - return this.result; - } - - parse(data) { - const { hasUpdate, fft: inputFft } = data; - const fft = this.parser.parseFFT(inputFft); - const { - outputMode, - range: { x1, y1, x2, y2 }, - } = this.properties; - const start = floor(x1 * fft.length); - const end = ceil(x2 * fft.length); - - let { output } = this.result; - let sum = 0; - - for (let i = start; i < end; i += 1) { - sum += normalize(fft[i], 1 - y2, 1 - y1); - } - - const avg = sum / (end - start); - - switch (outputMode) { - case 'Add': - output = avg; - break; - - case 'Subtract': - output = 1 - avg; - break; - - case 'Forward': - if (hasUpdate) { - output += avg * CYCLE_MODIFIER; - if (output > 1) { - output = 1 - output; - } - } - break; - - case 'Reverse': - if (hasUpdate) { - output -= avg * CYCLE_MODIFIER; - if (output < 0) { - output = 1 - output; - } - } - break; - - case 'Cycle': - if (hasUpdate) { - if (this.direction > 0) { - output += avg * CYCLE_MODIFIER; - if (output > 1) { - this.direction = -1; - } - } else { - output -= avg * CYCLE_MODIFIER; - if (output < 0) { - this.direction = 1; - } - } - } - break; - } - - this.result.fft = fft; - this.result.output = output; - - return this.result; - } - - toJSON() { - const { id, name, type, displayName, enabled, properties } = this; - - return { - id, - name, - type, - displayName, - enabled, - properties: cloneDeep(properties), - }; - } -} diff --git a/src/audio/FFTParser.js b/src/audio/FFTParser.js deleted file mode 100644 index 7e30b74f..00000000 --- a/src/audio/FFTParser.js +++ /dev/null @@ -1,117 +0,0 @@ -import Entity from 'core/Entity'; -import { db2mag, floor, normalize } from 'utils/math'; -import { FFT_SIZE, SAMPLE_RATE } from 'view/constants'; - -export default class FFTParser extends Entity { - static defaultProperties = { - fftSize: FFT_SIZE, - sampleRate: SAMPLE_RATE, - smoothingTimeConstant: 0.5, - minDecibels: -100, - maxDecibels: 0, - minFrequency: 0, - maxFrequency: SAMPLE_RATE / 2, - }; - - constructor(properties) { - super('FFTParser', { ...FFTParser.defaultProperties, ...properties }); - - this.init(); - } - - init() { - const { fftSize, sampleRate, minFrequency, maxFrequency } = this.properties; - - const range = sampleRate / fftSize; - - this.startBin = floor(minFrequency / range); - this.endBin = floor(maxFrequency / range); - this.totalBins = this.endBin - this.startBin; - } - - update(properties) { - const changed = super.update(properties); - - if (changed) { - this.init(); - } - - return changed; - } - - getValue(fft) { - const { minDecibels, maxDecibels } = this.properties; - const db = minDecibels * (1 - fft / 256); - - return normalize(db2mag(db), db2mag(minDecibels), db2mag(maxDecibels)); - } - - parseFFT(fft, bins) { - let { output, buffer } = this; - const { startBin, endBin, totalBins } = this; - const { smoothingTimeConstant } = this.properties; - const size = bins || totalBins; - - // Resize data arrays - if (output?.length !== size) { - output = new Float32Array(size); - buffer = new Float32Array(size); - this.output = output; - this.buffer = buffer; - } - - // Straight conversion - if (size === totalBins) { - for (let i = startBin, k = 0; i < endBin; i += 1, k += 1) { - output[k] = this.getValue(fft[i]); - } - } - // Compress data - else if (size < totalBins) { - const step = totalBins / size; - - for (let i = startBin, k = 0; i < endBin; i += 1, k += 1) { - const start = ~~(i * step); - const end = ~~(start + step); - let max = 0; - - // Find max value within range - for (let j = start, n = ~~(step / 10) || 1; j < end; j += n) { - const val = fft[j]; - - if (val > max) { - max = val; - } else if (-val > max) { - max = -val; - } - } - - output[k] = this.getValue(max); - } - } - // Expand data - else if (size > totalBins) { - const step = size / totalBins; - - for (let i = startBin, j = 0; i < endBin; i += 1, j += 1) { - const val = this.getValue(fft[i]); - const start = ~~(j * step); - const end = start + step; - - for (let k = start; k < end; k += 1) { - output[k] = val; - } - } - } - - // Apply smoothing - if (smoothingTimeConstant > 0) { - for (let i = 0; i < size; i += 1) { - output[i] = buffer[i] * smoothingTimeConstant + output[i] * (1.0 - smoothingTimeConstant); - buffer[i] = output[i]; - } - } - - return output; - } -} diff --git a/src/audio/Player.js b/src/audio/Player.js deleted file mode 100644 index b684aeca..00000000 --- a/src/audio/Player.js +++ /dev/null @@ -1,157 +0,0 @@ -import EventEmitter from 'core/EventEmitter'; - -const UPDATE_INTERVAL = 200; - -export default class Player extends EventEmitter { - constructor(context) { - super(); - - this.audioContext = context; - this.nodes = []; - this.audio = null; - - this.volume = this.audioContext.createGain(); - this.volume.connect(this.audioContext.destination); - - this.loop = false; - } - - load(audio) { - this.unload(); - - this.audio = audio; - this.audio.addNode(this.volume); - - this.emit('audio-load'); - } - - unload() { - const { audio } = this; - - if (audio) { - this.stop(); - audio.unload(); - - this.emit('audio-unload'); - } - } - - play() { - const { audio } = this; - - if (audio) { - if (audio.playing) { - this.pause(); - } else { - audio.play(); - - this.timer = setInterval(() => { - if (!audio.repeat && audio.getPosition() >= 1.0) { - if (this.loop) { - this.seek(0); - } else { - this.stop(); - } - } - - this.emit('tick'); - }, UPDATE_INTERVAL); - - this.emit('play'); - this.emit('playback-change'); - } - } - } - - pause() { - const { audio } = this; - - if (audio) { - audio.pause(); - - clearInterval(this.timer); - - this.emit('pause'); - this.emit('playback-change'); - } - } - - stop() { - const { audio } = this; - - if (audio) { - audio.stop(); - clearInterval(this.timer); - this.emit('stop'); - this.emit('playback-change'); - } - } - - seek(val) { - const { audio } = this; - - if (audio) { - audio.seek(val); - this.emit('seek'); - } - } - - getAudio() { - return this.audio; - } - - hasAudio() { - return !!this.getAudio(); - } - - setVolume(val) { - if (this.volume) { - this.volume.gain.value = val; - } - } - - getVolume() { - return this.volume.gain.value; - } - - getCurrentTime() { - const { audio } = this; - - if (audio) { - return audio.getCurrentTime(); - } - return 0; - } - - getDuration() { - const { audio } = this; - - if (audio) { - return audio.getDuration(); - } - - return 0; - } - - getPosition() { - const { audio } = this; - - if (audio) { - return audio.getPosition(); - } - - return 0; - } - - setLoop(val) { - this.loop = val; - } - - isPlaying() { - return !!(this.audio && this.audio.playing); - } - - isLooping() { - return !!this.loop; - } -} diff --git a/src/audio/SpectrumAnalyzer.js b/src/audio/SpectrumAnalyzer.js deleted file mode 100644 index 1c9b0439..00000000 --- a/src/audio/SpectrumAnalyzer.js +++ /dev/null @@ -1,151 +0,0 @@ -import Entity from 'core/Entity'; -import fft from 'fourier-transform'; -import blackman from 'window-function/blackman'; -import { FFT_SIZE } from 'view/constants'; -import { mag2db, normalize } from 'utils/math'; -import { downmix } from 'utils/audio'; -import { updateExistingProps } from '../utils/object'; - -export default class SpectrumAnalyzer extends Entity { - static defaultProperties = { - fftSize: FFT_SIZE, - minDecibels: -100, - maxDecibels: 0, - smoothingTimeConstant: 0, - }; - - constructor(context, properties) { - super('SpectrumAnalyzer', { ...SpectrumAnalyzer.defaultProperties, ...properties }); - - this.audioContext = context; - - this.analyzer = Object.assign(context.createAnalyser(), this.properties); - - this.init(); - } - - update(properties) { - const changed = super.update(properties); - - const { fftSize } = properties; - - if (changed) { - updateExistingProps(this.analyzer, properties); - - if (fftSize !== undefined) { - this.init(); - } - } - - return changed; - } - - init() { - const { audioContext, analyzer: { fftSize } } = this; - - this.fft = new Uint8Array(fftSize / 2); - this.td = new Float32Array(fftSize); - - this.blackmanTable = new Float32Array(fftSize); - - for (let i = 0; i < fftSize; i++) { - this.blackmanTable[i] = blackman(i, fftSize); - } - - this.buffer = audioContext.createBuffer(1, fftSize, audioContext.sampleRate); - - this.smoothing = new Float32Array(fftSize / 2); - } - - get gain() { - const { fft } = this; - return fft.reduce((a, b) => a + b) / fft.length; - } - - getFloatTimeDomainData(array) { - array.set(this.buffer.getChannelData(0)); - } - - getFloatFrequencyData(array) { - const { fftSize, smoothingTimeConstant } = this.analyzer; - const waveform = new Float32Array(fftSize); - - // Get waveform from buffer - this.getFloatTimeDomainData(waveform); - - // Apply blackman function - for (let i = 0; i < fftSize; i++) { - waveform[i] = waveform[i] * this.blackmanTable[i] || 0; - } - - // Get FFT - const spectrum = fft(waveform); - - for (let i = 0, n = fftSize / 2; i < n; i++) { - let db = mag2db(spectrum[i]); - - if (smoothingTimeConstant) { - this.smoothing[i] = - spectrum[i] * smoothingTimeConstant * this.smoothing[i] + (1 - smoothingTimeConstant); - - db = mag2db(this.smoothing[i]); - } - - array[i] = Number.isFinite(db) ? db : -Infinity; - } - } - - getByteTimeDomainData(array) { - const { fftSize } = this.analyzer; - const waveform = new Float32Array(fftSize); - - this.getFloatTimeDomainData(waveform); - - for (let i = 0, n = waveform.length; i < n; i++) { - array[i] = Math.round(normalize(waveform[i], -1, 1) * 255); - } - } - - getByteFrequencyData(array) { - const { minDecibels, maxDecibels, frequencyBinCount } = this.analyzer; - const spectrum = new Float32Array(frequencyBinCount); - - this.getFloatFrequencyData(spectrum); - - for (let i = 0, n = spectrum.length; i < n; i++) { - array[i] = Math.round(normalize(spectrum[i], minDecibels, maxDecibels) * 255); - } - } - - process(input) { - if (input) { - const data = downmix(input); - this.buffer.copyToChannel(data, 0); - } - - this.updateTimeData(input); - this.updateFrequencyData(input); - } - - updateFrequencyData(input) { - if (input) { - this.getByteFrequencyData(this.fft); - } else { - this.analyzer.getByteFrequencyData(this.fft); - } - } - - updateTimeData(input) { - if (input) { - this.getFloatTimeDomainData(this.td); - } else { - this.analyzer.getFloatTimeDomainData(this.td); - } - } - - reset() { - this.fft.fill(0); - this.td.fill(0); - this.smoothing.fill(0); - } -} diff --git a/src/audio/WaveParser.js b/src/audio/WaveParser.js deleted file mode 100644 index 4b18a278..00000000 --- a/src/audio/WaveParser.js +++ /dev/null @@ -1,43 +0,0 @@ -import Entity from 'core/Entity'; -import { normalize } from 'utils/math'; - -export default class WaveParser extends Entity { - static defaultProperties = { - smoothingTimeConstant: 0, - }; - - constructor(properties) { - super('WaveParser', { ...WaveParser.defaultProperties, ...properties }); - - this.output = new Float32Array(); - this.buffer = new Float32Array(); - } - - parseTimeData(data, size) { - let { output, buffer } = this; - const { smoothingTimeConstant } = this.properties; - const step = data.length / size; - - // Resize data arrays - if (output === undefined || output.length !== size) { - output = new Float32Array(size); - buffer = new Float32Array(size); - this.output = output; - this.buffer = buffer; - } - - for (let i = 0, j = 0; i < size; i += 1, j += step) { - output[i] = normalize(data[~~j], -1, 1); - } - - // Apply smoothing - if (smoothingTimeConstant > 0) { - for (let i = 0; i < size; i += 1) { - output[i] = buffer[i] * smoothingTimeConstant + output[i] * (1.0 - smoothingTimeConstant); - buffer[i] = output[i]; - } - } - - return output; - } -} diff --git a/src/build/app/dev-app-update.yml b/src/build/app/dev-app-update.yml deleted file mode 100644 index bfb4c3d5..00000000 --- a/src/build/app/dev-app-update.yml +++ /dev/null @@ -1,3 +0,0 @@ -provider: generic -url: 'https://files.astrofox.io/download' -channel: latest diff --git a/src/build/loaders/glsl-loader.js b/src/build/loaders/glsl-loader.js deleted file mode 100644 index eca8b4ed..00000000 --- a/src/build/loaders/glsl-loader.js +++ /dev/null @@ -1,34 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const glslman = require('glsl-man'); - -const regex = /#include "(.*)"/g; - -function minify(code) { - return glslman.string(glslman.parse(code), { tab: '', space: '', newline: '' }); -} - -function parseInclude(match, context, imports) { - const [, file] = match.split('"'); - - const filePath = path.resolve(context, file); - - if (!imports[filePath]) { - imports[filePath] = fs.readFileSync(filePath, 'utf-8'); - - // eslint-disable-next-line no-use-before-define - return parseContent(imports[filePath], path.dirname(filePath), imports); - } - - return imports[filePath]; -} - -function parseContent(content, context, imports) { - return content.replace(regex, match => parseInclude(match, context, imports)); -} - -module.exports = function glslLoader(content) { - const source = parseContent(content, this.context, {}); - - return `module.exports = ${JSON.stringify(minify(source))}`; -}; diff --git a/src/canvas/CanvasAudio.js b/src/canvas/CanvasAudio.js deleted file mode 100644 index 9a686586..00000000 --- a/src/canvas/CanvasAudio.js +++ /dev/null @@ -1,57 +0,0 @@ -import Entity from 'core/Entity'; -import CanvasBars from 'canvas/CanvasBars'; - -export default class CanvasAudio extends Entity { - static defaultProperties = { - bars: 100, - }; - - constructor(properties, canvas) { - super('CanvasAudio', { ...CanvasAudio.defaultProperties, ...properties }); - - this.bars = new CanvasBars(properties, canvas); - this.results = new Float32Array(this.properties.bars); - } - - getCanvas() { - return this.bars.canvas; - } - - parseAudioBuffer(buffer) { - const { results } = this; - const size = buffer.length / results.length; - const step = ~~(size / 10) || 1; - - // Process each channel - for (let c = 0; c < buffer.numberOfChannels; c += 1) { - const data = buffer.getChannelData(c); - - // Process each bar - for (let i = 0; i < results.length; i += 1) { - const start = ~~(i * size); - const end = ~~(start + size); - let max = 0; - - // Find max value within range - for (let j = start; j < end; j += step) { - const val = data[j]; - if (val > max) { - max = val; - } else if (-val > max) { - max = -val; - } - } - - if (c === 0 || max > results[i]) { - results[i] = max; - } - } - } - - return results; - } - - render(data) { - this.bars.render(this.parseAudioBuffer(data)); - } -} diff --git a/src/canvas/CanvasBars.js b/src/canvas/CanvasBars.js deleted file mode 100644 index e4aa0d8c..00000000 --- a/src/canvas/CanvasBars.js +++ /dev/null @@ -1,83 +0,0 @@ -import Entity from 'core/Entity'; -import { resetCanvas, setColor } from 'utils/canvas'; -import { clamp } from 'utils/math'; - -export default class CanvasBars extends Entity { - static defaultProperties = { - width: 300, - height: 100, - minHeight: 0, - barWidth: -1, - barSpacing: -1, - shadowHeight: 100, - color: '#FFFFFF', - shadowColor: '#CCCCCC', - }; - - constructor(properties, canvas) { - super('CanvasBars', { ...CanvasBars.defaultProperties, ...properties }); - - this.canvas = canvas; - this.context = this.canvas.getContext('2d'); - } - - render(data) { - const bars = data.length; - const { canvas, context } = this; - const { height, width, color, shadowHeight, shadowColor, minHeight } = this.properties; - let { barWidth, barSpacing } = this.properties; - - // Reset canvas - resetCanvas(canvas, width, height + shadowHeight); - - // Calculate bar widths - if (barWidth < 0 && barSpacing < 0) { - barSpacing = width / bars / 2; - barWidth = barSpacing; - } else if (barSpacing >= 0 && barWidth < 0) { - barWidth = (width - bars * barSpacing) / bars; - if (barWidth <= 0) barWidth = 1; - } else if (barWidth > 0 && barSpacing < 0) { - barSpacing = (width - bars * barWidth) / bars; - if (barSpacing <= 0) barSpacing = 1; - } - - // Calculate bars to display - const barSize = barWidth + barSpacing; - const fullWidth = barSize * bars; - - // Stepping - const step = fullWidth > width ? fullWidth / width : 1; - - // Canvas setup - setColor(context, color, 0, 0, 0, height); - - // Draw bars - for (let i = 0, x = 0, last = null; i < bars && x < fullWidth; i += step, x += barSize) { - const index = ~~i; - - if (index !== last) { - const val = clamp(data[index] * height, minHeight, height); - last = index; - - context.fillRect(x, height, barWidth, -val); - } - } - - // Draw shadow bars - if (shadowHeight > 0) { - setColor(context, shadowColor, 0, height, 0, height + shadowHeight); - - for (let i = 0, x = 0, last = null; i < bars && x < fullWidth; i += step, x += barSize) { - const index = ~~i; - - if (index !== last) { - const val = data[index] * shadowHeight; - last = index; - - context.fillRect(x, height, barWidth, val); - } - } - } - } -} diff --git a/src/canvas/CanvasImage.js b/src/canvas/CanvasImage.js deleted file mode 100644 index 423014e1..00000000 --- a/src/canvas/CanvasImage.js +++ /dev/null @@ -1,98 +0,0 @@ -import Entity from 'core/Entity'; -import { resetCanvas } from 'utils/canvas'; - -const MIN_RESIZE_WIDTH = 100; - -export default class CanvasImage extends Entity { - static defaultProperties = { - src: '', - width: 1, - height: 1, - }; - - constructor(properties, canvas) { - super('CanvasImage', { ...CanvasImage.defaultProperties, ...properties }); - - const { src } = this.properties; - - this.canvas = canvas; - this.context = this.canvas.getContext('2d'); - - this.image = new Image(); - this.image.onload = () => { - this.generateMipMaps(); - this.render(); - }; - this.image.src = src; - } - - getResizeSteps(sourceWidth, targetWidth) { - return Math.ceil(Math.log(sourceWidth / targetWidth) / Math.log(2)); - } - - generateMipMaps() { - const { image } = this; - const steps = this.getResizeSteps(image.naturalWidth, MIN_RESIZE_WIDTH); - const mipmaps = []; - let src = image; - let width = image.naturalWidth / 2; - let height = image.naturalHeight / 2; - - for (let i = 0; i < steps; i += 1) { - const canvas = new OffscreenCanvas(width, height); - - canvas.getContext('2d').drawImage(src, 0, 0, width, height); - - mipmaps.push(canvas); - - src = mipmaps[i]; - width /= 2; - height /= 2; - } - - this.mipmaps = mipmaps; - } - - update(properties) { - const changed = super.update(properties); - - if (changed) { - if (this.image.src !== this.properties.src) { - this.image.src = this.properties.src; - } - } - - return changed; - } - - render() { - const { - canvas, - context, - image, - properties: { width, height }, - } = this; - - if (!image.src) return; - - // Reset canvas - resetCanvas(canvas, width, height); - - // Resize smaller - if (width < image.naturalWidth || height < image.naturalHeight) { - let src = image; - - this.mipmaps.forEach(map => { - if (width < map.width) { - src = map; - } - }); - - context.drawImage(src, 0, 0, width, height); - } - // Draw normally - else { - context.drawImage(image, 0, 0, width, height); - } - } -} diff --git a/src/canvas/CanvasMeter.js b/src/canvas/CanvasMeter.js deleted file mode 100644 index a1b2933e..00000000 --- a/src/canvas/CanvasMeter.js +++ /dev/null @@ -1,45 +0,0 @@ -import Entity from 'core/Entity'; -import { resetCanvas, setColor } from 'utils/canvas'; - -export default class CanvasMeter extends Entity { - static defaultProperties = { - width: 100, - height: 50, - color: '#FFFFFF', - origin: 'left', - }; - - constructor(properties, canvas) { - super('CanvasMeter', { ...CanvasMeter.defaultProperties, ...properties }); - - this.canvas = canvas; - this.context = this.canvas.getContext('2d'); - } - - render(value) { - const { canvas, context } = this; - - const { height, width, color, origin } = this.properties; - - // Reset canvas - resetCanvas(canvas, width, height); - - // Canvas setup - setColor(context, color, 0, 0, 0, height); - - switch (origin) { - case 'left': - context.fillRect(0, 0, ~~(value * width), height); - break; - case 'bottom': - context.fillRect(0, height, width, ~~(-value * height)); - break; - case 'right': - context.fillRect(width, 0, ~~(-value * width), height); - break; - case 'top': - context.fillRect(0, 0, width, ~~(-value * height)); - break; - } - } -} diff --git a/src/canvas/CanvasShape.js b/src/canvas/CanvasShape.js deleted file mode 100644 index 4317ed26..00000000 --- a/src/canvas/CanvasShape.js +++ /dev/null @@ -1,104 +0,0 @@ -import Entity from 'core/Entity'; -import { resetCanvas } from 'utils/canvas'; -import { deg2rad } from 'utils/math'; - -const TRIANGLE_ANGLE = (2 * Math.PI) / 3; -const HEXAGON_ANGLE = (2 * Math.PI) / 6; - -export default class CanvasShape extends Entity { - static defaultProperties = { - shape: 'Circle', - width: 100, - height: 100, - fill: true, - color: '#FFFFFF', - stroke: false, - strokeColor: '#FFFFFF', - strokeWidth: 0, - }; - - constructor(properties, canvas) { - super('CanvasShape', { ...CanvasShape.defaultProperties, ...properties }); - - const { width, height, strokeWidth } = this.properties; - - this.canvas = canvas; - this.canvas.width = width + strokeWidth; - this.canvas.height = height + strokeWidth; - - this.context = this.canvas.getContext('2d'); - } - - render() { - const { canvas, context } = this; - const { shape, width, height, fill, color, stroke, strokeColor, strokeWidth } = this.properties; - const w = width + strokeWidth * 2; - const h = height + strokeWidth * 2; - const x = w / 2; - const y = h / 2; - const r = w > 0 ? w / 2 : 1; - - // Reset canvas - resetCanvas(canvas, w, h); - - // Draw - context.fillStyle = color; - context.strokeStyle = strokeColor; - context.lineWidth = strokeWidth; - - if (shape === 'Circle') { - context.beginPath(); - context.arc(x, y, r, 0, 2 * Math.PI); - } else if (shape === 'Triangle') { - const points = []; - - for (let i = 0; i < 3; i++) { - points.push({ - x: x + r * Math.cos(i * TRIANGLE_ANGLE - deg2rad(210)), - y: y + r * Math.sin(i * TRIANGLE_ANGLE - deg2rad(210)), - }); - } - - context.beginPath(); - context.moveTo(points[0].x, points[0].y); - for (let i = 1; i < points.length; i++) { - context.lineTo(points[i].x, points[i].y); - } - context.closePath(); - } else if (shape === 'Hexagon') { - const hexPoints = []; - - for (let i = 0; i < 6; i++) { - hexPoints.push({ - x: x + r * Math.cos(i * HEXAGON_ANGLE), - y: y + r * Math.sin(i * HEXAGON_ANGLE), - }); - } - - context.beginPath(); - context.moveTo(hexPoints[0].x, hexPoints[0].y); - for (let i = 1; i < hexPoints.length; i++) { - context.lineTo(hexPoints[i].x, hexPoints[i].y); - } - context.closePath(); - } else { - context.beginPath(); - context.moveTo(0, 0); - context.lineTo(w, 0); - context.lineTo(w, h); - context.lineTo(0, h); - context.closePath(); - } - - if (fill) { - context.fill(); - } - - if (stroke && strokeWidth > 0) { - context.save(); - context.clip(); - context.stroke(); - context.restore(); - } - } -} diff --git a/src/canvas/CanvasText.js b/src/canvas/CanvasText.js deleted file mode 100644 index 10c17256..00000000 --- a/src/canvas/CanvasText.js +++ /dev/null @@ -1,58 +0,0 @@ -import Entity from 'core/Entity'; -import { resetCanvas } from 'utils/canvas'; - -export default class CanvasText extends Entity { - static defaultProperties = { - text: '', - size: 40, - font: 'Roboto', - italic: false, - bold: false, - color: '#FFFFFF', - }; - - constructor(properties, canvas) { - super('CanvasText', { ...CanvasText.defaultProperties, ...properties }); - - this.canvas = canvas; - this.context = this.canvas.getContext('2d'); - } - - getFont() { - const { italic, bold, size, font } = this.properties; - - return [italic ? 'italic' : 'normal', bold ? 'bold' : 'normal', `${size}px`, font].join(' '); - } - - render() { - const { canvas, context } = this; - const { text, size, color } = this.properties; - const font = this.getFont(); - - context.font = font; - - const length = Math.ceil(context.measureText(text).width); - const spacing = text.length ? Math.ceil(length / text.length) : 0; - const width = length + spacing; - const height = size * 2; - - // Reset canvas - resetCanvas(canvas, width, height); - - // Draw text - context.font = font; - context.fillStyle = color; - context.textAlign = 'center'; - context.textBaseline = 'middle'; - context.fillText(text, width / 2, height / 2); - - // Debugging - /* - context.beginPath(); - context.rect(0, 0, canvas.width, canvas.height); - context.lineWidth = 2; - context.strokeStyle = 'red'; - context.stroke(); - */ - } -} diff --git a/src/canvas/CanvasWave.js b/src/canvas/CanvasWave.js deleted file mode 100644 index 99f1b2f5..00000000 --- a/src/canvas/CanvasWave.js +++ /dev/null @@ -1,97 +0,0 @@ -import Entity from 'core/Entity'; -import { drawPath } from 'drawing/bezierSpline'; -import { resetCanvas, setColor } from 'utils/canvas'; - -export default class CanvasWave extends Entity { - static defaultProperties = { - stroke: true, - strokeColor: '#FFFFFF', - fill: false, - fillColor: '#FFFFFF', - taper: false, - width: 400, - height: 200, - midpoint: 100, - lineWidth: 1.0, - }; - - constructor(properties, canvas) { - super('CanvasWave', { ...CanvasWave.defaultProperties, ...properties }); - - this.canvas = canvas; - this.context = this.canvas.getContext('2d'); - } - - render(points, smooth) { - const { canvas, context } = this; - const { - width, - height, - midpoint, - stroke, - strokeColor, - fill, - fillColor, - lineWidth, - taper, - } = this.properties; - - // Reset canvas - resetCanvas(canvas, width, height); - - // Canvas setup - context.lineWidth = lineWidth; - context.strokeStyle = strokeColor; - setColor(context, fillColor, 0, 0, 0, height); - - // Normalize points - for (let i = 0; i < points.length; i += 2) { - points[i + 1] = height - points[i + 1] * height; - } - - // Taper edges - if (taper) { - points[1] = midpoint; - points[points.length - 1] = midpoint; - } - - // Draw wave - if (smooth) { - context.beginPath(); - - // Draw bezier spline - drawPath(context, points); - - if (stroke) { - context.stroke(); - } - - if (fill) { - context.lineTo(width, midpoint); - context.lineTo(0, midpoint); - context.closePath(); - context.fill(); - } - } else { - context.beginPath(); - - if (fill) { - context.moveTo(0, midpoint); - } - - for (let i = 0; i < points.length; i += 2) { - context.lineTo(points[i], points[i + 1]); - } - - if (stroke) { - context.stroke(); - } - - if (fill) { - context.lineTo(width, midpoint); - context.closePath(); - context.fill(); - } - } - } -} diff --git a/src/config/app.json b/src/config/app.json deleted file mode 100644 index 8e5e001b..00000000 --- a/src/config/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "checkForUpdates": true, - "autoUpdate": true, - "autoPlayAudio": true -} diff --git a/src/config/colorPalettes.json b/src/config/colorPalettes.json deleted file mode 100644 index e75afe38..00000000 --- a/src/config/colorPalettes.json +++ /dev/null @@ -1,202 +0,0 @@ -[ - ["#69D2E7", "#A7DBD8", "#E0E4CC", "#F38630", "#FA6900"], - ["#FE4365", "#FC9D9A", "#F9CDAD", "#C8C8A9", "#83AF9B"], - ["#ECD078", "#D95B43", "#C02942", "#542437", "#53777A"], - ["#556270", "#4ECDC4", "#C7F464", "#FF6B6B", "#C44D58"], - ["#774F38", "#E08E79", "#F1D4AF", "#ECE5CE", "#C5E0DC"], - ["#E8DDCB", "#CDB380", "#036564", "#033649", "#031634"], - ["#490A3D", "#BD1550", "#E97F02", "#F8CA00", "#8A9B0F"], - ["#594F4F", "#547980", "#45ADA8", "#9DE0AD", "#E5FCC2"], - ["#00A0B0", "#6A4A3C", "#CC333F", "#EB6841", "#EDC951"], - ["#E94E77", "#D68189", "#C6A49A", "#C6E5D9", "#F4EAD5"], - ["#D9CEB2", "#948C75", "#D5DED9", "#7A6A53", "#99B2B7"], - ["#FFFFFF", "#CBE86B", "#F2E9E1", "#1C140D", "#CBE86B"], - ["#EFFFCD", "#DCE9BE", "#555152", "#2E2633", "#99173C"], - ["#3FB8AF", "#7FC7AF", "#DAD8A7", "#FF9E9D", "#FF3D7F"], - ["#343838", "#005F6B", "#008C9E", "#00B4CC", "#00DFFC"], - ["#413E4A", "#73626E", "#B38184", "#F0B49E", "#F7E4BE"], - ["#99B898", "#FECEA8", "#FF847C", "#E84A5F", "#2A363B"], - ["#FF4E50", "#FC913A", "#F9D423", "#EDE574", "#E1F5C4"], - ["#554236", "#F77825", "#D3CE3D", "#F1EFA5", "#60B99A"], - ["#351330", "#424254", "#64908A", "#E8CAA4", "#CC2A41"], - ["#00A8C6", "#40C0CB", "#F9F2E7", "#AEE239", "#8FBE00"], - ["#FF4242", "#F4FAD2", "#D4EE5E", "#E1EDB9", "#F0F2EB"], - ["#655643", "#80BCA3", "#F6F7BD", "#E6AC27", "#BF4D28"], - ["#8C2318", "#5E8C6A", "#88A65E", "#BFB35A", "#F2C45A"], - ["#FAD089", "#FF9C5B", "#F5634A", "#ED303C", "#3B8183"], - ["#BCBDAC", "#CFBE27", "#F27435", "#F02475", "#3B2D38"], - ["#D1E751", "#FFFFFF", "#000000", "#4DBCE9", "#26ADE4"], - ["#FF9900", "#424242", "#E9E9E9", "#BCBCBC", "#3299BB"], - ["#5D4157", "#838689", "#A8CABA", "#CAD7B2", "#EBE3AA"], - ["#5E412F", "#FCEBB6", "#78C0A8", "#F07818", "#F0A830"], - ["#EEE6AB", "#C5BC8E", "#696758", "#45484B", "#36393B"], - ["#1B676B", "#519548", "#88C425", "#BEF202", "#EAFDE6"], - ["#F8B195", "#F67280", "#C06C84", "#6C5B7B", "#355C7D"], - ["#452632", "#91204D", "#E4844A", "#E8BF56", "#E2F7CE"], - ["#F04155", "#FF823A", "#F2F26F", "#FFF7BD", "#95CFB7"], - ["#F0D8A8", "#3D1C00", "#86B8B1", "#F2D694", "#FA2A00"], - ["#2A044A", "#0B2E59", "#0D6759", "#7AB317", "#A0C55F"], - ["#67917A", "#170409", "#B8AF03", "#CCBF82", "#E33258"], - ["#B9D7D9", "#668284", "#2A2829", "#493736", "#7B3B3B"], - ["#BBBB88", "#CCC68D", "#EEDD99", "#EEC290", "#EEAA88"], - ["#A3A948", "#EDB92E", "#F85931", "#CE1836", "#009989"], - ["#E8D5B7", "#0E2430", "#FC3A51", "#F5B349", "#E8D5B9"], - ["#B3CC57", "#ECF081", "#FFBE40", "#EF746F", "#AB3E5B"], - ["#AB526B", "#BCA297", "#C5CEAE", "#F0E2A4", "#F4EBC3"], - ["#607848", "#789048", "#C0D860", "#F0F0D8", "#604848"], - ["#515151", "#FFFFFF", "#00B4FF", "#EEEEEE"], - ["#3E4147", "#FFFEDF", "#DFBA69", "#5A2E2E", "#2A2C31"], - ["#300030", "#480048", "#601848", "#C04848", "#F07241"], - ["#1C2130", "#028F76", "#B3E099", "#FFEAAD", "#D14334"], - ["#A8E6CE", "#DCEDC2", "#FFD3B5", "#FFAAA6", "#FF8C94"], - ["#EDEBE6", "#D6E1C7", "#94C7B6", "#403B33", "#D3643B"], - ["#FDF1CC", "#C6D6B8", "#987F69", "#E3AD40", "#FCD036"], - ["#AAB3AB", "#C4CBB7", "#EBEFC9", "#EEE0B7", "#E8CAAF"], - ["#CC0C39", "#E6781E", "#C8CF02", "#F8FCC1", "#1693A7"], - ["#3A111C", "#574951", "#83988E", "#BCDEA5", "#E6F9BC"], - ["#FC354C", "#29221F", "#13747D", "#0ABFBC", "#FCF7C5"], - ["#B9D3B0", "#81BDA4", "#B28774", "#F88F79", "#F6AA93"], - ["#5E3929", "#CD8C52", "#B7D1A3", "#DEE8BE", "#FCF7D3"], - ["#230F2B", "#F21D41", "#EBEBBC", "#BCE3C5", "#82B3AE"], - ["#5C323E", "#A82743", "#E15E32", "#C0D23E", "#E5F04C"], - ["#4E395D", "#827085", "#8EBE94", "#CCFC8E", "#DC5B3E"], - ["#DAD6CA", "#1BB0CE", "#4F8699", "#6A5E72", "#563444"], - ["#C2412D", "#D1AA34", "#A7A844", "#A46583", "#5A1E4A"], - ["#D1313D", "#E5625C", "#F9BF76", "#8EB2C5", "#615375"], - ["#9D7E79", "#CCAC95", "#9A947C", "#748B83", "#5B756C"], - ["#1C0113", "#6B0103", "#A30006", "#C21A01", "#F03C02"], - ["#8DCCAD", "#988864", "#FEA6A2", "#F9D6AC", "#FFE9AF"], - ["#CFFFDD", "#B4DEC1", "#5C5863", "#A85163", "#FF1F4C"], - ["#75616B", "#BFCFF7", "#DCE4F7", "#F8F3BF", "#D34017"], - ["#382F32", "#FFEAF2", "#FCD9E5", "#FBC5D8", "#F1396D"], - ["#B6D8C0", "#C8D9BF", "#DADABD", "#ECDBBC", "#FEDCBA"], - ["#E3DFBA", "#C8D6BF", "#93CCC6", "#6CBDB5", "#1A1F1E"], - ["#A7C5BD", "#E5DDCB", "#EB7B59", "#CF4647", "#524656"], - ["#9DC9AC", "#FFFEC7", "#F56218", "#FF9D2E", "#919167"], - ["#413D3D", "#040004", "#C8FF00", "#FA023C", "#4B000F"], - ["#EDF6EE", "#D1C089", "#B3204D", "#412E28", "#151101"], - ["#A8A7A7", "#CC527A", "#E8175D", "#474747", "#363636"], - ["#7E5686", "#A5AAD9", "#E8F9A2", "#F8A13F", "#BA3C3D"], - ["#FFEDBF", "#F7803C", "#F54828", "#2E0D23", "#F8E4C1"], - ["#C1B398", "#605951", "#FBEEC2", "#61A6AB", "#ACCEC0"], - ["#5E9FA3", "#DCD1B4", "#FAB87F", "#F87E7B", "#B05574"], - ["#951F2B", "#F5F4D7", "#E0DFB1", "#A5A36C", "#535233"], - ["#FFFBB7", "#A6F6AF", "#66B6AB", "#5B7C8D", "#4F2958"], - ["#000000", "#9F111B", "#B11623", "#292C37", "#CCCCCC"], - ["#9CDDC8", "#BFD8AD", "#DDD9AB", "#F7AF63", "#633D2E"], - ["#EFF3CD", "#B2D5BA", "#61ADA0", "#248F8D", "#605063"], - ["#84B295", "#ECCF8D", "#BB8138", "#AC2005", "#2C1507"], - ["#FCFEF5", "#E9FFE1", "#CDCFB7", "#D6E6C3", "#FAFBE3"], - ["#0CA5B0", "#4E3F30", "#FEFEEB", "#F8F4E4", "#A5B3AA"], - ["#4D3B3B", "#DE6262", "#FFB88C", "#FFD0B3", "#F5E0D3"], - ["#B5AC01", "#ECBA09", "#E86E1C", "#D41E45", "#1B1521"], - ["#379F7A", "#78AE62", "#BBB749", "#E0FBAC", "#1F1C0D"], - ["#FFE181", "#EEE9E5", "#FAD3B2", "#FFBA7F", "#FF9C97"], - ["#4E4D4A", "#353432", "#94BA65", "#2790B0", "#2B4E72"], - ["#A70267", "#F10C49", "#FB6B41", "#F6D86B", "#339194"], - ["#30261C", "#403831", "#36544F", "#1F5F61", "#0B8185"], - ["#2D2D29", "#215A6D", "#3CA2A2", "#92C7A3", "#DFECE6"], - ["#F38A8A", "#55443D", "#A0CAB5", "#CDE9CA", "#F1EDD0"], - ["#793A57", "#4D3339", "#8C873E", "#D1C5A5", "#A38A5F"], - ["#11766D", "#410936", "#A40B54", "#E46F0A", "#F0B300"], - ["#AAFF00", "#FFAA00", "#FF00AA", "#AA00FF", "#00AAFF"], - ["#C75233", "#C78933", "#D6CEAA", "#79B5AC", "#5E2F46"], - ["#F8EDD1", "#D88A8A", "#474843", "#9D9D93", "#C5CFC6"], - ["#6DA67A", "#77B885", "#86C28B", "#859987", "#4A4857"], - ["#1B325F", "#9CC4E4", "#E9F2F9", "#3A89C9", "#F26C4F"], - ["#BED6C7", "#ADC0B4", "#8A7E66", "#A79B83", "#BBB2A1"], - ["#046D8B", "#309292", "#2FB8AC", "#93A42A", "#ECBE13"], - ["#82837E", "#94B053", "#BDEB07", "#BFFA37", "#E0E0E0"], - ["#312736", "#D4838F", "#D6ABB1", "#D9D9D9", "#C4FFEB"], - ["#E5EAA4", "#A8C4A2", "#69A5A4", "#616382", "#66245B"], - ["#6DA67A", "#99A66D", "#A9BD68", "#B5CC6A", "#C0DE5D"], - ["#395A4F", "#432330", "#853C43", "#F25C5E", "#FFA566"], - ["#331327", "#991766", "#D90F5A", "#F34739", "#FF6E27"], - ["#FDFFD9", "#FFF0B8", "#FFD6A3", "#FAAD8E", "#142F30"], - ["#E21B5A", "#9E0C39", "#333333", "#FBFFE3", "#83A300"], - ["#FBC599", "#CDBB93", "#9EAE8A", "#335650", "#F35F55"], - ["#C7FCD7", "#D9D5A7", "#D9AB91", "#E6867A", "#ED4A6A"], - ["#EC4401", "#CC9B25", "#13CD4A", "#7B6ED6", "#5E525C"], - ["#BF496A", "#B39C82", "#B8C99D", "#F0D399", "#595151"], - ["#FFEFD3", "#FFFEE4", "#D0ECEA", "#9FD6D2", "#8B7A5E"], - ["#F1396D", "#FD6081", "#F3FFEB", "#ACC95F", "#8F9924"], - ["#F6F6F6", "#E8E8E8", "#333333", "#990100", "#B90504"], - ["#261C21", "#6E1E62", "#B0254F", "#DE4126", "#EB9605"], - ["#E9E0D1", "#91A398", "#33605A", "#070001", "#68462B"], - ["#F2E3C6", "#FFC6A5", "#E6324B", "#2B2B2B", "#353634"], - ["#FFAB07", "#E9D558", "#72AD75", "#0E8D94", "#434D53"], - ["#59B390", "#F0DDAA", "#E47C5D", "#E32D40", "#152B3C"], - ["#FDE6BD", "#A1C5AB", "#F4DD51", "#D11E48", "#632F53"], - ["#E4E4C5", "#B9D48B", "#8D2036", "#CE0A31", "#D3E4C5"], - ["#512B52", "#635274", "#7BB0A8", "#A7DBAB", "#E4F5B1"], - ["#805841", "#DCF7F3", "#FFFCDD", "#FFD8D8", "#F5A2A2"], - ["#E65540", "#F8ECC2", "#65A8A6", "#79896D"], - ["#CAFF42", "#EBF7F8", "#D0E0EB", "#88ABC2", "#49708A"], - ["#595643", "#4E6B66", "#ED834E", "#EBCC6E", "#EBE1C5"], - ["#E4DED0", "#ABCCBD", "#7DBEB8", "#181619", "#E32F21"], - ["#058789", "#503D2E", "#D54B1A", "#E3A72F", "#F0ECC9"], - ["#FF003C", "#FF8A00", "#FABE28", "#88C100", "#00C176"], - ["#311D39", "#67434F", "#9B8E7E", "#C3CCAF", "#A51A41"], - ["#EFD9B4", "#D6A692", "#A39081", "#4D6160", "#292522"], - ["#C6CCA5", "#8AB8A8", "#6B9997", "#54787D", "#615145"], - ["#CC5D4C", "#FFFEC6", "#C7D1AF", "#96B49C", "#5B5847"], - ["#111625", "#341931", "#571B3C", "#7A1E48", "#9D2053"], - ["#EFEECC", "#FE8B05", "#FE0557", "#400403", "#0AABBA"], - ["#CCF390", "#E0E05A", "#F7C41F", "#FC930A", "#FF003D"], - ["#73C8A9", "#DEE1B6", "#E1B866", "#BD5532", "#373B44"], - ["#79254A", "#795C64", "#79927D", "#AEB18E", "#E3CF9E"], - ["#E0EFF1", "#7DB4B5", "#FFFFFF", "#680148", "#000000"], - ["#F06D61", "#DA825F", "#C4975C", "#A8AB7B", "#8CBF99"], - ["#2D1B33", "#F36A71", "#EE887A", "#E4E391", "#9ABC8A"], - ["#2B2726", "#0A516D", "#018790", "#7DAD93", "#BACCA4"], - ["#95A131", "#C8CD3B", "#F6F1DE", "#F5B9AE", "#EE0B5B"], - ["#360745", "#D61C59", "#E7D84B", "#EFEAC5", "#1B8798"], - ["#E3E8CD", "#BCD8BF", "#D3B9A3", "#EE9C92", "#FE857E"], - ["#807462", "#A69785", "#B8FAFF", "#E8FDFF", "#665C49"], - ["#4B1139", "#3B4058", "#2A6E78", "#7A907C", "#C9B180"], - ["#FC284F", "#FF824A", "#FEA887", "#F6E7F7", "#D1D0D7"], - ["#FFB884", "#F5DF98", "#FFF8D4", "#C0D1C2", "#2E4347"], - ["#027B7F", "#FFA588", "#D62957", "#BF1E62", "#572E4F"], - ["#80A8A8", "#909D9E", "#A88C8C", "#FF0D51", "#7A8C89"], - ["#A69E80", "#E0BA9B", "#E7A97E", "#D28574", "#3B1922"], - ["#A1DBB2", "#FEE5AD", "#FACA66", "#F7A541", "#F45D4C"], - ["#641F5E", "#676077", "#65AC92", "#C2C092", "#EDD48E"], - ["#FFF3DB", "#E7E4D5", "#D3C8B4", "#C84648", "#703E3B"], - ["#F5DD9D", "#BCC499", "#92A68A", "#7B8F8A", "#506266"], - ["#2B222C", "#5E4352", "#965D62", "#C7956D", "#F2D974"], - ["#D4F7DC", "#DBE7B4", "#DBC092", "#E0846D", "#F51441"], - ["#A32C28", "#1C090B", "#384030", "#7B8055", "#BCA875"], - ["#85847E", "#AB6A6E", "#F7345B", "#353130", "#CBCFB4"], - ["#E6B39A", "#E6CBA5", "#EDE3B4", "#8B9E9B", "#6D7578"], - ["#11644D", "#A0B046", "#F2C94E", "#F78145", "#F24E4E"], - ["#6D9788", "#1E2528", "#7E1C13", "#BF0A0D", "#E6E1C2"], - ["#23192D", "#FD0A54", "#F57576", "#FEBF97", "#F5ECB7"], - ["#EB9C4D", "#F2D680", "#F3FFCF", "#BAC9A9", "#697060"], - ["#D3D5B0", "#B5CEA4", "#9DC19D", "#8C7C62", "#71443F"], - ["#452E3C", "#FF3D5A", "#FFB969", "#EAF27E", "#3B8C88"], - ["#041122", "#259073", "#7FDA89", "#C8E98E", "#E6F99D"], - ["#B1E6D1", "#77B1A9", "#3D7B80", "#270A33", "#451A3E"], - ["#9D9E94", "#C99E93", "#F59D92", "#E5B8AD", "#D5D2C8"], - ["#FDCFBF", "#FEB89F", "#E23D75", "#5F0D3B", "#742365"], - ["#540045", "#C60052", "#FF714B", "#EAFF87", "#ACFFE9"], - ["#B7CBBF", "#8C886F", "#F9A799", "#F4BFAD", "#F5DABD"], - ["#280904", "#680E34", "#9A151A", "#C21B12", "#FC4B2A"], - ["#F0FFC9", "#A9DA88", "#62997A", "#72243D", "#3B0819"], - ["#429398", "#6B5D4D", "#B0A18F", "#DFCDB4", "#FBEED3"], - ["#E6EBA9", "#ABBB9F", "#6F8B94", "#706482", "#703D6F"], - ["#A3C68C", "#879676", "#6E6662", "#4F364A", "#340735"], - ["#44749D", "#C6D4E1", "#FFFFFF", "#EBE7E0", "#BDB8AD"], - ["#322938", "#89A194", "#CFC89A", "#CC883A", "#A14016"], - ["#CFB590", "#9E9A41", "#758918", "#564334", "#49281F"], - ["#FA6A64", "#7A4E48", "#4A4031", "#F6E2BB", "#9EC6B8"], - ["#1D1313", "#24B694", "#D22042", "#A3B808", "#30C4C9"], - ["#F6D76B", "#FF9036", "#D6254D", "#FF5475", "#FDEBA9"], - ["#E7EDEA", "#FFC52C", "#FB0C06", "#030D4F", "#CEECEF"], - ["#373737", "#8DB986", "#ACCE91", "#BADB73", "#EFEAE4"], - ["#161616", "#C94D65", "#E7C049", "#92B35A", "#1F6764"], - ["#26251C", "#EB0A44", "#F2643D", "#F2A73D", "#A0E8B7"], - ["#4B3E4D", "#1E8C93", "#DBD8A2", "#C4AC30", "#D74F33"], - ["#8D7966", "#A8A39D", "#D8C8B8", "#E2DDD9", "#F8F1E9"], - ["#F2E8C4", "#98D9B6", "#3EC9A7", "#2B879E", "#616668"], - ["#5CACC4", "#8CD19D", "#CEE879", "#FCB653", "#FF5254"] -] diff --git a/src/config/fonts.json b/src/config/fonts.json deleted file mode 100644 index 23bb542e..00000000 --- a/src/config/fonts.json +++ /dev/null @@ -1,19 +0,0 @@ -[ - "Abel", - "Abril Fatface", - "Bangers", - "Cardo", - "Caveat", - "Chunkfive", - "Dynalight", - "Intro", - "Merriweather", - "Playfair Display", - "Permanent Marker", - "Oswald", - "Oxygen", - "Racing Sans One", - "Raleway", - "Roboto", - "Vast Shadow" -] diff --git a/src/config/menu.json b/src/config/menu.json deleted file mode 100644 index 8770749b..00000000 --- a/src/config/menu.json +++ /dev/null @@ -1,125 +0,0 @@ -[ - { - "label": "File", - "submenu": [ - { - "label": "New project", - "action": "new-project" - }, - { - "label": "Open project...", - "action": "open-project" - }, - { - "label": "Save project", - "action": "save-project" - }, - { - "label": "Save project as...", - "action": "save-project-as" - }, - { - "type": "separator" - }, - { - "label": "Load audio...", - "action": "load-audio" - }, - { - "label": "Save image...", - "action": "save-image" - }, - { - "label": "Save video...", - "action": "save-video" - }, - { - "type": "separator" - }, - { - "label": "Exit", - "role": "quit", - "action": "exit" - } - ] - }, - { - "label": "Edit", - "submenu": [ - { - "label": "Canvas", - "action": "edit-canvas" - }, - { - "label": "Settings", - "action": "edit-settings" - } - ] - }, - { - "label": "View", - "submenu": [ - { - "label": "Zoom in", - "action": "zoom-in" - }, - { - "label": "Zoom out", - "action": "zoom-out" - }, - { - "label": "Actual size", - "action": "zoom-reset" - }, - { - "label": "Fit to screen", - "action": "zoom-fit" - }, - { - "type": "separator" - }, - { - "label": "Control dock", - "type": "checkbox", - "checked": true, - "action": "view-control-dock" - }, - { - "label": "Player", - "type": "checkbox", - "checked": true, - "action": "view-player" - } - ] - }, - { - "label": "Developer", - "hidden": true, - "submenu": [ - { - "label": "Reload", - "role": "reload", - "accelerator": "CmdOrCtrl+R" - } - ] - }, - { - "label": "Help", - "submenu": [ - { - "label": "Check for updates...", - "action": "check-for-updates" - }, - { - "label": "Developer tools", - "action": "open-dev-tools", - "role": "toggledevtools", - "accelerator": "CmdOrCtrl+Shift+I" - }, - { - "label": "About", - "action": "about" - } - ] - } -] diff --git a/src/config/video.json b/src/config/video.json deleted file mode 100644 index 2a776550..00000000 --- a/src/config/video.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "codecs": { - "x264": { - "label": "x264", - "video": { - "encoder": "libx264", - "extension": "mp4", - "settings": { - "input": [], - "output": ["-profile:v", "high", "-tune", "animation", "-movflags", "+faststart"], - "low": ["-preset", "veryfast", "-crf", 23], - "medium": ["-preset", "medium", "-crf", 20], - "high": ["-preset", "slow", "-crf", 18] - } - }, - "audio": { - "encoder": "aac", - "extension": "aac", - "settings": ["-b:a", "192k"] - } - }, - "webm": { - "label": "WebM", - "video": { - "encoder": "libvpx", - "extension": "webm", - "settings": { - "input": [], - "output": ["-quality", "good", "-cpu-used", 0, "-qmin", 0, "-qmax", 50, "-b:v", "20M"], - "low": ["-crf", 10], - "medium": ["-crf", 5], - "high": ["-crf", 4] - } - }, - "audio": { - "encoder": "libvorbis", - "extension": "ogg", - "settings": ["-qscale:a", 6] - } - }, - "nvenc": { - "label": "NVEnc", - "video": { - "encoder": "h264_nvenc", - "extension": "mp4", - "settings": { - "input": [ - "-threads", - 1, - "-hwaccel", - "nvdec", - "-hwaccel_device", - 0, - "-hwaccel_output_format", - "cuda" - ], - "output": [ - "-movflags", - "+faststart" - ], - "low": [ - "-tune", - "ll", - "-preset", - "p3", - "-profile:v", - "high", - "-rc", - "constqp", - "-qp", - 27 - ], - "medium": [ - "-tune", - "hq", - "-preset", - "p4", - "-profile:v", - "high", - "-rc", - "constqp", - "-qp", - 23 - ], - "high": [ - "-tune", - "hq", - "-preset", - "p6", - "-profile:v", - "high", - "-rc", - "constqp", - "-qp", - 20 - ] - } - }, - "audio": { - "encoder": "aac", - "extension": "aac", - "settings": ["-b:a", "192k"] - } - } - } -} diff --git a/src/core/ArrayList.js b/src/core/ArrayList.js deleted file mode 100644 index 25201f55..00000000 --- a/src/core/ArrayList.js +++ /dev/null @@ -1,35 +0,0 @@ -export default class ArrayList extends Array { - static get [Symbol.species]() { - return Array; - } - - isEmpty() { - return this.length === 0; - } - - insert(item, index) { - this.splice(index, 0, item); - } - - remove(index) { - return !!this.splice(index, 1).length; - } - - swap(index, newIndex) { - if ( - index !== newIndex && - index > -1 && - index < this.length && - newIndex > -1 && - newIndex < this.length - ) { - const tmp = this[index]; - this[index] = this[newIndex]; - this[newIndex] = tmp; - } - } - - clear() { - this.length = 0; - } -} diff --git a/src/core/CanvasDisplay.js b/src/core/CanvasDisplay.js deleted file mode 100644 index 2506e425..00000000 --- a/src/core/CanvasDisplay.js +++ /dev/null @@ -1,28 +0,0 @@ -import Display from 'core/Display'; - -export default class CanvasDisplay extends Display { - constructor(Type, properties) { - super(Type, properties); - - const { width = 1, height = 1 } = this.properties; - - this.canvas = new OffscreenCanvas(width, height); - this.context = this.canvas.getContext('2d'); - } - - render(scene) { - const { canvas, properties } = this; - const { width, height } = canvas; - - if (width === 0 || height === 0) { - return; - } - - const origin = { - x: width / 2, - y: height / 2, - }; - - scene.renderToCanvas(canvas, properties, origin); - } -} diff --git a/src/core/Clock.js b/src/core/Clock.js deleted file mode 100644 index 4a5b2fa8..00000000 --- a/src/core/Clock.js +++ /dev/null @@ -1,41 +0,0 @@ -import { clamp, round } from 'utils/math'; - -export default class Clock { - constructor() { - this.time = 0; - this.elapsedTime = 0; - this.frames = 0; - this.delta = 0; - this.startTime = Date.now(); - } - - update() { - const time = Date.now(); - - if (this.time) { - const delta = time - this.time; - - this.elapsedTime += delta; - this.delta = delta; - } - - this.time = time; - this.frames += 1; - } - - getFPS() { - const { time, frames, elapsedTime } = this; - - if (!time) { - return 0; - } - - const seconds = elapsedTime / 1000; - const fps = clamp(round(frames / seconds), 0, 60); - - this.frames = 0; - this.elapsedTime = 0; - - return fps; - } -} diff --git a/src/core/Display.js b/src/core/Display.js deleted file mode 100644 index 1f5c903c..00000000 --- a/src/core/Display.js +++ /dev/null @@ -1,88 +0,0 @@ -import Entity from 'core/Entity'; -import cloneDeep from 'lodash/cloneDeep'; -import { getDisplayName } from 'utils/controls'; - -export default class Display extends Entity { - static create = (Type, config) => { - const { reactors = {} } = config; - const entity = Entity.create(Type, config); - - for (const [key, value] of Object.entries(reactors)) { - entity.setReactor(key, value); - } - - return entity; - }; - - constructor(Type, properties) { - const { - config: { name, label, defaultProperties }, - } = Type; - - super(name, { ...defaultProperties, ...properties }); - - Object.defineProperties(this, { - type: { value: 'display', writable: true, enumerable: true }, - displayName: { value: getDisplayName(label), writable: true, enumerable: true }, - enabled: { value: true, writable: true, enumerable: true }, - scene: { value: null, writable: true, enumerable: true }, - reactors: { value: {}, writable: true, enumerable: true }, - }); - } - - getReactor(prop) { - return this.reactors[prop]; - } - - setReactor(prop, config) { - this.reactors[prop] = config; - } - - removeReactor(prop) { - delete this.reactors[prop]; - } - - clearReactors() { - this.reactors = {}; - } - - updateReactors(data) { - if (!data.hasUpdate) { - return; - } - - const { reactors } = this; - const properties = {}; - let hasUpdate = false; - - for (const [key, value] of Object.entries(reactors)) { - const { id, min, max } = value; - const output = data.reactors[id]; - - if (output !== undefined) { - properties[key] = (max - min) * output + min; - hasUpdate = true; - } - } - - if (hasUpdate) { - this.update(properties); - } - } - - toJSON() { - const { id, name, type, enabled, displayName, properties, reactors } = this; - - return { - id, - name, - type, - enabled, - displayName, - properties: cloneDeep(properties), - reactors: cloneDeep(reactors), - }; - } - - render() {} -} diff --git a/src/core/Effect.js b/src/core/Effect.js deleted file mode 100644 index 9013e386..00000000 --- a/src/core/Effect.js +++ /dev/null @@ -1,37 +0,0 @@ -import Display from 'core/Display'; - -export default class Effect extends Display { - constructor(Type, properties) { - super(Type, properties); - - this.type = 'effect'; - } - - update(properties = {}) { - const changed = super.update(properties); - - if (changed) { - this.updatePass(); - } - - return changed; - } - - updatePass() { - const { pass } = this; - - if (pass.setUniforms) { - pass.setUniforms(this.properties); - } - } - - setSize(width, height) { - const { pass } = this; - - if (pass) { - pass.setSize(width, height); - } - } - - render() {} -} diff --git a/src/core/Entity.js b/src/core/Entity.js deleted file mode 100644 index 3e8bd3b7..00000000 --- a/src/core/Entity.js +++ /dev/null @@ -1,57 +0,0 @@ -import { updateExistingProps, resolve } from 'utils/object'; -import { uniqueId } from 'utils/crypto'; -import cloneDeep from 'lodash/cloneDeep'; - -export default class Entity { - static create = (Type, config) => { - const { id, name, properties, displays, effects, ...props } = config; - - const entity = new Type(properties); - - for (const [key, value] of Object.entries(props)) { - entity[key] = value; - } - - entity.id = id; - - return entity; - }; - - constructor(name, properties = {}) { - Object.defineProperties(this, { - id: { - value: uniqueId(), - enumerable: true, - writable: true - }, - name: { - value: name, - enumerable: true, - }, - properties: { - value: properties, - enumerable: true, - }, - }); - } - - update(properties = {}) { - return updateExistingProps(this.properties, resolve(properties, [this.properties])); - } - - toString() { - return `[${this.name} ${this.id}]`; - } - - toJSON() { - const { id, name, type, enabled, properties } = this; - - return { - id, - name, - type, - enabled, - properties: cloneDeep(properties), - }; - } -} diff --git a/src/core/EntityList.js b/src/core/EntityList.js deleted file mode 100644 index 1e796bc5..00000000 --- a/src/core/EntityList.js +++ /dev/null @@ -1,50 +0,0 @@ -import ArrayList from 'core/ArrayList'; - -export default class EntityList extends ArrayList { - getElementById(id) { - return this.find(e => e.id === id); - } - - hasElement(obj) { - return this.indexOf(obj) > -1; - } - - addElement(obj, index) { - if (!obj) { - return; - } - - if (index !== undefined) { - this.insert(obj, index); - } else { - this.push(obj); - } - - return obj; - } - - removeElement(obj) { - if (!this.hasElement(obj)) { - return false; - } - - return this.remove(this.indexOf(obj)); - } - - shiftElement(obj, spaces) { - if (!this.hasElement(obj)) { - return false; - } - - const index = this.indexOf(obj); - const newIndex = index + spaces; - - this.swap(index, newIndex); - - return this.indexOf(obj) !== index; - } - - toJSON() { - return this.map(e => e.toJSON()); - } -} diff --git a/src/core/EventEmitter.js b/src/core/EventEmitter.js deleted file mode 100644 index 4791139b..00000000 --- a/src/core/EventEmitter.js +++ /dev/null @@ -1,25 +0,0 @@ -export default class EventEmitter { - on(event, fn) { - this.events = this.events || {}; - this.events[event] = this.events[event] || []; - - return this.events[event].push(fn); - } - - off(event, fn) { - if (!this.events || !this.events[event]) return; - - const events = this.events[event]; - - this.events[event] = events.filter(e => e !== fn); - } - - emit(...args) { - this.events = this.events || {}; - - const event = args.shift(); - const events = this.events[event] || []; - - events.forEach(fn => fn(...args)); - } -} diff --git a/src/core/Logger.js b/src/core/Logger.js deleted file mode 100644 index a7f46b02..00000000 --- a/src/core/Logger.js +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable no-console */ -const LABEL_CSS = 'color:indigo;background-color:lavender;font-weight:bold;'; -const TIMER_CSS = 'color:green;background-color:honeydew;'; - -export default class Logger { - constructor(name) { - this.name = name; - this.timers = {}; - } - - output(method, args) { - const label = ['%c%s%c', LABEL_CSS, this.name, 'color:black']; - - // If format specifiers are defined, merge with label - if (args.length && typeof args[0] === 'string' && /%[sidfoOc]/.test(args[0])) { - label[0] += ` ${args[0]}`; - - args = args.slice(1); - } - - method.apply(console, label.concat(args)); - } - - log(...args) { - this.output(console.log, args); - } - - info(...args) { - this.output(console.info, args); - } - - warn(...args) { - this.output(console.warn, args); - } - - error(...args) { - this.output(console.error, args); - } - - trace(...args) { - this.output(console.trace, args); - } - - debug(...args) { - if (process.env.NODE_ENV !== 'production') { - this.output(console.log, args); - } - } - - time(id) { - this.timers[id] = window.performance.now(); - } - - timeEnd(id, ...args) { - const timer = this.timers[id]; - - if (timer) { - const t = (window.performance.now() - timer) / 1000; - const val = t < 1 ? `${~~(t * 1000)}ms` : `${t.toFixed(2)}s`; - - this.output(console.log, ['%c+%s', TIMER_CSS, val].concat(args)); - } - } -} diff --git a/src/core/Plugin.js b/src/core/Plugin.js deleted file mode 100644 index b3e4ebc7..00000000 --- a/src/core/Plugin.js +++ /dev/null @@ -1,36 +0,0 @@ -/* eslint-disable max-classes-per-file */ -import ShaderPass from 'graphics/ShaderPass'; -import Display from './Display'; -import Effect from './Effect'; - -export default class Plugin { - static create(module) { - const Type = module.config.type === 'effect' ? Effect : Display; - - class PluginClass extends Type { - constructor(properties) { - super(module, properties); - - if (module.shader) { - this.pass = new ShaderPass(module.shader, properties); - } - } - } - - // Add static properties - Object.getOwnPropertyNames(module).forEach(name => { - if (PluginClass[name] === undefined) { - PluginClass[name] = module[name]; - } - }); - - // Add methods - Object.getOwnPropertyNames(module.prototype).forEach(name => { - if (name !== 'constructor') { - PluginClass.prototype[name] = module.prototype[name]; - } - }); - - return PluginClass; - } -} diff --git a/src/core/Process.js b/src/core/Process.js deleted file mode 100644 index 1d9ae184..00000000 --- a/src/core/Process.js +++ /dev/null @@ -1,45 +0,0 @@ -import EventEmitter from 'core/EventEmitter'; -import { api, logger } from 'view/global'; - -export default class Process extends EventEmitter { - constructor(command) { - super(); - - this.command = command; - } - - start(args) { - logger.log('Starting process:', this.command, (args || []).join(' ')); - - const handlers = { - onStdOut: data => { - this.emit('stdout', data); - }, - onStdErr: data => { - this.emit('stderr', data); - }, - onClose: (code, signal) => { - logger.log('Process ended with code', code, 'and signal', signal); - - this.emit('close', code, signal); - }, - onExit: (code, signal) => { - this.emit('exit', code, signal); - }, - onError: err => { - this.emit('error', err); - }, - }; - - // Spawn process - const { stop, push, end } = api.spawnProcess(this.command, args, handlers); - - this.stop = stop; - this.push = push; - this.end = end; - - this.emit('start'); - - return null; - } -} diff --git a/src/core/Reactors.js b/src/core/Reactors.js deleted file mode 100644 index 79ac771e..00000000 --- a/src/core/Reactors.js +++ /dev/null @@ -1,32 +0,0 @@ -import AudioReactor from 'audio/AudioReactor'; -import EntityList from 'core/EntityList'; - -export default class Reactors extends EntityList { - constructor() { - super(); - - this.results = {}; - } - - addReactor(reactor) { - return this.addElement(reactor ?? new AudioReactor()); - } - - removeReactor(reactor) { - this.removeElement(reactor); - } - - clearReactors() { - this.clear(); - } - - getResults(data) { - if (data.hasUpdate) { - this.results = this.reduce((memo, reactor) => { - memo[reactor.id] = reactor.parse(data).output; - return memo; - }, {}); - } - return this.results; - } -} diff --git a/src/core/Renderer.js b/src/core/Renderer.js deleted file mode 100644 index 49d51af3..00000000 --- a/src/core/Renderer.js +++ /dev/null @@ -1,123 +0,0 @@ -import { events, stage, player, analyzer, reactors } from 'view/global'; -import { clamp } from 'utils/math'; -import Clock from './Clock'; - -const STOP_RENDERING = 0; -const VIDEO_RENDERING = -1; - -export default class Renderer { - constructor() { - this.rendering = false; - this.clock = new Clock(); - - // Frame render data - this.frameData = { - id: 0, - delta: 0, - fft: null, - td: null, - volume: 0, - audioPlaying: false, - hasUpdate: false, - reactors: {}, - }; - - // Bind context - this.render = this.render.bind(this); - - // Events - player.on('playback-change', this.resetAnalyzer); - } - - resetAnalyzer() { - const audio = player.getAudio(); - - if (audio && !audio.paused) { - analyzer.reset(); - } - } - - start() { - if (!this.rendering) { - this.time = Date.now(); - this.rendering = true; - - this.resetAnalyzer(); - this.render(); - } - } - - stop() { - const { id } = this.frameData; - - if (id) { - window.cancelAnimationFrame(id); - } - - this.frameData.id = STOP_RENDERING; - this.rendering = false; - } - - getFrameData(id) { - const { frameData, clock: { delta } } = this; - const playing = player.isPlaying(); - - frameData.id = id; - frameData.hasUpdate = playing || id === VIDEO_RENDERING; - frameData.audioPlaying = playing; - frameData.gain = analyzer.gain; - frameData.fft = analyzer.fft; - frameData.td = analyzer.td; - frameData.reactors = reactors.getResults(frameData); - frameData.delta = delta; - - return frameData; - } - - getAudioSample(time) { - const { fftSize } = analyzer.analyzer; - const audio = player.getAudio(); - const pos = audio.getBufferPosition(time); - const start = pos - fftSize / 2; - const end = pos + fftSize / 2; - - return audio.getAudioSlice(start, end); - } - - getFPS() { - return this.clock.getFPS(); - } - - renderFrame(frame, fps) { - return new Promise((resolve, reject) => { - try { - analyzer.process(this.getAudioSample(frame / fps)); - - const frameData = this.getFrameData(VIDEO_RENDERING); - frameData.delta = 1000 / fps; - - stage.render(frameData); - - resolve(stage.getPixels()); - } catch (e) { - reject(e); - } - }); - } - - render() { - const id = window.requestAnimationFrame(this.render); - - this.clock.update(); - - if (player.isPlaying()) { - analyzer.process(); - } - - const data = this.getFrameData(id); - - stage.render(data); - - events.emit('render', data); - } -} diff --git a/src/core/Scene.js b/src/core/Scene.js deleted file mode 100644 index 6fe238b5..00000000 --- a/src/core/Scene.js +++ /dev/null @@ -1,265 +0,0 @@ -import Display from 'core/Display'; -import Effect from 'core/Effect'; -import EntityList from 'core/EntityList'; -import Composer from 'graphics/Composer'; -import { renderImageToCanvas } from '../utils/canvas'; - -const blendOptions = [ - 'None', - 'Normal', - null, - 'Darken', - 'Multiply', - 'Color Burn', - 'Linear Burn', - null, - 'Lighten', - 'Screen', - 'Color Dodge', - 'Linear Dodge', - null, - 'Overlay', - 'Soft Light', - 'Hard Light', - 'Vivid Light', - 'Linear Light', - 'Pin Light', - 'Hard Mix', - null, - 'Difference', - 'Exclusion', - 'Subtract', - 'Divide', - null, - 'Negation', - 'Phoenix', - 'Glow', - 'Reflect', -]; - -export default class Scene extends Display { - static config = { - name: 'Scene', - description: 'Scene display.', - type: 'display', - label: 'Scene', - - defaultProperties: { - blendMode: 'Normal', - opacity: 1.0, - mask: false, - inverse: false, - stencil: false, - }, - controls: { - blendMode: { - label: 'Blending', - type: 'select', - items: blendOptions, - }, - opacity: { - label: 'Opacity', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - mask: { - label: 'Mask', - type: 'toggle', - }, - inverse: { - label: 'Inverse', - type: 'toggle', - hidden: display => !display.properties.mask, - }, - }, - }; - - constructor(properties) { - super(Scene, properties); - - this.stage = null; - this.displays = new EntityList(); - this.effects = new EntityList(); - - this.renderToCanvas = this.renderToCanvas.bind(this); - this.renderToScene = this.renderToScene.bind(this); - this.getSize = this.getSize.bind(this); - } - - addToStage(stage) { - this.composer = new Composer(stage.renderer); - } - - removeFromStage() { - this.displays.clear(); - this.effects.clear(); - this.composer.dispose(); - } - - getSize() { - return this.composer.getSize(); - } - - setSize(width, height) { - this.displays.forEach(display => { - if (display.setSize) { - display.setSize(width, height); - } - }); - - this.effects.forEach(effect => { - if (effect.setSize) { - effect.setSize(width, height); - } - }); - - this.composer.setSize(width, height); - } - - getTarget(obj) { - return obj instanceof Effect ? this.effects : this.displays; - } - - getElementById(id) { - return this.displays.getElementById(id) || this.effects.getElementById(id); - } - - hasElement(obj) { - return !!this.getElementById(obj.id); - } - - addElement(obj, index) { - if (!obj) { - return; - } - - const { renderToScene, renderToCanvas, getSize } = this; - const scene = { renderToScene, renderToCanvas, getSize }; - - const target = this.getTarget(obj); - - target.addElement(obj, index); - - obj.scene = this; - - if (obj.addToScene) { - obj.addToScene(scene); - } - - if (obj.setSize) { - const { width, height } = this.stage.getSize(); - - obj.setSize(width, height); - } - - return obj; - } - - removeElement(obj) { - if (!this.hasElement(obj)) { - return false; - } - - const target = this.getTarget(obj); - - target.removeElement(obj); - - obj.scene = null; - - if (obj.removeFromScene) { - obj.removeFromScene(this); - } - - return true; - } - - shiftElement(obj, spaces) { - if (!this.hasElement(obj)) { - return false; - } - - const target = this.getTarget(obj); - - return target.shiftElement(obj, spaces); - } - - renderToCanvas(image, props, origin) { - renderImageToCanvas(this.stage.canvasBuffer.getContext(), image, props, origin); - } - - renderToScene(scene, camera) { - this.stage.webglBuffer.render(scene, camera); - } - - toJSON() { - const json = super.toJSON(); - const { displays, effects } = this; - - return { - ...json, - displays: displays.map(display => display.toJSON()), - effects: effects.map(effect => effect.toJSON()), - }; - } - - clear() { - const { - composer, - stage: { canvasBuffer, webglBuffer }, - } = this; - - canvasBuffer.clear(); - webglBuffer.clear(); - composer.clearBuffer(); - } - - render(data) { - const { - composer, - displays, - effects, - stage: { canvasBuffer, webglBuffer }, - renderToScene, - renderToCanvas, - getSize, - } = this; - - this.clear(); - this.updateReactors(data); - - const scene = { renderToScene, renderToCanvas, getSize }; - const passes = [webglBuffer.pass, canvasBuffer.pass]; - - if (displays.length > 0 || effects.length > 0) { - displays.forEach(display => { - if (display.enabled) { - display.updateReactors(data); - display.render(scene, data); - - if (display.pass) { - passes.push(display.pass); - } - } - }); - - effects.forEach(effect => { - if (effect.enabled) { - effect.updateReactors(data); - effect.render(scene, data); - - if (effect.pass) { - passes.push(effect.pass); - } - } - }); - - composer.render(passes); - } - - return composer.inputBuffer; - } -} diff --git a/src/core/Stage.js b/src/core/Stage.js deleted file mode 100644 index 7a17130a..00000000 --- a/src/core/Stage.js +++ /dev/null @@ -1,181 +0,0 @@ -import { Color } from 'three'; -import cloneDeep from 'lodash/cloneDeep'; -import Scene from 'core/Scene'; -import Entity from 'core/Entity'; -import EntityList from 'core/EntityList'; -import Composer from 'graphics/Composer'; -import CanvasBuffer from 'graphics/CanvasBuffer'; -import WebGLBuffer from 'graphics/WebGLBuffer'; -import { - DEFAULT_CANVAS_WIDTH, - DEFAULT_CANVAS_HEIGHT, - DEFAULT_CANVAS_BGCOLOR, -} from 'view/constants'; -import { isDefined } from 'utils/array'; -import { getRenderer } from 'graphics/common'; - -export default class Stage extends Entity { - static defaultProperties = { - width: DEFAULT_CANVAS_WIDTH, - height: DEFAULT_CANVAS_HEIGHT, - backgroundColor: DEFAULT_CANVAS_BGCOLOR, - zoom: 1, - }; - - constructor(properties) { - super('Stage', { ...Stage.defaultProperties, ...properties }); - - this.scenes = new EntityList(); - } - - init(canvas) { - const { width, height, backgroundColor } = this.properties; - - this.renderer = getRenderer(canvas); - this.renderer.setSize(width, height); - - this.composer = new Composer(this.renderer); - - this.canvasBuffer = new CanvasBuffer(width, height); - this.webglBuffer = new WebGLBuffer(this.renderer); - - this.backgroundColor = new Color(backgroundColor); - } - - update(properties) { - const { width, height, backgroundColor } = properties; - const changed = super.update(properties); - - if (changed) { - if (isDefined(width, height)) { - this.setSize(width, height); - } - - if (backgroundColor !== undefined) { - this.backgroundColor.set(backgroundColor); - } - } - - return changed; - } - - getImage(format) { - return this.composer.getImage(format); - } - - getPixels() { - return this.composer.getPixels(); - } - - getSize() { - if (this.composer) { - return this.composer.getSize(); - } - - return { width: 0, height: 0 }; - } - - setSize(width, height) { - this.scenes.forEach(scene => { - scene.setSize(width, height); - }); - - this.composer.setSize(width, height); - - this.canvasBuffer.setSize(width, height); - this.webglBuffer.setSize(width, height); - } - - getSceneById(id) { - return this.scenes.getElementById(id); - } - - getStageElementById(id) { - return this.scenes.reduce((element, scene) => { - if (!element) { - element = scene.getElementById(id); - } - return element; - }, this.getSceneById(id)); - } - - removeStageElement(obj) { - if (obj instanceof Scene) { - this.removeScene(obj); - } else { - const scene = this.getSceneById(obj.scene.id); - if (scene) { - scene.removeElement(obj); - } - } - } - - shiftStageElement(obj, spaces) { - if (obj instanceof Scene) { - return this.scenes.shiftElement(obj, spaces); - } - - const scene = this.getSceneById(obj.scene.id); - - if (scene) { - return scene.shiftElement(obj, spaces); - } - - return false; - } - - addScene(scene = new Scene(), index) { - this.scenes.addElement(scene, index); - - scene.stage = this; - - if (scene.addToStage) { - scene.addToStage(this); - } - - return scene; - } - - removeScene(scene) { - this.scenes.removeElement(scene); - - scene.stage = null; - - scene.removeFromStage(this); - } - - clearScenes() { - [...this.scenes].forEach(scene => this.removeScene(scene)); - } - - hasScenes() { - return !this.scenes.isEmpty(); - } - - toJSON() { - const { id, name, type, properties } = this; - - return { - id, - name, - type, - properties: cloneDeep(properties), - }; - } - - render(data) { - const { composer, scenes, backgroundColor } = this; - - composer.clear(backgroundColor, 1); - - scenes.forEach(scene => { - if (scene.enabled) { - const buffer = scene.render(data); - - composer.blendBuffer(buffer, scene.properties); - } - }); - - composer.renderToScreen(); - } -} diff --git a/src/core/WebGLDisplay.js b/src/core/WebGLDisplay.js deleted file mode 100644 index 005ebdcd..00000000 --- a/src/core/WebGLDisplay.js +++ /dev/null @@ -1,9 +0,0 @@ -import Display from 'core/Display'; - -export default class WebGLDisplay extends Display { - constructor(info, properties) { - super(info, properties); - - this.type = 'webgl'; - } -} diff --git a/src/displays/BarSpectrumDisplay.js b/src/displays/BarSpectrumDisplay.js deleted file mode 100644 index d85c52f8..00000000 --- a/src/displays/BarSpectrumDisplay.js +++ /dev/null @@ -1,203 +0,0 @@ -import CanvasDisplay from 'core/CanvasDisplay'; -import CanvasBars from 'canvas/CanvasBars'; -import FFTParser from 'audio/FFTParser'; -import { FFT_SIZE, SAMPLE_RATE } from 'view/constants'; -import { property, stageWidth, stageHeight } from 'utils/controls'; - -export default class BarSpectrumDisplay extends CanvasDisplay { - static config = { - name: 'BarSpectrumDisplay', - description: 'Displays an audio bar spectrum.', - type: 'display', - label: 'Bar Spectrum', - defaultProperties: { - width: 770, - height: 240, - x: 0, - y: 0, - barWidth: -1, - barSpacing: -1, - barWidthAutoSize: 1, - barSpacingAutoSize: 1, - shadowHeight: 100, - color: ['#FFFFFF', '#FFFFFF'], - shadowColor: ['#333333', '#000000'], - rotation: 0, - opacity: 1.0, - fftSize: FFT_SIZE, - sampleRate: SAMPLE_RATE, - smoothingTimeConstant: 0.5, - minDecibels: -100, - maxDecibels: -12, - minFrequency: 0, - maxFrequency: 6000, - normalize: true, - }, - controls: { - maxDecibels: { - label: 'Max dB', - type: 'number', - min: -40, - max: 0, - step: 1, - withRange: true, - }, - minFrequency: { - label: 'Min Frequency', - type: 'number', - min: 0, - max: property('maxFrequency'), - step: 10, - withRange: true, - }, - maxFrequency: { - label: 'Max Frequency', - type: 'number', - min: property('minFrequency'), - max: 22000, - step: 10, - withRange: true, - }, - smoothingTimeConstant: { - label: 'Smoothing', - type: 'number', - min: 0, - max: 0.99, - step: 0.01, - withRange: true, - }, - width: { - label: 'Width', - type: 'number', - min: 0, - max: stageWidth(), - withRange: true, - }, - height: { - label: 'Height', - type: 'number', - min: 0, - max: stageHeight(), - withRange: true, - }, - shadowHeight: { - label: 'Shadow Height', - type: 'number', - min: 0, - max: stageWidth(), - withRange: true, - }, - barWidthAutoSize: { - label: 'Bar Width', - type: 'toggle', - inputProps: { - label: 'Auto-size', - }, - }, - barWidth: { - type: 'number', - min: property('barWidthAutoSize', n => (n ? -1 : 1)), - max: stageWidth(), - hidden: property('barWidthAutoSize'), - withRange: true, - }, - barSpacingAutoSize: { - label: 'Bar Spacing', - type: 'toggle', - inputProps: { - label: 'Auto-size', - }, - }, - barSpacing: { - type: 'number', - min: property('barSpacingAutoSize', n => (n ? -1 : 1)), - max: stageWidth(), - hidden: property('barSpacingAutoSize'), - withRange: true, - }, - color: { - label: 'Bar Color', - type: 'colorrange', - }, - shadowColor: { - label: 'Shadow Color', - type: 'colorrange', - }, - x: { - label: 'X', - type: 'number', - min: stageWidth(n => -n), - max: stageWidth(), - withRange: true, - }, - y: { - label: 'Y', - type: 'number', - min: stageWidth(n => -n), - max: stageWidth(), - withRange: true, - }, - rotation: { - label: 'Rotation', - type: 'number', - min: 0, - max: 360, - withRange: true, - withReactor: true, - }, - opacity: { - label: 'Opacity', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(BarSpectrumDisplay, properties); - - this.bars = new CanvasBars(this.properties, this.canvas); - this.parser = new FFTParser({ - ...this.properties, - fftSize: FFT_SIZE, - sampleRate: SAMPLE_RATE, - }); - } - - update(properties) { - const { barWidthAutoSize, barSpacingAutoSize } = properties; - - if (barWidthAutoSize !== undefined) { - properties.barWidth = barWidthAutoSize ? -1 : 1; - } - if (barSpacingAutoSize !== undefined) { - properties.barSpacing = barSpacingAutoSize ? -1 : 1; - } - - const changed = super.update(properties); - - if (changed) { - this.bars.update(properties); - this.parser.update(properties); - } - - return changed; - } - - render(scene, data) { - const fft = this.parser.parseFFT(data.fft); - - this.bars.render(fft); - - const origin = { - x: this.canvas.width / 2, - y: this.properties.height, - }; - - scene.renderToCanvas(this.canvas, this.properties, origin); - } -} diff --git a/src/displays/GeometryDisplay.js b/src/displays/GeometryDisplay.js deleted file mode 100644 index 75df084e..00000000 --- a/src/displays/GeometryDisplay.js +++ /dev/null @@ -1,406 +0,0 @@ -import { - Scene, - Mesh, - PerspectiveCamera, - PointLight, - MeshNormalMaterial, - MeshBasicMaterial, - MeshPhongMaterial, - MeshLambertMaterial, - MeshDepthMaterial, - MeshStandardMaterial, - MeshPhysicalMaterial, - PointsMaterial, - Color, - Object3D, - BoxBufferGeometry, - SphereBufferGeometry, - DodecahedronBufferGeometry, - IcosahedronBufferGeometry, - OctahedronBufferGeometry, - TetrahedronBufferGeometry, - TorusBufferGeometry, - TorusKnotBufferGeometry, - LineSegments, - EdgesGeometry, - LineBasicMaterial, - Points, - FrontSide, - DoubleSide, - TextureLoader, -} from 'three'; -import WebGLDisplay from 'core/WebGLDisplay'; -import FFTParser from 'audio/FFTParser'; -import POINT_SPRITE from 'assets/images/point.png'; -import { isDefined } from 'utils/array'; - -const shapeOptions = [ - 'Box', - 'Sphere', - 'Dodecahedron', - 'Icosahedron', - 'Octahedron', - 'Tetrahedron', - 'Torus', - 'Torus Knot', -]; - -const materialOptions = ['Basic', 'Lambert', 'Normal', 'Phong', 'Physical', 'Points', 'Standard']; - -const shadingOptions = ['Smooth', 'Flat']; - -const materials = { - Normal: MeshNormalMaterial, - Basic: MeshBasicMaterial, - Phong: MeshPhongMaterial, - Lambert: MeshLambertMaterial, - Depth: MeshDepthMaterial, - Standard: MeshStandardMaterial, - Physical: MeshPhysicalMaterial, - Points: PointsMaterial, -}; - -const FOV = 45; -const NEAR = 1; -const FAR = 10000; -const CAMERA_POS_Z = 250; -const POINT_SIZE = 5.0; - -export default class GeometryDisplay extends WebGLDisplay { - static config = { - name: 'GeometryDisplay', - description: 'Displays 3D geometry.', - type: 'display', - label: 'Geometry (3D)', - defaultProperties: { - shape: 'Box', - material: 'Standard', - shading: 'Smooth', - color: '#FFFFFF', - wireframe: false, - edges: false, - edgeColor: '#FFFFFF', - x: 0, - y: 0, - z: 0, - opacity: 1.0, - startX: 0, - startY: 0, - startZ: 0, - seed: 0, - lightIntensity: 1.0, - lightDistance: 500, - cameraZoom: 250, - }, - controls: { - shape: { - label: 'Shape', - type: 'select', - items: shapeOptions, - }, - material: { - label: 'Material', - type: 'select', - items: materialOptions, - }, - shading: { - label: 'Shading', - type: 'select', - items: shadingOptions, - }, - color: { - label: 'Color', - type: 'color', - }, - wireframe: { - label: 'Wireframe', - type: 'toggle', - }, - edges: { - label: 'Edges', - type: 'toggle', - }, - edgeColor: { - label: 'Edge Color', - type: 'color', - }, - x: { - label: 'X', - type: 'number', - min: -500, - max: 500, - withRange: true, - }, - y: { - label: 'Y', - type: 'number', - min: -500, - max: 500, - withRange: true, - }, - z: { - label: 'Z', - type: 'number', - min: -1000, - max: 1000, - withRange: true, - }, - opacity: { - label: 'Opacity', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(GeometryDisplay, properties); - - this.parser = new FFTParser(); - } - - update(properties) { - const changed = super.update(properties); - const { lights, camera } = this; - const { - shape, - material, - shading, - lines, - edges, - edgeColor, - wireframe, - opacity, - color, - x, - y, - z, - enabled, - lightDistance, - lightIntensity, - cameraZoom, - } = properties; - - if (changed) { - // Create new mesh - if (isDefined(shape, material, shading, lines, edges, edgeColor)) { - this.createMesh(); - } - // Change wireframe - else if (wireframe !== undefined) { - if (this.properties.material !== 'Points') { - this.material.wireframe = wireframe; - } - } - // Change opacity - else if (opacity !== undefined) { - this.material.opacity = opacity; - } - // Change color - else if (color !== undefined) { - this.material.color = new Color().set(color); - } - // Change position - else if (isDefined(x, y, z)) { - this.mesh.position.set( - x ?? this.properties.x, - y ?? this.properties.y, - z ?? this.properties.z, - ); - } - // Change visibility - else if (enabled !== undefined) { - this.group.visible = enabled; - } - // Change lights - else if (lights && isDefined(lightDistance, lightIntensity)) { - this.updateLights(); - } - // Change camera - else if (camera && cameraZoom !== undefined) { - camera.position.z = cameraZoom; - } - } - - return changed; - } - - addToScene({ getSize }) { - const { width, height } = getSize(); - - const scene = new Scene(); - const camera = new PerspectiveCamera(FOV, width / height, NEAR, FAR); - const lights = [ - new PointLight(0xffffff, 1, 0), - new PointLight(0xffffff, 1, 0), - new PointLight(0xffffff, 1, 0), - ]; - const group = new Object3D(); - const sprite = new TextureLoader().load(POINT_SPRITE); - - camera.position.set(0, 0, CAMERA_POS_Z); - - scene.add(camera); - scene.add(lights[0]); - scene.add(lights[1]); - scene.add(lights[2]); - scene.add(group); - - this._scene = scene; - this.camera = camera; - this.lights = lights; - this.group = group; - this.sprite = sprite; - - this.updateLights(); - this.createMesh(); - } - - setSize(width, height) { - this.camera.aspect = width / height; - this.camera.updateProjectionMatrix(); - } - - updateLights() { - const { lights } = this; - const { lightIntensity, lightDistance } = this.properties; - - lights[0].intensity = lightIntensity; - lights[1].intensity = lightIntensity; - lights[2].intensity = lightIntensity; - - lights[0].position.set(0, lightDistance * 2, 0); - lights[1].position.set(lightDistance, lightDistance * 2, lightDistance); - lights[2].position.set(-lightDistance, -lightDistance * 2, -lightDistance); - } - - createMesh() { - const { group, properties } = this; - - if (!group) return; - - let geometry; - let rotation; - - // Remove existing mesh - if (this.mesh) { - rotation = this.mesh.rotation.clone(); - group.remove(this.mesh); - } - - const mesh = new Object3D(); - - // Set geometry - switch (properties.shape) { - case 'Box': - // width, height, depth, widthSegments:1, heightSegments:1, depthSegments:1 - geometry = new BoxBufferGeometry(50, 50, 50); - break; - case 'Sphere': - // radius:50, widthSegments:8, heightSegments:6, phiStart:0, phiLength:PI*2, thetaStart:0, thetaLength:PI - geometry = new SphereBufferGeometry(40, 10, 10); - break; - case 'Dodecahedron': - // radius:1, detail:0 - geometry = new DodecahedronBufferGeometry(40, 0); - break; - case 'Icosahedron': - // radius:1, detail:0 - geometry = new IcosahedronBufferGeometry(40, 0); - break; - case 'Octahedron': - // radius:1, detail:0 - geometry = new OctahedronBufferGeometry(40, 0); - break; - case 'Tetrahedron': - // radius:1, detail:0 - geometry = new TetrahedronBufferGeometry(40, 0); - break; - case 'Torus': - // radius:100, tube:40, radialSegments:8, tubularSegments:6, arc:PI*2 - geometry = new TorusBufferGeometry(50, 20, 10, 10); - break; - case 'Torus Knot': - // radius:100, tube:40, radialSegments:64, tubularSegments:8, p:2, q:3, heightScale:1 - geometry = new TorusKnotBufferGeometry(50, 10, 20, 10); - break; - } - - // Add edges - if (properties.edges && properties.material !== 'Points') { - mesh.add( - new LineSegments( - new EdgesGeometry(geometry, 2), - new LineBasicMaterial({ - color: new Color().set(properties.edgeColor), - transparent: true, - opacity: 0.9, - }), - ), - ); - } - - // Get material - const material = new materials[properties.material](); - - // Create mesh - if (properties.material === 'Points') { - Object.assign(material, { - size: POINT_SIZE, - sizeAttenuation: true, - map: this.sprite, - transparent: true, - alphaTest: 0.5, - color: new Color().set(properties.color), - needsUpdate: true, - }); - - mesh.add(new Points(geometry, material)); - } else { - Object.assign(material, { - flatShading: properties.shading === 'Flat', - color: new Color().set(properties.color), - opacity: properties.opacity, - wireframe: properties.wireframe, - needsUpdate: true, - transparent: true, - side: properties.material === 'Basic' ? FrontSide : DoubleSide, - }); - - mesh.add(new Mesh(geometry, material)); - } - - group.add(mesh); - - mesh.position.set(properties.x, properties.y, properties.z); - - if (rotation) { - mesh.rotation.set(rotation.x, rotation.y, rotation.z); - } - - this.mesh = mesh; - this.material = material; - } - - render(scene, data) { - const { _scene, camera, mesh, properties, parser } = this; - - if (data.hasUpdate) { - const fft = parser.parseFFT(data.fft); - const x = fft[0]; - const y = fft[3]; - const z = fft[2]; - - mesh.rotation.x += 5 * x; - mesh.rotation.y += 3 * y; - mesh.rotation.z += 2 * z; - mesh.position.set(properties.x, properties.y, properties.z); - } - - scene.renderToScene(_scene, camera); - } -} diff --git a/src/displays/ImageDisplay.js b/src/displays/ImageDisplay.js deleted file mode 100644 index fb724fb3..00000000 --- a/src/displays/ImageDisplay.js +++ /dev/null @@ -1,231 +0,0 @@ -import { Texture, TextureLoader } from 'three'; -import WebGLDisplay from 'core/WebGLDisplay'; -import { BLANK_IMAGE } from 'view/constants'; -import ImagePass from 'graphics/ImagePass'; -import { deg2rad } from 'utils/math'; -import { isDefined } from 'utils/array'; - -const disabled = display => !display.hasImage; -const maxWidth = display => { - const { naturalWidth } = display.image; - const { width } = display.scene.getSize(); - - return naturalWidth > width ? naturalWidth : width; -}; -const maxHeight = display => { - const { naturalHeight } = display.image; - const { height } = display.scene.getSize(); - - return naturalHeight > height ? naturalHeight : height; -}; -const maxX = display => (disabled(display) ? 0 : maxWidth(display)); -const maxY = display => (disabled(display) ? 0 : maxHeight(display)); - -export default class ImageDisplay extends WebGLDisplay { - static config = { - name: 'ImageDisplay', - description: 'Displays an image.', - type: 'display', - label: 'Image', - defaultProperties: { - src: BLANK_IMAGE, - x: 0, - y: 0, - zoom: 1, - width: 0, - height: 0, - fixed: true, - rotation: 0, - opacity: 0, - }, - controls: { - src: { - label: 'Image', - type: 'image', - }, - width: { - label: 'Width', - type: 'number', - min: 0, - max: maxWidth, - withRange: true, - withLink: 'fixed', - disabled, - }, - height: { - label: 'Height', - type: 'number', - min: 0, - max: maxHeight, - withRange: true, - withLink: 'fixed', - disabled, - }, - x: { - label: 'X', - type: 'number', - min: display => -1 * maxX(display), - max: display => maxX(display), - withRange: true, - disabled, - }, - y: { - label: 'Y', - type: 'number', - min: display => -1 * maxY(display), - max: display => maxY(display), - withRange: true, - disabled, - }, - zoom: { - label: 'Zoom', - type: 'number', - min: 1.0, - max: 4.0, - step: 0.01, - withRange: true, - withReactor: true, - disabled, - }, - rotation: { - label: 'Rotation', - type: 'number', - min: 0, - max: 360, - withRange: true, - withReactor: true, - disabled, - }, - opacity: { - label: 'Opacity', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - disabled, - }, - }, - }; - - constructor(properties) { - super(ImageDisplay, properties); - - this.image = new Image(); - this.image.src = this.properties.src; - } - - get hasImage() { - return this.properties.src !== BLANK_IMAGE; - } - - update(properties) { - const { src: image, fixed, width, height } = properties; - const { src, width: w, height: h, fixed: f } = this.properties; - - // If we get an HTMLImageElement - if (typeof image === 'object') { - this.image = image; - - if (image.src === BLANK_IMAGE) { - // Image reset - properties = { ...ImageDisplay.config.defaultProperties }; - } else if (image.src !== src) { - // New image - properties = { - src: image.src, - width: image.naturalWidth, - height: image.naturalHeight, - opacity: 1, - }; - } else { - properties.src = image.src; - } - } - - // Sync width/height values - if (!image && (fixed || f)) { - const { naturalWidth, naturalHeight } = this.image; - const ratio = naturalWidth / naturalHeight; - - if (!isDefined(width, height)) { - if (w > h) { - properties.height = Math.round(w * (1 / ratio)) || 0; - properties.width = Math.round(properties.height * ratio); - } else { - properties.width = Math.round(h * ratio); - properties.height = Math.round(properties.width * (1 / ratio)) || 0; - } - } - - if (width) { - properties.height = Math.round(width * (1 / ratio)) || 0; - } - if (height) { - properties.width = Math.round(height * ratio); - } - } - - const changed = super.update(properties); - - if (changed) { - const { opacity, zoom, width, height, x, y, rotation } = properties; - - if (image) { - const texture = new Texture(image); - texture.needsUpdate = true; - - const { width, height } = this.scene.getSize(); - - this.pass = new ImagePass(texture, { width, height }); - - this.pass.camera.aspect = width / height; - this.pass.camera.updateProjectionMatrix(); - } - if (zoom !== undefined) { - const { camera } = this.pass; - - camera.zoom = zoom; - camera.updateProjectionMatrix(); - } - if (width) { - this.pass.mesh.scale.x = width / this.image.naturalWidth; - } - if (height) { - this.pass.mesh.scale.y = height / this.image.naturalHeight; - } - if (opacity) { - this.pass.material.opacity = opacity; - } - if (x !== undefined) { - this.pass.mesh.position.x = x; - } - if (y !== undefined) { - this.pass.mesh.position.y = y; - } - if (rotation !== undefined) { - this.pass.mesh.rotation.z = deg2rad(-rotation); - } - } - - return changed; - } - - addToScene({ getSize }) { - const { width, height } = getSize(); - - new TextureLoader().load(this.properties.src, texture => { - this.pass = new ImagePass(texture, { width, height }); - - this.setSize(width, height); - }); - } - - setSize(width, height) { - if (this.pass) { - this.pass.camera.aspect = width / height; - this.pass.camera.updateProjectionMatrix(); - } - } -} diff --git a/src/displays/ShapeDisplay.js b/src/displays/ShapeDisplay.js deleted file mode 100644 index 1bf6fc56..00000000 --- a/src/displays/ShapeDisplay.js +++ /dev/null @@ -1,139 +0,0 @@ -import CanvasDisplay from 'core/CanvasDisplay'; -import CanvasShape from 'canvas/CanvasShape'; -import { property, stageWidth, stageHeight, maxSize } from 'utils/controls'; - -const shapeOptions = ['Circle', 'Triangle', 'Square', 'Rectangle', 'Hexagon']; - -const isRectangle = display => display.properties.shape === 'Rectangle'; - -export default class ShapeDisplay extends CanvasDisplay { - static config = { - name: 'ShapeDisplay', - description: 'Displays a shape.', - type: 'display', - label: 'Shape', - defaultProperties: { - shape: 'Circle', - size: 100, - width: 100, - height: 100, - x: 0, - y: 0, - fill: true, - color: '#ffffff', - stroke: false, - strokeColor: '#ff0000', - strokeWidth: 5, - rotation: 0, - opacity: 1.0, - }, - controls: { - shape: { - label: 'Shape', - type: 'select', - items: shapeOptions, - }, - width: { - label: display => (isRectangle(display) ? 'Width' : 'Size'), - type: 'number', - min: 1, - max: maxSize(), - withRange: true, - withReactor: true, - }, - height: { - label: 'Height', - type: 'number', - min: 1, - max: maxSize(), - withRange: true, - withReactor: true, - hidden: display => !isRectangle(display), - }, - x: { - label: 'X', - type: 'number', - min: stageWidth(n => -n), - max: stageWidth(), - withRange: true, - }, - y: { - label: 'Y', - type: 'number', - min: stageHeight(n => -n), - max: stageHeight(), - withRange: true, - }, - fill: { - label: 'Fill', - type: 'toggle', - }, - color: { - label: 'Fill Color', - type: 'color', - }, - stroke: { - label: 'Stroke', - type: 'toggle', - }, - strokeColor: { - label: 'Stroke Color', - type: 'color', - }, - strokeWidth: { - label: 'Stroke Width', - type: 'number', - min: 1, - max: 100, - withRange: true, - withReactor: true, - hidden: property('stroke', false), - }, - rotation: { - label: 'Rotation', - type: 'number', - min: 0, - max: 360, - withRange: true, - withReactor: true, - }, - opacity: { - label: 'Opacity', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(ShapeDisplay, properties); - } - - addToScene() { - this.shape = new CanvasShape(this.properties, this.canvas); - this.shape.render(); - } - - update(properties) { - const { shape, width } = properties; - - if (width !== undefined && this.properties.shape !== 'Rectangle') { - properties.height = width; - } - - if (shape !== undefined && shape !== 'Rectangle') { - properties.width = this.properties.width; - properties.height = properties.width; - } - - if (this.shape.update(properties)) { - this.shape.render(); - } - - return super.update(properties); - } -} diff --git a/src/displays/SoundWaveDisplay.js b/src/displays/SoundWaveDisplay.js deleted file mode 100644 index 6882bd91..00000000 --- a/src/displays/SoundWaveDisplay.js +++ /dev/null @@ -1,177 +0,0 @@ -import CanvasDisplay from 'core/CanvasDisplay'; -import CanvasWave from 'canvas/CanvasWave'; -import WaveParser from 'audio/WaveParser'; -import { DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT } from 'view/constants'; -import { renderImageToCanvas } from 'utils/canvas'; -import { stageWidth, stageHeight } from 'utils/controls'; - -const WAVELENGTH_MAX = 0.25; - -export default class SoundWaveDisplay extends CanvasDisplay { - static config = { - name: 'SoundWaveDisplay', - description: 'Displays a sound wave.', - type: 'display', - label: 'Sound Wave', - defaultProperties: { - stroke: true, - strokeColor: '#FFFFFF', - fill: false, - fillColor: '#FFFFFF', - taper: false, - width: DEFAULT_CANVAS_WIDTH, - height: DEFAULT_CANVAS_HEIGHT / 2, - midpoint: DEFAULT_CANVAS_HEIGHT / 4, - lineWidth: 1.0, - wavelength: 0, - smoothingTimeConstant: 0, - x: 0, - y: 0, - rotation: 0, - opacity: 1.0, - }, - controls: { - lineWidth: { - label: 'Line Width', - type: 'number', - min: 1, - max: 10, - withRange: true, - }, - wavelength: { - label: 'Wavelength', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - }, - smoothingTimeConstant: { - label: 'Smoothing', - type: 'number', - min: 0, - max: 0.99, - step: 0.01, - withRange: true, - }, - stroke: { - label: 'Stroke', - type: 'toggle', - }, - strokeColor: { - label: 'Stroke Color', - type: 'color', - }, - fill: { - label: 'Fill', - type: 'toggle', - }, - fillColor: { - label: 'Fill Color', - type: 'color', - }, - taper: { - label: 'Taper Edges', - type: 'toggle', - }, - width: { - label: 'Width', - type: 'number', - min: 1, - max: stageWidth(n => n * 2), - withRange: true, - }, - height: { - label: 'Height', - type: 'number', - min: 1, - max: stageHeight(n => n * 2), - withRange: true, - }, - x: { - label: 'X', - type: 'number', - min: stageWidth(n => -n), - max: stageWidth(), - withRange: true, - }, - y: { - label: 'Y', - type: 'number', - min: stageHeight(n => -n), - max: stageHeight(), - withRange: true, - }, - rotation: { - label: 'Rotation', - type: 'number', - min: 0, - max: 360, - withRange: true, - withReactor: true, - }, - opacity: { - label: 'Opacity', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(SoundWaveDisplay, properties); - - this.wave = new CanvasWave(this.properties, this.canvas); - this.parser = new WaveParser(); - } - - update(properties) { - const changed = super.update(properties); - - if (changed) { - const { height } = properties; - - if (height !== undefined) { - properties.midpoint = height / 2; - } - - this.wave.update(properties); - this.parser.update(properties); - } - - return changed; - } - - getPoints(data, width) { - const step = width / (data.length - 1); - - return Array.from(data).flatMap((n, i) => [i * step, n]); - } - - render(scene, data) { - const { - wave, - parser, - canvas: { width, height }, - properties: { wavelength }, - } = this; - - const values = parser.parseTimeData( - data.td, - wavelength > 0 ? ~~(width / (wavelength * WAVELENGTH_MAX * width)) : width, - ); - - wave.render(this.getPoints(values, width), wavelength > 0.02); - - const origin = { - x: width / 2, - y: height / 2, - }; - - scene.renderToCanvas(this.canvas, this.properties, origin); - } -} diff --git a/src/displays/TextDisplay.js b/src/displays/TextDisplay.js deleted file mode 100644 index 22ef6bf1..00000000 --- a/src/displays/TextDisplay.js +++ /dev/null @@ -1,102 +0,0 @@ -import CanvasDisplay from 'core/CanvasDisplay'; -import CanvasText from 'canvas/CanvasText'; -import fonts from 'config/fonts.json'; -import { stageHeight, stageWidth } from 'utils/controls'; - -const fontOptions = fonts.map(item => ({ label: item, value: item, style: { fontFamily: item } })); - -export default class TextDisplay extends CanvasDisplay { - static config = { - name: 'TextDisplay', - description: 'Displays text.', - type: 'display', - label: 'Text', - defaultProperties: { - text: '', - size: 40, - font: 'Roboto', - italic: false, - bold: false, - x: 0, - y: 0, - color: '#FFFFFF', - rotation: 0, - opacity: 1.0, - }, - controls: { - text: { - label: 'Text', - type: 'text', - }, - size: { - label: 'Size', - type: 'number', - }, - font: { - label: 'Font', - type: 'select', - items: fontOptions, - }, - italic: { - label: 'Italic', - type: 'toggle', - }, - bold: { - label: 'Bold', - type: 'toggle', - }, - x: { - label: 'X', - type: 'number', - min: stageWidth(n => -n), - max: stageWidth(), - withRange: true, - }, - y: { - label: 'Y', - type: 'number', - min: stageHeight(n => -n), - max: stageHeight(), - withRange: true, - }, - color: { - label: 'Color', - type: 'color', - }, - rotation: { - label: 'Rotation', - type: 'number', - min: 0, - max: 360, - withRange: true, - withReactor: true, - }, - opacity: { - label: 'Opacity', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(TextDisplay, properties); - } - - addToScene() { - this.text = new CanvasText(this.properties, this.canvas); - this.text.render(); - } - - update(properties) { - if (this.text.update(properties)) { - this.text.render(); - } - - return super.update(properties); - } -} diff --git a/src/displays/WaveSpectrumDisplay.js b/src/displays/WaveSpectrumDisplay.js deleted file mode 100644 index 0940ca28..00000000 --- a/src/displays/WaveSpectrumDisplay.js +++ /dev/null @@ -1,197 +0,0 @@ -import CanvasDisplay from 'core/CanvasDisplay'; -import CanvasWave from 'canvas/CanvasWave'; -import FFTParser from 'audio/FFTParser'; -import { FFT_SIZE, SAMPLE_RATE } from 'view/constants'; -import { property, stageHeight, stageWidth } from 'utils/controls'; - -export default class WaveSpectrumDisplay extends CanvasDisplay { - static config = { - name: 'WaveSpectrumDisplay', - description: 'Displays an audio wave spectrum.', - type: 'display', - label: 'Wave Spectrum', - defaultProperties: { - width: 770, - height: 240, - midpoint: 240, - x: 0, - y: 0, - stroke: true, - strokeColor: '#FFFFFF', - fill: true, - fillColor: ['#C0C0C0', '#FFFFFF'], - taper: true, - rotation: 0, - opacity: 1.0, - fftSize: FFT_SIZE, - sampleRate: SAMPLE_RATE, - smoothingTimeConstant: 0.5, - minDecibels: -100, - maxDecibels: -14, - minFrequency: 0, - maxFrequency: 2000, - normalize: true, - }, - - controls: { - maxDecibels: { - label: 'Max dB', - type: 'number', - min: -40, - max: 0, - step: 1, - withRange: true, - }, - minFrequency: { - label: 'Min Frequency', - type: 'number', - min: 0, - max: property('maxFrequency'), - step: 10, - withRange: true, - }, - maxFrequency: { - label: 'Max Frequency', - type: 'number', - min: property('minFrequency'), - max: 22000, - step: 10, - withRange: true, - }, - smoothingTimeConstant: { - label: 'Smoothing', - type: 'number', - min: 0, - max: 0.99, - step: 0.01, - withRange: true, - }, - width: { - label: 'Width', - type: 'number', - min: 1, - max: stageWidth(), - withRange: true, - }, - height: { - label: 'Height', - type: 'number', - min: 1, - max: stageHeight(), - withRange: true, - }, - stroke: { - label: 'Stroke', - type: 'toggle', - }, - strokeColor: { - label: 'Stroke Color', - type: 'color', - }, - fill: { - label: 'Fill', - type: 'toggle', - }, - fillColor: { - label: 'Fill Color', - type: 'colorrange', - }, - taper: { - label: 'Taper Edges', - type: 'toggle', - }, - x: { - label: 'X', - type: 'number', - min: stageWidth(n => -n), - max: stageWidth(), - withRange: true, - }, - y: { - label: 'Y', - type: 'number', - min: stageHeight(n => -n), - max: stageWidth(), - withRange: true, - }, - rotation: { - label: 'Rotation', - type: 'number', - min: 0, - max: 360, - withRange: true, - withReactor: true, - }, - opacity: { - label: 'Opacity', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(WaveSpectrumDisplay, properties); - - this.wave = new CanvasWave(this.properties, this.canvas); - this.parser = new FFTParser(this.properties); - } - - update(properties) { - const changed = super.update(properties); - - if (changed) { - const { height } = properties; - - if (height !== undefined) { - properties.midpoint = height; - } - - this.wave.update(properties); - this.parser.update(properties); - } - - return changed; - } - - getPoints(fft, width) { - const points = []; - - for (let i = 0, j = 0, k = 0; i < fft.length; i += 1) { - j = fft[i]; - - if (i === 0 || i === fft.length - 1 || k !== j > fft[i - 1] ? 1 : -1) { - points.push(i * (width / fft.length)); - points.push(j); - } - - k = j > fft[i - 1] ? 1 : -1; - } - - points[points.length - 2] = width; - - return points; - } - - render(scene, data) { - const { - wave, - parser, - canvas: { width, height }, - } = this; - const fft = parser.parseFFT(data.fft); - - wave.render(this.getPoints(fft, width), true); - - const origin = { - x: width / 2, - y: height, - }; - - scene.renderToCanvas(this.canvas, this.properties, origin); - } -} diff --git a/src/displays/index.js b/src/displays/index.js deleted file mode 100644 index da64f118..00000000 --- a/src/displays/index.js +++ /dev/null @@ -1,7 +0,0 @@ -export BarSpectrumDisplay from './BarSpectrumDisplay'; -export GeometryDisplay from './GeometryDisplay'; -export ImageDisplay from './ImageDisplay'; -export ShapeDisplay from './ShapeDisplay'; -export SoundWaveDisplay from './SoundWaveDisplay'; -export TextDisplay from './TextDisplay'; -export WaveSpectrumDisplay from './WaveSpectrumDisplay'; diff --git a/src/drawing/bezierSpline.js b/src/drawing/bezierSpline.js deleted file mode 100644 index 9eb21f97..00000000 --- a/src/drawing/bezierSpline.js +++ /dev/null @@ -1,92 +0,0 @@ -function computeControlPoints(K) { - const p1 = []; - const p2 = []; - const n = K.length - 1; - - // RHS vector - const a = []; - const b = []; - const c = []; - const r = []; - - // Left most segment - a[0] = 0; - b[0] = 2; - c[0] = 1; - r[0] = K[0] + 2 * K[1]; - - // Internal segments - for (let i = 1; i < n - 1; i += 1) { - a[i] = 1; - b[i] = 4; - c[i] = 1; - r[i] = 4 * K[i] + 2 * K[i + 1]; - } - - // Right segment - a[n - 1] = 2; - b[n - 1] = 7; - c[n - 1] = 0; - r[n - 1] = 8 * K[n - 1] + K[n]; - - // Solves Ax=b with the Thomas algorithm (from Wikipedia) - for (let i = 1; i < n; i += 1) { - const m = a[i] / b[i - 1]; - b[i] -= m * c[i - 1]; - r[i] -= m * r[i - 1]; - } - - p1[n - 1] = r[n - 1] / b[n - 1]; - for (let i = n - 2; i >= 0; --i) { - p1[i] = (r[i] - c[i] * p1[i + 1]) / b[i]; - } - - // We have p1, now compute p2 - for (let i = 0; i < n - 1; i++) { - p2[i] = 2 * K[i + 1] - p1[i + 1]; - } - - p2[n - 1] = 0.5 * (K[n] + p1[n - 1]); - - return { p1, p2 }; -} - -export function getSplinePoints(points) { - const x = []; - const y = []; - - // Grab (x,y) coordinates of the control points - for (let i = 0; i < points.length; i += 2) { - x.push(points[i]); - y.push(points[i + 1]); - } - - // Computes control points p1 and p2 for x and y direction - const px = computeControlPoints(x); - const py = computeControlPoints(y); - - return { - x, - y, - px, - py, - }; -} - -export function drawPath(context, points) { - const { x, y, px, py } = getSplinePoints(points); - - context.moveTo(points[0], points[1]); - - for (let i = 0; i < points.length; i += 1) { - context.bezierCurveTo(px.p1[i], py.p1[i], px.p2[i], py.p2[i], x[i + 1], y[i + 1]); - } -} - -export function draw(context, points) { - context.beginPath(); - - drawPath(context, points); - - context.stroke(); -} diff --git a/src/effects/BloomEffect.js b/src/effects/BloomEffect.js deleted file mode 100644 index dc3b0f1a..00000000 --- a/src/effects/BloomEffect.js +++ /dev/null @@ -1,92 +0,0 @@ -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import CopyPass from 'graphics/CopyPass'; -import BlendPass from 'graphics/BlendPass'; -import GaussianBlurPass from 'effects/passes/GaussianBlurPass'; -import MultiPass from 'graphics/MultiPass'; -import LuminanceShader from 'shaders/LuminanceShader'; -import { createRenderTarget } from 'graphics/common'; - -const blendOptions = ['Add', 'Screen']; - -export default class BloomEffect extends Effect { - static config = { - name: 'BloomEffect', - description: 'Bloom effect.', - type: 'effect', - label: 'Bloom', - defaultProperties: { - blendMode: 'Screen', - amount: 0.1, - threshold: 1.0, - }, - controls: { - blendMode: { - label: 'Blend Mode', - type: 'select', - items: blendOptions, - }, - amount: { - label: 'Amount', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - threshold: { - label: 'Threshold', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(BloomEffect, properties); - } - - updatePass() { - const { amount, threshold, blendMode } = this.properties; - const [, lumPass, blurPass, blendPass] = this.pass.passes; - - lumPass.setUniforms({ amount: 1 - threshold }); - - blurPass.setUniforms({ amount }); - - blendPass.update({ blendMode }); - } - - addToScene() { - const passes = []; - - // Copy current frame - const copyPass = new CopyPass(createRenderTarget()); - copyPass.clearBuffer = true; - - passes.push(copyPass); - - // Apply luminance threshold - passes.push(new ShaderPass(LuminanceShader)); - - // Apply blur - passes.push(new GaussianBlurPass()); - - // Blend with original frame - passes.push(new BlendPass(copyPass.buffer)); - - // Set render pass - this.pass = new MultiPass(passes); - - this.updatePass(); - } - - removeFromScene() { - this.pass = null; - } -} diff --git a/src/effects/BlurEffect.js b/src/effects/BlurEffect.js deleted file mode 100644 index b94a6f17..00000000 --- a/src/effects/BlurEffect.js +++ /dev/null @@ -1,186 +0,0 @@ -import Effect from 'core/Effect'; -import BoxBlurShader from 'shaders/BoxBlurShader'; -import CircularBlurShader from 'shaders/CircularBlurShader'; -import ZoomBlurShader from 'shaders/ZoomBlurShader'; -import ShaderPass from 'graphics/ShaderPass'; -import GaussianBlurPass from 'effects/passes/GaussianBlurPass'; -import TriangleBlurPass from 'effects/passes/TriangleBlurPass'; -import LensBlurPass from 'effects/passes/LensBlurPass'; -import { normalize } from 'utils/math'; -import { stageWidth, stageHeight, property } from 'utils/controls'; - -const blurOptions = ['Box', 'Circular', 'Gaussian', 'Triangle', 'Zoom']; - -const shaderOptions = { - Box: BoxBlurShader, - Circular: CircularBlurShader, - Zoom: ZoomBlurShader, -}; - -const BOX_BLUR_MAX = 10; -const TRIANGLE_BLUR_MAX = 200; -const CIRCULAR_BLUR_MAX = 10; -const ZOOM_BLUR_MAX = 1; - -const showZoomOption = property('type', value => value !== 'Zoom'); -const showLensOption = property('type', value => value !== 'Lens'); - -export default class BlurEffect extends Effect { - static config = { - name: 'BlurEffect', - description: 'Blur effect.', - type: 'effect', - label: 'Blur', - defaultProperties: { - type: 'Gaussian', - amount: 0.3, - x: 0, - y: 0, - radius: 10, - brightness: 0.75, - angle: 0, - }, - controls: { - type: { - label: 'Type', - type: 'select', - items: blurOptions, - }, - amount: { - label: 'Amount', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - x: { - label: 'X', - type: 'number', - min: stageWidth(n => -n / 2), - max: stageWidth(n => n / 2), - hidden: showZoomOption, - withRange: true, - }, - y: { - label: 'Y', - type: 'number', - min: stageHeight(n => -n / 2), - max: stageHeight(n => n / 2), - hidden: showZoomOption, - withRange: true, - }, - radius: { - label: 'Radius', - type: 'number', - min: 0, - max: 50, - hidden: showLensOption, - withRange: true, - }, - brightness: { - label: 'Brightness', - type: 'number', - min: -1, - max: 1, - step: 0.01, - hidden: showLensOption, - withRange: true, - }, - angle: { - label: 'Angle', - type: 'number', - min: -180, - max: 180, - hidden: showLensOption, - withRange: true, - }, - }, - }; - - constructor(properties) { - super(BlurEffect, properties); - } - - update(properties) { - const { type } = properties; - const { type: currentType } = this.properties; - - if (type !== undefined && type !== currentType) { - this.pass = this.getShaderPass(type); - } - - return super.update(properties); - } - - updatePass() { - const { type, amount, x, y, radius, brightness, angle } = this.properties; - const { width, height } = this.scene.getSize(); - - switch (type) { - case 'Box': - this.pass.setUniforms({ amount: amount * BOX_BLUR_MAX }); - break; - - case 'Triangle': - this.pass.setUniforms({ amount: amount * TRIANGLE_BLUR_MAX, width, height }); - break; - - case 'Circular': - this.pass.setUniforms({ amount: amount * CIRCULAR_BLUR_MAX }); - break; - - case 'Gaussian': - this.pass.setUniforms({ amount }); - break; - - case 'Lens': - this.pass.setUniforms({ radius, brightness, angle, width, height }); - break; - - case 'Zoom': - this.pass.setUniforms({ - amount: amount * ZOOM_BLUR_MAX, - center: [normalize(x, -width / 2, width / 2), normalize(y, -height / 2, height / 2)], - }); - break; - } - } - - addToScene() { - this.pass = this.getShaderPass(this.properties.type); - - this.updatePass(); - } - - removeFromScene() { - this.pass = null; - } - - getShaderPass(type) { - const { width, height } = this.scene.getSize(); - let pass; - - switch (type) { - case 'Gaussian': - pass = new GaussianBlurPass(); - break; - - case 'Triangle': - pass = new TriangleBlurPass(); - break; - - case 'Lens': - pass = new LensBlurPass(); - break; - - default: - pass = new ShaderPass(shaderOptions[type]); - } - - pass.setSize(width, height); - - return pass; - } -} diff --git a/src/effects/ColorHalftoneEffect.js b/src/effects/ColorHalftoneEffect.js deleted file mode 100644 index 46933b96..00000000 --- a/src/effects/ColorHalftoneEffect.js +++ /dev/null @@ -1,59 +0,0 @@ -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import ColorHalftoneShader from 'shaders/ColorHalftoneShader'; -import { deg2rad } from '../utils/math'; - -export default class ColorHalftoneEffect extends Effect { - static config = { - name: 'ColorHalftoneEffect', - description: 'Color halftone effect.', - type: 'effect', - label: 'Color Halftone', - defaultProperties: { - scale: 0.5, - angle: 0, - }, - controls: { - scale: { - label: 'Scale', - type: 'number', - min: 0, - max: 1, - step: 0.01, - withRange: true, - withReactor: true, - }, - angle: { - label: 'Angle', - type: 'number', - min: 0, - max: 360, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(ColorHalftoneEffect, properties); - } - - updatePass() { - const { scale, angle } = this.properties; - - this.pass.setUniforms({ - scale: 1 - scale, - angle: deg2rad(angle), - }); - } - - addToScene() { - this.pass = new ShaderPass(ColorHalftoneShader); - - this.updatePass(); - } - - removeFromScene() { - this.pass = null; - } -} diff --git a/src/effects/DistortionEffect.js b/src/effects/DistortionEffect.js deleted file mode 100644 index e392e3fe..00000000 --- a/src/effects/DistortionEffect.js +++ /dev/null @@ -1,77 +0,0 @@ -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import DistortionShader from 'shaders/DistortionShader'; - -const DISTORTION_MAX = 30.0; - -export default class DistortionEffect extends Effect { - static config = { - name: 'DistortionEffect', - description: 'Distortion effect.', - type: 'effect', - label: 'Distortion', - defaultProperties: { - time: 0, - amount: 0.15, - speed: 0.5, - }, - controls: { - amount: { - label: 'Amount', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - speed: { - label: 'Speed', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(DistortionEffect, properties); - - this.time = 0; - } - - updatePass() { - this.pass.setUniforms({ - amount: this.properties.amount * DISTORTION_MAX, - }); - } - - addToScene() { - this.pass = new ShaderPass(DistortionShader); - - this.updatePass(); - } - - removeFromScene() { - this.pass = null; - } - - render(scene, data) { - if (!data.hasUpdate) { - return; - } - - const { speed } = this.properties; - - if (speed > 0) { - this.time += data.delta / (100 / speed); - } - - this.pass.setUniforms({ - time: this.time, - }); - } -} diff --git a/src/effects/DotScreenEffect.js b/src/effects/DotScreenEffect.js deleted file mode 100644 index 3c00abec..00000000 --- a/src/effects/DotScreenEffect.js +++ /dev/null @@ -1,59 +0,0 @@ -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import DotScreenShader from 'shaders/DotScreenShader'; -import { deg2rad } from 'utils/math'; - -export default class DotScreenEffect extends Effect { - static config = { - name: 'DotScreenEffect', - description: 'Dot screen effect.', - type: 'effect', - label: 'Dot Screen', - defaultProperties: { - angle: 90, - scale: 0.5, - }, - controls: { - scale: { - label: 'Scale', - type: 'number', - min: 0, - max: 1, - step: 0.01, - withRange: true, - withReactor: true, - }, - angle: { - label: 'Angle', - type: 'number', - min: 0, - max: 360, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(DotScreenEffect, properties); - } - - updatePass() { - const { scale, angle } = this.properties; - - this.pass.setUniforms({ - scale: 2 - scale * 2, - angle: deg2rad(angle), - }); - } - - addToScene() { - this.pass = new ShaderPass(DotScreenShader); - - this.updatePass(); - } - - removeFromScene() { - this.pass = null; - } -} diff --git a/src/effects/GlitchEffect.js b/src/effects/GlitchEffect.js deleted file mode 100644 index 56a1b49d..00000000 --- a/src/effects/GlitchEffect.js +++ /dev/null @@ -1,84 +0,0 @@ -import { Math as _Math, DataTexture, RGBFormat, FloatType } from 'three'; -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import GlitchShader from 'shaders/GlitchShader'; - -export default class GlitchEffect extends Effect { - static config = { - name: 'GlitchEffect', - description: 'Glitch effect.', - type: 'effect', - label: 'Glitch', - defaultProperties: { - amount: 0.5, - }, - controls: { - amount: { - label: 'Amount', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(GlitchEffect, properties); - - this.time = 0; - } - - addToScene() { - this.pass = new ShaderPass(GlitchShader); - - this.pass.setUniforms({ - displacementTexture: this.generateHeightmap(64), - }); - - this.updatePass(); - } - - removeFromScene() { - this.pass = null; - } - - generateHeightmap(size) { - const data = new Float32Array(size * size * 3); - const length = size * size; - - for (let i = 0; i < length; i++) { - const val = _Math.randFloat(0, 1); - data[i * 3] = val; - data[i * 3 + 1] = val; - data[i * 3 + 2] = val; - } - - const texture = new DataTexture(data, size, size, RGBFormat, FloatType); - texture.needsUpdate = true; - - return texture; - } - - render(scene, data) { - if (!data.hasUpdate) { - return; - } - - const { amount } = this.properties; - this.time += data.delta; - - this.pass.setUniforms({ - shift: (Math.random() / 90) * amount, - angle: _Math.randFloat(-Math.PI, Math.PI) * amount, - seed: Math.random() * amount, - seed_x: _Math.randFloat(-0.3, 0.3) * amount, - seed_y: _Math.randFloat(-0.3, 0.3) * amount, - distortion_x: _Math.randFloat(0, 1), - distortion_y: _Math.randFloat(0, 1), - col_s: amount > 0.25 ? 0.05 : _Math.randFloat(0, 1) * amount * 0.05, - }); - } -} diff --git a/src/effects/GlowEffect.js b/src/effects/GlowEffect.js deleted file mode 100644 index 24538527..00000000 --- a/src/effects/GlowEffect.js +++ /dev/null @@ -1,67 +0,0 @@ -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import GlowShader from 'shaders/GlowShader'; - -const GLOW_MAX = 5; - -export default class GlowEffect extends Effect { - static config = { - name: 'GlowEffect', - description: 'Glow effect.', - type: 'effect', - label: 'Glow', - defaultProperties: { - amount: 0.1, - intensity: 1, - }, - controls: { - amount: { - label: 'Amount', - type: 'number', - min: 0, - max: 1.0, - step: 0.01, - withRange: true, - withReactor: true, - }, - intensity: { - label: 'Intensity', - type: 'number', - min: 1, - max: 3, - step: 0.01, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(GlowEffect, properties); - } - - update(properties) { - const changed = super.update(properties); - - if (changed) { - const { amount, intensity } = this.properties; - - this.pass.setUniforms({ - amount: amount * GLOW_MAX, - intensity, - }); - } - - return changed; - } - - addToScene() { - this.pass = new ShaderPass(GlowShader); - - this.updatePass(); - } - - removeFromScene() { - this.pass = null; - } -} diff --git a/src/effects/KaleidoscopeEffect.js b/src/effects/KaleidoscopeEffect.js deleted file mode 100644 index 95a41276..00000000 --- a/src/effects/KaleidoscopeEffect.js +++ /dev/null @@ -1,48 +0,0 @@ -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import KaleidoscopeShader from 'shaders/KaleidoscopeShader'; - -export default class KaleidoscopeEffect extends Effect { - static config = { - name: 'KaleidoscopeEffect', - description: 'Kaleidoscope effect.', - type: 'effect', - label: 'Kaleidoscope', - defaultProperties: { - sides: 6, - angle: 0, - }, - controls: { - sides: { - label: 'Sides', - type: 'number', - min: 1, - max: 20, - withRange: true, - withReactor: true, - }, - angle: { - label: 'Angle', - type: 'number', - min: 0, - max: 360, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(KaleidoscopeEffect, properties); - } - - addToScene() { - this.pass = new ShaderPass(KaleidoscopeShader); - - this.updatePass(); - } - - removeFromScene() { - this.pass = null; - } -} diff --git a/src/effects/LEDEffect.js b/src/effects/LEDEffect.js deleted file mode 100644 index a5e109d9..00000000 --- a/src/effects/LEDEffect.js +++ /dev/null @@ -1,55 +0,0 @@ -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import LEDShader from 'shaders/LEDShader'; - -export default class LEDEffect extends Effect { - static config = { - name: 'LEDEffect', - description: 'LED effect.', - type: 'effect', - label: 'LED', - defaultProperties: { - spacing: 10, - size: 4, - blur: 4, - }, - controls: { - spacing: { - label: 'Spacing', - type: 'number', - min: 1, - max: 100, - withRange: true, - withReactor: true, - }, - size: { - label: 'Size', - type: 'number', - min: 0, - max: 100, - withRange: true, - withReactor: true, - }, - blur: { - label: 'Blur', - type: 'number', - min: 0, - max: 100, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(LEDEffect, properties); - } - - addToScene() { - this.pass = new ShaderPass(LEDShader); - } - - removeFromScene() { - this.pass = null; - } -} diff --git a/src/effects/MirrorEffect.js b/src/effects/MirrorEffect.js deleted file mode 100644 index ffb2396e..00000000 --- a/src/effects/MirrorEffect.js +++ /dev/null @@ -1,41 +0,0 @@ -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import MirrorShader from 'shaders/MirrorShader'; - -const mirrorOptions = [ - { label: 'Left 🠖 Right', value: 0 }, - { label: 'Right 🠖 Left', value: 1 }, - { label: 'Top 🠖 Bottom', value: 2 }, - { label: 'Bottom 🠖 Top', value: 3 }, -]; - -export default class MirrorEffect extends Effect { - static config = { - name: 'MirrorEffect', - description: 'Mirror effect.', - type: 'effect', - label: 'Mirror', - defaultProperties: { - side: 0, - }, - controls: { - side: { - label: 'Side', - type: 'select', - items: mirrorOptions, - }, - }, - }; - - constructor(properties) { - super(MirrorEffect, properties); - } - - addToScene() { - this.pass = new ShaderPass(MirrorShader); - } - - removeFromScene() { - this.pass = null; - } -} diff --git a/src/effects/PixelateEffect.js b/src/effects/PixelateEffect.js deleted file mode 100644 index 740dd1df..00000000 --- a/src/effects/PixelateEffect.js +++ /dev/null @@ -1,76 +0,0 @@ -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import PixelateShader from 'shaders/PixelateShader'; -import HexagonShader from 'shaders/HexagonShader'; - -const renderOptions = ['Square', 'Hexagon']; - -const shaders = { - Square: PixelateShader, - Hexagon: HexagonShader, -}; - -export default class PixelateEffect extends Effect { - static config = { - name: 'PixelateEffect', - description: 'Pixelate effect.', - type: 'effect', - label: 'Pixelate', - defaultProperties: { - type: 'Square', - size: 10, - }, - controls: { - type: { - label: 'Type', - type: 'select', - items: renderOptions, - }, - size: { - label: 'Size', - type: 'number', - min: 2, - max: 240, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(PixelateEffect, properties); - } - - update(properties) { - const changed = Effect.prototype.update.call(this, properties); - - if (this.pass && properties.type !== undefined) { - this.pass = this.getShaderPass(this.properties.type); - } - - return changed; - } - - updatePass() { - this.pass.setUniforms({ size: this.properties.size }); - } - - addToScene() { - this.pass = this.getShaderPass(this.properties.type); - this.pass.enabled = this.enabled; - } - - removeFromScene() { - this.pass = null; - } - - getShaderPass(type) { - const pass = new ShaderPass(shaders[type]); - const { width, height } = this.scene.getSize(); - - pass.setUniforms(this.properties); - pass.setSize(width, height); - - return pass; - } -} diff --git a/src/effects/RGBShiftEffect.js b/src/effects/RGBShiftEffect.js deleted file mode 100644 index d9a31a80..00000000 --- a/src/effects/RGBShiftEffect.js +++ /dev/null @@ -1,58 +0,0 @@ -import Effect from 'core/Effect'; -import ShaderPass from 'graphics/ShaderPass'; -import RGBShiftShader from 'shaders/RGBShiftShader'; -import { deg2rad } from 'utils/math'; -import { stageWidth } from 'utils/controls'; - -export default class RGBShiftEffect extends Effect { - static config = { - name: 'RGBShiftEffect', - description: 'RGB shift effect.', - type: 'effect', - label: 'RGB Shift', - defaultProperties: { - offset: 5, - angle: 45, - }, - controls: { - offset: { - label: 'Offset', - type: 'number', - min: 0, - max: stageWidth(), - withRange: true, - withReactor: true, - }, - angle: { - label: 'Angle', - type: 'number', - min: 0, - max: 360, - withRange: true, - withReactor: true, - }, - }, - }; - - constructor(properties) { - super(RGBShiftEffect, properties); - } - - updatePass() { - const { width } = this.scene.getSize(); - - this.pass.setUniforms({ - amount: this.properties.offset / width, - angle: deg2rad(this.properties.angle), - }); - } - - addToScene() { - this.pass = new ShaderPass(RGBShiftShader); - this.pass.enabled = this.enabled; - } - - removeFromScene() { - this.pass = null; - } -} diff --git a/src/effects/index.js b/src/effects/index.js deleted file mode 100644 index 7d490905..00000000 --- a/src/effects/index.js +++ /dev/null @@ -1,12 +0,0 @@ -export BloomEffect from './BloomEffect'; -export BlurEffect from './BlurEffect'; -export ColorHalftoneEffect from './ColorHalftoneEffect'; -export DistortionEffect from './DistortionEffect'; -export DotScreenEffect from './DotScreenEffect'; -export GlitchEffect from './GlitchEffect'; -export GlowEffect from './GlowEffect'; -export KaleidoscopeEffect from './KaleidoscopeEffect'; -export LEDEffect from './LEDEffect'; -export MirrorEffect from './MirrorEffect'; -export PixelateEffect from './PixelateEffect'; -export RGBShiftEffect from './RGBShiftEffect'; diff --git a/src/effects/passes/GaussianBlurPass.js b/src/effects/passes/GaussianBlurPass.js deleted file mode 100644 index 371c081f..00000000 --- a/src/effects/passes/GaussianBlurPass.js +++ /dev/null @@ -1,27 +0,0 @@ -import ShaderPass from 'graphics/ShaderPass'; -import MultiPass from 'graphics/MultiPass'; -import GaussianBlurShader from 'shaders/GaussianBlurShader'; - -const BLUR_PASSES = 8; - -export default class GaussianBlurPass extends MultiPass { - constructor() { - const passes = []; - - for (let i = 0; i < BLUR_PASSES; i++) { - passes.push(new ShaderPass(GaussianBlurShader)); - } - - super(passes); - - this.setUniforms({ amount: 1.0 }); - } - - setUniforms({ amount }) { - this.passes.forEach((pass, index) => { - const radius = (BLUR_PASSES - index) * amount; - - pass.setUniforms({ direction: index % 2 === 0 ? [0, radius] : [radius, 0] }); - }); - } -} diff --git a/src/effects/passes/LensBlurPass.js b/src/effects/passes/LensBlurPass.js deleted file mode 100644 index e5369b0f..00000000 --- a/src/effects/passes/LensBlurPass.js +++ /dev/null @@ -1,82 +0,0 @@ -import ShaderPass from 'graphics/ShaderPass'; -import MultiPass from 'graphics/MultiPass'; -import CopyPass from 'graphics/CopyPass'; -import LensBlurShader from 'shaders/LensBlurShader'; -import { clamp, deg2rad } from 'utils/math'; -import { createRenderTarget } from 'graphics/common'; - -export default class LensBlurPass extends MultiPass { - static defaultProperties = { - amount: 0.3, - rounds: 4, - }; - - constructor(properties) { - const passes = []; - const props = { ...LensBlurPass.defaultProperties, ...properties }; - - // Pre-blur pass - const preBlur = new ShaderPass(LensBlurShader); - preBlur.setUniforms({ pass: 0 }); - passes.push(preBlur); - - const blur1 = new ShaderPass(LensBlurShader); - blur1.setUniforms({ pass: 1 }); - passes.push(blur1); - - const blur2 = new ShaderPass(LensBlurShader); - blur2.setUniforms({ pass: 2 }); - passes.push(blur2); - - const blur3 = new ShaderPass(LensBlurShader); - blur3.setUniforms({ pass: 1 }); - passes.push(blur3); - - const blur4 = new ShaderPass(LensBlurShader); - blur4.setUniforms({ pass: 3 }); - passes.push(blur4); - - const copy = new CopyPass(createRenderTarget()); - passes.push(copy); - - super(passes, props); - } - - setUniforms({ radius, brightness, angle, width, height }) { - const [preBlur, blur1, blur2, blur3, blur4] = this.passes; - - const dir = []; - for (let i = 0; i < 3; i++) { - const a = deg2rad(angle) + (i * Math.PI * 2) / 3; - dir.push([(radius * Math.sin(a)) / width, (radius * Math.cos(a)) / height]); - } - const power = 10 ** clamp(brightness, -1, 1); - - preBlur.setUniforms({ power }); - blur1.setUniforms({ delta0: dir[0] }); - blur2.setUniforms({ delta0: dir[1], delta1: dir[2] }); - blur3.setUniforms({ delta0: dir[1] }); - blur4.setUniforms({ delta0: dir[2], power: 1 / power }); - } - - render(renderer, inputBuffer, outputBuffer) { - const [preBlur, blur1, blur2, blur3, blur4, copy] = this.passes; - const bufferA = inputBuffer; - const bufferB = outputBuffer; - - // Remap the texture values, which will help make the bokeh effect - preBlur.render(renderer, bufferA, bufferB); - - // Blur two rhombi in parallel into extraTexture - blur1.render(renderer, bufferB, bufferA); - blur2.render(renderer, bufferA, bufferB); - - copy.render(renderer, bufferA); - - // Blur the last rhombus and combine with extraTexture - blur3.render(renderer, bufferB, bufferA); - - blur4.setUniforms({ extraBuffer: copy.buffer.texture }); - blur4.render(renderer, bufferB, bufferA); - } -} diff --git a/src/effects/passes/TriangleBlurPass.js b/src/effects/passes/TriangleBlurPass.js deleted file mode 100644 index e48d2588..00000000 --- a/src/effects/passes/TriangleBlurPass.js +++ /dev/null @@ -1,25 +0,0 @@ -import ShaderPass from 'graphics/ShaderPass'; -import MultiPass from 'graphics/MultiPass'; -import TriangleBlurShader from 'shaders/TriangleBlurShader'; - -const BLUR_PASSES = 4; - -export default class TriangleBlurPass extends MultiPass { - constructor() { - const passes = []; - - for (let i = 0; i < BLUR_PASSES; i++) { - passes.push(new ShaderPass(TriangleBlurShader)); - } - - super(passes); - } - - setUniforms({ amount, width, height }) { - this.passes.forEach((pass, index) => { - const delta = index % 2 === 0 ? [amount / width, 0] : [0, amount / height]; - - pass.setUniforms({ delta }); - }); - } -} diff --git a/src/graphics/BlendPass.js b/src/graphics/BlendPass.js deleted file mode 100644 index 1165f4a4..00000000 --- a/src/graphics/BlendPass.js +++ /dev/null @@ -1,26 +0,0 @@ -import ShaderPass from 'graphics/ShaderPass'; -import BlendShader from 'shaders/BlendShader'; -import blendModes from 'graphics/blendModes'; - -export default class BlendPass extends ShaderPass { - constructor(buffer) { - super(BlendShader); - - this.buffer = buffer; - this.blendMode = 'Normal'; - this.opacity = 1.0; - } - - render(renderer, inputBuffer, outputBuffer) { - const { opacity, blendMode } = this; - - this.setUniforms({ - baseBuffer: this.buffer, - blendBuffer: inputBuffer.texture, - mode: blendModes[blendMode], - opacity, - }); - - super.render(renderer, inputBuffer, outputBuffer); - } -} diff --git a/src/graphics/CanvasBuffer.js b/src/graphics/CanvasBuffer.js deleted file mode 100644 index ac398950..00000000 --- a/src/graphics/CanvasBuffer.js +++ /dev/null @@ -1,30 +0,0 @@ -import { Texture } from 'three'; -import TexturePass from './TexturePass'; - -export default class CanvasBuffer { - constructor(width, height) { - this.canvas = new OffscreenCanvas(width, height); - - this.texture = new Texture(this.canvas); - - this.pass = new TexturePass(this.texture); - this.pass.alwaysUpdateTexture = true; - - this.context = this.canvas.getContext('2d'); - - this.setSize(width, height); - } - - getContext() { - return this.context; - } - - setSize(width, height) { - this.canvas.width = width; - this.canvas.height = height; - } - - clear() { - this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); - } -} diff --git a/src/graphics/ClearMaskPass.js b/src/graphics/ClearMaskPass.js deleted file mode 100644 index 65077ad1..00000000 --- a/src/graphics/ClearMaskPass.js +++ /dev/null @@ -1,10 +0,0 @@ -import Pass from 'graphics/Pass'; - -export default class ClearMaskPass extends Pass { - render(renderer) { - const { stencil } = renderer.state.buffers; - - stencil.setLocked(false); - stencil.setTest(false); - } -} diff --git a/src/graphics/Composer.js b/src/graphics/Composer.js deleted file mode 100644 index e00cfe9a..00000000 --- a/src/graphics/Composer.js +++ /dev/null @@ -1,137 +0,0 @@ -import { Color } from 'three'; -import ShaderPass from 'graphics/ShaderPass'; -import BlendShader from 'shaders/BlendShader'; -import CopyShader from 'shaders/CopyShader'; -import blendModes from 'graphics/blendModes'; -import { base64ToBytes } from 'utils/data'; -import { createRenderTarget } from './common'; - -export default class Composer { - constructor(renderer) { - this.renderer = renderer; - - this.blendPass = new ShaderPass(BlendShader); - this.blendPass.material.transparent = true; - - this.copyPass = new ShaderPass(CopyShader); - this.copyPass.material.transparent = true; - this.copyPass.renderToScreen = true; - - this.inputBuffer = createRenderTarget(); - this.outputBuffer = this.inputBuffer.clone(); - - this.dataBuffer = new Uint8Array(this.inputBuffer.width * this.inputBuffer.height * 4); - } - - getSize() { - return { - width: this.inputBuffer.width, - height: this.inputBuffer.height, - }; - } - - getImage(format = 'image/png') { - const img = this.renderer.domElement.toDataURL(format); - const data = img.replace(/^data:image\/\w+;base64,/, ''); - - return base64ToBytes(data); - } - - getPixels() { - this.renderer.readRenderTargetPixels( - this.inputBuffer, - 0, - 0, - this.inputBuffer.width, - this.inputBuffer.height, - this.dataBuffer, - ); - - return this.dataBuffer; - } - - setSize(width, height) { - this.renderer.setSize(width, height, true); - this.inputBuffer.setSize(width, height); - this.outputBuffer.setSize(width, height); - this.dataBuffer = new Uint8Array(this.inputBuffer.width * this.inputBuffer.height * 4); - } - - clearScreen(color = true, depth = true, stencil = true) { - this.renderer.clear(color, depth, stencil); - } - - clearBuffer(color = true, depth = true, stencil = true) { - this.renderer.setRenderTarget(this.inputBuffer); - this.renderer.clear(color, depth, stencil); - this.renderer.setRenderTarget(this.outputBuffer); - this.renderer.clear(color, depth, stencil); - } - - clear(color, alpha) { - const { renderer } = this; - const clearColor = new Color(); - renderer.getClearColor(clearColor); - const clearAlpha = renderer.getClearAlpha(); - - if (color) { - renderer.setClearColor(color, alpha); - } - - this.clearScreen(); - this.clearBuffer(); - - if (color) { - renderer.setClearColor(clearColor, clearAlpha); - } - } - - dispose() { - this.inputBuffer.dispose(); - this.outputBuffer.dispose(); - } - - swapBuffers() { - const tmp = this.inputBuffer; - this.inputBuffer = this.outputBuffer; - this.outputBuffer = tmp; - } - - blendBuffer(buffer, properties) { - const { renderer, blendPass, inputBuffer, outputBuffer } = this; - - const { opacity, blendMode, mask, inverse } = properties; - - blendPass.setUniforms({ - baseBuffer: inputBuffer.texture, - blendBuffer: buffer.texture, - mode: blendModes[blendMode], - alpha: 1, - opacity, - mask, - inverse, - }); - - blendPass.render(renderer, inputBuffer, outputBuffer); - - this.swapBuffers(); - } - - renderToScreen() { - const { renderer, inputBuffer, outputBuffer, copyPass } = this; - - copyPass.render(renderer, inputBuffer, outputBuffer); - } - - render(passes = []) { - const { renderer } = this; - - passes.forEach(pass => { - pass.render(renderer, this.inputBuffer, this.outputBuffer); - - if (pass.needsSwap) { - this.swapBuffers(); - } - }); - } -} diff --git a/src/graphics/CopyPass.js b/src/graphics/CopyPass.js deleted file mode 100644 index 734d3241..00000000 --- a/src/graphics/CopyPass.js +++ /dev/null @@ -1,32 +0,0 @@ -import ShaderPass from 'graphics/ShaderPass'; -import CopyShader from 'shaders/CopyShader'; - -export default class CopyPass extends ShaderPass { - constructor(buffer) { - super(CopyShader); - - this.buffer = buffer; - this.needsSwap = false; - this.copyFromBuffer = false; - this.clearBuffer = false; - } - - dispose() { - this.buffer.dispose(); - } - - render(renderer, inputBuffer) { - const { buffer, copyFromBuffer, clearBuffer } = this; - - if (clearBuffer) { - renderer.setRenderTarget(buffer); - renderer.clear(); - } - - super.render( - renderer, - copyFromBuffer ? buffer : inputBuffer, - copyFromBuffer ? inputBuffer : buffer, - ); - } -} diff --git a/src/graphics/ImagePass.js b/src/graphics/ImagePass.js deleted file mode 100644 index 2868104e..00000000 --- a/src/graphics/ImagePass.js +++ /dev/null @@ -1,35 +0,0 @@ -import { - MeshBasicMaterial, - OrthographicCamera, - PlaneBufferGeometry, -} from 'three'; -import Pass from './Pass'; - -export default class ImagePass extends Pass { - constructor(texture, resolution) { - super(); - - const { width, height } = resolution; - const { naturalWidth, naturalHeight } = texture.image; - - this.texture = texture; - - const material = new MeshBasicMaterial({ - map: texture, - depthTest: false, - depthWrite: false, - transparent: true, - }); - - const camera = new OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 0, 1); - const geometry = new PlaneBufferGeometry(naturalWidth, naturalHeight); - - this.setFullscreen(material, geometry, camera); - } - - render(renderer, inputBuffer) { - const { scene, camera } = this; - - super.render(renderer, scene, camera, inputBuffer); - } -} diff --git a/src/graphics/MaskPass.js b/src/graphics/MaskPass.js deleted file mode 100644 index 92a7400b..00000000 --- a/src/graphics/MaskPass.js +++ /dev/null @@ -1,43 +0,0 @@ -import Pass from 'graphics/Pass'; - -export default class MaskPass extends Pass { - constructor(scene, camera) { - super(); - - this.scene = scene; - this.camera = camera; - } - - render(renderer, inputBuffer, outputBuffer) { - const { context, state } = renderer; - const { clear, inverse } = this.properties; - const writeValue = inverse ? 0 : 1; - const clearValue = inverse ? 1 : 0; - - // Don't update color or depth - state.buffers.color.setMask(false); - state.buffers.depth.setMask(false); - - // Lock buffers - state.buffers.color.setLocked(true); - state.buffers.depth.setLocked(true); - - // Set up stencil - state.buffers.stencil.setTest(true); - state.buffers.stencil.setOp(context.REPLACE, context.REPLACE, context.REPLACE); - state.buffers.stencil.setFunc(context.ALWAYS, writeValue, 0xffffffff); - state.buffers.stencil.setClear(clearValue); - - // Draw into the stencil buffer - renderer.render(this.scene, this.camera, inputBuffer, clear); - renderer.render(this.scene, this.camera, outputBuffer, clear); - - // Unlock color and depth buffer for subsequent rendering - state.buffers.color.setLocked(false); - state.buffers.depth.setLocked(false); - - // Only render where stencil is set to 1 - state.buffers.stencil.setFunc(context.EQUAL, 1, 0xffffffff); - state.buffers.stencil.setOp(context.KEEP, context.KEEP, context.KEEP); - } -} diff --git a/src/graphics/MultiPass.js b/src/graphics/MultiPass.js deleted file mode 100644 index e3dce637..00000000 --- a/src/graphics/MultiPass.js +++ /dev/null @@ -1,49 +0,0 @@ -import Pass from './Pass'; - -export default class MultiPass extends Pass { - constructor(passes = []) { - super(); - - this.passes = passes; - this.needsSwap = true; - } - - addPass(pass) { - this.passes.push(pass); - - return pass; - } - - removePass(pass) { - this.passes = this.passes.filter(p => p !== pass); - } - - setSize(width, height) { - this.passes.forEach(pass => { - pass.setSize(width, height); - }); - } - - setUniforms(uniforms) { - for (const pass of this.passes) { - if (pass.setUniforms) { - pass.setUniforms(uniforms); - } - } - } - - render(renderer, readBuffer, writeBuffer) { - this.writeBuffer = writeBuffer; - this.readBuffer = readBuffer; - - this.passes.forEach(pass => { - pass.render(renderer, this.readBuffer, this.writeBuffer); - - if (pass.needsSwap) { - const tmp = this.readBuffer; - this.readBuffer = this.writeBuffer; - this.writeBuffer = tmp; - } - }); - } -} diff --git a/src/graphics/Pass.js b/src/graphics/Pass.js deleted file mode 100644 index 9b15d0af..00000000 --- a/src/graphics/Pass.js +++ /dev/null @@ -1,66 +0,0 @@ -import { Mesh, OrthographicCamera, Scene, Color } from 'three'; -import { getFullscreenGeometry } from './common'; - -export default class Pass { - constructor() { - this.needsSwap = false; - this.clearColor = false; - this.clearDepth = false; - this.clearStencil = false; - this.renderToScreen = false; - this.setClearColor = null; - this.setClearAlpha = 1.0; - } - - setFullscreen(material, geometry, camera) { - this.scene = new Scene(); - this.camera = camera || new OrthographicCamera(-1, 1, 1, -1, 0, 1); - this.geometry = geometry || getFullscreenGeometry(); - this.material = material; - - this.mesh = new Mesh(this.geometry, this.material); - this.mesh.frustumCulled = false; - - this.scene.add(this.mesh); - } - - update(properties = {}) { - for (const [key, value] of Object.entries(properties)) { - this[key] = value; - } - } - - render(renderer, scene, camera, renderTarget) { - const { - clearColor, - clearDepth, - clearStencil, - setClearColor, - setClearAlpha, - renderToScreen, - } = this; - - const oldColor = new Color(); - - // Set new values - if (setClearColor) { - renderer.getClearColor(oldColor); - renderer.setClearColor(setClearColor, setClearAlpha); - } - - // Clear buffers - if (clearColor || clearDepth || clearStencil) { - renderer.clear(clearColor, clearDepth, clearStencil); - } - - // Render - renderer.setRenderTarget(renderToScreen ? null : renderTarget); - - renderer.render(scene, camera); - - // Reset values - if (setClearColor) { - renderer.setClearColor(oldColor, renderer.getClearAlpha()); - } - } -} diff --git a/src/graphics/RenderPass.js b/src/graphics/RenderPass.js deleted file mode 100644 index bfcafee7..00000000 --- a/src/graphics/RenderPass.js +++ /dev/null @@ -1,16 +0,0 @@ -import Pass from 'graphics/Pass'; - -export default class RenderPass extends Pass { - constructor(scene, camera) { - super(); - - this.scene = scene; - this.camera = camera; - } - - render(renderer, inputBuffer, outputBuffer) { - const { scene, camera } = this; - - super.render(renderer, scene, camera, outputBuffer); - } -} diff --git a/src/graphics/ShaderPass.js b/src/graphics/ShaderPass.js deleted file mode 100644 index 34af20ca..00000000 --- a/src/graphics/ShaderPass.js +++ /dev/null @@ -1,50 +0,0 @@ -import { ShaderMaterial, UniformsUtils } from 'three'; -import Pass from './Pass'; - -export default class ShaderPass extends Pass { - constructor(shader) { - super(); - - const { uniforms = {}, defines = {}, ...props } = shader; - - this.material = new ShaderMaterial({ - ...props, - uniforms: UniformsUtils.clone(uniforms), - defines: { ...defines }, - }); - - this.setFullscreen(this.material); - - this.needsSwap = true; - } - - setUniforms(properties = {}) { - const { uniforms } = this.material; - - for (const [key, value] of Object.entries(properties)) { - if (uniforms[key] !== undefined) { - const item = uniforms[key].value; - - if (item?.set) { - item.set(...value); - } else { - uniforms[key].value = value; - } - } - } - } - - setSize(width, height) { - this.setUniforms({ resolution: [width, height] }); - } - - render(renderer, inputBuffer, outputBuffer) { - const { scene, camera, material } = this; - - if (inputBuffer && material.uniforms.inputTexture) { - material.uniforms.inputTexture.value = inputBuffer.texture; - } - - super.render(renderer, scene, camera, outputBuffer); - } -} diff --git a/src/graphics/TexturePass.js b/src/graphics/TexturePass.js deleted file mode 100644 index 12605a03..00000000 --- a/src/graphics/TexturePass.js +++ /dev/null @@ -1,29 +0,0 @@ -import { MeshBasicMaterial } from 'three'; -import Pass from './Pass'; - -export default class TexturePass extends Pass { - constructor(texture) { - super(); - - this.texture = texture; - - this.material = new MeshBasicMaterial({ - map: texture, - depthTest: false, - depthWrite: false, - transparent: true, - }); - - this.setFullscreen(this.material); - } - - render(renderer, inputBuffer) { - const { scene, camera, texture, alwaysUpdateTexture } = this; - - if (alwaysUpdateTexture) { - texture.needsUpdate = true; - } - - super.render(renderer, scene, camera, inputBuffer); - } -} diff --git a/src/graphics/WebGLBuffer.js b/src/graphics/WebGLBuffer.js deleted file mode 100644 index 19a929c8..00000000 --- a/src/graphics/WebGLBuffer.js +++ /dev/null @@ -1,40 +0,0 @@ -import { Scene, Camera } from 'three'; -import { WEBGL_BUFFER_SAMPLES } from 'view/constants'; -import { createRenderTarget } from './common'; -import CopyPass from './CopyPass'; - -export default class WebGLBuffer { - constructor(renderer) { - this.renderer = renderer; - - this.buffer = createRenderTarget({ samples: WEBGL_BUFFER_SAMPLES }); - - this.pass = new CopyPass(this.buffer); - this.pass.copyFromBuffer = true; - - this.scene = new Scene(); - this.camera = new Camera(); - } - - setSize(width, height) { - this.buffer.setSize(width, height); - } - - dispose() { - this.buffer.dispose(); - } - - clear() { - const { renderer, buffer } = this; - - renderer.setRenderTarget(buffer); - renderer.clear(); - } - - render(scene, camera) { - const { renderer, buffer } = this; - - renderer.setRenderTarget(buffer); - renderer.render(scene, camera); - } -} diff --git a/src/graphics/blendModes.js b/src/graphics/blendModes.js deleted file mode 100644 index b69b3eba..00000000 --- a/src/graphics/blendModes.js +++ /dev/null @@ -1,29 +0,0 @@ -export default { - None: 0, - Add: 1, - Average: 2, - 'Color Burn': 3, - 'Color Dodge': 4, - Darken: 5, - Difference: 6, - Exclusion: 7, - Glow: 8, - 'Hard Light': 9, - 'Hard Mix': 10, - Lighten: 11, - 'Linear Burn': 12, - 'Linear Dodge': 13, - 'Linear Light': 14, - Multiply: 15, - Negation: 16, - Normal: 17, - Overlay: 18, - Phoenix: 19, - 'Pin Light': 20, - Reflect: 21, - Screen: 22, - 'Soft Light': 23, - Subtract: 24, - 'Vivid Light': 25, - Divide: 26, -}; diff --git a/src/graphics/common.js b/src/graphics/common.js deleted file mode 100644 index db168dcd..00000000 --- a/src/graphics/common.js +++ /dev/null @@ -1,47 +0,0 @@ -import { WebGLRenderer, WebGLRenderTarget, BufferGeometry, BufferAttribute } from 'three'; - -let renderer = null; -let geometry = null; - -export function getRenderer(canvas) { - if (!renderer || (canvas && renderer.domElement !== canvas)) { - renderer = new WebGLRenderer({ - canvas, - antialias: false, - premultipliedAlpha: true, - alpha: false, - }); - - renderer.autoClear = false; - } - - return renderer; -} - -export function getFullscreenGeometry() { - if (!geometry) { - const vertices = new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0]); - const uvs = new Float32Array([0, 0, 2, 0, 0, 2]); - - geometry = new BufferGeometry(); - - geometry.setAttribute('position', new BufferAttribute(vertices, 3)); - geometry.setAttribute('uv', new BufferAttribute(uvs, 2)); - } - - return geometry; -} - -export function createRenderTarget(options = {}) { - const context = renderer.getContext(); - const pixelRatio = renderer.getPixelRatio(); - const width = Math.floor(context.canvas.width / pixelRatio) || 1; - const height = Math.floor(context.canvas.height / pixelRatio) || 1; - - return new WebGLRenderTarget(width, height, options); -} - -export function clearRenderTarget(target) { - renderer.setRenderTarget(target); - renderer.clear(); -} diff --git a/src/main/api/audio.js b/src/main/api/audio.js deleted file mode 100644 index 23af7fd9..00000000 --- a/src/main/api/audio.js +++ /dev/null @@ -1,32 +0,0 @@ -import path from 'path'; -import * as id3 from 'id3js'; -import { readFile } from 'utils/io'; -import { blobToArrayBuffer, dataToBlob } from 'utils/data'; -import { log } from './ipc'; - -export async function readAudioFile(file) { - const fileData = await readFile(file); - const blob = await dataToBlob(fileData, path.extname(file)); - - let { type } = blob; - - // mime module does not recognize opus - if (file.endsWith('.opus')) { - type = 'audio/opus'; - } - - if (!/^audio/.test(type)) { - throw new Error(`Unrecognized audio type: ${type}`); - } - - return blobToArrayBuffer(blob); -} - -export async function loadAudioTags(file) { - try { - return await id3.fromPath(file); - } catch (e) { - log(e); - return null; - } -} diff --git a/src/main/api/config.js b/src/main/api/config.js deleted file mode 100644 index 5ae87b8d..00000000 --- a/src/main/api/config.js +++ /dev/null @@ -1,21 +0,0 @@ -import { fileExists, readFileCompressed, writeFileCompressed } from 'utils/io'; -import { getGlobal } from './ipc'; - -export async function loadConfig() { - const { APP_CONFIG_FILE } = await getGlobal('env'); - - if (fileExists(APP_CONFIG_FILE)) { - const data = await readFileCompressed(APP_CONFIG_FILE); - return JSON.parse(data); - } - - return null; -} - -export async function saveConfig(config) { - const { APP_CONFIG_FILE } = await getGlobal('env'); - - const data = JSON.stringify(config); - - await writeFileCompressed(APP_CONFIG_FILE, data); -} diff --git a/src/main/api/image.js b/src/main/api/image.js deleted file mode 100644 index ec17164d..00000000 --- a/src/main/api/image.js +++ /dev/null @@ -1,20 +0,0 @@ -import path from 'path'; -import { readFile, writeFile } from 'utils/io'; -import { blobToDataUrl, dataToBlob } from 'utils/data'; - -export async function saveImageFile(file, data) { - if (['.jpg', '.png', '.gif'].includes(path.extname(file))) { - return writeFile(file, data); - } -} - -export async function readImageFile(file) { - const fileData = await readFile(file); - const blob = await dataToBlob(fileData, path.extname(file)); - - if (!/^image/.test(blob.type)) { - throw new Error('Invalid image file.'); - } - - return blobToDataUrl(blob); -} diff --git a/src/main/api/index.js b/src/main/api/index.js deleted file mode 100644 index effddbb2..00000000 --- a/src/main/api/index.js +++ /dev/null @@ -1,17 +0,0 @@ -export { loadAudioTags, readAudioFile } from './audio'; -export { loadConfig, saveConfig } from './config'; -export { readImageFile, saveImageFile } from './image'; -export { loadProjectFile, saveProjectFile } from './project'; -export { send, on, once, off, invoke, log, getGlobal } from './ipc'; -export { loadPlugins, getPlugins } from './plugin'; -export { spawnProcess } from './process'; -export { - maximizeWindow, - minimizeWindow, - unmaximizeWindow, - closeWindow, - getWindowState, - showOpenDialog, - showSaveDialog, - openDevTools, -} from './window'; diff --git a/src/main/api/ipc.js b/src/main/api/ipc.js deleted file mode 100644 index 587ff2c7..00000000 --- a/src/main/api/ipc.js +++ /dev/null @@ -1,33 +0,0 @@ -import { ipcRenderer } from 'electron'; - -export function send(channel, data) { - ipcRenderer.send(channel, data); -} - -export function on(channel, callback) { - ipcRenderer.on(channel, (event, ...args) => callback(...args)); -} - -export function once(channel, callback) { - ipcRenderer.once(channel, (event, ...args) => callback(...args)); -} - -export function off(channel, callback) { - if (callback) { - ipcRenderer.removeListener(channel, callback); - } else { - ipcRenderer.removeAllListeners(channel); - } -} - -export async function invoke(channel, data) { - return ipcRenderer.invoke(channel, data); -} - -export function log(...args) { - return invoke('log', args.join(' ')); -} - -export async function getGlobal(key) { - return invoke('get-global', key); -} diff --git a/src/main/api/plugin.js b/src/main/api/plugin.js deleted file mode 100644 index 66ca0830..00000000 --- a/src/main/api/plugin.js +++ /dev/null @@ -1,132 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import yauzl from 'yauzl'; - -const plugins = {}; - -function initPlugin(id) { - if (!plugins[id]) { - plugins[id] = {}; - } -} - -function getPluginId(file) { - return path.parse(file).base; -} - -function streamToBuffer(stream) { - const chunks = []; - - return new Promise((resolve, reject) => { - stream.on('data', chunk => chunks.push(chunk)); - stream.on('error', reject); - stream.on('end', () => resolve(Buffer.concat(chunks))); - }); -} - -function loadModule(id, data) { - initPlugin(id); - - const blob = new Blob([data], { type: 'text/javascript' }); - - plugins[id].src = URL.createObjectURL(blob); -} - -function loadIcon(id, data) { - initPlugin(id); - - const blob = new Blob([Uint8Array.from(data).buffer], { type: 'image/png' }); - - plugins[id].icon = URL.createObjectURL(blob); -} - -function loadPluginFile(dir, file) { - const id = getPluginId(dir); - const filename = path.join(dir, file); - - if (!plugins[id]) { - plugins[id] = {}; - } - - if (file === 'index.js') { - const plugin = fs.readFileSync(filename, 'utf-8'); - loadModule(id, plugin); - } else if (file === 'icon.png') { - const icon = fs.readFileSync(filename); - loadIcon(id, icon); - } -} - -async function loadZipFile(file) { - return new Promise((resolve, reject) => { - const id = getPluginId(file.replace('.zip', '')); - - yauzl.open(file, { lazyEntries: true }, (err, zip) => { - if (err) { - reject(err); - } - - zip.readEntry(); - - zip.on('entry', entry => { - if (!/\/$/.test(entry.fileName)) { - zip.openReadStream(entry, async (err, readStream) => { - if (err) { - reject(err); - } - readStream.on('end', () => { - zip.readEntry(); - }); - - const data = await streamToBuffer(readStream); - - if (entry.fileName === 'index.js') { - loadModule(id, data.toString('utf-8')); - } else if (entry.fileName === 'icon.png') { - loadIcon(id, data); - } - }); - } - }); - zip.on('end', resolve); - }); - }); -} - -async function loadDirectory(dir) { - const files = fs.readdirSync(dir); - const promises = []; - - for (const file of files) { - promises.push(loadPluginFile(dir, file)); - } - - await Promise.all(promises); -} - -export async function loadPlugins(dir) { - if (!fs.existsSync(dir)) { - return; - } - - const files = fs.readdirSync(dir); - const promises = []; - - for (const file of files) { - const filename = path.join(dir, file); - - if (file.endsWith('.zip')) { - promises.push(loadZipFile(filename)); - } else if (fs.statSync(filename).isDirectory()) { - promises.push(loadDirectory(filename)); - } - } - - await Promise.all(promises); - - return plugins; -} - -export function getPlugins() { - return plugins; -} diff --git a/src/main/api/process.js b/src/main/api/process.js deleted file mode 100644 index 52c93a7c..00000000 --- a/src/main/api/process.js +++ /dev/null @@ -1,28 +0,0 @@ -import { spawn } from 'child_process'; - -export function spawnProcess(command, args, props = {}) { - const process = spawn(command, args); - const { onStdOut, onStdErr, onClose, onExit, onError } = props; - - if (onStdOut) { - process.stdout.on('data', data => onStdOut(data.toString())); - } - if (onStdErr) { - process.stderr.on('data', data => onStdErr(data.toString())); - } - if (onClose) { - process.on('close', onClose); - } - if (onExit) { - process.on('exit', onExit); - } - if (onError) { - process.on('error', onError); - } - - const stop = signal => process.kill(signal); - const push = data => process.stdin.write(data); - const end = () => process.stdin.destroy(); - - return { stop, push, end }; -} diff --git a/src/main/api/project.js b/src/main/api/project.js deleted file mode 100644 index c190c714..00000000 --- a/src/main/api/project.js +++ /dev/null @@ -1,23 +0,0 @@ -import path from 'path'; -import { readFile, readFileCompressed, writeFileCompressed } from 'utils/io'; - -export async function loadProjectFile(file) { - try { - const data = await readFileCompressed(file); - - return JSON.parse(data); - } catch (error) { - if (error.message.indexOf('incorrect header check') > -1) { - const data = readFile(file); - - return JSON.parse(data); - } - } -} - -export async function saveProjectFile(file, data) { - if (path.extname(file) !== '.afx') { - file = `${file}.afx`; - } - return writeFileCompressed(file, JSON.stringify(data)); -} diff --git a/src/main/api/window.js b/src/main/api/window.js deleted file mode 100644 index 34224512..00000000 --- a/src/main/api/window.js +++ /dev/null @@ -1,33 +0,0 @@ -import { invoke } from './ipc'; - -export function maximizeWindow() { - return invoke('maximize-window'); -} - -export function unmaximizeWindow() { - return invoke('unmaximize-window'); -} - -export function minimizeWindow() { - return invoke('minimize-window'); -} - -export function closeWindow() { - return invoke('close-window'); -} - -export function openDevTools() { - return invoke('open-dev-tools'); -} - -export async function showOpenDialog(props) { - return invoke('show-open-dialog', props); -} - -export async function showSaveDialog(props) { - return invoke('show-save-dialog', props); -} - -export async function getWindowState() { - return invoke('get-window-state'); -} diff --git a/src/main/autoupdate.js b/src/main/autoupdate.js deleted file mode 100644 index 6e455eee..00000000 --- a/src/main/autoupdate.js +++ /dev/null @@ -1,58 +0,0 @@ -import { ipcMain } from 'electron'; -import { autoUpdater } from 'electron-updater'; -import debug from 'debug'; -import { sendMessage } from './window'; -import { USER_AGENT } from './environment'; - -const log = debug('autoupdate'); - -export default function init() { - autoUpdater.autoDownload = false; - autoUpdater.requestHeaders = { 'User-Agent': USER_AGENT }; - - autoUpdater.on('error', error => { - log('update-error'); - - sendMessage('update-error', error); - }); - - autoUpdater.on('checking-for-update', () => { - log('checking-for-update'); - }); - - autoUpdater.on('update-available', info => { - log('update-available'); - - sendMessage('update-available', info); - }); - - autoUpdater.on('update-not-available', info => { - log('update-not-available'); - - sendMessage('update-not-available', info); - }); - - autoUpdater.on('download-progress', progress => { - log('download-progress', progress); - - sendMessage('download-progress', progress); - }); - - autoUpdater.on('update-downloaded', info => { - log('update-downloaded'); - - sendMessage('update-downloaded', info); - }); - - ipcMain.handle('check-for-updates', () => { - return autoUpdater.checkForUpdates(); - }); - - ipcMain.handle('download-update', () => { - return autoUpdater.downloadUpdate(); - }); - - ipcMain.handle('quit-and-install', () => { - return autoUpdater.quitAndInstall(); - }); -} diff --git a/src/main/constants.js b/src/main/constants.js deleted file mode 100644 index b3714865..00000000 --- a/src/main/constants.js +++ /dev/null @@ -1,5 +0,0 @@ -export const WINDOW_WIDTH = 1320; -export const WINDOW_HEIGHT = 1200; -export const WINDOW_MINWIDTH = 200; -export const WINDOW_MINHEIGHT = 100; -export const WINDOW_BGCOLOR = '#222222'; diff --git a/src/main/environment.js b/src/main/environment.js deleted file mode 100644 index e66c3895..00000000 --- a/src/main/environment.js +++ /dev/null @@ -1,30 +0,0 @@ -import path from 'path'; -import os from 'os'; -import { app } from 'electron'; - -const version = app.getVersion(); - -export const APP_NAME = 'Astrofox'; -export const APP_VERSION = version; -export const APP_PATH = app.getAppPath(); -export const OS_PLATFORM = os.platform(); -export const IS_WINDOWS = OS_PLATFORM === 'win32'; -export const IS_MACOS = OS_PLATFORM === 'darwin'; -export const USER_DATA_PATH = app.getPath('userData'); -export const PLUGIN_PATH = path.join(APP_PATH, '..', 'plugins'); -export const TEMP_PATH = path.join(app.getPath('temp'), APP_NAME); -export const FFMPEG_BINARY = path.join(APP_PATH, '..', 'bin', IS_WINDOWS ? 'ffmpeg.exe' : 'ffmpeg'); -export const APP_CONFIG_FILE = path.join( - USER_DATA_PATH, - process.env.NODE_ENV === 'production' ? 'app.config' : 'app.dev.config', -); -export const LICENSE_FILE = path.join(USER_DATA_PATH, 'license.dat'); -export const ELECTRON_VERSION = process.versions.electron; -export const CHROME_VERSION = process.versions.chrome; -export const V8_VERSION = process.versions.v8; -export const NODE_VERSION = process.versions.node; -export const USER_AGENT = [ - `${APP_NAME}/${APP_VERSION} (${OS_PLATFORM})`, - `Chrome/${CHROME_VERSION}`, - `Electron/${ELECTRON_VERSION}`, -].join(' '); diff --git a/src/main/events.js b/src/main/events.js deleted file mode 100644 index 981fc56c..00000000 --- a/src/main/events.js +++ /dev/null @@ -1,52 +0,0 @@ -import { ipcMain, dialog } from 'electron'; -import debug from 'debug'; -import { getWindow, getWindowState } from './window'; - -const log = debug('preload'); - -export default function init() { - ipcMain.handle('log', (event, data) => { - log(data); - }); - - ipcMain.handle('get-global', (event, key) => { - return global[key]; - }); - - ipcMain.handle('maximize-window', () => { - const win = getWindow(); - if (win.isMaximized()) { - win.unmaximize(); - } else { - win.maximize(); - } - }); - - ipcMain.handle('unmaximize-window', () => { - getWindow().unmaximize(); - }); - - ipcMain.handle('minimize-window', () => { - getWindow().minimize(); - }); - - ipcMain.handle('close-window', () => { - getWindow().close(); - }); - - ipcMain.handle('open-dev-tools', () => { - getWindow().webContents.openDevTools(); - }); - - ipcMain.handle('show-open-dialog', (event, props) => { - return dialog.showOpenDialog(getWindow(), props); - }); - - ipcMain.handle('show-save-dialog', (event, props) => { - return dialog.showSaveDialog(getWindow(), props); - }); - - ipcMain.handle('get-window-state', () => { - return getWindowState(); - }); -} diff --git a/src/main/index.js b/src/main/index.js deleted file mode 100644 index 28c7bf12..00000000 --- a/src/main/index.js +++ /dev/null @@ -1,64 +0,0 @@ -import { app, BrowserWindow } from 'electron'; -import debug from 'debug'; -import * as env from './environment'; -import init from './init'; -import { createWindow, disposeWindow } from './window'; - -const log = debug('main'); - -// Show environment -log('NODE_ENV', process.env.NODE_ENV); - -// Set global variables -global.env = env; -global.plugins = {}; - -// Chrome flags -// Hardware acceleration -app.commandLine.appendSwitch('ignore-gpu-blacklist'); - -// Memory profiling -if (process.env.NODE_ENV !== 'production') { - app.commandLine.appendSwitch('enable-precise-memory-info'); - - // Avoid "Skip checkForUpdatesAndNotify because application is not packed" error - Object.defineProperty(app, 'isPackaged', { - get() { - return true; - }, - }); -} - -// Electron bug: https://github.com/electron/electron/issues/22119 -app.allowRendererProcessReuse = false; - -// Application events -app.on('ready', async () => { - log('ready'); - - await init(); - - createWindow(); -}); - -app.on('activate', () => { - log('activate'); - - if (BrowserWindow.getAllWindows().length === 0) { - createWindow(); - } -}); - -app.on('window-all-closed', () => { - log('window-all-closed'); - - disposeWindow(); - - if (process.platform !== 'darwin') { - app.quit(); - } -}); - -app.on('will-quit', () => { - log('will-quit'); -}); diff --git a/src/main/init.js b/src/main/init.js deleted file mode 100644 index 5c3ad014..00000000 --- a/src/main/init.js +++ /dev/null @@ -1,81 +0,0 @@ -import { app, session, systemPreferences } from 'electron'; -import fs from 'fs'; -import path from 'path'; -import glob from 'glob'; -import debug from 'debug'; -import { removeFile, createFolder } from 'utils/io'; -import * as env from './environment'; -import initMenu from './menu'; -import initAutoUpdate from './autoupdate'; -import initEvents from './events'; - -const log = debug('init'); - -async function removeTempFiles() { - const files = glob.sync('*.*', { cwd: env.TEMP_PATH }); - const promises = []; - - files.forEach(file => promises.push(removeFile(path.join(env.TEMP_PATH, file)))); - - return Promise.all(promises); -} - -function loadExtensions(session) { - const dirs = { - win32: '/AppData/Local/Google/Chrome/User Data/Default/Extensions', - darwin: '/Library/Application Support/Google/Chrome/Default/Extensions', - linux: '/.config/google-chrome/Default/Extensions', - }; - - const extensions = ['fmkadmapgofadopljbjfkapdkoienihi', 'lmhkpmbekcpmknklioeibfkpmmfibljd']; - const promises = []; - - for (const ext of extensions) { - const fullPath = path.join(app.getPath('home'), dirs[process.platform], ext); - - if (fs.existsSync(fullPath)) { - const dir = fs - .readdirSync(fullPath) - .filter(file => fs.statSync(path.join(fullPath, file)).isDirectory()); - - if (dir.length) { - log('Adding extension:', ext); - const extPath = path.join(fullPath, dir[0]); - promises.push(session.loadExtension(extPath)); - } - } - } - - return Promise.all(promises); -} - -export default async function init() { - log('Initialize application'); - - await createFolder(env.TEMP_PATH); - await removeTempFiles(); - - if (process.env.NODE_ENV !== 'production') { - await loadExtensions(session.defaultSession); - } - - initMenu(); - initEvents(); - initAutoUpdate(); - - // Modify the user agent for all requests to the following urls - const filter = { - urls: ['https://*.astrofox.io/*'], - }; - - session.defaultSession.webRequest.onBeforeSendHeaders(filter, (details, callback) => { - details.requestHeaders['User-Agent'] = env.USER_AGENT; - callback({ cancel: false, requestHeaders: details.requestHeaders }); - }); - - // Disable menu items on macOS - if (process.platform === 'darwin') { - systemPreferences.setUserDefault('NSDisabledDictationMenuItem', 'boolean', true); - systemPreferences.setUserDefault('NSDisabledCharacterPaletteMenuItem', 'boolean', true); - } -} diff --git a/src/main/menu.js b/src/main/menu.js deleted file mode 100644 index c4c83185..00000000 --- a/src/main/menu.js +++ /dev/null @@ -1,28 +0,0 @@ -import { Menu } from 'electron'; -import { sendMessage } from 'main/window'; -import menuConfig from 'config/menu.json'; - -export default function init() { - const { setApplicationMenu, buildFromTemplate } = Menu; - let menu = [...menuConfig]; - - if (process.env.NODE_ENV === 'production') { - menu = menu.filter(item => !item.hidden); - } - - function executeAction({ action }) { - sendMessage('menu-action', action); - } - - menu.forEach(menuItem => { - if (menuItem.submenu) { - menuItem.submenu.forEach(item => { - if (item.action && !item.role) { - item.click = executeAction; - } - }); - } - }); - - setApplicationMenu(buildFromTemplate(menu)); -} diff --git a/src/main/preload.js b/src/main/preload.js deleted file mode 100644 index 7f45b4d5..00000000 --- a/src/main/preload.js +++ /dev/null @@ -1,17 +0,0 @@ -import { contextBridge } from 'electron'; -import * as api from 'main/api'; - -async function init() { - api.log('Preload script loaded'); - - const env = await api.getGlobal('env'); - - await api.loadPlugins(env.PLUGIN_PATH); - - contextBridge.exposeInMainWorld('__ASTROFOX__', { - ...api, - getEnvironment: () => env, - }); -} - -init(); diff --git a/src/main/window.js b/src/main/window.js deleted file mode 100644 index 4bb1fa87..00000000 --- a/src/main/window.js +++ /dev/null @@ -1,114 +0,0 @@ -import { BrowserWindow, BrowserView } from 'electron'; -import path from 'path'; -import url from 'url'; -import debug from 'debug'; -import { - WINDOW_WIDTH, - WINDOW_HEIGHT, - WINDOW_MINWIDTH, - WINDOW_MINHEIGHT, - WINDOW_BGCOLOR, -} from './constants'; - -const PORT = process.env.PORT || 3000; -const log = debug('window'); - -let win = null; - -export function getWindow() { - return win; -} - -export function showWindow() { - win.show(); - - if (process.env.NODE_ENV !== 'production') { - win.webContents.openDevTools(); - } -} - -export function disposeWindow() { - win = null; -} - -export function sendMessage(channel, data) { - win.webContents.send(channel, data); -} - -export function getWindowState() { - return { - focused: win.isFocused(), - maximized: win.isMaximized(), - minimized: win.isMinimized(), - }; -} - -export function updateWindowState() { - sendMessage('window-state-changed', getWindowState()); -} - -export function createWindow() { - if (win !== null) return; - - // Create window - win = new BrowserWindow({ - width: WINDOW_WIDTH, - height: WINDOW_HEIGHT, - minWidth: WINDOW_MINWIDTH, - minHeight: WINDOW_MINHEIGHT, - backgroundColor: WINDOW_BGCOLOR, - show: false, - frame: false, - titleBarStyle: 'hiddenInset', - webPreferences: { - preload: path.join(__dirname, 'preload.js'), - nodeIntegration: false, - contextIsolation: true, - enableRemoteModule: false, - backgroundThrottling: false, - textAreasAreResizable: false, - devTools: true, - webgl: true, - }, - }); - - if (process.env.NODE_ENV === 'production') { - const view = new BrowserView(); - win.setBrowserView(view); - view.setBounds({ x: 0, y: 0, width: 0, height: 0 }); - view.webContents.loadURL('https://astrofox.io/hello'); - } - - // Load index page - win.loadURL( - process.env.NODE_ENV === 'production' - ? url.format({ - pathname: path.join(__dirname, 'index.html'), - protocol: 'file', - slashes: true, - }) - : `http://localhost:${PORT}`, - ); - - // Show window only when ready - win.on('ready-to-show', () => { - log('ready-to-show'); - showWindow(); - }); - - // Window close - win.on('close', () => { - log('close'); - }); - - win.on('closed', () => { - log('closed'); - }); - - // State events - win.on('minimize', updateWindowState); - win.on('maximize', updateWindowState); - win.on('unmaximize', updateWindowState); - win.on('focus', updateWindowState); - win.on('blur', updateWindowState); -} diff --git a/src/shaders/BarrelBlurShader.js b/src/shaders/BarrelBlurShader.js deleted file mode 100644 index 73d27502..00000000 --- a/src/shaders/BarrelBlurShader.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/barrel-blur.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/BlendShader.js b/src/shaders/BlendShader.js deleted file mode 100644 index bde96821..00000000 --- a/src/shaders/BlendShader.js +++ /dev/null @@ -1,16 +0,0 @@ -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/blend.glsl'; - -export default { - uniforms: { - baseBuffer: { type: 't', value: null }, - blendBuffer: { type: 't', value: null }, - mode: { type: 'i', value: 0 }, - alpha: { type: 'i', value: 1 }, - opacity: { type: 'f', value: 1.0 }, - mask: { type: 'i', value: 0 }, - inverse: { type: 'i', value: 0 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/BoxBlurShader.js b/src/shaders/BoxBlurShader.js deleted file mode 100644 index 5ee05de7..00000000 --- a/src/shaders/BoxBlurShader.js +++ /dev/null @@ -1,13 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/box-blur.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - amount: { type: 'f', value: 0.0 }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/CircularBlurShader.js b/src/shaders/CircularBlurShader.js deleted file mode 100644 index 877abdcb..00000000 --- a/src/shaders/CircularBlurShader.js +++ /dev/null @@ -1,13 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/circular-blur.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - amount: { type: 'f', value: 1.0 }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/ColorHalftoneShader.js b/src/shaders/ColorHalftoneShader.js deleted file mode 100644 index 478f6af6..00000000 --- a/src/shaders/ColorHalftoneShader.js +++ /dev/null @@ -1,15 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/color-halftone.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - angle: { type: 'f', value: 1.0 }, - scale: { type: 'f', value: 1.0 }, - center: { type: 'v2', value: new Vector2(0, 0) }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/ColorShiftShader.js b/src/shaders/ColorShiftShader.js deleted file mode 100644 index ffe59f95..00000000 --- a/src/shaders/ColorShiftShader.js +++ /dev/null @@ -1,10 +0,0 @@ -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/color-shift.glsl'; - -export default { - uniforms: { - time: { type: 'f', value: 1.0 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/CopyShader.js b/src/shaders/CopyShader.js deleted file mode 100644 index fb779789..00000000 --- a/src/shaders/CopyShader.js +++ /dev/null @@ -1,12 +0,0 @@ -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/copy.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - opacity: { type: 'f', value: 1.0 }, - alpha: { type: 'i', value: 0 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/DistortionShader.js b/src/shaders/DistortionShader.js deleted file mode 100644 index 27a2dd16..00000000 --- a/src/shaders/DistortionShader.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/distortion.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - time: { type: 'f', value: 1.0 }, - amount: { type: 'f', value: 1.0 }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/DotScreenShader.js b/src/shaders/DotScreenShader.js deleted file mode 100644 index f11f26b0..00000000 --- a/src/shaders/DotScreenShader.js +++ /dev/null @@ -1,15 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/dot-screen.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - tSize: { type: 'v2', value: new Vector2(256, 256) }, - center: { type: 'v2', value: new Vector2(0.5, 0.5) }, - angle: { type: 'f', value: 1.57 }, - scale: { type: 'f', value: 1.0 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/FXAAShader.js b/src/shaders/FXAAShader.js deleted file mode 100644 index a8a07df1..00000000 --- a/src/shaders/FXAAShader.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/fxaa.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/GaussianBlurShader.js b/src/shaders/GaussianBlurShader.js deleted file mode 100644 index 2bc770ea..00000000 --- a/src/shaders/GaussianBlurShader.js +++ /dev/null @@ -1,13 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/gaussian-blur.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - direction: { type: 'v2', value: new Vector2(0, 1) }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/GlitchShader.js b/src/shaders/GlitchShader.js deleted file mode 100644 index 5c95f506..00000000 --- a/src/shaders/GlitchShader.js +++ /dev/null @@ -1,21 +0,0 @@ -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/glitch.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - displacementTexture: { type: 't', value: null }, - shift: { type: 'f', value: 0.08 }, - angle: { type: 'f', value: 0.02 }, - seed: { type: 'f', value: 0.02 }, - seed_x: { type: 'f', value: 0.02 }, // -1,1 - seed_y: { type: 'f', value: 0.02 }, // -1,1 - distortion_x: { type: 'f', value: 0.5 }, - distortion_y: { type: 'f', value: 0.6 }, - col_s: { type: 'f', value: 0.05 }, - horizontal: { type: 'i', value: 1 }, - vertical: { type: 'i', value: 0 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/GlowShader.js b/src/shaders/GlowShader.js deleted file mode 100644 index a062c418..00000000 --- a/src/shaders/GlowShader.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/glow.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - amount: { type: 'f', value: 1.0 }, - intensity: { type: 'f', value: 1.0 }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/GridShader.js b/src/shaders/GridShader.js deleted file mode 100644 index 3e51ab79..00000000 --- a/src/shaders/GridShader.js +++ /dev/null @@ -1,10 +0,0 @@ -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/grid.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/HalftoneShader.js b/src/shaders/HalftoneShader.js deleted file mode 100644 index d5c29b8d..00000000 --- a/src/shaders/HalftoneShader.js +++ /dev/null @@ -1,15 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'src/shaders/glsl/fragment/color-halftone.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - center: { type: 'v2', value: new Vector2(0.5, 0.5) }, - angle: { type: 'f', value: 1.57 }, - scale: { type: 'f', value: 1.0 }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/HexagonShader.js b/src/shaders/HexagonShader.js deleted file mode 100644 index 59979966..00000000 --- a/src/shaders/HexagonShader.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/hexagon.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - center: { type: 'v2', value: new Vector2(0.5, 0.5) }, - size: { type: 'f', value: 10.0 }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/KaleidoscopeShader.js b/src/shaders/KaleidoscopeShader.js deleted file mode 100644 index 3981941e..00000000 --- a/src/shaders/KaleidoscopeShader.js +++ /dev/null @@ -1,12 +0,0 @@ -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/kaleidoscope.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - sides: { type: 'f', value: 0 }, - angle: { type: 'f', value: 0 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/LEDShader.js b/src/shaders/LEDShader.js deleted file mode 100644 index d0c3a44a..00000000 --- a/src/shaders/LEDShader.js +++ /dev/null @@ -1,15 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/led.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - spacing: { type: 'f', value: 10.0 }, - size: { type: 'f', value: 4.0 }, - blur: { type: 'f', value: 4.0 }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/LensBlurShader.js b/src/shaders/LensBlurShader.js deleted file mode 100644 index a77ba024..00000000 --- a/src/shaders/LensBlurShader.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/lens-blur.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - extraBuffer: { type: 't', value: null }, - delta0: { type: 'v2', value: new Vector2(1, 1) }, - delta1: { type: 'v2', value: new Vector2(1, 1) }, - power: { type: 'f', value: 1.0 }, - pass: { type: 'i', value: 0 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/LuminanceShader.js b/src/shaders/LuminanceShader.js deleted file mode 100644 index 3653670d..00000000 --- a/src/shaders/LuminanceShader.js +++ /dev/null @@ -1,11 +0,0 @@ -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/luminance.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - amount: { type: 'f', value: 0.0 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/MirrorShader.js b/src/shaders/MirrorShader.js deleted file mode 100644 index 788d6769..00000000 --- a/src/shaders/MirrorShader.js +++ /dev/null @@ -1,11 +0,0 @@ -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/mirror.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - side: { type: 'i', value: 1 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/PixelateShader.js b/src/shaders/PixelateShader.js deleted file mode 100644 index bfc5ada9..00000000 --- a/src/shaders/PixelateShader.js +++ /dev/null @@ -1,13 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/pixelate.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - size: { type: 'f', value: 10 }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/PointShader.js b/src/shaders/PointShader.js deleted file mode 100644 index f5bc76a6..00000000 --- a/src/shaders/PointShader.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Color } from 'three'; -import vertexShader from 'shaders/glsl/vertex/point.glsl'; -import fragmentShader from 'shaders/glsl/fragment/point.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - opacity: { type: 'f', value: 1.0 }, - color: { type: 'c', value: new Color(0xffffff) }, - }, - vertexShader, - fragmentShader, - alphaTest: 0.9, -}; diff --git a/src/shaders/RGBShiftShader.js b/src/shaders/RGBShiftShader.js deleted file mode 100644 index b83433a3..00000000 --- a/src/shaders/RGBShiftShader.js +++ /dev/null @@ -1,12 +0,0 @@ -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/rgb-shift.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - amount: { type: 'f', value: 0.005 }, - angle: { type: 'f', value: 0.0 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/RippleShader.js b/src/shaders/RippleShader.js deleted file mode 100644 index c9f400e7..00000000 --- a/src/shaders/RippleShader.js +++ /dev/null @@ -1,13 +0,0 @@ -import vertexShader from 'src/shaders/glsl/vertex/ripple.glsl'; -import fragmentShader from 'src/shaders/glsl/fragment/ripple.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - time: { type: 'f', value: 0.0 }, - size: { type: 'f', value: 0.0 }, - depth: { type: 'f', value: 0.0 }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/TriangleBlurShader.js b/src/shaders/TriangleBlurShader.js deleted file mode 100644 index 8b755462..00000000 --- a/src/shaders/TriangleBlurShader.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/triangle-blur.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - delta: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/ZoomBlurShader.js b/src/shaders/ZoomBlurShader.js deleted file mode 100644 index 684f94a0..00000000 --- a/src/shaders/ZoomBlurShader.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Vector2 } from 'three'; -import vertexShader from 'shaders/glsl/vertex/basic.glsl'; -import fragmentShader from 'shaders/glsl/fragment/zoom-blur.glsl'; - -export default { - uniforms: { - inputTexture: { type: 't', value: null }, - center: { type: 'v2', value: new Vector2(0.5, 0.5) }, - amount: { type: 'f', value: 1.0 }, - resolution: { type: 'v2', value: new Vector2(1, 1) }, - }, - vertexShader, - fragmentShader, -}; diff --git a/src/shaders/glsl/fragment/barrel-blur.glsl b/src/shaders/glsl/fragment/barrel-blur.glsl deleted file mode 100644 index cd76f708..00000000 --- a/src/shaders/glsl/fragment/barrel-blur.glsl +++ /dev/null @@ -1,32 +0,0 @@ -uniform sampler2D inputTexture; -uniform vec2 resolution; -varying vec2 vUv; - -vec2 barrelDistortion(vec2 coord, float amt) { - vec2 cc = coord - 0.5; - float dist = dot(cc, cc); - return coord + cc * dist * amt; -} - -void main() { - vec2 uv=(gl_FragCoord.xy/resolution.xy*.5)+.25; - - vec4 a1=texture2D(inputTexture, barrelDistortion(uv,0.0)); - vec4 a2=texture2D(inputTexture, barrelDistortion(uv,0.2)); - vec4 a3=texture2D(inputTexture, barrelDistortion(uv,0.4)); - vec4 a4=texture2D(inputTexture, barrelDistortion(uv,0.6)); - - vec4 a5=texture2D(inputTexture, barrelDistortion(uv,0.8)); - vec4 a6=texture2D(inputTexture, barrelDistortion(uv,1.0)); - vec4 a7=texture2D(inputTexture, barrelDistortion(uv,1.2)); - vec4 a8=texture2D(inputTexture, barrelDistortion(uv,1.4)); - - vec4 a9=texture2D(inputTexture, barrelDistortion(uv,1.6)); - vec4 a10=texture2D(inputTexture, barrelDistortion(uv,1.8)); - vec4 a11=texture2D(inputTexture, barrelDistortion(uv,2.0)); - vec4 a12=texture2D(inputTexture, barrelDistortion(uv,2.2)); - - vec4 tx=(a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12)/12.; - - gl_FragColor = vec4(tx.rgb, tx.a); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/blend.glsl b/src/shaders/glsl/fragment/blend.glsl deleted file mode 100644 index 834d2e4b..00000000 --- a/src/shaders/glsl/fragment/blend.glsl +++ /dev/null @@ -1,332 +0,0 @@ -uniform sampler2D baseBuffer; -uniform sampler2D blendBuffer; -uniform int mode; -uniform int alpha; -uniform float opacity; -uniform int mask; -uniform int inverse; -varying vec2 vUv; - -const vec3 vLuma = vec3(0.2126, 0.7152, 0.0722); - -// Color Dodge -float blendColorDodge(float base, float blend) { - return (blend==1.0)?blend:min(base/(1.0-blend),1.0); -} - -vec3 blendColorDodge(vec3 base, vec3 blend) { - return vec3(blendColorDodge(base.r,blend.r),blendColorDodge(base.g,blend.g),blendColorDodge(base.b,blend.b)); -} - -// Color Burn -float blendColorBurn(float base, float blend) { - return (blend==0.0)?blend:max((1.0-((1.0-base)/blend)),0.0); -} - -vec3 blendColorBurn(vec3 base, vec3 blend) { - return vec3(blendColorBurn(base.r,blend.r),blendColorBurn(base.g,blend.g),blendColorBurn(base.b,blend.b)); -} - -// Vivid Light -float blendVividLight(float base, float blend) { - return (blend<0.5)?blendColorBurn(base,(2.0*blend)):blendColorDodge(base,(2.0*(blend-0.5))); -} - -vec3 blendVividLight(vec3 base, vec3 blend) { - return vec3(blendVividLight(base.r,blend.r),blendVividLight(base.g,blend.g),blendVividLight(base.b,blend.b)); -} - -// Hard Mix -float blendHardMix(float base, float blend) { - return (blendVividLight(base,blend)<0.5)?0.0:1.0; -} - -vec3 blendHardMix(vec3 base, vec3 blend) { - return vec3(blendHardMix(base.r,blend.r),blendHardMix(base.g,blend.g),blendHardMix(base.b,blend.b)); -} - -// Linear Dodge -float blendLinearDodge(float base, float blend) { - // Note : Same implementation as BlendAddf - return min(base+blend,1.0); -} - -vec3 blendLinearDodge(vec3 base, vec3 blend) { - // Note : Same implementation as BlendAdd - return min(base+blend,vec3(1.0)); -} - -// Linear Burn -float blendLinearBurn(float base, float blend) { - // Note : Same implementation as BlendSubtractf - return max(base+blend-1.0,0.0); -} - -vec3 blendLinearBurn(vec3 base, vec3 blend) { - // Note : Same implementation as BlendSubtract - return max(base+blend-vec3(1.0),vec3(0.0)); -} - -// Linear Light -float blendLinearLight(float base, float blend) { - return blend<0.5?blendLinearBurn(base,(2.0*blend)):blendLinearDodge(base,(2.0*(blend-0.5))); -} - -vec3 blendLinearLight(vec3 base, vec3 blend) { - return vec3(blendLinearLight(base.r,blend.r),blendLinearLight(base.g,blend.g),blendLinearLight(base.b,blend.b)); -} - -// Lighten -float blendLighten(float base, float blend) { - return max(blend,base); -} - -vec3 blendLighten(vec3 base, vec3 blend) { - return vec3(blendLighten(base.r,blend.r),blendLighten(base.g,blend.g),blendLighten(base.b,blend.b)); -} - -// Darken -float blendDarken(float base, float blend) { - return min(blend,base); -} - -vec3 blendDarken(vec3 base, vec3 blend) { - return vec3(blendDarken(base.r,blend.r),blendDarken(base.g,blend.g),blendDarken(base.b,blend.b)); -} - -// Pin Light -float blendPinLight(float base, float blend) { - return (blend<0.5)?blendDarken(base,(2.0*blend)):blendLighten(base,(2.0*(blend-0.5))); -} - -vec3 blendPinLight(vec3 base, vec3 blend) { - return vec3(blendPinLight(base.r,blend.r),blendPinLight(base.g,blend.g),blendPinLight(base.b,blend.b)); -} - -// Reflect -float blendReflect(float base, float blend) { - return (blend==1.0)?blend:min(base*base/(1.0-blend),1.0); -} - -vec3 blendReflect(vec3 base, vec3 blend) { - return vec3(blendReflect(base.r,blend.r),blendReflect(base.g,blend.g),blendReflect(base.b,blend.b)); -} - -// Glow -vec3 blendGlow(vec3 base, vec3 blend) { - return blendReflect(blend,base); -} - -// Overlay -float blendOverlay(float base, float blend) { - return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend)); -} - -vec3 blendOverlay(vec3 base, vec3 blend) { - return vec3(blendOverlay(base.r,blend.r),blendOverlay(base.g,blend.g),blendOverlay(base.b,blend.b)); -} - -// Hard Light -vec3 blendHardLight(vec3 base, vec3 blend) { - return blendOverlay(blend,base); -} - -// Phoenix -vec3 blendPhoenix(vec3 base, vec3 blend) { - return min(base,blend)-max(base,blend)+vec3(1.0); -} - -// Normal -vec3 blendNormal(vec3 base, vec3 blend) { - return blend; -} - -// Negation -vec3 blendNegation(vec3 base, vec3 blend) { - return vec3(1.0)-abs(vec3(1.0)-base-blend); -} - -// Multiply -vec3 blendMultiply(vec3 base, vec3 blend) { - return base*blend; -} - -// Average -vec3 blendAverage(vec3 base, vec3 blend) { - return (base+blend)/2.0; -} - -// Screen -float blendScreen(float base, float blend) { - return 1.0-((1.0-base)*(1.0-blend)); -} - -vec3 blendScreen(vec3 base, vec3 blend) { - return vec3(blendScreen(base.r,blend.r),blendScreen(base.g,blend.g),blendScreen(base.b,blend.b)); -} - -// Soft Light -float blendSoftLight(float base, float blend) { - return (blend<0.5)?(2.0*base*blend+base*base*(1.0-2.0*blend)):(sqrt(base)*(2.0*blend-1.0)+2.0*base*(1.0-blend)); -} - -vec3 blendSoftLight(vec3 base, vec3 blend) { - return vec3(blendSoftLight(base.r,blend.r),blendSoftLight(base.g,blend.g),blendSoftLight(base.b,blend.b)); -} - -// Subtract -float blendSubtract(float base, float blend) { - //return max(base+blend-1.0,0.0); - return max(base-blend,0.0); -} - -vec3 blendSubtract(vec3 base, vec3 blend) { - //return max(base+blend-vec3(1.0),vec3(0.0)); - return max(base-blend,vec3(0.0)); -} - -// Exclusion -vec3 blendExclusion(vec3 base, vec3 blend) { - return base+blend-2.0*base*blend; -} - -// Difference -vec3 blendDifference(vec3 base, vec3 blend) { - return abs(base-blend); -} - -// Add -float blendAdd(float base, float blend) { - return min(base+blend,1.0); -} - -vec3 blendAdd(vec3 base, vec3 blend) { - return min(base+blend,vec3(1.0)); -} - -// Divide -float blendDivide(float base, float blend) { - return min(base/blend,1.0); -} - -vec3 blendDivide(vec3 base, vec3 blend) { - return min(base/blend,vec3(1.0)); -} - -vec3 blendColor(int mode, vec3 base, vec3 blend) { - if (mode == 0) { - return blend; - } - if (mode == 1) { - return blendAdd(base, blend); - } - if (mode == 2) { - return blendAverage(base, blend); - } - if (mode == 3) { - return blendColorBurn(base, blend); - } - if (mode == 4) { - return blendColorDodge(base, blend); - } - if (mode == 5) { - return blendDarken(base, blend); - } - if (mode == 6) { - return blendDifference(base, blend); - } - if (mode == 7) { - return blendExclusion(base, blend); - } - if (mode == 8) { - return blendGlow(base, blend); - } - if (mode == 9) { - return blendHardLight(base, blend); - } - if (mode == 10) { - return blendHardMix(base, blend); - } - if (mode == 11) { - return blendLighten(base, blend); - } - if (mode == 12) { - return blendLinearBurn(base, blend); - } - if (mode == 13) { - return blendLinearDodge(base, blend); - } - if (mode == 14) { - return blendLinearLight(base, blend); - } - if (mode == 15) { - return blendMultiply(base, blend); - } - if (mode == 16) { - return blendNegation(base, blend); - } - if (mode == 17) { - return blendNormal(base, blend); - } - if (mode == 18) { - return blendOverlay(base, blend); - } - if (mode == 19) { - return blendPhoenix(base, blend); - } - if (mode == 20) { - return blendPinLight(base, blend); - } - if (mode == 21) { - return blendReflect(base, blend); - } - if (mode == 22) { - return blendScreen(base, blend); - } - if (mode == 23) { - return blendSoftLight(base, blend); - } - if (mode == 24) { - return blendSubtract(base, blend); - } - if (mode == 25) { - return blendVividLight(base, blend); - } - if (mode == 26) { - return blendDivide(base, blend); - } - - return vec3(1.0, 0.0, 1.0); -} - -void main() { - vec4 base = texture2D(baseBuffer, vUv); - vec4 blend = texture2D(blendBuffer, vUv) * opacity; - float luma = dot(vLuma, blend.rgb); - float a = inverse == 1 ? 1.0 - luma : luma; - - // Pre-multiplied alpha - if (alpha == 1) { - blend.rgb /= (blend.a > 0.0) ? blend.a : 1.0; - } - - vec3 color = blendColor(mode, base.rgb, blend.rgb); - - // No blending, set base to black - if (mode == 0) { - base = vec4(0.0, 0.0, 0.0, 1.0); - } - - if (mask == 1) { - // Normal - if (mode == 17) { - gl_FragColor = vec4(base.r, base.g, base.b, a); - } - else { - gl_FragColor = vec4(color.r, color.g, color.b, a); - } - } - else { - gl_FragColor = mix(base, vec4(color, 1.0), blend.a); - } -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/box-blur.glsl b/src/shaders/glsl/fragment/box-blur.glsl deleted file mode 100644 index 844ed473..00000000 --- a/src/shaders/glsl/fragment/box-blur.glsl +++ /dev/null @@ -1,35 +0,0 @@ -uniform sampler2D inputTexture; -uniform float amount; -uniform vec2 resolution; - -varying vec2 vUv; - -void main() { - vec4 sum = vec4(0.0); - float h = amount / resolution.x; - float v = amount / resolution.y; - - // horizontal blur - sum += texture2D(inputTexture, vec2(vUv.x - 4.0 * h, vUv.y)) * 0.051; - sum += texture2D(inputTexture, vec2(vUv.x - 3.0 * h, vUv.y)) * 0.0918; - sum += texture2D(inputTexture, vec2(vUv.x - 2.0 * h, vUv.y)) * 0.12245; - sum += texture2D(inputTexture, vec2(vUv.x - 1.0 * h, vUv.y)) * 0.1531; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y)) * 0.1633; - sum += texture2D(inputTexture, vec2(vUv.x + 1.0 * h, vUv.y)) * 0.1531; - sum += texture2D(inputTexture, vec2(vUv.x + 2.0 * h, vUv.y)) * 0.12245; - sum += texture2D(inputTexture, vec2(vUv.x + 3.0 * h, vUv.y)) * 0.0918; - sum += texture2D(inputTexture, vec2(vUv.x + 4.0 * h, vUv.y)) * 0.051; - - // vertical blur - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y - 4.0 * v)) * 0.051; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y - 3.0 * v)) * 0.0918; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y - 2.0 * v)) * 0.12245; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y - 1.0 * v)) * 0.1531; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y)) * 0.1633; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y + 1.0 * v)) * 0.1531; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y + 2.0 * v)) * 0.12245; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y + 3.0 * v)) * 0.0918; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y + 4.0 * v)) * 0.051; - - gl_FragColor = sum * 0.5; -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/circular-blur.glsl b/src/shaders/glsl/fragment/circular-blur.glsl deleted file mode 100644 index 38e2180c..00000000 --- a/src/shaders/glsl/fragment/circular-blur.glsl +++ /dev/null @@ -1,50 +0,0 @@ -uniform sampler2D inputTexture; -uniform vec2 resolution; -uniform float amount; -varying vec2 vUv; - -float nrand(vec2 n) { - return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); -} - -vec2 rot2d(vec2 p, float a) { - vec2 sc = vec2(sin(a),cos(a)); - return vec2(dot(p, vec2(sc.y, -sc.x)), dot(p, sc.xy)); -} - -void main() { - vec2 uv = gl_FragCoord.xy / resolution.xy; - vec4 src = texture2D(inputTexture, vUv); - - float maxofs = 12.0 * amount; - const int NUM_SAMPLES = 16; - const int NUM_SAMPLES2 = NUM_SAMPLES / 2; - const float NUM_SAMPLES_F = float(NUM_SAMPLES); - const float anglestep = 6.28 / NUM_SAMPLES_F; - const float MIPBIAS = -8.0; - - float rnd = nrand(0.01 * gl_FragCoord.xy); - - vec2 ofs[NUM_SAMPLES]; - { - float angle = 3.1416 * rnd; - for (int i = 0; i < NUM_SAMPLES2; ++i) { - ofs[i] = rot2d(vec2(maxofs, 0.0), angle) / resolution.xy; - angle += anglestep; - } - } - - vec4 sum = vec4(0.0); - - for (int i = 0; i < NUM_SAMPLES2; ++i) { - sum += texture2D(inputTexture, vec2(uv.x, uv.y) + ofs[i], MIPBIAS); - } - - for (int i = 0; i < NUM_SAMPLES2; ++i) { - sum += texture2D(inputTexture, vec2(uv.x, uv.y) - ofs[i], MIPBIAS); - } - - //gl_FragColor.rgb = sum.rgb / NUM_SAMPLES_F; - //gl_FragColor.a = sum.a + src.a; - gl_FragColor = sum / NUM_SAMPLES_F; -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/color-halftone.glsl b/src/shaders/glsl/fragment/color-halftone.glsl deleted file mode 100644 index 8bfa230d..00000000 --- a/src/shaders/glsl/fragment/color-halftone.glsl +++ /dev/null @@ -1,26 +0,0 @@ -uniform sampler2D inputTexture; -uniform float angle; -uniform float scale; -uniform vec2 resolution; -varying vec2 vUv; - -float pattern(float angle) { - float s = sin(angle), c = cos(angle); - vec2 center = vec2(resolution.x * 0.5, resolution.y * 0.5); - vec2 tex = vUv * resolution - center; - vec2 point = vec2(c * tex.x - s * tex.y, s * tex.x + c * tex.y) * scale; - - return (sin(point.x) * sin(point.y)) * 4.0; -} - -void main() { - vec4 color = texture2D(inputTexture, vUv); - vec3 cmy = 1.0 - color.rgb; - float k = min(cmy.x, min(cmy.y, cmy.z)); - - cmy = (cmy - k) / (1.0 - k); - cmy = clamp(cmy * 10.0 - 3.0 + vec3(pattern(angle + 0.26179), pattern(angle + 1.30899), pattern(angle)), 0.0, 1.0); - k = clamp(k * 10.0 - 5.0 + pattern(angle + 0.78539), 0.0, 1.0); - - gl_FragColor = vec4(1.0 - cmy - k, color.a); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/color-shift.glsl b/src/shaders/glsl/fragment/color-shift.glsl deleted file mode 100644 index 9980225f..00000000 --- a/src/shaders/glsl/fragment/color-shift.glsl +++ /dev/null @@ -1,12 +0,0 @@ -uniform float time; -varying vec2 vUv; - -void main( void ) { - vec2 position = -1.0 + 2.0 * vUv; - - float red = abs(sin(position.x * position.y + time / 5.0)); - float green = abs(sin(position.x * position.y + time / 4.0)); - float blue = abs(sin(position.x * position.y + time / 3.0)); - - gl_FragColor = vec4(red, green, blue, 1.0); -} diff --git a/src/shaders/glsl/fragment/copy.glsl b/src/shaders/glsl/fragment/copy.glsl deleted file mode 100644 index 1351f91e..00000000 --- a/src/shaders/glsl/fragment/copy.glsl +++ /dev/null @@ -1,14 +0,0 @@ -uniform sampler2D inputTexture; -uniform float opacity; -uniform int alpha; -varying vec2 vUv; - -void main() { - vec4 texture = texture2D(inputTexture, vUv); - - gl_FragColor = opacity * texture; - - if (alpha == 1) { - gl_FragColor.rgb /= gl_FragColor.a + 0.00001; - } -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/distortion.glsl b/src/shaders/glsl/fragment/distortion.glsl deleted file mode 100644 index fd04201a..00000000 --- a/src/shaders/glsl/fragment/distortion.glsl +++ /dev/null @@ -1,18 +0,0 @@ -uniform sampler2D inputTexture; -uniform float time; -uniform float amount; -uniform vec2 resolution; -varying vec2 vUv; - -void main() { - vec2 uv1 = vUv; - vec2 uv = gl_FragCoord.xy/resolution.xy; - float frequency = 6.0; - float amplitude = 0.015 * amount; - float x = uv1.y * frequency + time * .7; - float y = uv1.x * frequency + time * .3; - uv1.x += cos(x+y) * amplitude * cos(y); - uv1.y += sin(x-y) * amplitude * cos(y); - - gl_FragColor = texture2D(inputTexture, uv1); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/dot-screen.glsl b/src/shaders/glsl/fragment/dot-screen.glsl deleted file mode 100644 index fc0fd0be..00000000 --- a/src/shaders/glsl/fragment/dot-screen.glsl +++ /dev/null @@ -1,25 +0,0 @@ -uniform sampler2D inputTexture; -uniform vec2 center; -uniform float angle; -uniform float scale; -uniform vec2 tSize; -varying vec2 vUv; - -float pattern() { - float s = sin(angle), c = cos(angle); - - vec2 tex = vUv * tSize - center; - vec2 point = vec2(c * tex.x - s * tex.y, s * tex.x + c * tex.y) * scale; - - float p = (sin( point.x ) * sin( point.y )) * 4.0; - - return p; -} - -void main() { - vec4 color = texture2D(inputTexture, vUv); - - float average = (color.r + color.g + color.b) / 3.0; - - gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/fxaa.glsl b/src/shaders/glsl/fragment/fxaa.glsl deleted file mode 100644 index 3615a701..00000000 --- a/src/shaders/glsl/fragment/fxaa.glsl +++ /dev/null @@ -1,56 +0,0 @@ -uniform sampler2D inputTexture; -uniform vec2 resolution; -varying vec2 vUv; - -void main() { - vec2 texcoordOffset = 1. / resolution; - vec4 vertTexcoord = vec4( vUv, 1., 1. ); - - float FXAA_SPAN_MAX = 8.0; - float FXAA_REDUCE_MUL = 1.0/8.0; - float FXAA_REDUCE_MIN = (1.0/128.0); - - vec3 rgbNW = texture2D(inputTexture, vertTexcoord.xy + (vec2(-1.0, -1.0) * texcoordOffset)).xyz; - vec3 rgbNE = texture2D(inputTexture, vertTexcoord.xy + (vec2(+1.0, -1.0) * texcoordOffset)).xyz; - vec3 rgbSW = texture2D(inputTexture, vertTexcoord.xy + (vec2(-1.0, +1.0) * texcoordOffset)).xyz; - vec3 rgbSE = texture2D(inputTexture, vertTexcoord.xy + (vec2(+1.0, +1.0) * texcoordOffset)).xyz; - vec3 rgbM = texture2D(inputTexture, vertTexcoord.xy).xyz; - - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot( rgbM, luma); - - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce); - - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * texcoordOffset; - - vec3 rgbA = (1.0/2.0) * ( - texture2D(inputTexture, vertTexcoord.xy + dir * (1.0/3.0 - 0.5)).xyz + - texture2D(inputTexture, vertTexcoord.xy + dir * (2.0/3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * ( - texture2D(inputTexture, vertTexcoord.xy + dir * (0.0/3.0 - 0.5)).xyz + - texture2D(inputTexture, vertTexcoord.xy + dir * (3.0/3.0 - 0.5)).xyz); - float lumaB = dot(rgbB, luma); - - if ((lumaB < lumaMin) || (lumaB > lumaMax)){ - gl_FragColor.xyz=rgbA; - } - else { - gl_FragColor.xyz=rgbB; - } - - gl_FragColor.a = 1.0; -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/gaussian-blur.glsl b/src/shaders/glsl/fragment/gaussian-blur.glsl deleted file mode 100644 index ceef3f63..00000000 --- a/src/shaders/glsl/fragment/gaussian-blur.glsl +++ /dev/null @@ -1,46 +0,0 @@ -uniform sampler2D inputTexture; -uniform vec2 resolution; -uniform vec2 direction; -varying vec2 vUv; - -vec4 blur13(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) { - vec4 color = vec4(0.0); - vec2 off1 = vec2(1.411764705882353) * direction; - vec2 off2 = vec2(3.2941176470588234) * direction; - vec2 off3 = vec2(5.176470588235294) * direction; - color += texture2D(image, uv) * 0.1964825501511404; - color += texture2D(image, uv + (off1 / resolution)) * 0.2969069646728344; - color += texture2D(image, uv - (off1 / resolution)) * 0.2969069646728344; - color += texture2D(image, uv + (off2 / resolution)) * 0.09447039785044732; - color += texture2D(image, uv - (off2 / resolution)) * 0.09447039785044732; - color += texture2D(image, uv + (off3 / resolution)) * 0.010381362401148057; - color += texture2D(image, uv - (off3 / resolution)) * 0.010381362401148057; - return color; -} - -vec4 blur9(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) { - vec4 color = vec4(0.0); - vec2 off1 = vec2(1.3846153846) * direction; - vec2 off2 = vec2(3.2307692308) * direction; - color += texture2D(image, uv) * 0.2270270270; - color += texture2D(image, uv + (off1 / resolution)) * 0.3162162162; - color += texture2D(image, uv - (off1 / resolution)) * 0.3162162162; - color += texture2D(image, uv + (off2 / resolution)) * 0.0702702703; - color += texture2D(image, uv - (off2 / resolution)) * 0.0702702703; - return color; -} - -vec4 blur5(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) { - vec4 color = vec4(0.0); - vec2 off1 = vec2(1.3333333333333333) * direction; - color += texture2D(image, uv) * 0.29411764705882354; - color += texture2D(image, uv + (off1 / resolution)) * 0.35294117647058826; - color += texture2D(image, uv - (off1 / resolution)) * 0.35294117647058826; - return color; -} - -void main() { - vec2 uv = vec2(gl_FragCoord.xy / resolution.xy); - - gl_FragColor = blur9(inputTexture, uv, resolution.xy, direction); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/glitch.glsl b/src/shaders/glsl/fragment/glitch.glsl deleted file mode 100644 index 9ed44657..00000000 --- a/src/shaders/glsl/fragment/glitch.glsl +++ /dev/null @@ -1,49 +0,0 @@ -uniform sampler2D inputTexture; -uniform sampler2D displacementTexture; -uniform float shift; -uniform float angle; -uniform float seed; -uniform float seed_x; -uniform float seed_y; -uniform float distortion_x; -uniform float distortion_y; -uniform float col_s; -uniform int horizontal; -uniform int vertical; -varying vec2 vUv; - -#include "../func/random.glsl" - -void main() { - vec2 p = vUv; - float xs = floor(gl_FragCoord.x / 0.5); - float ys = floor(gl_FragCoord.y / 0.5); - - // based on staffantans glitch shader for unity https://github.com/staffantan/unityglitch - vec4 normal = texture2D (displacementTexture, p * seed * seed); - if (horizontal > 0 && p.y < distortion_x + col_s && p.y > distortion_x - col_s * seed) { - if (seed_x > 0.){ - p.y = 1. - (p.y + distortion_y); - } - else { - p.y = distortion_y; - } - } - if (vertical > 0 && p.x < distortion_y + col_s && p.x > distortion_y - col_s * seed) { - if (seed_y > 0.) { - p.x = distortion_x; - } - else { - p.x = 1. - (p.x + distortion_x); - } - } - p.x += normal.x * seed_x * (seed/5.); - p.y += normal.y * seed_y * (seed/5.); - - vec2 offset = shift * vec2(cos(angle), sin(angle)); - vec4 cr = texture2D(inputTexture, p + offset); - vec4 cga = texture2D(inputTexture, p); - vec4 cb = texture2D(inputTexture, p - offset); - - gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/glow.glsl b/src/shaders/glsl/fragment/glow.glsl deleted file mode 100644 index 5f7a4047..00000000 --- a/src/shaders/glsl/fragment/glow.glsl +++ /dev/null @@ -1,36 +0,0 @@ -uniform sampler2D inputTexture; -uniform float amount; -uniform float intensity; -uniform vec2 resolution; -varying vec2 vUv; - -void main() { - vec4 src = texture2D(inputTexture, vUv); - vec4 sum = vec4(0.0); - float h = amount / resolution.x; - float v = amount / resolution.y; - - // horizontal blur - sum += texture2D(inputTexture, vec2(vUv.x - 4.0 * h, vUv.y)) * 0.051; - sum += texture2D(inputTexture, vec2(vUv.x - 3.0 * h, vUv.y)) * 0.0918; - sum += texture2D(inputTexture, vec2(vUv.x - 2.0 * h, vUv.y)) * 0.12245; - sum += texture2D(inputTexture, vec2(vUv.x - 1.0 * h, vUv.y)) * 0.1531; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y)) * 0.1633; - sum += texture2D(inputTexture, vec2(vUv.x + 1.0 * h, vUv.y)) * 0.1531; - sum += texture2D(inputTexture, vec2(vUv.x + 2.0 * h, vUv.y)) * 0.12245; - sum += texture2D(inputTexture, vec2(vUv.x + 3.0 * h, vUv.y)) * 0.0918; - sum += texture2D(inputTexture, vec2(vUv.x + 4.0 * h, vUv.y)) * 0.051; - - // vertical blur - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y - 4.0 * v)) * 0.051; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y - 3.0 * v)) * 0.0918; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y - 2.0 * v)) * 0.12245; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y - 1.0 * v)) * 0.1531; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y)) * 0.1633; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y + 1.0 * v)) * 0.1531; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y + 2.0 * v)) * 0.12245; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y + 3.0 * v)) * 0.0918; - sum += texture2D(inputTexture, vec2(vUv.x, vUv.y + 4.0 * v)) * 0.051; - - gl_FragColor = vec4(mix(src.rgb, sum.rgb, 0.6) * intensity, sum.a); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/grid.glsl b/src/shaders/glsl/fragment/grid.glsl deleted file mode 100644 index 6227c2b9..00000000 --- a/src/shaders/glsl/fragment/grid.glsl +++ /dev/null @@ -1,111 +0,0 @@ -/* - * http://madebyevan.com/shaders/grid/ - */ -#extension GL_OES_standard_derivatives : enable - -varying vec3 vPos; -uniform sampler2D inputTexture; -varying vec2 vUv; - -vec4 grid_y() { - // Pick a coordinate to visualize in a grid - float coord = vPos.y; - - // Compute anti-aliased world-space grid lines - float line = abs(fract(coord - 0.5) - 0.5) / fwidth(coord); - - // Just visualize the grid lines directly - vec4 results = vec4(vec3(1.0 - min(line, 1.0)), 1.0); - - return results; -} - -vec4 grid_xz() { - // Pick a coordinate to visualize in a grid - vec2 coord = vPos.xz; - - // Compute anti-aliased world-space grid lines - vec2 grid = abs(fract(coord - 0.5) - 0.5) / fwidth(coord); - float line = min(grid.x, grid.y); - - // Just visualize the grid lines directly - vec4 results = vec4(vec3(1.0 - min(line, 1.0)), 1.0); - - return results; -} - -vec4 grid_xyz() { - // Pick a coordinate to visualize in a grid - vec3 coord = vPos.xyz; - - // Compute anti-aliased world-space grid lines - vec3 grid = abs(fract(coord - 0.5) - 0.5) / fwidth(coord); - float line = min(min(grid.x, grid.y), grid.z); - - // Just visualize the grid lines directly - vec4 results = vec4(vec3(1.0 - min(line, 1.0)), 1.0); - - return results; -} - -vec4 grid_length_xz() { - // Pick a coordinate to visualize in a grid - float coord = length(vPos.xz); - - // Compute anti-aliased world-space grid lines - float line = abs(fract(coord - 0.5) - 0.5) / fwidth(coord); - - // Just visualize the grid lines directly - vec4 results = vec4(vec3(1.0 - min(line, 1.0)), 1.0); - - return results; -} - -vec4 grid_web() { - // Pick a coordinate to visualize in a grid - const float pi = 3.141592653589793; - const float scale = 10.0; - vec2 coord = vec2(length(vPos.xz), atan(vPos.x, vPos.z) * scale / pi); - - // Handling the wrap-around is tricky in this case. The function atan() - // is not continuous and jumps when it wraps from -pi to pi. The screen- - // space partial derivative will be huge along that boundary. To avoid - // this, compute another coordinate that places the jump at a different - // place, then use the coordinate where the jump is farther away. - // - // When doing this, make sure to always evaluate both fwidth() calls even - // though we only use one. All fragment shader threads in the thread group - // actually share a single instruction pointer, so threads that diverge - // down different conditional branches actually cause both branches to be - // serialized one after the other. Calling fwidth() from a thread next to - // an inactive thread ends up reading inactive registers with old values - // in them and you get an undefined value. - // - // The conditional uses +/-scale/2 since coord.y has a range of +/-scale. - // The jump is at +/-scale for coord and at 0 for wrapped. - vec2 wrapped = vec2(coord.x, fract(coord.y / (2.0 * scale)) * (2.0 * scale)); - vec2 coordWidth = fwidth(coord); - vec2 wrappedWidth = fwidth(wrapped); - vec2 width = coord.y < -scale * 0.5 || coord.y > scale * 0.5 ? wrappedWidth : coordWidth; - - // Compute anti-aliased world-space grid lines - vec2 grid = abs(fract(coord - 0.5) - 0.5) / width; - float line = min(grid.x, grid.y); - - // Just visualize the grid lines directly - vec4 results = vec4(vec3(1.0 - min(line, 1.0)), 1.0); - - return results; -} - -void main() { - // Pick a coordinate to visualize in a grid - vec2 coord = vPos.xz; - - // Compute anti-aliased world-space grid lines - vec2 grid = abs(fract(coord - 0.5) - 0.5) / fwidth(coord); - float line = min(grid.x, grid.y); - - // Just visualize the grid lines directly - gl_FragColor = vec4(vec3(1.0 - min(line, 1.0)), 1.0); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/hatch.glsl b/src/shaders/glsl/fragment/hatch.glsl deleted file mode 100644 index fcccfebe..00000000 --- a/src/shaders/glsl/fragment/hatch.glsl +++ /dev/null @@ -1,39 +0,0 @@ -uniform vec3 uBaseColor; -uniform vec3 uLineColor1; -uniform vec3 uLineColor2; -uniform vec3 uLineColor3; -uniform vec3 uLineColor4; -uniform vec3 uDirLightPos; -uniform vec3 uDirLightColor; -uniform vec3 uAmbientLightColor; -varying vec3 vNormal; - -void main() { - float directionalLightWeighting = max( dot( normalize(vNormal), uDirLightPos ), 0.0); - vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting; - gl_FragColor = vec4( uBaseColor, 1.0 ); - - if ( length(lightWeighting) < 1.00 ) { - if ( mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) { - gl_FragColor = vec4( uLineColor1, 1.0 ); - } - } - - if ( length(lightWeighting) < 0.75 ) { - if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) { - gl_FragColor = vec4( uLineColor2, 1.0 ); - } - } - - if ( length(lightWeighting) < 0.50 ) { - if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) { - gl_FragColor = vec4( uLineColor3, 1.0 ); - } - } - - if ( length(lightWeighting) < 0.3465 ) { - if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) { - gl_FragColor = vec4( uLineColor4, 1.0 ); - } - } -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/hexagon.glsl b/src/shaders/glsl/fragment/hexagon.glsl deleted file mode 100644 index 501b2390..00000000 --- a/src/shaders/glsl/fragment/hexagon.glsl +++ /dev/null @@ -1,54 +0,0 @@ -uniform sampler2D inputTexture; -uniform vec2 center; -uniform float size; -uniform vec2 resolution; -varying vec2 vUv; - -void main() { - vec2 tex = (vUv * resolution - center) / size; - tex.y /= 0.866025404; - tex.x -= tex.y * 0.5; - - vec2 a; - if (tex.x + tex.y - floor(tex.x) - floor(tex.y) < 1.0) { - a = vec2(floor(tex.x), floor(tex.y)); - } - else { - a = vec2(ceil(tex.x), ceil(tex.y)); - } - - vec2 b = vec2(ceil(tex.x), floor(tex.y)); - vec2 c = vec2(floor(tex.x), ceil(tex.y)); - - vec3 TEX = vec3(tex.x, tex.y, 1.0 - tex.x - tex.y); - vec3 A = vec3(a.x, a.y, 1.0 - a.x - a.y); - vec3 B = vec3(b.x, b.y, 1.0 - b.x - b.y); - vec3 C = vec3(c.x, c.y, 1.0 - c.x - c.y); - - float alen = length(TEX - A); - float blen = length(TEX - B); - float clen = length(TEX - C); - - vec2 choice; - if (alen < blen) { - if (alen < clen) { - choice = a; - } - else { - choice = c; - } - } else { - if (blen < clen) { - choice = b; - } - else { - choice = c; - } - } - - choice.x += choice.y * 0.5; - choice.y *= 0.866025404; - choice *= size / resolution; - - gl_FragColor = texture2D(inputTexture, choice + center / resolution); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/kaleidoscope.glsl b/src/shaders/glsl/fragment/kaleidoscope.glsl deleted file mode 100644 index d103e92e..00000000 --- a/src/shaders/glsl/fragment/kaleidoscope.glsl +++ /dev/null @@ -1,16 +0,0 @@ -uniform sampler2D inputTexture; -uniform float sides; -uniform float angle; -varying vec2 vUv; - -void main() { - vec2 p = vUv - 0.5; - float r = length(p); - float a = atan(p.y, p.x) + angle; - float tau = 2. * 3.1416; - a = mod(a, tau/sides); - a = abs(a - tau/sides/2.); - p = r * vec2(cos(a), sin(a)); - - gl_FragColor = texture2D(inputTexture, p + 0.5); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/led.glsl b/src/shaders/glsl/fragment/led.glsl deleted file mode 100644 index 7cc17f7d..00000000 --- a/src/shaders/glsl/fragment/led.glsl +++ /dev/null @@ -1,18 +0,0 @@ -uniform sampler2D inputTexture; -uniform float spacing; -uniform float size; -uniform float blur; -uniform vec2 resolution; -varying vec2 vUv; - -void main() { - vec2 count = vec2(resolution / spacing); - vec2 p = floor(vUv * count) / count; - - vec4 color = texture2D(inputTexture, p); - - vec2 pos = mod(gl_FragCoord.xy, vec2(spacing)) - vec2(spacing / 2.0); - float dist_squared = dot(pos, pos); - - gl_FragColor = mix(color, vec4(0.0), smoothstep(size, size + blur, dist_squared)); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/lens-blur.glsl b/src/shaders/glsl/fragment/lens-blur.glsl deleted file mode 100644 index aff826c1..00000000 --- a/src/shaders/glsl/fragment/lens-blur.glsl +++ /dev/null @@ -1,43 +0,0 @@ -uniform sampler2D inputTexture; -uniform sampler2D extraBuffer; -uniform vec2 delta0; -uniform vec2 delta1; -uniform float power; -uniform int pass; -varying vec2 vUv; - -#include "../func/random.glsl" - -vec4 blur(vec2 delta) { - float offset = random(delta); - vec4 color = vec4(0.0); - float total = 0.0; - - for (float t = 0.0; t <= 30.0; t++) { - float percent = (t + offset) / 30.0; - color += texture2D(inputTexture, vUv + delta * percent); - total += 1.0; - } - - return color / total; -} - -void main() { - if (pass == 0) { - vec4 color = texture2D(inputTexture, vUv); - gl_FragColor = pow(color, vec4(power)); - } - - if (pass == 1) { - gl_FragColor = blur(delta0); - } - - if (pass == 2) { - gl_FragColor = (blur(delta0) + blur(delta1)) * 0.5; - } - - if (pass == 3) { - vec4 color = (blur(delta0) + 2.0 * texture2D(extraBuffer, vUv)) / 3.0; - gl_FragColor = pow(color, vec4(power)); - } -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/luminance.glsl b/src/shaders/glsl/fragment/luminance.glsl deleted file mode 100644 index 5d63ce8c..00000000 --- a/src/shaders/glsl/fragment/luminance.glsl +++ /dev/null @@ -1,14 +0,0 @@ -uniform sampler2D inputTexture; -uniform float amount; -varying vec2 vUv; - -const vec3 vLuma = vec3(0.2126, 0.7152, 0.0722); - -void main(void) { - vec4 src = texture2D(inputTexture, vUv); - float luma = dot(vLuma, src.rgb); - - luma = max(0.0, luma - amount); - - gl_FragColor = src * sign(luma); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/mirror.glsl b/src/shaders/glsl/fragment/mirror.glsl deleted file mode 100644 index bc73b76a..00000000 --- a/src/shaders/glsl/fragment/mirror.glsl +++ /dev/null @@ -1,24 +0,0 @@ -uniform sampler2D inputTexture; -uniform int side; -varying vec2 vUv; - -void main() { - vec2 p = vUv; - - if (side == 0) { - if (p.x > 0.5) p.x = 1.0 - p.x; - } - else if (side == 1) { - if (p.x < 0.5) p.x = 1.0 - p.x; - } - else if (side == 2) { - if (p.y < 0.5) p.y = 1.0 - p.y; - } - else if (side == 3) { - if (p.y > 0.5) p.y = 1.0 - p.y; - } - - vec4 color = texture2D(inputTexture, p); - - gl_FragColor = color; -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/pixelate.glsl b/src/shaders/glsl/fragment/pixelate.glsl deleted file mode 100644 index f29a3a12..00000000 --- a/src/shaders/glsl/fragment/pixelate.glsl +++ /dev/null @@ -1,14 +0,0 @@ -uniform sampler2D inputTexture; -uniform float size; -uniform vec2 resolution; -varying vec2 vUv; - -void main() { - float d = size / resolution.x; - float u = floor(vUv.x / d) * d; - - d = size / resolution.y; - float v = floor(vUv.y / d) * d; - - gl_FragColor = texture2D(inputTexture, vec2(u, v)); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/point.glsl b/src/shaders/glsl/fragment/point.glsl deleted file mode 100644 index bd3da5b2..00000000 --- a/src/shaders/glsl/fragment/point.glsl +++ /dev/null @@ -1,14 +0,0 @@ -uniform vec3 color; -uniform sampler2D inputTexture; -uniform float opacity; -varying vec3 vColor; - -void main() { - gl_FragColor = vec4(color * vColor, 1.0) * texture2D(inputTexture, gl_PointCoord); - - if (gl_FragColor.a < ALPHATEST) { - discard; - } - - gl_FragColor.a = gl_FragColor.a * opacity; -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/rgb-shift.glsl b/src/shaders/glsl/fragment/rgb-shift.glsl deleted file mode 100644 index b085847b..00000000 --- a/src/shaders/glsl/fragment/rgb-shift.glsl +++ /dev/null @@ -1,14 +0,0 @@ -uniform sampler2D inputTexture; -uniform float amount; -uniform float angle; -varying vec2 vUv; - -void main() { - vec2 offset = amount * vec2(cos(angle), sin(angle)); - vec4 cr = texture2D(inputTexture, vUv + offset); - vec4 cg = texture2D(inputTexture, vUv); - vec4 cb = texture2D(inputTexture, vUv - offset); - float opacity = cr.a + cg.a + cb.a; - - gl_FragColor = vec4(cr.r, cg.g, cb.b, opacity); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/ripple.glsl b/src/shaders/glsl/fragment/ripple.glsl deleted file mode 100644 index b608057d..00000000 --- a/src/shaders/glsl/fragment/ripple.glsl +++ /dev/null @@ -1,17 +0,0 @@ -uniform float time; -varying vec2 vUv; -varying float vNoise; - -const vec3 black = vec3(0.0, 0.0, 0.0); - -vec3 hsv2rgb(vec3 c) { - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); -} - -void main() { - vec3 c = hsv2rgb(vec3((vUv.x + time, 0.8, 0.7))); - - gl_FragColor = vec4(mix(c, black, -vNoise), 1.0); -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/triangle-blur.glsl b/src/shaders/glsl/fragment/triangle-blur.glsl deleted file mode 100644 index 8a25983e..00000000 --- a/src/shaders/glsl/fragment/triangle-blur.glsl +++ /dev/null @@ -1,21 +0,0 @@ -uniform sampler2D inputTexture; -uniform vec2 delta; -varying vec2 vUv; - -#include "../func/random.glsl" - -void main() { - vec4 color = vec4(0.0); - float total = 0.0; - float offset = random(vUv); - - for (float t = -30.0; t <= 30.0; t++) { - float percent = (t + offset - 0.5) / 30.0; - float weight = 1.0 - abs(percent); - - color += texture2D(inputTexture, vUv + delta * percent) * weight; - total += weight; - } - - gl_FragColor = color / total; -} \ No newline at end of file diff --git a/src/shaders/glsl/fragment/zoom-blur.glsl b/src/shaders/glsl/fragment/zoom-blur.glsl deleted file mode 100644 index 0b0b570f..00000000 --- a/src/shaders/glsl/fragment/zoom-blur.glsl +++ /dev/null @@ -1,25 +0,0 @@ -uniform sampler2D inputTexture; -uniform vec2 center; -uniform float amount; -uniform vec2 resolution; -varying vec2 vUv; - -#include "../func/random.glsl" - -void main() { - vec4 color = vec4(0.0); - float total = 0.0; - vec2 c = center * resolution; - vec2 toCenter = c - vUv * resolution; - float offset = random(vUv); - - for (float t = 0.0; t <= 40.0; t++) { - float percent = (t) / 40.0; - float weight = 4.0 * (percent - percent * percent); - vec4 s = texture2D(inputTexture, vUv + toCenter * percent * amount / resolution); - color += s * weight; - total += weight; - } - - gl_FragColor = color / total; -} diff --git a/src/shaders/glsl/func/classic-noise-2d.glsl b/src/shaders/glsl/func/classic-noise-2d.glsl deleted file mode 100644 index 3ca11d88..00000000 --- a/src/shaders/glsl/func/classic-noise-2d.glsl +++ /dev/null @@ -1,113 +0,0 @@ -// -// GLSL textureless classic 2D noise "cnoise", -// with an RSL-style periodic variant "pnoise". -// Author: Stefan Gustavson (stefan.gustavson@liu.se) -// Version: 2011-08-22 -// -// Many thanks to Ian McEwan of Ashima Arts for the -// ideas for permutation and gradient selection. -// -// Copyright (c) 2011 Stefan Gustavson. All rights reserved. -// Distributed under the MIT license. See LICENSE file. -// https://github.com/ashima/webgl-noise -// - -vec4 mod289(vec4 x) -{ - return x - floor(x * (1.0 / 289.0)) * 289.0; -} - -vec4 permute(vec4 x) -{ - return mod289(((x*34.0)+1.0)*x); -} - -vec4 taylorInvSqrt(vec4 r) -{ - return 1.79284291400159 - 0.85373472095314 * r; -} - -vec2 fade(vec2 t) { - return t*t*t*(t*(t*6.0-15.0)+10.0); -} - -// Classic Perlin noise -float cnoise(vec2 P) -{ - vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); - vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); - Pi = mod289(Pi);// To avoid truncation effects in permutation - vec4 ix = Pi.xzxz; - vec4 iy = Pi.yyww; - vec4 fx = Pf.xzxz; - vec4 fy = Pf.yyww; - - vec4 i = permute(permute(ix) + iy); - - vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0; - vec4 gy = abs(gx) - 0.5; - vec4 tx = floor(gx + 0.5); - gx = gx - tx; - - vec2 g00 = vec2(gx.x, gy.x); - vec2 g10 = vec2(gx.y, gy.y); - vec2 g01 = vec2(gx.z, gy.z); - vec2 g11 = vec2(gx.w, gy.w); - - vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); - g00 *= norm.x; - g01 *= norm.y; - g10 *= norm.z; - g11 *= norm.w; - - float n00 = dot(g00, vec2(fx.x, fy.x)); - float n10 = dot(g10, vec2(fx.y, fy.y)); - float n01 = dot(g01, vec2(fx.z, fy.z)); - float n11 = dot(g11, vec2(fx.w, fy.w)); - - vec2 fade_xy = fade(Pf.xy); - vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); - float n_xy = mix(n_x.x, n_x.y, fade_xy.y); - return 2.3 * n_xy; -} - -// Classic Perlin noise, periodic variant -float pnoise(vec2 P, vec2 rep) -{ - vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); - vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); - Pi = mod(Pi, rep.xyxy);// To create noise with explicit period - Pi = mod289(Pi);// To avoid truncation effects in permutation - vec4 ix = Pi.xzxz; - vec4 iy = Pi.yyww; - vec4 fx = Pf.xzxz; - vec4 fy = Pf.yyww; - - vec4 i = permute(permute(ix) + iy); - - vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0; - vec4 gy = abs(gx) - 0.5; - vec4 tx = floor(gx + 0.5); - gx = gx - tx; - - vec2 g00 = vec2(gx.x, gy.x); - vec2 g10 = vec2(gx.y, gy.y); - vec2 g01 = vec2(gx.z, gy.z); - vec2 g11 = vec2(gx.w, gy.w); - - vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); - g00 *= norm.x; - g01 *= norm.y; - g10 *= norm.z; - g11 *= norm.w; - - float n00 = dot(g00, vec2(fx.x, fy.x)); - float n10 = dot(g10, vec2(fx.y, fy.y)); - float n01 = dot(g01, vec2(fx.z, fy.z)); - float n11 = dot(g11, vec2(fx.w, fy.w)); - - vec2 fade_xy = fade(Pf.xy); - vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); - float n_xy = mix(n_x.x, n_x.y, fade_xy.y); - return 2.3 * n_xy; -} diff --git a/src/shaders/glsl/func/classic-noise-3d.glsl b/src/shaders/glsl/func/classic-noise-3d.glsl deleted file mode 100644 index 1c7f9b6d..00000000 --- a/src/shaders/glsl/func/classic-noise-3d.glsl +++ /dev/null @@ -1,177 +0,0 @@ -// -// GLSL textureless classic 3D noise "cnoise", -// with an RSL-style periodic variant "pnoise". -// Author: Stefan Gustavson (stefan.gustavson@liu.se) -// Version: 2011-10-11 -// -// Many thanks to Ian McEwan of Ashima Arts for the -// ideas for permutation and gradient selection. -// -// Copyright (c) 2011 Stefan Gustavson. All rights reserved. -// Distributed under the MIT license. See LICENSE file. -// https://github.com/ashima/webgl-noise -// - -vec3 mod289(vec3 x) -{ - return x - floor(x * (1.0 / 289.0)) * 289.0; -} - -vec4 mod289(vec4 x) -{ - return x - floor(x * (1.0 / 289.0)) * 289.0; -} - -vec4 permute(vec4 x) -{ - return mod289(((x*34.0)+1.0)*x); -} - -vec4 taylorInvSqrt(vec4 r) -{ - return 1.79284291400159 - 0.85373472095314 * r; -} - -vec3 fade(vec3 t) { - return t*t*t*(t*(t*6.0-15.0)+10.0); -} - -// Classic Perlin noise -float cnoise(vec3 P) -{ - vec3 Pi0 = floor(P);// Integer part for indexing - vec3 Pi1 = Pi0 + vec3(1.0);// Integer part + 1 - Pi0 = mod289(Pi0); - Pi1 = mod289(Pi1); - vec3 Pf0 = fract(P);// Fractional part for interpolation - vec3 Pf1 = Pf0 - vec3(1.0);// Fractional part - 1.0 - vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); - vec4 iy = vec4(Pi0.yy, Pi1.yy); - vec4 iz0 = Pi0.zzzz; - vec4 iz1 = Pi1.zzzz; - - vec4 ixy = permute(permute(ix) + iy); - vec4 ixy0 = permute(ixy + iz0); - vec4 ixy1 = permute(ixy + iz1); - - vec4 gx0 = ixy0 * (1.0 / 7.0); - vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5; - gx0 = fract(gx0); - vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); - vec4 sz0 = step(gz0, vec4(0.0)); - gx0 -= sz0 * (step(0.0, gx0) - 0.5); - gy0 -= sz0 * (step(0.0, gy0) - 0.5); - - vec4 gx1 = ixy1 * (1.0 / 7.0); - vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5; - gx1 = fract(gx1); - vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); - vec4 sz1 = step(gz1, vec4(0.0)); - gx1 -= sz1 * (step(0.0, gx1) - 0.5); - gy1 -= sz1 * (step(0.0, gy1) - 0.5); - - vec3 g000 = vec3(gx0.x, gy0.x, gz0.x); - vec3 g100 = vec3(gx0.y, gy0.y, gz0.y); - vec3 g010 = vec3(gx0.z, gy0.z, gz0.z); - vec3 g110 = vec3(gx0.w, gy0.w, gz0.w); - vec3 g001 = vec3(gx1.x, gy1.x, gz1.x); - vec3 g101 = vec3(gx1.y, gy1.y, gz1.y); - vec3 g011 = vec3(gx1.z, gy1.z, gz1.z); - vec3 g111 = vec3(gx1.w, gy1.w, gz1.w); - - vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); - g000 *= norm0.x; - g010 *= norm0.y; - g100 *= norm0.z; - g110 *= norm0.w; - vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); - g001 *= norm1.x; - g011 *= norm1.y; - g101 *= norm1.z; - g111 *= norm1.w; - - float n000 = dot(g000, Pf0); - float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); - float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); - float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); - float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); - float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); - float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); - float n111 = dot(g111, Pf1); - - vec3 fade_xyz = fade(Pf0); - vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); - vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); - float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); - return 2.2 * n_xyz; -} - -// Classic Perlin noise, periodic variant -float pnoise(vec3 P, vec3 rep) -{ - vec3 Pi0 = mod(floor(P), rep);// Integer part, modulo period - vec3 Pi1 = mod(Pi0 + vec3(1.0), rep);// Integer part + 1, mod period - Pi0 = mod289(Pi0); - Pi1 = mod289(Pi1); - vec3 Pf0 = fract(P);// Fractional part for interpolation - vec3 Pf1 = Pf0 - vec3(1.0);// Fractional part - 1.0 - vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); - vec4 iy = vec4(Pi0.yy, Pi1.yy); - vec4 iz0 = Pi0.zzzz; - vec4 iz1 = Pi1.zzzz; - - vec4 ixy = permute(permute(ix) + iy); - vec4 ixy0 = permute(ixy + iz0); - vec4 ixy1 = permute(ixy + iz1); - - vec4 gx0 = ixy0 * (1.0 / 7.0); - vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5; - gx0 = fract(gx0); - vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); - vec4 sz0 = step(gz0, vec4(0.0)); - gx0 -= sz0 * (step(0.0, gx0) - 0.5); - gy0 -= sz0 * (step(0.0, gy0) - 0.5); - - vec4 gx1 = ixy1 * (1.0 / 7.0); - vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5; - gx1 = fract(gx1); - vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); - vec4 sz1 = step(gz1, vec4(0.0)); - gx1 -= sz1 * (step(0.0, gx1) - 0.5); - gy1 -= sz1 * (step(0.0, gy1) - 0.5); - - vec3 g000 = vec3(gx0.x, gy0.x, gz0.x); - vec3 g100 = vec3(gx0.y, gy0.y, gz0.y); - vec3 g010 = vec3(gx0.z, gy0.z, gz0.z); - vec3 g110 = vec3(gx0.w, gy0.w, gz0.w); - vec3 g001 = vec3(gx1.x, gy1.x, gz1.x); - vec3 g101 = vec3(gx1.y, gy1.y, gz1.y); - vec3 g011 = vec3(gx1.z, gy1.z, gz1.z); - vec3 g111 = vec3(gx1.w, gy1.w, gz1.w); - - vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); - g000 *= norm0.x; - g010 *= norm0.y; - g100 *= norm0.z; - g110 *= norm0.w; - vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); - g001 *= norm1.x; - g011 *= norm1.y; - g101 *= norm1.z; - g111 *= norm1.w; - - float n000 = dot(g000, Pf0); - float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); - float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); - float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); - float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); - float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); - float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); - float n111 = dot(g111, Pf1); - - vec3 fade_xyz = fade(Pf0); - vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); - vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); - float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); - return 2.2 * n_xyz; -} diff --git a/src/shaders/glsl/func/classic-noise-4d.glsl b/src/shaders/glsl/func/classic-noise-4d.glsl deleted file mode 100644 index ee15d8f4..00000000 --- a/src/shaders/glsl/func/classic-noise-4d.glsl +++ /dev/null @@ -1,302 +0,0 @@ -// -// GLSL textureless classic 4D noise "cnoise", -// with an RSL-style periodic variant "pnoise". -// Author: Stefan Gustavson (stefan.gustavson@liu.se) -// Version: 2011-08-22 -// -// Many thanks to Ian McEwan of Ashima Arts for the -// ideas for permutation and gradient selection. -// -// Copyright (c) 2011 Stefan Gustavson. All rights reserved. -// Distributed under the MIT license. See LICENSE file. -// https://github.com/ashima/webgl-noise -// - -vec4 mod289(vec4 x) -{ - return x - floor(x * (1.0 / 289.0)) * 289.0; -} - -vec4 permute(vec4 x) -{ - return mod289(((x*34.0)+1.0)*x); -} - -vec4 taylorInvSqrt(vec4 r) -{ - return 1.79284291400159 - 0.85373472095314 * r; -} - -vec4 fade(vec4 t) { - return t*t*t*(t*(t*6.0-15.0)+10.0); -} - -// Classic Perlin noise -float cnoise(vec4 P) -{ - vec4 Pi0 = floor(P);// Integer part for indexing - vec4 Pi1 = Pi0 + 1.0;// Integer part + 1 - Pi0 = mod289(Pi0); - Pi1 = mod289(Pi1); - vec4 Pf0 = fract(P);// Fractional part for interpolation - vec4 Pf1 = Pf0 - 1.0;// Fractional part - 1.0 - vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); - vec4 iy = vec4(Pi0.yy, Pi1.yy); - vec4 iz0 = vec4(Pi0.zzzz); - vec4 iz1 = vec4(Pi1.zzzz); - vec4 iw0 = vec4(Pi0.wwww); - vec4 iw1 = vec4(Pi1.wwww); - - vec4 ixy = permute(permute(ix) + iy); - vec4 ixy0 = permute(ixy + iz0); - vec4 ixy1 = permute(ixy + iz1); - vec4 ixy00 = permute(ixy0 + iw0); - vec4 ixy01 = permute(ixy0 + iw1); - vec4 ixy10 = permute(ixy1 + iw0); - vec4 ixy11 = permute(ixy1 + iw1); - - vec4 gx00 = ixy00 * (1.0 / 7.0); - vec4 gy00 = floor(gx00) * (1.0 / 7.0); - vec4 gz00 = floor(gy00) * (1.0 / 6.0); - gx00 = fract(gx00) - 0.5; - gy00 = fract(gy00) - 0.5; - gz00 = fract(gz00) - 0.5; - vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00); - vec4 sw00 = step(gw00, vec4(0.0)); - gx00 -= sw00 * (step(0.0, gx00) - 0.5); - gy00 -= sw00 * (step(0.0, gy00) - 0.5); - - vec4 gx01 = ixy01 * (1.0 / 7.0); - vec4 gy01 = floor(gx01) * (1.0 / 7.0); - vec4 gz01 = floor(gy01) * (1.0 / 6.0); - gx01 = fract(gx01) - 0.5; - gy01 = fract(gy01) - 0.5; - gz01 = fract(gz01) - 0.5; - vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01); - vec4 sw01 = step(gw01, vec4(0.0)); - gx01 -= sw01 * (step(0.0, gx01) - 0.5); - gy01 -= sw01 * (step(0.0, gy01) - 0.5); - - vec4 gx10 = ixy10 * (1.0 / 7.0); - vec4 gy10 = floor(gx10) * (1.0 / 7.0); - vec4 gz10 = floor(gy10) * (1.0 / 6.0); - gx10 = fract(gx10) - 0.5; - gy10 = fract(gy10) - 0.5; - gz10 = fract(gz10) - 0.5; - vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10); - vec4 sw10 = step(gw10, vec4(0.0)); - gx10 -= sw10 * (step(0.0, gx10) - 0.5); - gy10 -= sw10 * (step(0.0, gy10) - 0.5); - - vec4 gx11 = ixy11 * (1.0 / 7.0); - vec4 gy11 = floor(gx11) * (1.0 / 7.0); - vec4 gz11 = floor(gy11) * (1.0 / 6.0); - gx11 = fract(gx11) - 0.5; - gy11 = fract(gy11) - 0.5; - gz11 = fract(gz11) - 0.5; - vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11); - vec4 sw11 = step(gw11, vec4(0.0)); - gx11 -= sw11 * (step(0.0, gx11) - 0.5); - gy11 -= sw11 * (step(0.0, gy11) - 0.5); - - vec4 g0000 = vec4(gx00.x, gy00.x, gz00.x, gw00.x); - vec4 g1000 = vec4(gx00.y, gy00.y, gz00.y, gw00.y); - vec4 g0100 = vec4(gx00.z, gy00.z, gz00.z, gw00.z); - vec4 g1100 = vec4(gx00.w, gy00.w, gz00.w, gw00.w); - vec4 g0010 = vec4(gx10.x, gy10.x, gz10.x, gw10.x); - vec4 g1010 = vec4(gx10.y, gy10.y, gz10.y, gw10.y); - vec4 g0110 = vec4(gx10.z, gy10.z, gz10.z, gw10.z); - vec4 g1110 = vec4(gx10.w, gy10.w, gz10.w, gw10.w); - vec4 g0001 = vec4(gx01.x, gy01.x, gz01.x, gw01.x); - vec4 g1001 = vec4(gx01.y, gy01.y, gz01.y, gw01.y); - vec4 g0101 = vec4(gx01.z, gy01.z, gz01.z, gw01.z); - vec4 g1101 = vec4(gx01.w, gy01.w, gz01.w, gw01.w); - vec4 g0011 = vec4(gx11.x, gy11.x, gz11.x, gw11.x); - vec4 g1011 = vec4(gx11.y, gy11.y, gz11.y, gw11.y); - vec4 g0111 = vec4(gx11.z, gy11.z, gz11.z, gw11.z); - vec4 g1111 = vec4(gx11.w, gy11.w, gz11.w, gw11.w); - - vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); - g0000 *= norm00.x; - g0100 *= norm00.y; - g1000 *= norm00.z; - g1100 *= norm00.w; - - vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); - g0001 *= norm01.x; - g0101 *= norm01.y; - g1001 *= norm01.z; - g1101 *= norm01.w; - - vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); - g0010 *= norm10.x; - g0110 *= norm10.y; - g1010 *= norm10.z; - g1110 *= norm10.w; - - vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); - g0011 *= norm11.x; - g0111 *= norm11.y; - g1011 *= norm11.z; - g1111 *= norm11.w; - - float n0000 = dot(g0000, Pf0); - float n1000 = dot(g1000, vec4(Pf1.x, Pf0.yzw)); - float n0100 = dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw)); - float n1100 = dot(g1100, vec4(Pf1.xy, Pf0.zw)); - float n0010 = dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w)); - float n1010 = dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); - float n0110 = dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w)); - float n1110 = dot(g1110, vec4(Pf1.xyz, Pf0.w)); - float n0001 = dot(g0001, vec4(Pf0.xyz, Pf1.w)); - float n1001 = dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w)); - float n0101 = dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); - float n1101 = dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w)); - float n0011 = dot(g0011, vec4(Pf0.xy, Pf1.zw)); - float n1011 = dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw)); - float n0111 = dot(g0111, vec4(Pf0.x, Pf1.yzw)); - float n1111 = dot(g1111, Pf1); - - vec4 fade_xyzw = fade(Pf0); - vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w); - vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w); - vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z); - vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y); - float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); - return 2.2 * n_xyzw; -} - -// Classic Perlin noise, periodic version -float pnoise(vec4 P, vec4 rep) -{ - vec4 Pi0 = mod(floor(P), rep);// Integer part modulo rep - vec4 Pi1 = mod(Pi0 + 1.0, rep);// Integer part + 1 mod rep - Pi0 = mod289(Pi0); - Pi1 = mod289(Pi1); - vec4 Pf0 = fract(P);// Fractional part for interpolation - vec4 Pf1 = Pf0 - 1.0;// Fractional part - 1.0 - vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); - vec4 iy = vec4(Pi0.yy, Pi1.yy); - vec4 iz0 = vec4(Pi0.zzzz); - vec4 iz1 = vec4(Pi1.zzzz); - vec4 iw0 = vec4(Pi0.wwww); - vec4 iw1 = vec4(Pi1.wwww); - - vec4 ixy = permute(permute(ix) + iy); - vec4 ixy0 = permute(ixy + iz0); - vec4 ixy1 = permute(ixy + iz1); - vec4 ixy00 = permute(ixy0 + iw0); - vec4 ixy01 = permute(ixy0 + iw1); - vec4 ixy10 = permute(ixy1 + iw0); - vec4 ixy11 = permute(ixy1 + iw1); - - vec4 gx00 = ixy00 * (1.0 / 7.0); - vec4 gy00 = floor(gx00) * (1.0 / 7.0); - vec4 gz00 = floor(gy00) * (1.0 / 6.0); - gx00 = fract(gx00) - 0.5; - gy00 = fract(gy00) - 0.5; - gz00 = fract(gz00) - 0.5; - vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00); - vec4 sw00 = step(gw00, vec4(0.0)); - gx00 -= sw00 * (step(0.0, gx00) - 0.5); - gy00 -= sw00 * (step(0.0, gy00) - 0.5); - - vec4 gx01 = ixy01 * (1.0 / 7.0); - vec4 gy01 = floor(gx01) * (1.0 / 7.0); - vec4 gz01 = floor(gy01) * (1.0 / 6.0); - gx01 = fract(gx01) - 0.5; - gy01 = fract(gy01) - 0.5; - gz01 = fract(gz01) - 0.5; - vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01); - vec4 sw01 = step(gw01, vec4(0.0)); - gx01 -= sw01 * (step(0.0, gx01) - 0.5); - gy01 -= sw01 * (step(0.0, gy01) - 0.5); - - vec4 gx10 = ixy10 * (1.0 / 7.0); - vec4 gy10 = floor(gx10) * (1.0 / 7.0); - vec4 gz10 = floor(gy10) * (1.0 / 6.0); - gx10 = fract(gx10) - 0.5; - gy10 = fract(gy10) - 0.5; - gz10 = fract(gz10) - 0.5; - vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10); - vec4 sw10 = step(gw10, vec4(0.0)); - gx10 -= sw10 * (step(0.0, gx10) - 0.5); - gy10 -= sw10 * (step(0.0, gy10) - 0.5); - - vec4 gx11 = ixy11 * (1.0 / 7.0); - vec4 gy11 = floor(gx11) * (1.0 / 7.0); - vec4 gz11 = floor(gy11) * (1.0 / 6.0); - gx11 = fract(gx11) - 0.5; - gy11 = fract(gy11) - 0.5; - gz11 = fract(gz11) - 0.5; - vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11); - vec4 sw11 = step(gw11, vec4(0.0)); - gx11 -= sw11 * (step(0.0, gx11) - 0.5); - gy11 -= sw11 * (step(0.0, gy11) - 0.5); - - vec4 g0000 = vec4(gx00.x, gy00.x, gz00.x, gw00.x); - vec4 g1000 = vec4(gx00.y, gy00.y, gz00.y, gw00.y); - vec4 g0100 = vec4(gx00.z, gy00.z, gz00.z, gw00.z); - vec4 g1100 = vec4(gx00.w, gy00.w, gz00.w, gw00.w); - vec4 g0010 = vec4(gx10.x, gy10.x, gz10.x, gw10.x); - vec4 g1010 = vec4(gx10.y, gy10.y, gz10.y, gw10.y); - vec4 g0110 = vec4(gx10.z, gy10.z, gz10.z, gw10.z); - vec4 g1110 = vec4(gx10.w, gy10.w, gz10.w, gw10.w); - vec4 g0001 = vec4(gx01.x, gy01.x, gz01.x, gw01.x); - vec4 g1001 = vec4(gx01.y, gy01.y, gz01.y, gw01.y); - vec4 g0101 = vec4(gx01.z, gy01.z, gz01.z, gw01.z); - vec4 g1101 = vec4(gx01.w, gy01.w, gz01.w, gw01.w); - vec4 g0011 = vec4(gx11.x, gy11.x, gz11.x, gw11.x); - vec4 g1011 = vec4(gx11.y, gy11.y, gz11.y, gw11.y); - vec4 g0111 = vec4(gx11.z, gy11.z, gz11.z, gw11.z); - vec4 g1111 = vec4(gx11.w, gy11.w, gz11.w, gw11.w); - - vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); - g0000 *= norm00.x; - g0100 *= norm00.y; - g1000 *= norm00.z; - g1100 *= norm00.w; - - vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); - g0001 *= norm01.x; - g0101 *= norm01.y; - g1001 *= norm01.z; - g1101 *= norm01.w; - - vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); - g0010 *= norm10.x; - g0110 *= norm10.y; - g1010 *= norm10.z; - g1110 *= norm10.w; - - vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); - g0011 *= norm11.x; - g0111 *= norm11.y; - g1011 *= norm11.z; - g1111 *= norm11.w; - - float n0000 = dot(g0000, Pf0); - float n1000 = dot(g1000, vec4(Pf1.x, Pf0.yzw)); - float n0100 = dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw)); - float n1100 = dot(g1100, vec4(Pf1.xy, Pf0.zw)); - float n0010 = dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w)); - float n1010 = dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); - float n0110 = dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w)); - float n1110 = dot(g1110, vec4(Pf1.xyz, Pf0.w)); - float n0001 = dot(g0001, vec4(Pf0.xyz, Pf1.w)); - float n1001 = dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w)); - float n0101 = dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); - float n1101 = dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w)); - float n0011 = dot(g0011, vec4(Pf0.xy, Pf1.zw)); - float n1011 = dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw)); - float n0111 = dot(g0111, vec4(Pf0.x, Pf1.yzw)); - float n1111 = dot(g1111, Pf1); - - vec4 fade_xyzw = fade(Pf0); - vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w); - vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w); - vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z); - vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y); - float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); - return 2.2 * n_xyzw; -} diff --git a/src/shaders/glsl/func/random.glsl b/src/shaders/glsl/func/random.glsl deleted file mode 100644 index 39e31918..00000000 --- a/src/shaders/glsl/func/random.glsl +++ /dev/null @@ -1,3 +0,0 @@ -float random(vec2 co){ - return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); -} \ No newline at end of file diff --git a/src/shaders/glsl/func/simplex-noise-2d.glsl b/src/shaders/glsl/func/simplex-noise-2d.glsl deleted file mode 100644 index ce26b626..00000000 --- a/src/shaders/glsl/func/simplex-noise-2d.glsl +++ /dev/null @@ -1,70 +0,0 @@ -// -// Description : Array and textureless GLSL 2D simplex noise function. -// Author : Ian McEwan, Ashima Arts. -// Maintainer : ijm -// Lastmod : 20110822 (ijm) -// License : Copyright (C) 2011 Ashima Arts. All rights reserved. -// Distributed under the MIT License. See LICENSE file. -// https://github.com/ashima/webgl-noise -// - -vec3 mod289(vec3 x) { - return x - floor(x * (1.0 / 289.0)) * 289.0; -} - -vec2 mod289(vec2 x) { - return x - floor(x * (1.0 / 289.0)) * 289.0; -} - -vec3 permute(vec3 x) { - return mod289(((x*34.0)+1.0)*x); -} - -float snoise(vec2 v) -{ - const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 - 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) - -0.577350269189626, // -1.0 + 2.0 * C.x - 0.024390243902439);// 1.0 / 41.0 - // First corner - vec2 i = floor(v + dot(v, C.yy)); - vec2 x0 = v - i + dot(i, C.xx); - - // Other corners - vec2 i1; - //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 - //i1.y = 1.0 - i1.x; - i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); - // x0 = x0 - 0.0 + 0.0 * C.xx ; - // x1 = x0 - i1 + 1.0 * C.xx ; - // x2 = x0 - 1.0 + 2.0 * C.xx ; - vec4 x12 = x0.xyxy + C.xxzz; - x12.xy -= i1; - - // Permutations - i = mod289(i);// Avoid truncation effects in permutation - vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) - + i.x + vec3(0.0, i1.x, 1.0)); - - vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0); - m = m*m; - m = m*m; - - // Gradients: 41 points uniformly over a line, mapped onto a diamond. - // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) - - vec3 x = 2.0 * fract(p * C.www) - 1.0; - vec3 h = abs(x) - 0.5; - vec3 ox = floor(x + 0.5); - vec3 a0 = x - ox; - - // Normalise gradients implicitly by scaling m - // Approximation of: m *= inversesqrt( a0*a0 + h*h ); - m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h); - - // Compute final noise value at P - vec3 g; - g.x = a0.x * x0.x + h.x * x0.y; - g.yz = a0.yz * x12.xz + h.yz * x12.yw; - return 130.0 * dot(m, g); -} diff --git a/src/shaders/glsl/func/simplex-noise-3d.glsl b/src/shaders/glsl/func/simplex-noise-3d.glsl deleted file mode 100644 index fbbdff89..00000000 --- a/src/shaders/glsl/func/simplex-noise-3d.glsl +++ /dev/null @@ -1,102 +0,0 @@ -// -// Description : Array and textureless GLSL 2D/3D/4D simplex -// noise functions. -// Author : Ian McEwan, Ashima Arts. -// Maintainer : ijm -// Lastmod : 20110822 (ijm) -// License : Copyright (C) 2011 Ashima Arts. All rights reserved. -// Distributed under the MIT License. See LICENSE file. -// https://github.com/ashima/webgl-noise -// - -vec3 mod289(vec3 x) { - return x - floor(x * (1.0 / 289.0)) * 289.0; -} - -vec4 mod289(vec4 x) { - return x - floor(x * (1.0 / 289.0)) * 289.0; -} - -vec4 permute(vec4 x) { - return mod289(((x*34.0)+1.0)*x); -} - -vec4 taylorInvSqrt(vec4 r) -{ - return 1.79284291400159 - 0.85373472095314 * r; -} - -float snoise(vec3 v) -{ - const vec2 C = vec2(1.0/6.0, 1.0/3.0); - const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); - - // First corner - vec3 i = floor(v + dot(v, C.yyy)); - vec3 x0 = v - i + dot(i, C.xxx); - - // Other corners - vec3 g = step(x0.yzx, x0.xyz); - vec3 l = 1.0 - g; - vec3 i1 = min(g.xyz, l.zxy); - vec3 i2 = max(g.xyz, l.zxy); - - // x0 = x0 - 0.0 + 0.0 * C.xxx; - // x1 = x0 - i1 + 1.0 * C.xxx; - // x2 = x0 - i2 + 2.0 * C.xxx; - // x3 = x0 - 1.0 + 3.0 * C.xxx; - vec3 x1 = x0 - i1 + C.xxx; - vec3 x2 = x0 - i2 + C.yyy;// 2.0*C.x = 1/3 = C.y - vec3 x3 = x0 - D.yyy;// -1.0+3.0*C.x = -0.5 = -D.y - - // Permutations - i = mod289(i); - vec4 p = permute(permute(permute( - i.z + vec4(0.0, i1.z, i2.z, 1.0)) - + i.y + vec4(0.0, i1.y, i2.y, 1.0)) - + i.x + vec4(0.0, i1.x, i2.x, 1.0)); - - // Gradients: 7x7 points over a square, mapped onto an octahedron. - // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) - float n_ = 0.142857142857;// 1.0/7.0 - vec3 ns = n_ * D.wyz - D.xzx; - - vec4 j = p - 49.0 * floor(p * ns.z * ns.z);// mod(p,7*7) - - vec4 x_ = floor(j * ns.z); - vec4 y_ = floor(j - 7.0 * x_);// mod(j,N) - - vec4 x = x_ *ns.x + ns.yyyy; - vec4 y = y_ *ns.x + ns.yyyy; - vec4 h = 1.0 - abs(x) - abs(y); - - vec4 b0 = vec4(x.xy, y.xy); - vec4 b1 = vec4(x.zw, y.zw); - - //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; - //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; - vec4 s0 = floor(b0)*2.0 + 1.0; - vec4 s1 = floor(b1)*2.0 + 1.0; - vec4 sh = -step(h, vec4(0.0)); - - vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy; - vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww; - - vec3 p0 = vec3(a0.xy, h.x); - vec3 p1 = vec3(a0.zw, h.y); - vec3 p2 = vec3(a1.xy, h.z); - vec3 p3 = vec3(a1.zw, h.w); - - //Normalise gradients - vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); - p0 *= norm.x; - p1 *= norm.y; - p2 *= norm.z; - p3 *= norm.w; - - // Mix final noise value - vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0); - m = m * m; - return 42.0 * dot(m*m, vec4(dot(p0, x0), dot(p1, x1), - dot(p2, x2), dot(p3, x3))); -} diff --git a/src/shaders/glsl/func/simplex-noise-4d.glsl b/src/shaders/glsl/func/simplex-noise-4d.glsl deleted file mode 100644 index 1608a0c7..00000000 --- a/src/shaders/glsl/func/simplex-noise-4d.glsl +++ /dev/null @@ -1,128 +0,0 @@ -// -// Description : Array and textureless GLSL 2D/3D/4D simplex -// noise functions. -// Author : Ian McEwan, Ashima Arts. -// Maintainer : ijm -// Lastmod : 20110822 (ijm) -// License : Copyright (C) 2011 Ashima Arts. All rights reserved. -// Distributed under the MIT License. See LICENSE file. -// https://github.com/ashima/webgl-noise -// - -vec4 mod289(vec4 x) { - return x - floor(x * (1.0 / 289.0)) * 289.0; } - -float mod289(float x) { - return x - floor(x * (1.0 / 289.0)) * 289.0; } - -vec4 permute(vec4 x) { - return mod289(((x*34.0)+1.0)*x); -} - -float permute(float x) { - return mod289(((x*34.0)+1.0)*x); -} - -vec4 taylorInvSqrt(vec4 r) -{ - return 1.79284291400159 - 0.85373472095314 * r; -} - -float taylorInvSqrt(float r) -{ - return 1.79284291400159 - 0.85373472095314 * r; -} - -vec4 grad4(float j, vec4 ip) -{ - const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0); - vec4 p, s; - - p.xyz = floor(fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0; - p.w = 1.5 - dot(abs(p.xyz), ones.xyz); - s = vec4(lessThan(p, vec4(0.0))); - p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; - - return p; -} - - // (sqrt(5) - 1)/4 = F4, used once below - #define F4 0.309016994374947451 - -float snoise(vec4 v) -{ - const vec4 C = vec4(0.138196601125011, // (5 - sqrt(5))/20 G4 - 0.276393202250021, // 2 * G4 - 0.414589803375032, // 3 * G4 - -0.447213595499958);// -1 + 4 * G4 - - // First corner - vec4 i = floor(v + dot(v, vec4(F4))); - vec4 x0 = v - i + dot(i, C.xxxx); - - // Other corners - - // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) - vec4 i0; - vec3 isX = step(x0.yzw, x0.xxx); - vec3 isYZ = step(x0.zww, x0.yyz); - // i0.x = dot( isX, vec3( 1.0 ) ); - i0.x = isX.x + isX.y + isX.z; - i0.yzw = 1.0 - isX; - // i0.y += dot( isYZ.xy, vec2( 1.0 ) ); - i0.y += isYZ.x + isYZ.y; - i0.zw += 1.0 - isYZ.xy; - i0.z += isYZ.z; - i0.w += 1.0 - isYZ.z; - - // i0 now contains the unique values 0,1,2,3 in each channel - vec4 i3 = clamp(i0, 0.0, 1.0); - vec4 i2 = clamp(i0-1.0, 0.0, 1.0); - vec4 i1 = clamp(i0-2.0, 0.0, 1.0); - - // x0 = x0 - 0.0 + 0.0 * C.xxxx - // x1 = x0 - i1 + 1.0 * C.xxxx - // x2 = x0 - i2 + 2.0 * C.xxxx - // x3 = x0 - i3 + 3.0 * C.xxxx - // x4 = x0 - 1.0 + 4.0 * C.xxxx - vec4 x1 = x0 - i1 + C.xxxx; - vec4 x2 = x0 - i2 + C.yyyy; - vec4 x3 = x0 - i3 + C.zzzz; - vec4 x4 = x0 + C.wwww; - - // Permutations - i = mod289(i); - float j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x); - vec4 j1 = permute(permute(permute(permute ( - i.w + vec4(i1.w, i2.w, i3.w, 1.0)) - + i.z + vec4(i1.z, i2.z, i3.z, 1.0)) - + i.y + vec4(i1.y, i2.y, i3.y, 1.0)) - + i.x + vec4(i1.x, i2.x, i3.x, 1.0)); - - // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope - // 7*7*6 = 294, which is close to the ring size 17*17 = 289. - vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0); - - vec4 p0 = grad4(j0, ip); - vec4 p1 = grad4(j1.x, ip); - vec4 p2 = grad4(j1.y, ip); - vec4 p3 = grad4(j1.z, ip); - vec4 p4 = grad4(j1.w, ip); - - // Normalise gradients - vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); - p0 *= norm.x; - p1 *= norm.y; - p2 *= norm.z; - p3 *= norm.w; - p4 *= taylorInvSqrt(dot(p4, p4)); - - // Mix contributions from the five corners - vec3 m0 = max(0.6 - vec3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), 0.0); - vec2 m1 = max(0.6 - vec2(dot(x3, x3), dot(x4, x4)), 0.0); - m0 = m0 * m0; - m1 = m1 * m1; - return 49.0 * (dot(m0*m0, vec3(dot(p0, x0), dot(p1, x1), dot(p2, x2))) - + dot(m1*m1, vec2(dot(p3, x3), dot(p4, x4)))); - -} diff --git a/src/shaders/glsl/vertex/basic.glsl b/src/shaders/glsl/vertex/basic.glsl deleted file mode 100644 index 5de90f63..00000000 --- a/src/shaders/glsl/vertex/basic.glsl +++ /dev/null @@ -1,6 +0,0 @@ -varying vec2 vUv; - -void main() { - vUv = uv; - gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); -} \ No newline at end of file diff --git a/src/shaders/glsl/vertex/normal.glsl b/src/shaders/glsl/vertex/normal.glsl deleted file mode 100644 index f157ae1e..00000000 --- a/src/shaders/glsl/vertex/normal.glsl +++ /dev/null @@ -1,8 +0,0 @@ -varying vec2 vUv; -varying vec3 vNormal; - -void main() { - vUv = uv; - vNormal = normalize(normalMatrix * normal); - gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); -} \ No newline at end of file diff --git a/src/shaders/glsl/vertex/point.glsl b/src/shaders/glsl/vertex/point.glsl deleted file mode 100644 index b046b71a..00000000 --- a/src/shaders/glsl/vertex/point.glsl +++ /dev/null @@ -1,14 +0,0 @@ -attribute float size; -attribute vec3 customColor; - -varying vec3 vColor; - -void main() { - vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); - - vColor = customColor; - - gl_PointSize = size * (300.0 / -mvPosition.z); - - gl_Position = projectionMatrix * mvPosition; -} \ No newline at end of file diff --git a/src/shaders/glsl/vertex/position.glsl b/src/shaders/glsl/vertex/position.glsl deleted file mode 100644 index a2d24eaf..00000000 --- a/src/shaders/glsl/vertex/position.glsl +++ /dev/null @@ -1,8 +0,0 @@ -varying vec2 vUv; -varying vec3 vPos; - -void main() { - vUv = uv; - vPos = position; - gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); -} \ No newline at end of file diff --git a/src/shaders/glsl/vertex/ripple.glsl b/src/shaders/glsl/vertex/ripple.glsl deleted file mode 100644 index 03fa75a9..00000000 --- a/src/shaders/glsl/vertex/ripple.glsl +++ /dev/null @@ -1,16 +0,0 @@ -uniform float time; -uniform float size; -uniform float depth; -varying vec2 vUv; -varying float vNoise; - -#include "../func/simplex-noise-2d.glsl" - -void main() { - vUv = uv; - vNoise = snoise(vUv* size + time); - - vec3 newPosition = position + normal * vNoise * depth; - - gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0); -} \ No newline at end of file diff --git a/src/utils/array.js b/src/utils/array.js deleted file mode 100644 index 3e477c97..00000000 --- a/src/utils/array.js +++ /dev/null @@ -1,11 +0,0 @@ -export function isDefined(...arr) { - return arr.filter(e => e !== undefined).length > 0; -} - -export function contains(arr1, arr2) { - return arr1.some(e => arr2.includes(e)); -} - -export function reverse(arr) { - return [...arr].reverse(); -} diff --git a/src/utils/audio.js b/src/utils/audio.js deleted file mode 100644 index 41346471..00000000 --- a/src/utils/audio.js +++ /dev/null @@ -1,36 +0,0 @@ -import Audio from 'audio/Audio'; -import { audioContext } from 'view/global'; - -export function loadAudioData(data) { - return new Promise((resolve, reject) => { - const audio = new Audio(audioContext); - - return audio - .load(data) - .then(() => { - resolve(audio); - }) - .catch(error => { - reject(error); - }); - }); -} - -export function downmix(input) { - const { length, numberOfChannels } = input; - const output = new Float32Array(length); - - if (numberOfChannels < 2) { - return input.getChannelData(0); - } - - for (let i = 0; i < numberOfChannels; i++) { - const ch = input.getChannelData(i); - - for (let j = 0; j < length; j++) { - output[j] += ch[j]; - } - } - - return output.map(x => x / numberOfChannels); -} diff --git a/src/utils/canvas.js b/src/utils/canvas.js deleted file mode 100644 index 2fbe176f..00000000 --- a/src/utils/canvas.js +++ /dev/null @@ -1,68 +0,0 @@ -import { deg2rad } from './math'; - -export function getColor(start, end, pct) { - const startColor = { - r: parseInt(start.substring(1, 3), 16), - g: parseInt(start.substring(3, 5), 16), - b: parseInt(start.substring(5, 7), 16), - }; - - const endColor = { - r: parseInt(end.substring(1, 3), 16), - g: parseInt(end.substring(3, 5), 16), - b: parseInt(end.substring(5, 7), 16), - }; - - const c = { - r: ~~((endColor.r - startColor.r) * pct) + startColor.r, - g: ~~((endColor.g - startColor.g) * pct) + startColor.g, - b: ~~((endColor.b - startColor.b) * pct) + startColor.b, - }; - - return `#${c.r.toString(16)}${c.g.toString(16)}${c.b.toString(16)}`; -} - -export function setColor(context, color, x1, y1, x2, y2) { - if (color instanceof Array) { - const gradient = context.createLinearGradient(x1, y1, x2, y2); - - for (let i = 0; i < color.length; i++) { - gradient.addColorStop(i / (color.length - 1), color[i]); - } - - context.fillStyle = gradient; - } else { - context.fillStyle = color; - } -} - -export function resetCanvas(canvas, width = 1, height = 1) { - if (canvas.width !== width || canvas.height !== height) { - canvas.width = width; - canvas.height = height; - } else { - canvas.getContext('2d').clearRect(0, 0, width, height); - } -} - -export function renderImageToCanvas(context, image, props = { x: 0, y: 0 }, origin = { x: 0, y: 0 }) { - const { width, height } = context.canvas; - const { x, y, opacity, rotation } = props; - - const halfSceneWidth = width / 2; - const halfSceneHeight = height / 2; - - context.globalAlpha = opacity; - - if (rotation && rotation % 360 !== 0) { - context.save(); - context.translate(halfSceneWidth + x, halfSceneHeight - y); - context.rotate(deg2rad(rotation)); - context.drawImage(image, -origin.x, -origin.y); - context.restore(); - } else { - context.drawImage(image, halfSceneWidth + x - origin.x, halfSceneHeight - y - origin.y); - } - - context.globalAlpha = 1.0; -} diff --git a/src/utils/controls.js b/src/utils/controls.js deleted file mode 100644 index f4e56be4..00000000 --- a/src/utils/controls.js +++ /dev/null @@ -1,46 +0,0 @@ -let labelCount = {}; - -export function resetLabelCount() { - labelCount = {}; -} - -export function getDisplayName(label) { - if (labelCount[label] === undefined) { - labelCount[label] = 1; - } else { - labelCount[label] += 1; - } - - return `${label} ${labelCount[label]}`; -} - -export function property(name, compare) { - return display => { - const value = display.properties[name]; - if (compare !== undefined) { - return typeof compare === 'function' ? compare(value) : value === compare; - } - return value; - }; -} - -export function stageWidth(transform) { - return display => { - const value = display.scene.getSize().width; - return transform ? transform(value) : value; - }; -} - -export function stageHeight(transform) { - return display => { - const value = display.scene.getSize().height; - return transform ? transform(value) : value; - }; -} - -export function maxSize() { - return display => { - const { width, height } = display.scene.getSize(); - return Math.max(width, height); - }; -} diff --git a/src/utils/crypto.js b/src/utils/crypto.js deleted file mode 100644 index 4bc5ce42..00000000 --- a/src/utils/crypto.js +++ /dev/null @@ -1,19 +0,0 @@ -const byteToHex = []; - -for (let n = 0; n <= 0xff; n++) { - byteToHex.push(n.toString(16).padStart(2, '0')); -} - -function toHexString(buffer) { - const hexOctets = new Array(buffer.length); - - for (let i = 0; i < buffer.length; i++) { - hexOctets[i] = byteToHex[buffer[i]]; - } - - return hexOctets.join(''); -} - -export function uniqueId() { - return toHexString(window.crypto.getRandomValues(new Uint8Array(20))); -} diff --git a/src/utils/data.js b/src/utils/data.js deleted file mode 100644 index 1b7d25ef..00000000 --- a/src/utils/data.js +++ /dev/null @@ -1,47 +0,0 @@ -import mime from 'mime'; - -export function blobToDataUrl(blob) { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - - reader.onload = e => { - resolve(e.target.result); - }; - - reader.onerror = e => { - reject(e.target.error); - }; - - reader.readAsDataURL(blob); - }); -} - -export function blobToArrayBuffer(blob) { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - - reader.onload = e => { - resolve(e.target.result); - }; - - reader.onerror = e => { - reject(e.target.error); - }; - - return reader.readAsArrayBuffer(blob); - }); -} - -export async function dataToBlob(data, ext) { - return new Blob([new Uint8Array(data).buffer], { type: mime.getType(ext) }); -} - -export function base64ToBytes(base64) { - const str = atob(base64); - const len = str.length; - const bytes = new Uint8Array(len); - for (let i = 0; i < len; i++) { - bytes[i] = str.charCodeAt(i); - } - return bytes; -} diff --git a/src/utils/easing.js b/src/utils/easing.js deleted file mode 100644 index eadf1441..00000000 --- a/src/utils/easing.js +++ /dev/null @@ -1,40 +0,0 @@ -// Constant -export const linear = t => t; - -// Accelerating from zero velocity -export const easeInQuad = t => t * t; - -// Decelerating to zero velocity -export const easeOutQuad = t => t * (2 - t); - -// Acceleration until halfway, then deceleration -export const easeInOutQuad = t => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t); - -// Accelerating from zero velocity -export const easeInCubic = t => t * t * t; - -// Decelerating to zero velocity -export const easeOutCubic = t => --t * t * t + 1; - -// Acceleration until halfway, then deceleration -export const easeInOutCubic = t => - t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; - -// Accelerating from zero velocity -export const easeInQuart = t => t * t * t * t; - -// Decelerating to zero velocity -export const easeOutQuart = t => 1 - --t * t * t * t; - -// Acceleration until halfway, then deceleration -export const easeInOutQuart = t => (t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t); - -// Accelerating from zero velocity -export const easeInQuint = t => t * t * t * t * t; - -// Decelerating to zero velocity -export const easeOutQuint = t => 1 + --t * t * t * t * t; - -// Acceleration until halfway, then deceleration -export const easeInOutQuint = t => - t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t; diff --git a/src/utils/ffmpeg.js b/src/utils/ffmpeg.js deleted file mode 100644 index 9277ac56..00000000 --- a/src/utils/ffmpeg.js +++ /dev/null @@ -1,111 +0,0 @@ -import Process from 'core/Process'; - -export function getVersion(ffmpeg) { - return new Promise((resolve, reject) => { - let buffer = ''; - - const process = new Process(ffmpeg); - - process.on('stdout', data => { - buffer += data.toString(); - }); - - process.on('error', err => { - reject(err); - }); - - process.on('close', () => { - const lines = buffer.split(/\r\n|\r|\n/); - const regex = /^ffmpeg version ([^ ]+)/; - const match = lines[0].match(regex); - - if (match) { - resolve(match[1]); - } - - reject(new Error('Invalid file')); - }); - - process.start(['-version']); - }); -} - -export function getFormats(ffmpeg) { - return new Promise((resolve, reject) => { - let buffer = ''; - - const process = new Process(ffmpeg); - - process.on('stdout', data => { - buffer += data.toString(); - }); - - process.on('error', err => { - reject(err); - }); - - process.on('close', () => { - const formats = {}; - const lines = buffer.split(/\r\n|\r|\n/); - const regex = /^\s*([D ])([E ]) ([^ ]+) +(.*)$/; - - lines.forEach(line => { - const match = line.match(regex); - if (match) { - match[3].split(',').forEach(id => { - formats[id] = { - description: match[4], - canDemux: match[1] === 'D', - canMux: match[2] === 'E', - }; - }); - } - }); - - resolve(formats); - }); - - process.start(['-formats']); - }); -} - -export function getCodecs(ffmpeg) { - return new Promise((resolve, reject) => { - let buffer = ''; - - const process = new Process(ffmpeg); - - process.on('stdout', data => { - buffer += data.toString(); - }); - - process.on('error', err => { - reject(err); - }); - - process.on('close', () => { - const codecs = { audio: {}, video: {}, subtitle: {} }; - const lines = buffer.split(/\r\n|\r|\n/); - const regex = /^\s*([D.])([E.])([VAS])([I.])([L.])([S.]) ([^ ]+) +(.*)$/; - const types = { V: 'video', A: 'audio', S: 'subtitle' }; - - lines.forEach(line => { - const match = line.match(regex); - if (match && match[7] !== '=') { - codecs[types[match[3]]][match[7]] = { - description: match[8], - canDecode: match[1] === 'D', - canEncode: match[2] === 'E', - intraFrameOnly: match[4] === 'I', - isLossy: match[5] === 'L', - isLossless: match[6] === 'S', - }; - } - }); - - resolve(codecs); - }); - - process.start(['-codecs']); - }); -} diff --git a/src/utils/file.js b/src/utils/file.js deleted file mode 100644 index fd16c059..00000000 --- a/src/utils/file.js +++ /dev/null @@ -1,6 +0,0 @@ -import path from 'path-browserify'; - -export function replaceExt(file, ext) { - const base = path.basename(file, path.extname(file)) + ext; - return path.join(path.dirname(file), base); -} diff --git a/src/utils/format.js b/src/utils/format.js deleted file mode 100644 index 9e48e35b..00000000 --- a/src/utils/format.js +++ /dev/null @@ -1,76 +0,0 @@ -const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; - -export function formatSize(val, decimals) { - if (val === 0) return 'N/A'; - - const precision = 10 ** (decimals || 0); - const i = Math.floor(Math.log(val) / Math.log(1024)); - - return `${Math.round((val * precision) / 1024 ** i) / precision} ${sizes[i]}`; -} - -export function parseTime(val) { - const days = ~~(val / 86400); - const hours = ~~(val / 3600) - days * 24; - const minutes = ~~(val / 60) - days * 1440 - hours * 60; - const seconds = ~~val - days * 86400 - hours * 3600 - minutes * 60; - const ms = (val - ~~val) * 1000; - - return { - days, - hours, - minutes, - seconds, - ms, - }; -} - -export function formatTime(val) { - const { hours, minutes, seconds } = parseTime(val); - const h = hours > 0 ? `${hours}:` : ''; - const m = hours > 0 ? minutes.toString().padStart(2, '0') : minutes; - const s = seconds.toString().padStart(2, '0'); - - return `${h}${m}:${s}`; -} - -export function formatShortTime(val, formats = ['m', 's'], space = '') { - if (val === 0) { - return `0${formats[formats.length - 1]}`; - } - - const { days, hours, minutes, seconds, ms } = parseTime(val); - let t = ''; - - if (days > 0 && formats.indexOf('d') !== -1) t += `${days}d${space}`; - if (hours > 0 && formats.indexOf('h') !== -1) t += `${hours}h${space}`; - if (minutes > 0 && formats.indexOf('m') !== -1) t += `${minutes}m${space}`; - if (seconds > 0 && formats.indexOf('s') !== -1) t += `${seconds}s${space}`; - if (ms > 0 && formats.indexOf('ms') !== -1) t += `${ms}ms`; - - return t; -} - -export function parseSeekTime(val) { - const matches = val.match(/^(0?\d+:)?(0?\d+):(\d{2})$/); - - if (matches) { - const h = matches[1] !== undefined ? Number(matches[1].replace(':', '')) * 3600 : 0; - const m = Number(matches[2]) * 60; - const s = Number(matches[3]); - - return h + m + s; - } - - return null; -} - -export function formatSeekTime(val) { - const { hours, minutes, seconds } = parseTime(val); - - return [ - `${hours}`.padStart(2, '0'), - `${minutes}`.padStart(2, '0'), - `${seconds}`.padStart(2, '0'), - ].join(':'); -} diff --git a/src/utils/io.js b/src/utils/io.js deleted file mode 100644 index a2d9d9a5..00000000 --- a/src/utils/io.js +++ /dev/null @@ -1,82 +0,0 @@ -import fs from 'fs'; -import zlib from 'zlib'; - -export function compress(data) { - return new Promise((resolve, reject) => { - zlib.gzip(data, (error, buffer) => { - if (error) { - reject(error); - } else { - resolve(buffer); - } - }); - }); -} - -export function decompress(data) { - return new Promise((resolve, reject) => { - zlib.unzip(data, (error, buffer) => { - if (error) { - reject(error); - } else { - resolve(buffer); - } - }); - }); -} - -export function readFile(file) { - return new Promise((resolve, reject) => { - try { - resolve(fs.readFileSync(file)); - } catch (err) { - reject(err); - } - }); -} - -export async function readFileCompressed(file) { - const data = await readFile(file); - return decompress(data); -} - -export function writeFile(file, data) { - return new Promise((resolve, reject) => { - try { - resolve(fs.writeFileSync(file, data)); - } catch (err) { - reject(err); - } - }); -} - -export async function writeFileCompressed(file, data) { - const buffer = await compress(data); - return writeFile(file, buffer); -} - -export function removeFile(file) { - return new Promise((resolve, reject) => { - try { - resolve(fs.unlinkSync(file)); - } catch (err) { - reject(err); - } - }); -} - -export function createFolder(path) { - return new Promise((resolve, reject) => { - try { - resolve(fs.mkdirSync(path)); - } catch (err) { - if (err.code === 'EEXIST') resolve(); - - reject(err); - } - }); -} - -export function fileExists(file) { - return fs.existsSync(file); -} diff --git a/src/utils/math.js b/src/utils/math.js deleted file mode 100644 index d32350ad..00000000 --- a/src/utils/math.js +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint-disable no-bitwise, no-nested-ternary */ -// Fast rounding -export function round(val) { - return (val + 0.5) << 0; -} - -// Fast ceiling -export function ceil(val) { - const n = val << 0; - return n === val ? n : n + 1; -} - -// Fast floor -export function floor(val) { - return ~~val; -} - -// Clamps value between min and max -export function clamp(num, min, max) { - return num < min ? min : num > max ? max : num; -} - -// Decimal places in a number -export function decimals(num) { - if (num % 1 !== 0) { - return +num.toString().split('.')[1].length; - } - return 0; -} - -// Round to nearest given interval -export function roundTo(num, step) { - const d = decimals(step); - const n = ceil(num / step) * step; - - return d > 0 ? +n.toFixed(d) : n; -} - -// Normalize value over a given range -export function normalize(val, min, max) { - const n = (val - min) / (max - min); - - return clamp(n, 0, 1); -} - -// Log base 10 -export function log10(val) { - return Math.log(val) / Math.LN10; -} - -// Decibels to magnitude: Math.pow(10, 0.05 * val); -export function db2mag(val) { - return Math.exp(0.1151292546497023 * val); -} - -// Magnitude to decibels: 20 * log10(db) -export function mag2db(val) { - return 20 * log10(val); -} - -// Degrees to radians -export function deg2rad(val) { - return val * 0.017453292519943295; -} - -// Radians to degrees -export function rad2deg(val) { - return val * 57.29577951308232; -} - -// Hash code of a string -export function hash(s) { - let h = 0; - if (s.length === 0) return h; - - for (let i = 0; i < s.length; i++) { - const chr = s.charCodeAt(i); - h = (h << 5) - h + chr; - h |= 0; - } - - return h; -} diff --git a/src/utils/object.js b/src/utils/object.js deleted file mode 100644 index fe98a291..00000000 --- a/src/utils/object.js +++ /dev/null @@ -1,20 +0,0 @@ -export function updateExistingProps(obj, props) { - let changed = false; - - for (let keys = Object.keys(props), len = keys.length, i = 0; i < len; ++i) { - const key = keys[i]; - if (key in obj) { - const value = props[key]; - if (value !== obj[key]) { - obj[key] = value; - changed = true; - } - } - } - - return changed; -} - -export function resolve(value, args = []) { - return typeof value === 'function' ? value(...args) : value; -} diff --git a/src/utils/react.js b/src/utils/react.js deleted file mode 100644 index 42344303..00000000 --- a/src/utils/react.js +++ /dev/null @@ -1,25 +0,0 @@ -import { Children, Fragment, cloneElement } from 'react'; - -export function ignoreEvents(e) { - e.stopPropagation(); - e.preventDefault(); -} - -export function inputValueToProps(callback) { - return (name, value) => callback({ [name]: value }); -} - -export function mapChildren(children, props, callback) { - return Children.map(children, (child, index) => { - if (child) { - if (child.type === Fragment) { - return mapChildren(child.props.children, props); - } - - const args = callback ? callback(child, props, index) : [child, props]; - - return cloneElement(...args); - } - return child; - }); -} diff --git a/src/utils/string.js b/src/utils/string.js deleted file mode 100644 index e613cd1e..00000000 --- a/src/utils/string.js +++ /dev/null @@ -1,4 +0,0 @@ -export function trimChars(str) { - // eslint-disable-next-line no-control-regex - return str.replace(/[\x00-\x1F\x7F-\x9F]/g, ''); -} diff --git a/src/utils/work.js b/src/utils/work.js deleted file mode 100644 index a9a1d675..00000000 --- a/src/utils/work.js +++ /dev/null @@ -1,3 +0,0 @@ -export function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); -} diff --git a/src/video/AudioProcess.js b/src/video/AudioProcess.js deleted file mode 100644 index d277f3bf..00000000 --- a/src/video/AudioProcess.js +++ /dev/null @@ -1,55 +0,0 @@ -import path from 'path-browserify'; -import Process from 'core/Process'; -import { replaceExt } from 'utils/file'; -import videoConfig from 'config/video.json'; - -export default class AudioProcess extends Process { - start({ audioFile, outputFile, codec, timeStart, timeEnd }) { - return new Promise((resolve, reject) => { - const ext = path.extname(audioFile); - const duration = timeEnd - timeStart; - const { encoder, extension, settings } = videoConfig.codecs[codec].audio; - const output = replaceExt(outputFile, `.${extension}`); - - // If source is already in correct format, just copy - if ( - (/x264|nvenc/.test(codec) && /\.(mp4|aac)/.test(ext)) || - (codec === 'webm' && ext === '.ogg') - ) { - codec = 'copy'; - } - - this.on('close', code => { - if (code !== 0) { - reject(new Error('Process terminated.')); - } - resolve(output); - }); - - this.on('error', err => { - reject(err); - }); - - this.on('stderr', data => { - this.emit('output', data); - }); - - // Encoding options - const args = [ - '-y', - '-i', - audioFile, - '-ss', - timeStart, - '-t', - duration, - '-c:a', - encoder, - ...settings, - output, - ]; - - super.start(args); - }); - } -} diff --git a/src/video/MergeProcess.js b/src/video/MergeProcess.js deleted file mode 100644 index d76cd0a5..00000000 --- a/src/video/MergeProcess.js +++ /dev/null @@ -1,35 +0,0 @@ -import Process from 'core/Process'; - -export default class MergeProcess extends Process { - start({ inputFiles, outputFile }) { - return new Promise((resolve, reject) => { - const inputs = inputFiles.flatMap(file => ['-i', file]); - - this.on('close', code => { - if (code !== 0) { - reject(new Error('Process terminated.')); - } - resolve(); - }); - - this.on('error', err => { - reject(err); - }); - - this.on('stderr', data => { - this.emit('output', data); - }); - - super.start([ - '-y', - ...inputs, - '-codec', - 'copy', - '-shortest', - '-movflags', - '+faststart', - outputFile, - ]); - }); - } -} diff --git a/src/video/RenderProcess.js b/src/video/RenderProcess.js deleted file mode 100644 index 603250ab..00000000 --- a/src/video/RenderProcess.js +++ /dev/null @@ -1,61 +0,0 @@ -import Process from 'core/Process'; -import { replaceExt } from 'utils/file'; -import videoConfig from 'config/video.json'; - -export default class RenderProcess extends Process { - start({ outputFile, codec, fps, quality, width, height }) { - return new Promise((resolve, reject) => { - const { extension, settings, encoder } = videoConfig.codecs[codec].video; - const output = replaceExt(outputFile, `.${extension}`); - - this.on('close', code => { - if (code !== 0) { - reject(new Error('Process terminated.')); - } - resolve(output); - }); - - this.on('error', err => { - reject(err); - }); - - this.on('stderr', data => { - this.emit('output', data); - }); - - // Encoding options - const args = [ - '-loglevel', - 'debug', - '-y', - '-stats', - '-f', - 'rawvideo', - '-c:v', - 'rawvideo', - '-pix_fmt', - 'rgba', - '-s', - `${width}x${height}`, - '-r', - fps, - ...settings.input, - '-i', - 'pipe:0', - '-c:v', - encoder, - '-f', - extension, - '-pix_fmt', - 'yuv420p', - '-vf', - 'vflip', - ...settings.output, - ...settings[quality], - output - ]; - - super.start(args); - }); - } -} diff --git a/src/video/VideoRenderer.js b/src/video/VideoRenderer.js deleted file mode 100644 index b66982e7..00000000 --- a/src/video/VideoRenderer.js +++ /dev/null @@ -1,156 +0,0 @@ -import path from 'path-browserify'; -import RenderProcess from 'video/RenderProcess'; -import AudioProcess from 'video/AudioProcess'; -import MergeProcess from 'video/MergeProcess'; -import { api, logger, stage } from 'view/global'; -import { updateState } from 'actions/video'; -import { raiseError } from 'actions/error'; -import { uniqueId } from 'utils/crypto'; -import { sleep } from 'utils/work'; - -export default class VideoRenderer { - constructor(renderer) { - const { FFMPEG_BINARY } = api.getEnvironment(); - - this.renderer = renderer; - this.renderProcess = new RenderProcess(FFMPEG_BINARY); - this.audioProcess = new AudioProcess(FFMPEG_BINARY); - this.mergeProcess = new MergeProcess(FFMPEG_BINARY); - - this.renderProcess.on('output', data => { - logger.log(data); - - // Start rendering frames when ffmpeg is ready - if (!this.running && /^ffmpeg version/.test(data)) { - setTimeout(() => { - this.running = true; - - this.renderFrames(); - }, 500); - } - }); - - this.audioProcess.on('output', data => { - logger.log(data); - }); - - this.mergeProcess.on('output', data => { - logger.log(data); - }); - } - - async start({ videoFile, audioFile, fps, quality, codec, timeStart, timeEnd }) { - try { - this.renderer.stop(); - this.startTime = Date.now(); - this.running = false; - this.finished = false; - this.currentProcess = null; - this.fps = fps; - this.totalFrames = fps * (timeEnd - timeStart); - this.startFrame = fps * timeStart; - this.endFrame = this.startFrame + this.totalFrames; - - const { renderProcess, audioProcess, mergeProcess } = this; - - const id = uniqueId(); - const { TEMP_PATH } = api.getEnvironment(); - const tempVideoFile = path.join(TEMP_PATH, `${id}.video`); - const tempAudioFile = path.join(TEMP_PATH, `${id}.audio`); - - logger.log('Starting video render', id); - - // Render video - updateState({ status: 'Rendering video' }); - this.currentProcess = renderProcess; - const { width, height } = stage.getSize(); - const outputVideoFile = await renderProcess.start({ - outputFile: tempVideoFile, - codec, - fps, - quality, - width, - height, - }); - - // Render audio - updateState({ status: 'Rendering audio' }); - this.currentProcess = audioProcess; - const outputAudioFile = await audioProcess.start({ - audioFile, - outputFile: tempAudioFile, - codec, - timeStart, - timeEnd, - }); - - // Merge audio and video - updateState({ status: 'Merging audio and video' }); - this.currentProcess = mergeProcess; - await mergeProcess.start({ - inputFiles: [outputVideoFile, outputAudioFile], - outputFile: videoFile, - }); - - this.finished = true; - - updateState({ status: 'Finished', finished: true }); - } catch (error) { - if (error.message.indexOf('Process terminated') < 0) { - updateState({ status: 'Error' }); - - raiseError('Video rendering failed.', error); - } - } finally { - this.stop(); - - this.running = false; - - this.renderer.start(); - } - } - - stop() { - if (!this.finished) { - this.currentProcess?.stop(); - this.running = false; - - logger.log('Video rendering stopped.'); - } - } - - async renderFrames() { - const { renderer, renderProcess, startTime, startFrame, endFrame, totalFrames, fps } = this; - - try { - this.frame = startFrame; - - while (this.frame < endFrame && this.running) { - const image = await renderer.renderFrame(this.frame, fps); - - // This is required for the UI to respond - await sleep(20); - - if (image) { - renderProcess.push(image); - } - - this.frame += 1; - - updateState({ - currentFrame: totalFrames - (endFrame - this.frame), - totalFrames, - startTime, - }); - } - } catch (error) { - if (!error.message.includes('write EPIPE')) { - raiseError('Frame rendering failed.', error); - - this.stop(); - } - } finally { - renderProcess.end(); - } - } -} diff --git a/src/view/actions/app.js b/src/view/actions/app.js deleted file mode 100644 index 52152ea6..00000000 --- a/src/view/actions/app.js +++ /dev/null @@ -1,240 +0,0 @@ -import create from 'zustand'; -import Plugin from 'core/Plugin'; -import { api, logger, renderer, stage, library } from 'view/global'; -import configStore, { loadConfig } from 'actions/config'; -import updateStore, { checkForUpdates, updateDownloadProgress } from 'actions/updates'; -import projectStore, { - checkUnsavedChanges, - newProject, - openProjectFile, - saveProjectFile, -} from 'actions/project'; -import { showModal } from 'actions/modals'; -import { raiseError } from 'actions/error'; -import { openAudioFile } from 'actions/audio'; -import { setZoom, zoomIn, zoomOut, fitToScreen } from 'actions/stage'; -import * as displays from 'displays'; -import * as effects from 'effects'; - -const initialState = { - statusText: '', - showControlDock: true, - showPlayer: true, - showReactor: false, - showWaveform: true, - showOsc: false, - activeReactorId: null, - activeElementId: null, -}; - -const appStore = create(() => ({ - ...initialState, -})); - -export function toggleState(key) { - appStore.setState(state => ({ [key]: !state[key] })); -} - -export function exitApp() { - api.closeWindow(); -} - -export async function saveImage() { - const { filePath, canceled } = await api.showSaveDialog({ - defaultPath: `image-${Date.now()}.png`, - filters: [ - { name: 'PNG', extensions: ['png'] }, - { name: 'JPEG', extensions: ['jpg'] }, - ], - }); - - if (!canceled) { - try { - const data = renderer.getFrameData(false); - - stage.render(data); - - const buffer = stage.getImage(/jpe?g$/.test(filePath) ? 'image/jpeg' : 'image/png'); - - await api.saveImageFile(filePath, buffer); - - logger.log('Image saved:', filePath); - } catch (error) { - raiseError('Failed to save image file.', error); - } - } -} - -export function setActiveReactorId(reactorId) { - appStore.setState({ activeReactorId: reactorId || null }); -} - -export function setActiveElementId(elementId) { - appStore.setState({ activeElementId: elementId || null }); -} - -export async function handleMenuAction(action) { - const { file } = projectStore.getState(); - - switch (action) { - case 'new-project': - await checkUnsavedChanges(action, newProject); - break; - - case 'open-project': - await checkUnsavedChanges(action, openProjectFile); - break; - - case 'save-project': - await saveProjectFile(file); - break; - - case 'save-project-as': - await saveProjectFile(); - break; - - case 'load-audio': - await openAudioFile(); - break; - - case 'save-image': - await saveImage(); - break; - - case 'save-video': - await showModal('VideoSettings', { title: 'Save Video' }); - break; - - case 'edit-canvas': - await showModal('CanvasSettings', { title: 'Canvas' }); - break; - - case 'edit-settings': - await showModal('AppSettings', { title: 'Settings' }); - break; - - case 'zoom-in': - await zoomIn(); - break; - - case 'zoom-out': - await zoomOut(); - break; - - case 'zoom-reset': - await setZoom(1); - break; - - case 'zoom-fit': - await fitToScreen(); - break; - - case 'view-control-dock': - await toggleState('showControlDock'); - break; - - case 'view-player': - await toggleState('showPlayer'); - break; - - case 'check-for-updates': - await showModal('AppUpdates', { title: 'Updates' }); - break; - - case 'open-dev-tools': - api.openDevTools(); - break; - - case 'about': - await showModal('About'); - break; - - case 'exit': - await exitApp(); - break; - } -} - -export async function loadPlugins() { - logger.time('plugins'); - - const plugins = {}; - - for (const [key, plugin] of Object.entries(api.getPlugins())) { - try { - const module = await import(/* webpackIgnore: true */ plugin.src); - - module.default.config.icon = plugin.icon; - - plugins[key] = Plugin.create(module.default); - } catch (e) { - logger.error(e); - } - } - - library.set('plugins', plugins); - - logger.timeEnd('plugins', 'Loaded plugins', plugins); -} - -export async function loadLibrary() { - const plugins = library.get('plugins'); - - const coreDisplays = {}; - for (const [key, display] of Object.entries(displays)) { - display.config.icon = `images/controls/${key}.png`; - - coreDisplays[key] = display; - } - - const coreEffects = {}; - for (const [key, effect] of Object.entries(effects)) { - effect.config.icon = `images/controls/${key}.png`; - - coreEffects[key] = effect; - } - - for (const [key, plugin] of Object.entries(plugins)) { - const { type } = plugin.config; - - if (type === 'display') { - coreDisplays[key] = plugin; - } else if (type === 'effect') { - coreEffects[key] = plugin; - } - } - - library.set('displays', coreDisplays); - library.set('effects', coreEffects); - - logger.log('Loaded library', library); -} - -export async function initApp() { - await loadConfig(); - await loadPlugins(); - await loadLibrary(); - await newProject(); - - const config = configStore.getState(); - - api.on('download-progress', info => { - updateDownloadProgress(info); - }); - - if (config.checkForUpdates) { - await checkForUpdates(); - - const { hasUpdate } = updateStore.getState(); - - if (hasUpdate) { - showModal('AppUpdates', { title: 'Updates' }); - } - } - - api.on('menu-action', handleMenuAction); - - renderer.start(); -} - -export default appStore; diff --git a/src/view/actions/audio.js b/src/view/actions/audio.js deleted file mode 100644 index 93de4485..00000000 --- a/src/view/actions/audio.js +++ /dev/null @@ -1,83 +0,0 @@ -import create from 'zustand'; -import { api, analyzer, logger, player } from 'global'; -import { loadAudioData } from 'utils/audio'; -import { trimChars } from 'utils/string'; -import appStore from './app'; -import configStore from './config'; -import { raiseError } from './error'; - -export const initialState = { - file: '', - duration: 0, - loading: false, - tags: null, - error: null, -}; - -const audioStore = create(() => ({ - ...initialState, -})); - -export async function loadAudioFile(file, play) { - audioStore.setState({ loading: true }); - - player.stop(); - - logger.time('audio-file-load'); - - try { - const data = await api.readAudioFile(file); - const audio = await loadAudioData(data); - const duration = audio.getDuration(); - - player.load(audio); - audio.addNode(analyzer.analyzer); - - if (!play) { - play = configStore.getState().autoPlayAudio; - } - - if (play) { - player.play(); - } - - logger.timeEnd('audio-file-load', 'Audio file loaded:', file); - - const tags = await api.loadAudioTags(file); - - if (tags) { - const { artist, title } = tags; - - appStore.setState({ statusText: trimChars(`${artist} - ${title}`) }); - } else { - appStore.setState({ statusText: trimChars(file) }); - } - - audioStore.setState({ file, duration, tags, loading: false }); - } catch (error) { - raiseError('Invalid audio file.', error); - - audioStore.setState({ loading: false }); - } -} - -export async function openAudioFile(play) { - const { filePaths, canceled } = await api.showOpenDialog({ - filters: [ - { - name: 'audio files', - extensions: ['aac', 'flac', 'mp3', 'm4a', 'opus', 'ogg', 'wav'], - }, - ], - }); - - if (!canceled) { - if (!play) { - play = configStore.getState().autoPlayAudio; - } - - await loadAudioFile(filePaths[0], play); - } -} - -export default audioStore; diff --git a/src/view/actions/config.js b/src/view/actions/config.js deleted file mode 100644 index 73f993e9..00000000 --- a/src/view/actions/config.js +++ /dev/null @@ -1,41 +0,0 @@ -import create from 'zustand'; -import { api, env, logger } from 'global'; -import { uniqueId } from 'utils/crypto'; -import defaultAppConfig from 'config/app.json'; -import { raiseError } from './error'; - -const { APP_CONFIG_FILE } = env; - -const configStore = create(() => ({ - ...defaultAppConfig, -})); - -export async function saveConfig(config) { - try { - await api.saveConfig(config); - - logger.log('Saved config file', APP_CONFIG_FILE, config); - - configStore.setState(config); - } catch (error) { - raiseError('Failed to save config file.', error); - } -} - -export async function loadConfig() { - try { - const config = await api.loadConfig(); - - if (config === null) { - return configStore.setState({ ...defaultAppConfig, uid: uniqueId() }); - } - - logger.log('Loaded config file', APP_CONFIG_FILE, config); - - configStore.setState(config); - } catch (error) { - raiseError('Failed to load config file.', error); - } -} - -export default configStore; diff --git a/src/view/actions/error.js b/src/view/actions/error.js deleted file mode 100644 index 0ee50b65..00000000 --- a/src/view/actions/error.js +++ /dev/null @@ -1,28 +0,0 @@ -import create from 'zustand'; -import { logger } from 'global'; -import { showModal } from './modals'; - -const initialState = { - error: null, - message: null, -}; - -const errorStore = create(() => ({ - ...initialState, -})); - -export function clearError() { - errorStore.setState({ ...initialState }); -} - -export function raiseError(message, error) { - if (error) { - logger.error(`${message}\n`, error.toString()); - } - - errorStore.setState({ message, error }); - - showModal('ErrorDialog', { title: 'Error' }); -} - -export default errorStore; diff --git a/src/view/actions/modals.js b/src/view/actions/modals.js deleted file mode 100644 index 9b142d8f..00000000 --- a/src/view/actions/modals.js +++ /dev/null @@ -1,22 +0,0 @@ -import create from 'zustand'; -import { uniqueId } from 'utils/crypto'; - -const initialState = { - modals: [], -}; - -const modalStore = create(() => ({ - ...initialState, -})); - -export function showModal(component, modalProps, componentProps) { - modalStore.setState(({ modals }) => ({ - modals: modals.concat({ id: uniqueId(), component, modalProps, componentProps }), - })); -} - -export function closeModal() { - modalStore.setState(({ modals }) => ({ modals: modals.slice(0, -1) })); -} - -export default modalStore; diff --git a/src/view/actions/project.js b/src/view/actions/project.js deleted file mode 100644 index c67b25fd..00000000 --- a/src/view/actions/project.js +++ /dev/null @@ -1,180 +0,0 @@ -import create from 'zustand'; -import { api, env, logger, reactors, stage, library } from 'global'; -import { updateCanvas, updateStage } from 'actions/stage'; -import { loadScenes, resetScenes } from 'actions/scenes'; -import { loadReactors, resetReactors } from 'actions/reactors'; -import { raiseError } from 'actions/error'; -import { showModal } from 'actions/modals'; -import Entity from 'core/Entity'; -import Stage from 'core/Stage'; -import Scene from 'core/Scene'; -import Display from 'core/Display'; -import AudioReactor from 'audio/AudioReactor'; -import { - DEFAULT_CANVAS_BGCOLOR, - DEFAULT_CANVAS_HEIGHT, - DEFAULT_CANVAS_WIDTH, -} from 'view/constants'; -import { resetLabelCount } from 'utils/controls'; - -const initialState = { - file: '', - opened: 0, - lastModified: 0, -}; - -const projectStore = create(() => ({ - ...initialState, -})); - -export function touchProject() { - projectStore.setState({ lastModified: Date.now() }); -} - -export function resetProject() { - projectStore.setState({ ...initialState }); -} - -export function loadProject(data) { - logger.log('Loaded project:', data); - - const displays = library.get('displays'); - const effects = library.get('effects'); - - const loadElement = (scene, config) => { - const { name } = config; - - const module = displays[name] || effects[name]; - - if (module) { - const entity = Display.create(module, config); - - scene.addElement(entity); - } else { - logger.warn('Component not found:', name); - } - }; - - resetScenes(false); - resetReactors(); - resetLabelCount(); - - if (data.stage) { - stage.update(data.stage.properties); - updateStage(data.stage.properties); - } else { - stage.update(Stage.defaultProperties); - } - - if (data.reactors) { - data.reactors.forEach(config => { - const reactor = Entity.create(AudioReactor, config); - - reactors.addReactor(reactor); - }); - } - - if (data.scenes) { - data.scenes.forEach(config => { - const scene = Display.create(Scene, config); - - stage.addScene(scene); - - if (config.displays) { - config.displays.forEach(display => loadElement(scene, display)); - } - - if (config.effects) { - config.effects.forEach(effect => loadElement(scene, effect)); - } - }); - } -} - -export async function newProject() { - resetLabelCount(); - await resetScenes(); - await resetReactors(); - await updateCanvas(DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_BGCOLOR); - - const scene = stage.addScene(); - const displays = library.get('displays'); - - scene.addElement(new displays.ImageDisplay()); - scene.addElement(new displays.BarSpectrumDisplay()); - scene.addElement(new displays.TextDisplay()); - - await loadScenes(); - await loadReactors(); - await resetProject(); -} - -export function checkUnsavedChanges(menuAction, action) { - const { opened, lastModified } = projectStore.getState(); - - if (lastModified > opened) { - showModal('UnsavedChangesDialog', { showCloseButton: false }, { action: menuAction }); - } else { - action(); - } -} - -export async function loadProjectFile(file) { - try { - const data = await api.loadProjectFile(file); - - await loadProject(data); - await loadScenes(); - await projectStore.setState({ file, opened: Date.now(), lastModified: 0 }); - } catch (e) { - return raiseError('Invalid project file.', e); - } -} - -export async function saveProjectFile(file) { - if (file) { - const data = { - version: env.APP_VERSION, - stage: stage.toJSON(), - scenes: stage.scenes.toJSON(), - reactors: reactors.toJSON(), - }; - - logger.debug('Save data', data); - - try { - await api.saveProjectFile(file, data); - - logger.log('Project saved:', file, data); - - projectStore.setState({ file, lastModified: 0 }); - - return true; - } catch (error) { - raiseError('Failed to save project file.', error); - } - } else { - const { filePath, canceled } = await api.showSaveDialog({ - defaultPath: 'project.afx', - filters: [{ name: 'Project files', extensions: ['afx'] }], - }); - - if (!canceled) { - await saveProjectFile(filePath); - } - } - - return false; -} - -export async function openProjectFile() { - const { filePaths, canceled } = await api.showOpenDialog({ - filters: [{ name: 'Project files', extensions: ['afx'] }], - }); - - if (!canceled) { - loadProjectFile(filePaths[0]); - } -} - -export default projectStore; diff --git a/src/view/actions/reactors.js b/src/view/actions/reactors.js deleted file mode 100644 index 16df5bc6..00000000 --- a/src/view/actions/reactors.js +++ /dev/null @@ -1,45 +0,0 @@ -import create from 'zustand'; -import { reactors } from 'global'; -import { setActiveReactorId } from './app'; - -const initialState = { - reactors: [], -}; - -const reactorStore = create(() => ({ - ...initialState, -})); - -export function loadReactors() { - reactorStore.setState({ reactors: reactors.toJSON() }); -} - -export function resetReactors() { - reactorStore.setState({ ...initialState }); - - reactors.clearReactors(); - - setActiveReactorId(null); -} - -export function addReactor(reactor) { - const newReactor = reactors.addReactor(reactor); - - loadReactors(); - - return newReactor; -} - -export function removeReactor(reactor) { - reactors.removeReactor(reactor); - - loadReactors(); -} - -export function clearReactors() { - reactors.clearReactors(); - - loadReactors(); -} - -export default reactorStore; diff --git a/src/view/actions/scenes.js b/src/view/actions/scenes.js deleted file mode 100644 index b421f2ef..00000000 --- a/src/view/actions/scenes.js +++ /dev/null @@ -1,89 +0,0 @@ -import create from 'zustand'; -import { stage } from 'global'; -import { touchProject } from './project'; - -const initialState = { - scenes: [], -}; - -const sceneStore = create(() => ({ - ...initialState, -})); - -export function loadScenes(touch = true) { - sceneStore.setState({ scenes: stage.scenes.toJSON() }); - - if (touch) { - touchProject(); - } -} - -export function resetScenes(touch = true) { - sceneStore.setState({ ...initialState }); - - stage.clearScenes(); - - if (touch) { - touchProject(); - } -} - -export function addScene() { - const scene = stage.addScene(); - - loadScenes(); - - return scene; -} - -export function addElement(element, sceneId) { - const scene = sceneId ? stage.getSceneById(sceneId) : stage.scenes[0]; - - if (scene) { - scene.addElement(element); - } - - loadScenes(); -} - -export function updateElement(id, prop, value) { - const element = stage.getStageElementById(id); - - if (element) { - element[prop] = value; - - loadScenes(); - } -} - -export function updateElementProperty(id, prop, value) { - const element = stage.getStageElementById(id); - - if (element) { - element.update({ [prop]: value }); - - loadScenes(); - } -} - -export function removeElement(id) { - const element = stage.getStageElementById(id); - - if (element) { - stage.removeStageElement(element); - - loadScenes(); - } -} - -export function moveElement(id, spaces) { - const element = stage.getStageElementById(id); - - if (element) { - stage.shiftStageElement(element, spaces); - - loadScenes(); - } -} - -export default sceneStore; diff --git a/src/view/actions/stage.js b/src/view/actions/stage.js deleted file mode 100644 index 9512d883..00000000 --- a/src/view/actions/stage.js +++ /dev/null @@ -1,66 +0,0 @@ -import create from 'zustand'; -import { stage } from 'view/global'; -import { - DEFAULT_CANVAS_BGCOLOR, - DEFAULT_CANVAS_HEIGHT, - DEFAULT_CANVAS_WIDTH, - DEFAULT_ZOOM, -} from 'view/constants'; -import { clamp } from 'utils/math'; -import { touchProject } from './project'; - -const initialState = { - width: DEFAULT_CANVAS_WIDTH, - height: DEFAULT_CANVAS_HEIGHT, - backgroundColor: DEFAULT_CANVAS_BGCOLOR, - zoom: DEFAULT_ZOOM, - loading: false, -}; - -const stageStore = create(() => ({ - ...initialState, -})); - -export function updateStage(props) { - stageStore.setState(props); - - stage.update(props); -} - -export function updateCanvas(width, height, backgroundColor) { - updateStage({ width, height, backgroundColor }); - - touchProject(); -} - -export function setZoom(value) { - updateStage({ zoom: clamp(value, 0.1, 1) }); -} - -export function zoomIn() { - const { zoom } = stageStore.getState(); - - const newValue = clamp(zoom - 0.1, 0.1, 1); - - updateStage({ zoom: newValue }); -} - -export function zoomOut() { - const { zoom } = stageStore.getState(); - - const newValue = clamp(zoom + 0.1, 0.1, 1.0); - - updateStage({ zoom: newValue }); -} - -export function fitToScreen() { - const viewport = document.getElementById('viewport'); - const { width, height, zoom } = stageStore.getState(); - - const newWidth = clamp((viewport.clientWidth * 0.8) / width, 0.1, 1); - const newHeight = clamp((viewport.clientHeight * 0.8) / height, 0.1, 1); - - updateStage({ zoom: Math.min(newWidth, newHeight) }); -} - -export default stageStore; diff --git a/src/view/actions/updates.js b/src/view/actions/updates.js deleted file mode 100644 index 0433c5d2..00000000 --- a/src/view/actions/updates.js +++ /dev/null @@ -1,70 +0,0 @@ -import create from 'zustand'; -import semver from 'semver'; -import { api, env, logger } from 'global'; -import configStore from './config'; - -const initialState = { - status: null, - checked: false, - hasUpdate: false, - downloadComplete: false, - downloadProgress: 0, - lastCheck: 0, - updateInfo: null, -}; - -const updateStore = create(() => ({ - ...initialState, -})); - -export function updateDownloadProgress(info) { - updateStore.setState({ downloadProgress: info.percent }); -} - -export async function downloadUpdate() { - updateStore.setState({ status: 'downloading' }); - - const result = await api.invoke('download-update'); - - logger.log('Update downloaded:', result); - - updateStore.setState({ downloadComplete: true, status: null }); -} - -export async function quitAndInstall() { - const { downloadComplete } = updateStore.getState(); - - if (downloadComplete) { - await api.invoke('quit-and-install'); - } -} - -export async function checkForUpdates() { - updateStore.setState({ status: 'checking', lastCheck: Date.now() }); - - try { - const { updateInfo } = await api.invoke('check-for-updates'); - - const hasUpdate = semver.gt(updateInfo.version, env.APP_VERSION); - const { autoUpdate } = configStore.getState(); - const status = autoUpdate && hasUpdate ? 'downloading' : null; - - logger.log('Update check complete', updateInfo); - - updateStore.setState({ checked: true, status, updateInfo, hasUpdate }); - - if (autoUpdate && hasUpdate) { - await downloadUpdate(); - } - } catch (e) { - updateStore.setState({ status: 'error' }); - - logger.error('Update check failed:', e); - } -} - -export function resetUpdates() { - updateStore.setState({ status: null }); -} - -export default updateStore; diff --git a/src/view/actions/video.js b/src/view/actions/video.js deleted file mode 100644 index 6c6f13f4..00000000 --- a/src/view/actions/video.js +++ /dev/null @@ -1,40 +0,0 @@ -import create from 'zustand'; -import { videoRenderer, player } from 'global'; - -const initialState = { - active: false, - finished: false, - status: '', - totalFrames: 0, - currentFrame: 0, - lastFrame: 0, - startTime: 0, -}; - -const videoStore = create(() => ({ ...initialState })); - -export function startRender(props) { - player.stop(); - - setTimeout(() => { - videoRenderer.start(props); - }, 500); - - videoStore.setState({ ...initialState, active: true }); -} - -export function stopRender() { - const { active } = videoStore.getState(); - - if (active) { - videoRenderer.stop(); - - videoStore.setState(state => ({ ...state, active: false })); - } -} - -export function updateState(props) { - videoStore.setState(state => ({ ...state, ...props })); -} - -export default videoStore; diff --git a/src/view/assets/fonts/LICENSE.txt b/src/view/assets/fonts/LICENSE.txt deleted file mode 100644 index 04df8a50..00000000 --- a/src/view/assets/fonts/LICENSE.txt +++ /dev/null @@ -1,86 +0,0 @@ ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/src/view/assets/fonts/abel.woff2 b/src/view/assets/fonts/abel.woff2 deleted file mode 100644 index 4daf9f79..00000000 Binary files a/src/view/assets/fonts/abel.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/abril-fatface.woff2 b/src/view/assets/fonts/abril-fatface.woff2 deleted file mode 100644 index 6d957af0..00000000 Binary files a/src/view/assets/fonts/abril-fatface.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/alegreya.woff2 b/src/view/assets/fonts/alegreya.woff2 deleted file mode 100644 index 8abdddc4..00000000 Binary files a/src/view/assets/fonts/alegreya.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/arimo.woff2 b/src/view/assets/fonts/arimo.woff2 deleted file mode 100644 index 71346b0f..00000000 Binary files a/src/view/assets/fonts/arimo.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/bangers.woff2 b/src/view/assets/fonts/bangers.woff2 deleted file mode 100644 index ab7c5234..00000000 Binary files a/src/view/assets/fonts/bangers.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/cardo.woff2 b/src/view/assets/fonts/cardo.woff2 deleted file mode 100644 index a717b25b..00000000 Binary files a/src/view/assets/fonts/cardo.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/caveat.woff2 b/src/view/assets/fonts/caveat.woff2 deleted file mode 100644 index 007e9632..00000000 Binary files a/src/view/assets/fonts/caveat.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/chunkfive.woff2 b/src/view/assets/fonts/chunkfive.woff2 deleted file mode 100644 index 4f45f1fb..00000000 Binary files a/src/view/assets/fonts/chunkfive.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/dynalight.woff2 b/src/view/assets/fonts/dynalight.woff2 deleted file mode 100644 index 8ad13497..00000000 Binary files a/src/view/assets/fonts/dynalight.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/felipa.woff2 b/src/view/assets/fonts/felipa.woff2 deleted file mode 100644 index 119350ef..00000000 Binary files a/src/view/assets/fonts/felipa.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/fira_sans.woff2 b/src/view/assets/fonts/fira_sans.woff2 deleted file mode 100644 index f8bd5dec..00000000 Binary files a/src/view/assets/fonts/fira_sans.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/intro.woff2 b/src/view/assets/fonts/intro.woff2 deleted file mode 100644 index 2ce88ad7..00000000 Binary files a/src/view/assets/fonts/intro.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/merriweather.woff2 b/src/view/assets/fonts/merriweather.woff2 deleted file mode 100644 index 0623a723..00000000 Binary files a/src/view/assets/fonts/merriweather.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/oswald.woff2 b/src/view/assets/fonts/oswald.woff2 deleted file mode 100644 index eab123f2..00000000 Binary files a/src/view/assets/fonts/oswald.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/oxygen.woff2 b/src/view/assets/fonts/oxygen.woff2 deleted file mode 100644 index 43d67d55..00000000 Binary files a/src/view/assets/fonts/oxygen.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/permanent-marker.woff2 b/src/view/assets/fonts/permanent-marker.woff2 deleted file mode 100644 index 1bbca8a6..00000000 Binary files a/src/view/assets/fonts/permanent-marker.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/playfair-display.woff2 b/src/view/assets/fonts/playfair-display.woff2 deleted file mode 100644 index ad97ded2..00000000 Binary files a/src/view/assets/fonts/playfair-display.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/racing-sans-one.woff2 b/src/view/assets/fonts/racing-sans-one.woff2 deleted file mode 100644 index 39ff98dd..00000000 Binary files a/src/view/assets/fonts/racing-sans-one.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/raleway.woff2 b/src/view/assets/fonts/raleway.woff2 deleted file mode 100644 index 35e3dbee..00000000 Binary files a/src/view/assets/fonts/raleway.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/roboto-condensed.woff2 b/src/view/assets/fonts/roboto-condensed.woff2 deleted file mode 100644 index 38e3f934..00000000 Binary files a/src/view/assets/fonts/roboto-condensed.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/roboto.woff2 b/src/view/assets/fonts/roboto.woff2 deleted file mode 100644 index 7f8c727f..00000000 Binary files a/src/view/assets/fonts/roboto.woff2 and /dev/null differ diff --git a/src/view/assets/fonts/vast-shadow.woff2 b/src/view/assets/fonts/vast-shadow.woff2 deleted file mode 100644 index e7c83528..00000000 Binary files a/src/view/assets/fonts/vast-shadow.woff2 and /dev/null differ diff --git a/src/view/assets/icons/adjust.svg b/src/view/assets/icons/adjust.svg deleted file mode 100644 index 4d2c5108..00000000 --- a/src/view/assets/icons/adjust.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/angle-double-left.svg b/src/view/assets/icons/angle-double-left.svg deleted file mode 100644 index f6edccb0..00000000 --- a/src/view/assets/icons/angle-double-left.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/angle-double-right.svg b/src/view/assets/icons/angle-double-right.svg deleted file mode 100644 index 6cd137a2..00000000 --- a/src/view/assets/icons/angle-double-right.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/arrows-cw.svg b/src/view/assets/icons/arrows-cw.svg deleted file mode 100644 index ecbecbb7..00000000 --- a/src/view/assets/icons/arrows-cw.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/arrows-h.svg b/src/view/assets/icons/arrows-h.svg deleted file mode 100644 index db4bff2e..00000000 --- a/src/view/assets/icons/arrows-h.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/bar-graph.svg b/src/view/assets/icons/bar-graph.svg deleted file mode 100644 index 1d582ea5..00000000 --- a/src/view/assets/icons/bar-graph.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/block.svg b/src/view/assets/icons/block.svg deleted file mode 100644 index b121cae2..00000000 --- a/src/view/assets/icons/block.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/ccw.svg b/src/view/assets/icons/ccw.svg deleted file mode 100644 index 04c9dbeb..00000000 --- a/src/view/assets/icons/ccw.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/check-circle.svg b/src/view/assets/icons/check-circle.svg deleted file mode 100644 index 8214cf14..00000000 --- a/src/view/assets/icons/check-circle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/chevron-down.svg b/src/view/assets/icons/chevron-down.svg deleted file mode 100644 index a75a55a9..00000000 --- a/src/view/assets/icons/chevron-down.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/chevron-left.svg b/src/view/assets/icons/chevron-left.svg deleted file mode 100644 index 07172ea8..00000000 --- a/src/view/assets/icons/chevron-left.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/chevron-right.svg b/src/view/assets/icons/chevron-right.svg deleted file mode 100644 index 27b27703..00000000 --- a/src/view/assets/icons/chevron-right.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/chevron-up.svg b/src/view/assets/icons/chevron-up.svg deleted file mode 100644 index 52fb5aa9..00000000 --- a/src/view/assets/icons/chevron-up.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/circle-filled.svg b/src/view/assets/icons/circle-filled.svg deleted file mode 100644 index a226699e..00000000 --- a/src/view/assets/icons/circle-filled.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/circle-with-cross.svg b/src/view/assets/icons/circle-with-cross.svg deleted file mode 100644 index f2dd74ce..00000000 --- a/src/view/assets/icons/circle-with-cross.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/circle.svg b/src/view/assets/icons/circle.svg deleted file mode 100644 index bbe6522e..00000000 --- a/src/view/assets/icons/circle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/cloud.svg b/src/view/assets/icons/cloud.svg deleted file mode 100644 index 0860d51a..00000000 --- a/src/view/assets/icons/cloud.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/code.svg b/src/view/assets/icons/code.svg deleted file mode 100644 index c9812be3..00000000 --- a/src/view/assets/icons/code.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/cog.svg b/src/view/assets/icons/cog.svg deleted file mode 100644 index cdf962e6..00000000 --- a/src/view/assets/icons/cog.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/contrast.svg b/src/view/assets/icons/contrast.svg deleted file mode 100644 index 67a3d3cd..00000000 --- a/src/view/assets/icons/contrast.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/crop.svg b/src/view/assets/icons/crop.svg deleted file mode 100644 index e51565ed..00000000 --- a/src/view/assets/icons/crop.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/cross.svg b/src/view/assets/icons/cross.svg deleted file mode 100644 index 78bf6bee..00000000 --- a/src/view/assets/icons/cross.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/cube.svg b/src/view/assets/icons/cube.svg deleted file mode 100644 index d0d54ef4..00000000 --- a/src/view/assets/icons/cube.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/cw.svg b/src/view/assets/icons/cw.svg deleted file mode 100644 index 8998f8f9..00000000 --- a/src/view/assets/icons/cw.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/cycle.svg b/src/view/assets/icons/cycle.svg deleted file mode 100644 index 609f9145..00000000 --- a/src/view/assets/icons/cycle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/document-landscape.svg b/src/view/assets/icons/document-landscape.svg deleted file mode 100644 index 677552c2..00000000 --- a/src/view/assets/icons/document-landscape.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/dots-three-horizontal.svg b/src/view/assets/icons/dots-three-horizontal.svg deleted file mode 100644 index d0f8a62a..00000000 --- a/src/view/assets/icons/dots-three-horizontal.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/download.svg b/src/view/assets/icons/download.svg deleted file mode 100644 index 65d3df3e..00000000 --- a/src/view/assets/icons/download.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/edit.svg b/src/view/assets/icons/edit.svg deleted file mode 100644 index 7638e00c..00000000 --- a/src/view/assets/icons/edit.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/expand.svg b/src/view/assets/icons/expand.svg deleted file mode 100644 index 9c9d6af4..00000000 --- a/src/view/assets/icons/expand.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/eye.svg b/src/view/assets/icons/eye.svg deleted file mode 100644 index f7e31f44..00000000 --- a/src/view/assets/icons/eye.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/flash.svg b/src/view/assets/icons/flash.svg deleted file mode 100644 index ee7507ec..00000000 --- a/src/view/assets/icons/flash.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/flashlight.svg b/src/view/assets/icons/flashlight.svg deleted file mode 100644 index 33523331..00000000 --- a/src/view/assets/icons/flashlight.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/folder-open.svg b/src/view/assets/icons/folder-open.svg deleted file mode 100644 index 101cfc41..00000000 --- a/src/view/assets/icons/folder-open.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/gear.svg b/src/view/assets/icons/gear.svg deleted file mode 100644 index 013b135f..00000000 --- a/src/view/assets/icons/gear.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/hand.svg b/src/view/assets/icons/hand.svg deleted file mode 100644 index f11d523f..00000000 --- a/src/view/assets/icons/hand.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/help-with-circle.svg b/src/view/assets/icons/help-with-circle.svg deleted file mode 100644 index 0ee08811..00000000 --- a/src/view/assets/icons/help-with-circle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/hour-glass.svg b/src/view/assets/icons/hour-glass.svg deleted file mode 100644 index 506fdcb2..00000000 --- a/src/view/assets/icons/hour-glass.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/info.svg b/src/view/assets/icons/info.svg deleted file mode 100644 index 4c8c3fd7..00000000 --- a/src/view/assets/icons/info.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/levels.svg b/src/view/assets/icons/levels.svg deleted file mode 100644 index ab99acc0..00000000 --- a/src/view/assets/icons/levels.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/light-up.svg b/src/view/assets/icons/light-up.svg deleted file mode 100644 index b9fd0466..00000000 --- a/src/view/assets/icons/light-up.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/light.svg b/src/view/assets/icons/light.svg deleted file mode 100644 index e65c8b80..00000000 --- a/src/view/assets/icons/light.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/lightbulb.svg b/src/view/assets/icons/lightbulb.svg deleted file mode 100644 index b6aa5758..00000000 --- a/src/view/assets/icons/lightbulb.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/link.svg b/src/view/assets/icons/link.svg deleted file mode 100644 index 6863dbdb..00000000 --- a/src/view/assets/icons/link.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/lock-open.svg b/src/view/assets/icons/lock-open.svg deleted file mode 100644 index 6e832a19..00000000 --- a/src/view/assets/icons/lock-open.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/lock.svg b/src/view/assets/icons/lock.svg deleted file mode 100644 index d0ef951a..00000000 --- a/src/view/assets/icons/lock.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/mask.svg b/src/view/assets/icons/mask.svg deleted file mode 100644 index 48ca902e..00000000 --- a/src/view/assets/icons/mask.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/menu.svg b/src/view/assets/icons/menu.svg deleted file mode 100644 index 3162be01..00000000 --- a/src/view/assets/icons/menu.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/minus.svg b/src/view/assets/icons/minus.svg deleted file mode 100644 index 7ba47df7..00000000 --- a/src/view/assets/icons/minus.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/move.svg b/src/view/assets/icons/move.svg deleted file mode 100644 index 4b5907d9..00000000 --- a/src/view/assets/icons/move.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/multiply.svg b/src/view/assets/icons/multiply.svg deleted file mode 100644 index e1f901de..00000000 --- a/src/view/assets/icons/multiply.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/music.svg b/src/view/assets/icons/music.svg deleted file mode 100644 index 15309229..00000000 --- a/src/view/assets/icons/music.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/pause.svg b/src/view/assets/icons/pause.svg deleted file mode 100644 index c151cb70..00000000 --- a/src/view/assets/icons/pause.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/pencil.svg b/src/view/assets/icons/pencil.svg deleted file mode 100644 index 9967ad67..00000000 --- a/src/view/assets/icons/pencil.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/picture.svg b/src/view/assets/icons/picture.svg deleted file mode 100644 index d85dedff..00000000 --- a/src/view/assets/icons/picture.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/play.svg b/src/view/assets/icons/play.svg deleted file mode 100644 index 20c8028b..00000000 --- a/src/view/assets/icons/play.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/plus.svg b/src/view/assets/icons/plus.svg deleted file mode 100644 index c810089d..00000000 --- a/src/view/assets/icons/plus.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/view/assets/icons/puzzle.svg b/src/view/assets/icons/puzzle.svg deleted file mode 100644 index 9dd89df5..00000000 --- a/src/view/assets/icons/puzzle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/refresh.svg b/src/view/assets/icons/refresh.svg deleted file mode 100644 index b80d40ab..00000000 --- a/src/view/assets/icons/refresh.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/retweet.svg b/src/view/assets/icons/retweet.svg deleted file mode 100644 index 09a1eeb1..00000000 --- a/src/view/assets/icons/retweet.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/search.svg b/src/view/assets/icons/search.svg deleted file mode 100644 index c9eb8120..00000000 --- a/src/view/assets/icons/search.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/selection.svg b/src/view/assets/icons/selection.svg deleted file mode 100644 index 2175fe51..00000000 --- a/src/view/assets/icons/selection.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/sound-bars.svg b/src/view/assets/icons/sound-bars.svg deleted file mode 100644 index 9e2544b3..00000000 --- a/src/view/assets/icons/sound-bars.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/sound-waves.svg b/src/view/assets/icons/sound-waves.svg deleted file mode 100644 index f614c9db..00000000 --- a/src/view/assets/icons/sound-waves.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/square-circle.svg b/src/view/assets/icons/square-circle.svg deleted file mode 100644 index 70109b1d..00000000 --- a/src/view/assets/icons/square-circle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/square.svg b/src/view/assets/icons/square.svg deleted file mode 100644 index dcb5c68c..00000000 --- a/src/view/assets/icons/square.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/stop.svg b/src/view/assets/icons/stop.svg deleted file mode 100644 index 8dc27775..00000000 --- a/src/view/assets/icons/stop.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/times-circle.svg b/src/view/assets/icons/times-circle.svg deleted file mode 100644 index 4496c1dd..00000000 --- a/src/view/assets/icons/times-circle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/times.svg b/src/view/assets/icons/times.svg deleted file mode 100644 index c7b596d0..00000000 --- a/src/view/assets/icons/times.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/trash-empty.svg b/src/view/assets/icons/trash-empty.svg deleted file mode 100644 index 6663f37b..00000000 --- a/src/view/assets/icons/trash-empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/trash.svg b/src/view/assets/icons/trash.svg deleted file mode 100644 index 73eb1e6c..00000000 --- a/src/view/assets/icons/trash.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/trashcan.svg b/src/view/assets/icons/trashcan.svg deleted file mode 100644 index d7f905ee..00000000 --- a/src/view/assets/icons/trashcan.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/video.svg b/src/view/assets/icons/video.svg deleted file mode 100644 index 5b05c6c8..00000000 --- a/src/view/assets/icons/video.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/videocam.svg b/src/view/assets/icons/videocam.svg deleted file mode 100644 index 0e820fe7..00000000 --- a/src/view/assets/icons/videocam.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/volume.svg b/src/view/assets/icons/volume.svg deleted file mode 100644 index 2f324ecd..00000000 --- a/src/view/assets/icons/volume.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/volume2.svg b/src/view/assets/icons/volume2.svg deleted file mode 100644 index 4c79a987..00000000 --- a/src/view/assets/icons/volume2.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/volume3.svg b/src/view/assets/icons/volume3.svg deleted file mode 100644 index 0294fd7d..00000000 --- a/src/view/assets/icons/volume3.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/volume4.svg b/src/view/assets/icons/volume4.svg deleted file mode 100644 index 9f9ec612..00000000 --- a/src/view/assets/icons/volume4.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/warning.svg b/src/view/assets/icons/warning.svg deleted file mode 100644 index 269ae2c1..00000000 --- a/src/view/assets/icons/warning.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/icons/wave.svg b/src/view/assets/icons/wave.svg deleted file mode 100644 index 811fcccb..00000000 --- a/src/view/assets/icons/wave.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/assets/images/about_bg.jpg b/src/view/assets/images/about_bg.jpg deleted file mode 100644 index 90915450..00000000 Binary files a/src/view/assets/images/about_bg.jpg and /dev/null differ diff --git a/src/view/assets/images/blank.gif b/src/view/assets/images/blank.gif deleted file mode 100644 index b3aa80d8..00000000 Binary files a/src/view/assets/images/blank.gif and /dev/null differ diff --git a/src/view/assets/images/controls/BarSpectrumDisplay.png b/src/view/assets/images/controls/BarSpectrumDisplay.png deleted file mode 100644 index 7289c10a..00000000 Binary files a/src/view/assets/images/controls/BarSpectrumDisplay.png and /dev/null differ diff --git a/src/view/assets/images/controls/BloomEffect.png b/src/view/assets/images/controls/BloomEffect.png deleted file mode 100644 index 570049da..00000000 Binary files a/src/view/assets/images/controls/BloomEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/BlurEffect.png b/src/view/assets/images/controls/BlurEffect.png deleted file mode 100644 index cd5edda4..00000000 Binary files a/src/view/assets/images/controls/BlurEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/ColorHalftoneEffect.png b/src/view/assets/images/controls/ColorHalftoneEffect.png deleted file mode 100644 index d39fafa0..00000000 Binary files a/src/view/assets/images/controls/ColorHalftoneEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/DistortionEffect.png b/src/view/assets/images/controls/DistortionEffect.png deleted file mode 100644 index 4db06e69..00000000 Binary files a/src/view/assets/images/controls/DistortionEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/DotScreenEffect.png b/src/view/assets/images/controls/DotScreenEffect.png deleted file mode 100644 index b76d0e1c..00000000 Binary files a/src/view/assets/images/controls/DotScreenEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/GeometryDisplay.png b/src/view/assets/images/controls/GeometryDisplay.png deleted file mode 100644 index ccb71de3..00000000 Binary files a/src/view/assets/images/controls/GeometryDisplay.png and /dev/null differ diff --git a/src/view/assets/images/controls/GlitchEffect.png b/src/view/assets/images/controls/GlitchEffect.png deleted file mode 100644 index 13655dc3..00000000 Binary files a/src/view/assets/images/controls/GlitchEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/GlowEffect.png b/src/view/assets/images/controls/GlowEffect.png deleted file mode 100644 index 1488112f..00000000 Binary files a/src/view/assets/images/controls/GlowEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/ImageDisplay.png b/src/view/assets/images/controls/ImageDisplay.png deleted file mode 100644 index 90e2f15f..00000000 Binary files a/src/view/assets/images/controls/ImageDisplay.png and /dev/null differ diff --git a/src/view/assets/images/controls/KaleidoscopeEffect.png b/src/view/assets/images/controls/KaleidoscopeEffect.png deleted file mode 100644 index 89d6e6b8..00000000 Binary files a/src/view/assets/images/controls/KaleidoscopeEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/LEDEffect.png b/src/view/assets/images/controls/LEDEffect.png deleted file mode 100644 index 38527290..00000000 Binary files a/src/view/assets/images/controls/LEDEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/MirrorEffect.png b/src/view/assets/images/controls/MirrorEffect.png deleted file mode 100644 index c2b792a8..00000000 Binary files a/src/view/assets/images/controls/MirrorEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/PixelateEffect.png b/src/view/assets/images/controls/PixelateEffect.png deleted file mode 100644 index 99b9c7ca..00000000 Binary files a/src/view/assets/images/controls/PixelateEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/Plugin.png b/src/view/assets/images/controls/Plugin.png deleted file mode 100644 index 47756eab..00000000 Binary files a/src/view/assets/images/controls/Plugin.png and /dev/null differ diff --git a/src/view/assets/images/controls/RGBShiftEffect.png b/src/view/assets/images/controls/RGBShiftEffect.png deleted file mode 100644 index 77bad93e..00000000 Binary files a/src/view/assets/images/controls/RGBShiftEffect.png and /dev/null differ diff --git a/src/view/assets/images/controls/ShapeDisplay.png b/src/view/assets/images/controls/ShapeDisplay.png deleted file mode 100644 index c20e5c3b..00000000 Binary files a/src/view/assets/images/controls/ShapeDisplay.png and /dev/null differ diff --git a/src/view/assets/images/controls/SoundWaveDisplay.png b/src/view/assets/images/controls/SoundWaveDisplay.png deleted file mode 100644 index 8e144073..00000000 Binary files a/src/view/assets/images/controls/SoundWaveDisplay.png and /dev/null differ diff --git a/src/view/assets/images/controls/TextDisplay.png b/src/view/assets/images/controls/TextDisplay.png deleted file mode 100644 index f21e98c1..00000000 Binary files a/src/view/assets/images/controls/TextDisplay.png and /dev/null differ diff --git a/src/view/assets/images/controls/WaveSpectrumDisplay.png b/src/view/assets/images/controls/WaveSpectrumDisplay.png deleted file mode 100644 index f2c5010f..00000000 Binary files a/src/view/assets/images/controls/WaveSpectrumDisplay.png and /dev/null differ diff --git a/src/view/assets/images/point.png b/src/view/assets/images/point.png deleted file mode 100644 index 356b999d..00000000 Binary files a/src/view/assets/images/point.png and /dev/null differ diff --git a/src/view/assets/logo.svg b/src/view/assets/logo.svg deleted file mode 100644 index 6a3fcd98..00000000 --- a/src/view/assets/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/view/components/App.js b/src/view/components/App.js deleted file mode 100644 index 98114a18..00000000 --- a/src/view/components/App.js +++ /dev/null @@ -1,41 +0,0 @@ -import React, { useEffect } from 'react'; -import { ignoreEvents } from 'utils/react'; -import Layout from 'components/layout/Layout'; -import Modals from 'components/window/Modals'; -import Preload from 'components/window/Preload'; -import StatusBar from 'components/window/StatusBar'; -import TitleBar from 'components/window/TitleBar'; -import ControlDock from 'components/panels/ControlDock'; -import ReactorPanel from 'components/panels/ReactorPanel'; -import Player from 'components/player/Player'; -import Stage from 'components/stage/Stage'; -import { initApp } from 'actions/app'; - -function App() { - async function init() { - await initApp(); - } - - useEffect(() => { - init(); - }, []); - - return ( - - - - - - - - - - - - - - - ); -} - -export default App; diff --git a/src/view/components/controls/Control.js b/src/view/components/controls/Control.js deleted file mode 100644 index ced97316..00000000 --- a/src/view/components/controls/Control.js +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import Option from 'components/controls/Option'; -import useEntity from 'hooks/useEntity'; -import { inputValueToProps } from 'utils/react'; -import { resolve } from 'utils/object'; -import styles from './Control.less'; - -export default function Control({ display, className, showHeader = true }) { - const { - displayName, - constructor: { - config: { label, controls = {} }, - }, - } = display; - - const onChange = useEntity(display); - - function mapOption(name, option) { - const props = {}; - - for (const [name, value] of Object.entries(option)) { - props[name] = resolve(value, [display]); - } - - return ( -