├── .browserslistrc
├── .gitignore
├── .prettierrc
├── LICENSE
├── README.md
├── lib
├── perceptive-design.common.js
├── perceptive-design.common.js.map
└── perceptive-design.css
├── package.json
├── public
├── .htaccess
├── assets
│ ├── Beko-mochi.jpg
│ ├── Dango.jpg
│ ├── Mochi.jpg
│ ├── icon_b.svg
│ ├── icon_chain.svg
│ ├── icon_cross.svg
│ ├── icon_drag-handle.svg
│ ├── icon_gear.svg
│ ├── icon_h.svg
│ ├── icon_hamburger.svg
│ ├── icon_pause.svg
│ ├── icon_play.svg
│ ├── icon_plus.svg
│ ├── icon_refresh.svg
│ ├── icon_right-arrow.svg
│ ├── icon_s.svg
│ ├── icon_swap.svg
│ ├── icon_unlinked-chain.svg
│ ├── page-link_abstract.png
│ ├── page-link_components-list.png
│ ├── page-link_hardware-assign.png
│ ├── page-link_parameter-control.png
│ ├── page-link_pentool.png
│ ├── page-link_transformation-matrix.png
│ └── page-link_velocity-curve.png
└── index.html
├── src
├── App.vue
├── assets
│ ├── Mochi.jpg
│ └── dice.svg
├── components
│ ├── ConfigProvider.ts
│ ├── InputAngle
│ │ ├── InputAngle.vue
│ │ └── index.ts
│ ├── InputButton
│ │ ├── InputButton.vue
│ │ └── index.ts
│ ├── InputCheckbox
│ │ ├── InputCheckbox.vue
│ │ └── index.ts
│ ├── InputCodeEditor
│ │ ├── InputCodeEditor.vue
│ │ └── index.ts
│ ├── InputColor
│ │ ├── InputColor.vue
│ │ ├── InputColorElement.vue
│ │ └── index.ts
│ ├── InputColorButton
│ │ ├── InputColorButton.vue
│ │ └── index.ts
│ ├── InputColorPicker
│ │ ├── InputColorPicker.vue
│ │ └── index.ts
│ ├── InputDropdown
│ │ ├── InputDropdown.vue
│ │ └── index.ts
│ ├── InputIconAction
│ │ ├── InputIconAction.vue
│ │ └── index.ts
│ ├── InputIconButton
│ │ ├── InputIconButton.vue
│ │ └── index.ts
│ ├── InputIconToggle
│ │ ├── InputIconToggle.vue
│ │ └── index.ts
│ ├── InputMatrix
│ │ ├── InputMatrix.vue
│ │ └── index.ts
│ ├── InputMode
│ │ ├── InputMode.vue
│ │ └── index.ts
│ ├── InputNumber
│ │ ├── InputNumber.vue
│ │ └── index.ts
│ ├── InputPoint
│ │ ├── InputPoint.vue
│ │ └── index.ts
│ ├── InputRange
│ │ ├── InputRange.vue
│ │ └── index.ts
│ ├── InputSlider
│ │ ├── InputSlider.vue
│ │ └── index.ts
│ ├── InputString
│ │ ├── InputString.vue
│ │ └── index.ts
│ ├── InputTime
│ │ ├── InputTime.vue
│ │ └── index.ts
│ ├── InputVector
│ │ ├── InputVector.vue
│ │ └── index.ts
│ ├── LayoutSplitter
│ │ ├── LayoutSplitter.vue
│ │ └── index.ts
│ ├── LayoutTab
│ │ ├── LayoutTab.vue
│ │ └── index.ts
│ ├── LayoutTabs
│ │ ├── LayoutTabs.vue
│ │ └── index.ts
│ ├── PaneBind
│ │ ├── PaneBind.vue
│ │ └── index.ts
│ ├── ParamFieldAffine.vue
│ ├── ParamFieldAngle.vue
│ ├── ParamFieldBind.vue
│ ├── ParamFieldCheckbox.vue
│ ├── ParamFieldColor.vue
│ ├── ParamFieldDropdown.vue
│ ├── ParamFieldMode.vue
│ ├── ParamFieldNumber.vue
│ ├── ParamFieldPoint.vue
│ ├── ParamFieldRange.vue
│ ├── ParamFieldScale.vue
│ ├── ParamFieldSeed.vue
│ ├── ParamFieldSlider.vue
│ ├── ParamFieldString.vue
│ ├── ParamFieldVector.vue
│ ├── ParameterList
│ │ ├── Parameter.vue
│ │ ├── ParameterList.vue
│ │ └── index.ts
│ ├── SelectionManager.vue
│ ├── Timeline
│ │ ├── Timeline.vue
│ │ ├── TimelineSeekbarScale.vue
│ │ └── index.ts
│ ├── TimelineColor
│ │ ├── TimelineColor.vue
│ │ └── index.ts
│ ├── TimelineDraw
│ │ ├── TimelineDraw.vue
│ │ └── index.ts
│ ├── common
│ │ ├── Drag.ts
│ │ ├── GradientPalette
│ │ │ ├── GradientPalette.vue
│ │ │ ├── gradient-palette.frag
│ │ │ ├── gradient-palette.vert
│ │ │ └── index.ts
│ │ ├── Icon.vue
│ │ ├── Menu
│ │ │ ├── Menu.vue
│ │ │ ├── MenuItem.ts
│ │ │ ├── Submenu.vue
│ │ │ └── index.ts
│ │ ├── Modal.vue
│ │ ├── Popover.vue
│ │ ├── Portal.ts
│ │ ├── SvgArcArrow.vue
│ │ ├── SvgArrow.vue
│ │ └── SvgOverlayHorizontalDrag.vue
│ └── index.ts
├── core
│ ├── config.ts
│ └── index.ts
├── data
│ ├── BaseNode.ts
│ ├── Color.ts
│ ├── IndexedNode.ts
│ ├── Mat2.ts
│ ├── Mat2d.ts
│ ├── Mat3.ts
│ ├── Mat4.ts
│ ├── Schema.ts
│ ├── Time.ts
│ ├── Vec2.ts
│ ├── Vec3.ts
│ ├── common.ts
│ └── index.ts
├── index.ts
├── main.ts
├── manager
│ ├── BindManager.ts
│ └── HistoryManager.ts
├── math
│ └── index.ts
├── pages
│ ├── Abstract.vue
│ ├── ComponentsList.vue
│ ├── Easing
│ │ ├── Easing.vue
│ │ └── index.ts
│ ├── GraphicsOnLisp
│ │ ├── GraphicsOnLisp.vue
│ │ ├── index.ts
│ │ └── parser.ts
│ ├── Home
│ │ ├── Home.vue
│ │ ├── PageLink.vue
│ │ └── index.ts
│ ├── ParameterControl
│ │ ├── ParameterControl.vue
│ │ ├── index.ts
│ │ ├── polar-disp.frag
│ │ └── polar-disp.meta.txt
│ ├── Settings.vue
│ └── TransformationMatrix
│ │ ├── Param.vue
│ │ ├── TransformationMatrix.vue
│ │ ├── index.ts
│ │ ├── matrix-util.ts
│ │ ├── transform-stack-store.ts
│ │ └── transform-store.ts
├── router.ts
├── shims-modules.d.ts
├── shims-tsx.d.ts
├── shims-vue.d.ts
├── style
│ ├── article.styl
│ ├── common.styl
│ └── config.styl
└── util
│ ├── MouseDragEvent.ts
│ ├── RoteryDrag.ts
│ ├── Timecode.ts
│ ├── constrain-value.ts
│ ├── deepcopy.ts
│ ├── deserialize.ts
│ ├── disable-reactive.ts
│ ├── force-notify.ts
│ ├── index.ts
│ └── split-to-parent-and-key.ts
├── tsconfig.json
├── tslint.json
├── typings
├── components
│ ├── ConfigProvider.d.ts
│ ├── InputAngle.vue.d.ts
│ ├── InputButton.vue.d.ts
│ ├── InputCheckbox.vue.d.ts
│ ├── InputCodeEditor
│ │ ├── InputCodeEditor.vue.d.ts
│ │ └── index.d.ts
│ ├── InputColor
│ │ ├── InputColor.vue.d.ts
│ │ ├── InputColorElement.vue.d.ts
│ │ └── index.d.ts
│ ├── InputColorButton.vue.d.ts
│ ├── InputColorPicker.vue.d.ts
│ ├── InputDropdown.vue.d.ts
│ ├── InputIconAction
│ │ ├── InputIconAction.vue.d.ts
│ │ └── index.d.ts
│ ├── InputIconButton.vue.d.ts
│ ├── InputIconToggle.vue.d.ts
│ ├── InputMatrix.vue.d.ts
│ ├── InputMode.vue.d.ts
│ ├── InputNumber.vue.d.ts
│ ├── InputPoint.vue.d.ts
│ ├── InputRange.vue.d.ts
│ ├── InputSlider.vue.d.ts
│ ├── InputString.vue.d.ts
│ ├── InputTime
│ │ ├── InputTime.vue.d.ts
│ │ └── index.d.ts
│ ├── InputVector.vue.d.ts
│ ├── ParamFieldAffine.vue.d.ts
│ ├── ParamFieldAngle.vue.d.ts
│ ├── ParamFieldColor.vue.d.ts
│ ├── ParamFieldNumber.vue.d.ts
│ ├── ParamFieldPoint.vue.d.ts
│ ├── ParamFieldRange.vue.d.ts
│ ├── ParamFieldScale.vue.d.ts
│ ├── ParamFieldSeed.vue.d.ts
│ ├── ParamFieldSlider.vue.d.ts
│ ├── Parameter.vue.d.ts
│ ├── SelectionManager.vue.d.ts
│ ├── Timeline
│ │ ├── Timeline.vue.d.ts
│ │ ├── TimelineSeekbarScale.vue.d.ts
│ │ └── index.d.ts
│ ├── TimelineColor.vue.d.ts
│ ├── common
│ │ ├── ButtonWrapper.d.ts
│ │ ├── Drag.d.ts
│ │ ├── GradientPalette
│ │ │ ├── GradientPalette.vue.d.ts
│ │ │ └── index.d.ts
│ │ ├── Icon.vue.d.ts
│ │ ├── Menu
│ │ │ ├── Menu.vue.d.ts
│ │ │ ├── MenuItem.d.ts
│ │ │ ├── Submenu.vue.d.ts
│ │ │ └── index.d.ts
│ │ ├── Popover.vue.d.ts
│ │ ├── Portal.d.ts
│ │ ├── SvgArcArrow.vue.d.ts
│ │ └── SvgArrow.vue.d.ts
│ └── index.d.ts
├── data
│ └── index.d.ts
├── index.d.ts
├── math
│ └── index.d.ts
└── util
│ ├── RoteryDrag.d.ts
│ ├── Timecode.d.ts
│ ├── index.d.ts
│ └── keypressed.d.ts
├── vue.config.js
└── yarn.lock
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not ie <= 8
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | /resources
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 |
15 | # Editor directories and files
16 | .idea
17 | .vscode
18 | *.suo
19 | *.ntvs*
20 | *.njsproj
21 | *.sln
22 | *.sw*
23 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": true,
3 | "singleQuote": true,
4 | "bracketSpacing": false,
5 | "semi": false
6 | }
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018 Baku Hashimoto
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # UI Study
2 |
3 | 
4 |
5 | **[Demo](http://ui.baku89.com)**
6 |
7 | Study of patameter controls UI for creative-purpose softwares. (Such as AfterEffects, Cinema4D)
8 |
9 | The motivation of this project is described here: [Study of UI](http://baku89.com/ui-study)
10 |
11 | ## Development Environment
12 |
13 | ### Transpiler languages
14 |
15 | - JavaScript: [TypeScript](https://www.typescriptlang.org/)
16 | - CSS: [Stylus](http://stylus-lang.com/)
17 |
18 | ### Build tools
19 |
20 | - Yarn
21 | - Vue CLI 3
22 |
23 | ### To transpile and debug:
24 |
25 | ```
26 | yarn install
27 | yarn serve
28 | ```
29 |
30 | ## Relating Documents
31 |
32 | - [Classified Table of Parameter Controls](https://docs.google.com/spreadsheets/d/1iyjMUTgJAZhPu4Rg2aV1QPgwSUWBAfuuRCwx0Yki4XM/edit#gid=0)
33 |
34 | ## License
35 |
36 | This repository is published under a MIT License. See the included [LISENCE file](/LICENSE).
37 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ui-study",
3 | "version": "2.0.3",
4 | "author": {
5 | "name": "Baku Hashimoto",
6 | "email": "mail@baku89.com"
7 | },
8 | "types": "typings/index.d.ts",
9 | "private": true,
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/baku89/ui-study.git"
13 | },
14 | "files": [
15 | "lib"
16 | ],
17 | "main": "lib/perceptive-design.common.js",
18 | "scripts": {
19 | "serve": "vue-cli-service serve --modern",
20 | "build": "vue-cli-service build --modern",
21 | "lint": "vue-cli-service lint",
22 | "build:lib": "vue-cli-service build --modern --target lib --formats commonjs --name perceptive-design ./src/index.ts --dest lib; rm -rf ./typings/router.d.ts ./typings/main.d.ts ./typings/pages"
23 | },
24 | "dependencies": {},
25 | "devDependencies": {
26 | "@types/color-convert": "^1.9.0",
27 | "@types/gl-matrix": "^2.4.5",
28 | "@types/hex-rgb": "^3.0.0",
29 | "@types/json5": "^0.0.30",
30 | "@types/mathjs": "^5.0.1",
31 | "@types/mousetrap": "^1.6.2",
32 | "@types/raf": "^3.4.0",
33 | "@types/webgl2": "^0.0.4",
34 | "@vue/cli-plugin-typescript": "^3.3.0",
35 | "@vue/cli-service": "^3.3.0",
36 | "autoprefixer-stylus": "^0.14.0",
37 | "brace": "^0.11.1",
38 | "case": "^1.6.1",
39 | "change-case": "^3.1.0",
40 | "color-convert": "^2.0.0",
41 | "core-decorators": "^0.20.0",
42 | "declaration-bundler-webpack-plugin": "^1.0.3",
43 | "deepcopy": "^2.0.0",
44 | "deepmerge": "^3.2.0",
45 | "eventemitter3": "^3.1.0",
46 | "fuzzy": "^0.1.3",
47 | "gl-matrix": "^3.0.0",
48 | "glslify-loader": "^2.0.0",
49 | "hex-rgb": "^4.0.0",
50 | "interactive-shader-format": "^2.9.0",
51 | "json-formatter-js": "^2.2.1",
52 | "json5": "^2.1.0",
53 | "keycode": "^2.2.0",
54 | "mathjs": "^5.9.0",
55 | "mobx": "^5.9.4",
56 | "mobx-vue": "^2.0.8",
57 | "mouse-event": "^1.0.5",
58 | "mousetrap": "^1.6.3",
59 | "nib": "^1.1.2",
60 | "popper.js": "^1.15.0",
61 | "raw-loader": "^1.0.0",
62 | "stylus": "^0.54.5",
63 | "stylus-loader": "^3.0.2",
64 | "tslint-config-prettier": "^1.17.0",
65 | "twgl.js": "^4.9.1",
66 | "typescript": "^3.0.0",
67 | "uid": "^0.0.2",
68 | "vue": "^2.6.10",
69 | "vue-class-component": "^7.0.2",
70 | "vue-property-decorator": "^8.1.0",
71 | "vue-router": "^3.0.3",
72 | "vue-template-compiler": "^2.6.10",
73 | "vuedraggable": "^2.20.0",
74 | "webmidi": "^2.3.3"
75 | },
76 | "license": "MIT"
77 | }
78 |
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | RewriteEngine On
3 | RewriteBase /
4 | RewriteRule ^index\.html$ - [L]
5 | RewriteCond %{REQUEST_FILENAME} !-f
6 | RewriteCond %{REQUEST_FILENAME} !-d
7 | RewriteRule . /index.html [L]
8 |
--------------------------------------------------------------------------------
/public/assets/Beko-mochi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/public/assets/Beko-mochi.jpg
--------------------------------------------------------------------------------
/public/assets/Dango.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/public/assets/Dango.jpg
--------------------------------------------------------------------------------
/public/assets/Mochi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/public/assets/Mochi.jpg
--------------------------------------------------------------------------------
/public/assets/icon_b.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_chain.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_cross.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_drag-handle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_gear.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_h.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_hamburger.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_pause.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_play.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_plus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_refresh.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_right-arrow.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_s.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_swap.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/icon_unlinked-chain.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/page-link_abstract.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/public/assets/page-link_abstract.png
--------------------------------------------------------------------------------
/public/assets/page-link_components-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/public/assets/page-link_components-list.png
--------------------------------------------------------------------------------
/public/assets/page-link_hardware-assign.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/public/assets/page-link_hardware-assign.png
--------------------------------------------------------------------------------
/public/assets/page-link_parameter-control.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/public/assets/page-link_parameter-control.png
--------------------------------------------------------------------------------
/public/assets/page-link_pentool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/public/assets/page-link_pentool.png
--------------------------------------------------------------------------------
/public/assets/page-link_transformation-matrix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/public/assets/page-link_transformation-matrix.png
--------------------------------------------------------------------------------
/public/assets/page-link_velocity-curve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/public/assets/page-link_velocity-curve.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | The UI Design for Design
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/assets/Mochi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/src/assets/Mochi.jpg
--------------------------------------------------------------------------------
/src/assets/dice.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/ConfigProvider.ts:
--------------------------------------------------------------------------------
1 | import {Component, Vue} from 'vue-property-decorator'
2 | import Case from 'case'
3 |
4 | import {ConfigDefault} from '../core/config'
5 | import Color from '../data/Color'
6 | import deepcopy from '../util/deepcopy'
7 |
8 | @Component({
9 | data() {
10 | return {
11 | Config: deepcopy(ConfigDefault)
12 | }
13 | },
14 | provide() {
15 | return {
16 | Config: this.$data.Config
17 | }
18 | }
19 | })
20 | export default class ConfigProvider extends Vue {
21 | private Config!: any
22 |
23 | private get attrElement(): HTMLElement {
24 | return document.documentElement
25 | }
26 |
27 | private created() {
28 | this.$watch('Config.lang', this.updateLang, {immediate: true})
29 | }
30 |
31 | private mounted() {
32 | // Set theme
33 | const {theme} = this.Config
34 | for (const key of Object.keys(theme)) {
35 | this.$watch(
36 | `Config.theme.${key}`,
37 | (newValue: any) => {
38 | this.updateThemeProperty(key, newValue)
39 | },
40 | {immediate: true}
41 | )
42 | }
43 | }
44 |
45 | private render() {
46 | return this.$scopedSlots.default!({
47 | Config: this.Config
48 | })
49 | }
50 |
51 | private updateLang(lang: string = this.Config.lang) {
52 | this.attrElement.classList.remove('en', 'ja')
53 | this.attrElement.classList.add(lang)
54 | }
55 |
56 | private updateThemeProperty(key: string, value: any) {
57 | const variableName = `--${Case.kebab(key)}`
58 | let cssValue = value
59 |
60 | if (/^color/.test(key)) {
61 | cssValue = (value as Color).cssColor
62 | } else if (/^layout/.test(key)) {
63 | cssValue += 'em'
64 | } else if (key === 'fontSize') {
65 | cssValue += 'px'
66 | }
67 | this.attrElement.style.setProperty(variableName, cssValue)
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/components/InputAngle/InputAngle.vue:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
106 |
107 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/src/components/InputAngle/index.ts:
--------------------------------------------------------------------------------
1 | import InputAngle from './InputAngle.vue'
2 |
3 | export default InputAngle
4 |
--------------------------------------------------------------------------------
/src/components/InputButton/InputButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
31 |
32 |
33 |
68 |
--------------------------------------------------------------------------------
/src/components/InputButton/index.ts:
--------------------------------------------------------------------------------
1 | import InputButton from './InputButton.vue'
2 |
3 | export default InputButton
4 |
--------------------------------------------------------------------------------
/src/components/InputCheckbox/InputCheckbox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
26 |
27 |
28 |
72 |
73 |
--------------------------------------------------------------------------------
/src/components/InputCheckbox/index.ts:
--------------------------------------------------------------------------------
1 | import InputCheckbox from './InputCheckbox.vue'
2 |
3 | export default InputCheckbox
4 |
--------------------------------------------------------------------------------
/src/components/InputCodeEditor/InputCodeEditor.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
62 |
63 |
79 |
--------------------------------------------------------------------------------
/src/components/InputCodeEditor/index.ts:
--------------------------------------------------------------------------------
1 | import InputCodeEditor from './InputCodeEditor.vue'
2 |
3 | export default InputCodeEditor
4 |
--------------------------------------------------------------------------------
/src/components/InputColor/InputColor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
17 |
23 |
29 |
30 |
31 |
32 |
33 |
80 |
81 |
86 |
--------------------------------------------------------------------------------
/src/components/InputColor/index.ts:
--------------------------------------------------------------------------------
1 | import InputColor from './InputColor.vue'
2 |
3 | export default InputColor
4 |
--------------------------------------------------------------------------------
/src/components/InputColorButton/InputColorButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
34 |
35 |
36 |
95 |
96 |
97 |
144 |
145 |
--------------------------------------------------------------------------------
/src/components/InputColorButton/index.ts:
--------------------------------------------------------------------------------
1 | import InputColorButton from './InputColorButton.vue'
2 |
3 | export default InputColorButton
4 |
--------------------------------------------------------------------------------
/src/components/InputColorPicker/index.ts:
--------------------------------------------------------------------------------
1 | import InputColorPicker from './InputColorPicker.vue'
2 |
3 | export default InputColorPicker
4 |
--------------------------------------------------------------------------------
/src/components/InputDropdown/InputDropdown.vue:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
41 |
42 |
43 |
98 |
99 |
--------------------------------------------------------------------------------
/src/components/InputDropdown/index.ts:
--------------------------------------------------------------------------------
1 | import InputDropdown from './InputDropdown.vue'
2 |
3 | export default InputDropdown
4 |
--------------------------------------------------------------------------------
/src/components/InputIconAction/InputIconAction.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
40 |
41 |
42 |
63 |
64 |
--------------------------------------------------------------------------------
/src/components/InputIconAction/index.ts:
--------------------------------------------------------------------------------
1 | import InputIconAction from './InputIconAction.vue'
2 |
3 | export default InputIconAction
4 |
--------------------------------------------------------------------------------
/src/components/InputIconButton/InputIconButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
25 |
26 |
27 |
63 |
64 |
--------------------------------------------------------------------------------
/src/components/InputIconButton/index.ts:
--------------------------------------------------------------------------------
1 | import InputIconButton from './InputIconButton.vue'
2 |
3 | export default InputIconButton
4 |
--------------------------------------------------------------------------------
/src/components/InputIconToggle/InputIconToggle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
15 |
34 |
35 |
36 |
69 |
70 |
--------------------------------------------------------------------------------
/src/components/InputIconToggle/index.ts:
--------------------------------------------------------------------------------
1 | import InputIconToggle from './InputIconToggle.vue'
2 |
3 | export default InputIconToggle
4 |
--------------------------------------------------------------------------------
/src/components/InputMatrix/InputMatrix.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
19 |
20 |
21 |
22 |
91 |
92 |
105 |
--------------------------------------------------------------------------------
/src/components/InputMatrix/index.ts:
--------------------------------------------------------------------------------
1 | import InputMatrix from './InputMatrix.vue'
2 |
3 | export default InputMatrix
4 |
--------------------------------------------------------------------------------
/src/components/InputMode/InputMode.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
35 |
36 |
91 |
92 |
--------------------------------------------------------------------------------
/src/components/InputMode/index.ts:
--------------------------------------------------------------------------------
1 | import InputMode from './InputMode.vue'
2 |
3 | export default InputMode
4 |
--------------------------------------------------------------------------------
/src/components/InputNumber/index.ts:
--------------------------------------------------------------------------------
1 | import InputNumber from './InputNumber.vue'
2 |
3 | export default InputNumber
4 |
--------------------------------------------------------------------------------
/src/components/InputPoint/index.ts:
--------------------------------------------------------------------------------
1 | import InputPoint from './InputPoint.vue'
2 |
3 | export default InputPoint
4 |
--------------------------------------------------------------------------------
/src/components/InputRange/index.ts:
--------------------------------------------------------------------------------
1 | import InputRange from './InputRange.vue'
2 |
3 | export default InputRange
4 |
--------------------------------------------------------------------------------
/src/components/InputSlider/index.ts:
--------------------------------------------------------------------------------
1 | import InputSlider from './InputSlider.vue'
2 |
3 | export default InputSlider
4 |
--------------------------------------------------------------------------------
/src/components/InputString/InputString.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
42 |
43 |
44 |
60 |
61 |
--------------------------------------------------------------------------------
/src/components/InputString/index.ts:
--------------------------------------------------------------------------------
1 | import InputString from './InputString.vue'
2 |
3 | export default InputString
4 |
--------------------------------------------------------------------------------
/src/components/InputTime/index.ts:
--------------------------------------------------------------------------------
1 | import InputTime from './InputTime.vue'
2 |
3 | export default InputTime
4 |
--------------------------------------------------------------------------------
/src/components/InputVector/InputVector.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
20 |
21 |
22 |
61 |
62 |
66 |
--------------------------------------------------------------------------------
/src/components/InputVector/index.ts:
--------------------------------------------------------------------------------
1 | import InputVector from './InputVector.vue'
2 |
3 | export default InputVector
4 |
--------------------------------------------------------------------------------
/src/components/LayoutSplitter/index.ts:
--------------------------------------------------------------------------------
1 | import LayoutSplitter from './LayoutSplitter.vue'
2 |
3 | export default LayoutSplitter
4 |
--------------------------------------------------------------------------------
/src/components/LayoutTab/LayoutTab.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
30 |
31 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/components/LayoutTab/index.ts:
--------------------------------------------------------------------------------
1 | import LayoutTab from './LayoutTab.vue'
2 |
3 | export default LayoutTab
4 |
--------------------------------------------------------------------------------
/src/components/LayoutTabs/LayoutTabs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
19 |
20 |
21 |
22 |
68 |
69 |
70 |
121 |
122 |
--------------------------------------------------------------------------------
/src/components/LayoutTabs/index.ts:
--------------------------------------------------------------------------------
1 | import LayoutTabs from './LayoutTabs.vue'
2 |
3 | export default LayoutTabs
4 |
--------------------------------------------------------------------------------
/src/components/PaneBind/index.ts:
--------------------------------------------------------------------------------
1 | import PaneBind from './PaneBind.vue'
2 | export default PaneBind
3 |
--------------------------------------------------------------------------------
/src/components/ParamFieldAffine.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 |
35 |
36 |
37 |
40 |
--------------------------------------------------------------------------------
/src/components/ParamFieldAngle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
34 |
35 |
36 |
42 |
--------------------------------------------------------------------------------
/src/components/ParamFieldBind.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
16 |
17 |
18 |
19 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/src/components/ParamFieldCheckbox.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/ParamFieldColor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
28 |
29 |
30 |
43 |
--------------------------------------------------------------------------------
/src/components/ParamFieldDropdown.vue:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/components/ParamFieldMode.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/ParamFieldNumber.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/ParamFieldPoint.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
15 |
16 |
17 |
18 |
46 |
47 |
48 |
54 |
--------------------------------------------------------------------------------
/src/components/ParamFieldRange.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 |
16 |
47 |
48 |
49 |
58 |
--------------------------------------------------------------------------------
/src/components/ParamFieldScale.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
27 |
33 |
34 |
35 |
36 |
37 |
121 |
122 |
123 |
129 |
--------------------------------------------------------------------------------
/src/components/ParamFieldSeed.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 |
16 |
52 |
53 |
54 |
60 |
--------------------------------------------------------------------------------
/src/components/ParamFieldSlider.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
15 |
16 |
17 |
45 |
46 |
47 |
56 |
--------------------------------------------------------------------------------
/src/components/ParamFieldString.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/ParamFieldVector.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/ParameterList/Parameter.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
85 |
86 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/src/components/ParameterList/index.ts:
--------------------------------------------------------------------------------
1 | import ParameterList from './ParameterList.vue'
2 |
3 | export default ParameterList
4 |
--------------------------------------------------------------------------------
/src/components/Timeline/TimelineSeekbarScale.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
62 |
63 |
64 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/src/components/Timeline/index.ts:
--------------------------------------------------------------------------------
1 | import Timeline from './Timeline.vue'
2 |
3 | export default Timeline
4 |
--------------------------------------------------------------------------------
/src/components/TimelineColor/TimelineColor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
60 |
61 |
62 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/src/components/TimelineColor/index.ts:
--------------------------------------------------------------------------------
1 | import TimelineColor from './TimelineColor.vue'
2 |
3 | export default TimelineColor
4 |
--------------------------------------------------------------------------------
/src/components/TimelineDraw/TimelineDraw.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
85 |
86 |
87 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/src/components/TimelineDraw/index.ts:
--------------------------------------------------------------------------------
1 | import TimelineDraw from './TimelineDraw.vue'
2 |
3 | export default TimelineDraw
4 |
--------------------------------------------------------------------------------
/src/components/common/GradientPalette/GradientPalette.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
153 |
--------------------------------------------------------------------------------
/src/components/common/GradientPalette/gradient-palette.frag:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 |
3 | #define MODE_HSL_H 10
4 | #define MODE_HSL_S 11
5 | #define MODE_HSL_L 12
6 | #define MODE_HSL_HS 13
7 | #define MODE_HSL_SL 14
8 | #define MODE_HSL_HL 15
9 |
10 | #define MODE_RGB_R 20
11 | #define MODE_RGB_G 21
12 | #define MODE_RGB_B 22
13 | #define MODE_RGB_RG 23
14 | #define MODE_RGB_GB 24
15 | #define MODE_RGB_BR 25
16 |
17 | #define MODE_HSV_H 30
18 | #define MODE_HSV_S 31
19 | #define MODE_HSV_V 32
20 | #define MODE_HSV_HS 33
21 | #define MODE_HSV_SV 34
22 | #define MODE_HSV_HV 35
23 |
24 | float hue2rgb(float f1, float f2, float hue) {
25 | if (hue < 0.0)
26 | hue += 1.0;
27 | else if (hue > 1.0)
28 | hue -= 1.0;
29 | float res;
30 | if ((6.0 * hue) < 1.0)
31 | res = f1 + (f2 - f1) * 6.0 * hue;
32 | else if ((2.0 * hue) < 1.0)
33 | res = f2;
34 | else if ((3.0 * hue) < 2.0)
35 | res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0;
36 | else
37 | res = f1;
38 | return res;
39 | }
40 |
41 | vec3 hsl2rgb(vec3 hsl) {
42 | vec3 rgb;
43 |
44 | if (hsl.y == 0.0) {
45 | rgb = vec3(hsl.z); // Luminance
46 | } else {
47 | float f2;
48 |
49 | if (hsl.z < 0.5)
50 | f2 = hsl.z * (1.0 + hsl.y);
51 | else
52 | f2 = hsl.z + hsl.y - hsl.y * hsl.z;
53 |
54 | float f1 = 2.0 * hsl.z - f2;
55 |
56 | rgb.r = hue2rgb(f1, f2, hsl.x + (1.0/3.0));
57 | rgb.g = hue2rgb(f1, f2, hsl.x);
58 | rgb.b = hue2rgb(f1, f2, hsl.x - (1.0/3.0));
59 | }
60 | return rgb;
61 | }
62 |
63 | vec3 hsl2rgb(float h, float s, float l) {
64 | return hsl2rgb(vec3(h, s, l));
65 | }
66 |
67 | vec3 hsv2rgb(vec3 c) {
68 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
69 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
70 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
71 | }
72 |
73 | vec3 hsv2rgb(float h, float s, float v) {
74 | return hsv2rgb(vec3(h, s, v));
75 | }
76 |
77 | uniform vec2 resolution;
78 | uniform int mode;
79 | uniform vec3 elements;
80 |
81 | void main() {
82 | vec2 uv = gl_FragCoord.xy / resolution;
83 | vec3 rgb = vec3(1.0, 0.0, 0.0);
84 |
85 | // HSL
86 | if (mode == MODE_HSL_H) {
87 | rgb = hsl2rgb(uv.y, elements.y / 100.0, elements.z / 100.0);
88 | } else if (mode == MODE_HSL_S) {
89 | rgb = hsl2rgb(elements.x / 360.0, uv.y, elements.z / 100.0);
90 | } else if (mode == MODE_HSL_L) {
91 | rgb = hsl2rgb(elements.x / 360.0, elements.y / 100.0, uv.y);
92 | } else if (mode == MODE_HSL_HS) {
93 | rgb = hsl2rgb(uv.x, uv.y, elements.z / 100.0);
94 | } else if (mode == MODE_HSL_SL) {
95 | rgb = hsl2rgb(elements.x / 360.0, uv.x, uv.y);
96 | } else if (mode == MODE_HSL_HL) {
97 | rgb = hsl2rgb(uv.x, elements.y / 100.0, uv.y);
98 |
99 | // RGB
100 | } else if (mode == MODE_RGB_R) {
101 | rgb = vec3(uv.y, elements.y / 255.0, elements.z / 255.0);
102 | } else if (mode == MODE_RGB_G) {
103 | rgb = vec3(elements.x / 255.0, uv.y, elements.z / 255.0);
104 | } else if (mode == MODE_RGB_B) {
105 | rgb = vec3(elements.x / 255.0, elements.y / 255.0, uv.y);
106 | } else if (mode == MODE_RGB_RG) {
107 | rgb = vec3(uv.x, uv.y, elements.z / 255.0);
108 | } else if (mode == MODE_RGB_GB) {
109 | rgb = vec3(elements.x / 255.0, uv.x, uv.y);
110 | } else if (mode == MODE_RGB_BR) {
111 | rgb = vec3(uv.y, elements.y / 255.0, uv.x);
112 |
113 | // HSV
114 | } else if (mode == MODE_HSV_H) {
115 | rgb = hsv2rgb(uv.y, elements.y / 100.0, elements.z / 100.0);
116 | } else if (mode == MODE_HSV_S) {
117 | rgb = hsv2rgb(elements.x / 360.0, uv.y, elements.z / 100.0);
118 | } else if (mode == MODE_HSV_V) {
119 | rgb = hsv2rgb(elements.x / 360.0, elements.y / 100.0, uv.y);
120 | } else if (mode == MODE_HSV_HS) {
121 | rgb = hsv2rgb(uv.x, uv.y, elements.z / 100.0);
122 | } else if (mode == MODE_HSV_SV) {
123 | rgb = hsv2rgb(elements.x / 360.0, uv.x, uv.y);
124 | } else if (mode == MODE_HSV_HV) {
125 | rgb = hsv2rgb(uv.x, elements.y / 100.0, uv.y);
126 | }
127 |
128 | gl_FragColor = vec4(rgb, 1.0);
129 | }
--------------------------------------------------------------------------------
/src/components/common/GradientPalette/gradient-palette.vert:
--------------------------------------------------------------------------------
1 | attribute vec4 position;
2 |
3 | void main() {
4 | gl_Position = position;
5 | }
--------------------------------------------------------------------------------
/src/components/common/GradientPalette/index.ts:
--------------------------------------------------------------------------------
1 | import GradientPalette from './GradientPalette.vue'
2 |
3 | export default GradientPalette
4 |
--------------------------------------------------------------------------------
/src/components/common/Icon.vue:
--------------------------------------------------------------------------------
1 |
80 |
81 |
91 |
92 |
--------------------------------------------------------------------------------
/src/components/common/Menu/Menu.vue:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
130 |
131 |
152 |
--------------------------------------------------------------------------------
/src/components/common/Menu/MenuItem.ts:
--------------------------------------------------------------------------------
1 | export default interface MenuItem {
2 | value: string | number | symbol
3 | label: string
4 | shortLabel?: string
5 | icon?: string
6 | type?: 'submenu' | 'compact'
7 | submenu?: MenuItem[]
8 | }
9 |
--------------------------------------------------------------------------------
/src/components/common/Menu/index.ts:
--------------------------------------------------------------------------------
1 | import Menu from './Menu.vue'
2 |
3 | export default Menu
4 |
--------------------------------------------------------------------------------
/src/components/common/Modal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
27 |
28 |
55 |
--------------------------------------------------------------------------------
/src/components/common/Popover.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
144 |
145 |
146 |
152 |
153 |
--------------------------------------------------------------------------------
/src/components/common/Portal.ts:
--------------------------------------------------------------------------------
1 | import {Component, Vue} from 'vue-property-decorator'
2 |
3 | @Component({})
4 | export default class Portal extends Vue {
5 | private originalParentEl!: (Node & ParentNode) | null
6 |
7 | private mounted() {
8 | if (!this.originalParentEl) {
9 | this.originalParentEl = this.$el.parentNode
10 | this.$emit('initial-parent', this.$el.parentNode)
11 | }
12 |
13 | this.changeParentEl(this.$root.$el)
14 | }
15 |
16 | private beforeDestroy() {
17 | this.killGhostElement(this.$el)
18 | }
19 |
20 | private render() {
21 | const defaultSlot = this.$slots.default
22 |
23 | if (defaultSlot && defaultSlot[0]) {
24 | return defaultSlot[0]
25 | }
26 | }
27 |
28 | private killGhostElement(el: Element) {
29 | if (el.parentNode) {
30 | this.changeParentEl(this.originalParentEl)
31 | // @ts-ignore
32 | this.$options._parentElm = this.originalParentEl
33 | el.parentNode.removeChild(el)
34 | }
35 | }
36 |
37 | private changeParentEl(newTarget: (Node & ParentNode) | null) {
38 | newTarget!.appendChild(this.$el)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/components/common/SvgArcArrow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
67 |
--------------------------------------------------------------------------------
/src/components/common/SvgArrow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
55 |
--------------------------------------------------------------------------------
/src/components/common/SvgOverlayHorizontalDrag.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 | {{props.text}}
25 |
26 |
27 |
28 |
44 |
--------------------------------------------------------------------------------
/src/components/index.ts:
--------------------------------------------------------------------------------
1 | import ConfigProvider from './ConfigProvider'
2 | import InputAngle from './InputAngle'
3 | import InputButton from './InputButton'
4 | import InputCodeEditor from './InputCodeEditor'
5 | import InputCheckbox from './InputCheckbox'
6 | import InputColor from './InputColor'
7 | import InputColorButton from './InputColorButton'
8 | import InputDropdown from './InputDropdown'
9 | import InputIconAction from './InputIconAction'
10 | import InputIconButton from './InputIconButton'
11 | import InputIconToggle from './InputIconToggle'
12 | import InputMatrix from './InputMatrix'
13 | import InputMode from './InputMode'
14 | import InputNumber from './InputNumber'
15 | import InputPoint from './InputPoint'
16 | import InputRange from './InputRange'
17 | import InputSlider from './InputSlider'
18 | import InputString from './InputString'
19 | import InputTime from './InputTime'
20 | import InputVector from './InputVector'
21 | import LayoutSplitter from './LayoutSplitter'
22 | import LayoutTabs from './LayoutTabs'
23 | import LayoutTab from './LayoutTab'
24 | import ParameterList from './ParameterList'
25 | import ParamFieldAffine from './ParamFieldAffine.vue'
26 | import ParamFieldAngle from './ParamFieldAngle.vue'
27 | import ParamFieldCheckbox from './ParamFieldCheckbox.vue'
28 | import ParamFieldColor from './ParamFieldColor.vue'
29 | import ParamFieldDropdown from './ParamFieldDropdown.vue'
30 | import ParamFieldNumber from './ParamFieldNumber.vue'
31 | import ParamFieldMode from './ParamFieldMode.vue'
32 | import ParamFieldPoint from './ParamFieldPoint.vue'
33 | import ParamFieldRange from './ParamFieldRange.vue'
34 | import ParamFieldScale from './ParamFieldScale.vue'
35 | import ParamFieldSeed from './ParamFieldSeed.vue'
36 | import ParamFieldSlider from './ParamFieldSlider.vue'
37 | import ParamFieldString from './ParamFieldString.vue'
38 | import SelectionManager from './SelectionManager.vue'
39 | import Timeline from './Timeline'
40 | import TimelineColor from './TimelineColor'
41 | import TimelineDraw from './TimelineDraw'
42 |
43 | export default {
44 | ConfigProvider,
45 | InputAngle,
46 | InputButton,
47 | InputCodeEditor,
48 | InputCheckbox,
49 | InputColor,
50 | InputColorButton,
51 | InputDropdown,
52 | InputIconAction,
53 | InputIconButton,
54 | InputIconToggle,
55 | InputMatrix,
56 | InputMode,
57 | InputNumber,
58 | InputPoint,
59 | InputRange,
60 | InputSlider,
61 | InputString,
62 | InputTime,
63 | InputVector,
64 | LayoutSplitter,
65 | LayoutTabs,
66 | LayoutTab,
67 | ParameterList,
68 | ParamFieldAffine,
69 | ParamFieldAngle,
70 | ParamFieldCheckbox,
71 | ParamFieldColor,
72 | ParamFieldDropdown,
73 | ParamFieldNumber,
74 | ParamFieldMode,
75 | ParamFieldPoint,
76 | ParamFieldRange,
77 | ParamFieldSeed,
78 | ParamFieldScale,
79 | ParamFieldSlider,
80 | ParamFieldString,
81 | SelectionManager,
82 | Timeline,
83 | TimelineColor,
84 | TimelineDraw
85 | }
86 |
--------------------------------------------------------------------------------
/src/core/config.ts:
--------------------------------------------------------------------------------
1 | import Color from '../data/Color'
2 | import {p, g, SchemaGroup} from '../data/Schema'
3 |
4 | export const ConfigDefault = {
5 | lang: 'en',
6 | dragSpeed: 0.5,
7 | keySlower: '/key/alt',
8 | keyFaster: '/key/shift',
9 | keySymmetry: '/key/s',
10 | keyQuantize: '/key/q',
11 | keyScale: '/key/alt',
12 | quantizeAngles: [0, 45, 90, 135, 180, 225, 270, 315],
13 | theme: {
14 | fontSize: 12,
15 | fontMonospace: '"Roboto Condensed", monospace, sans-serif',
16 | fontCode: '"Fira Code", monospace, sans-serif',
17 | fontNormal: '"Roboto", Helvetica, Arial, sans-serif',
18 | colorActive: new Color('hex', '#63acf9'),
19 | colorBorder: new Color('hex', '#e0e0e0'),
20 | colorBorderText: new Color('hex', '#bbbbbb'),
21 | colorControl: new Color('hex', '#bbbbbb'),
22 | colorControlText: new Color('hex', '#999999'),
23 | colorBg: new Color('hex', '#f0f0f0'),
24 | colorField: new Color('hex', '#f9f9f9'),
25 | colorText: new Color('hex', '#444444'),
26 | colorSeek: new Color('hex', '#ff3854'),
27 | colorMenuBg: new Color('hex', '#000000'),
28 | colorMenuText: new Color('hex', '#ffffff'),
29 | colorMenuField: new Color('hex', '#000000'),
30 | colorMenuBorder: new Color('hex', '#333333'),
31 | layoutParamHeight: 2.8,
32 | layoutParamField1w: 6,
33 | layoutParamFieldGapWidget: 0.5,
34 | layoutParamFieldGapBox: 0.3,
35 | layoutInputHeight: 2,
36 | layoutPopoverPadding: 0.5
37 | }
38 | }
39 |
40 | export const ConfigSchema: SchemaGroup = g('config', {}, [
41 | p('lang', {
42 | ui: 'dropdown',
43 | label: 'Language',
44 | labels: ['English', '日本語'],
45 | values: ['en', 'ja']
46 | }),
47 | p('dragSpeed', {
48 | ui: 'number',
49 | unit: '/px'
50 | }),
51 | p('keySlower', {ui: 'bind'}),
52 | p('keyFaster', {ui: 'bind'}),
53 | p('keySymmetry', {ui: 'bind'}),
54 | p('keyQuantize', {ui: 'bind'}),
55 | p('keyScale', {ui: 'bind'}),
56 | p('quantizeAngles', {
57 | ui: 'string',
58 | toField: (v: number[]) => v.join(', '),
59 | toData: (v: string) => JSON.parse(`[${v}]`)
60 | }),
61 | g('theme', {label: 'Theme'}, [
62 | p('fontSize', {
63 | ui: 'number',
64 | label: 'Font Size',
65 | min: 7,
66 | max: 20,
67 | step: 1,
68 | unit: 'px'
69 | }),
70 | p('fontMonospace', {
71 | ui: 'string'
72 | }),
73 | p('fontCode', {
74 | ui: 'string'
75 | }),
76 | p('fontNormal', {
77 | ui: 'string'
78 | }),
79 | p('colorActive', {ui: 'color'}),
80 | p('colorBorder', {ui: 'color'}),
81 | p('colorBorderText', {ui: 'color'}),
82 | p('colorControl', {ui: 'color'}),
83 | p('colorControlText', {ui: 'color'}),
84 | p('colorBg', {ui: 'color'}),
85 | p('colorField', {ui: 'color'}),
86 | p('colorText', {ui: 'color'}),
87 | p('colorSeek', {ui: 'color'}),
88 | p('colorMenuBg', {ui: 'color'}),
89 | p('colorMenuText', {ui: 'color'}),
90 | p('colorMenuField', {ui: 'color'}),
91 | p('colorMenuBorder', {ui: 'color'}),
92 | p('layoutParamHeight', {
93 | ui: 'number',
94 | unit: 'em',
95 | min: 0,
96 | max: 20,
97 | precision: 1
98 | }),
99 | p('layoutParamField1w', {
100 | ui: 'number',
101 | unit: 'em',
102 | min: 0,
103 | max: 20,
104 | precision: 1
105 | }),
106 | p('layoutParamFieldGapWidget', {
107 | ui: 'number',
108 | unit: 'em',
109 | min: 0,
110 | max: 20,
111 | precision: 1
112 | }),
113 | p('layoutParamFieldGapBox', {
114 | ui: 'number',
115 | unit: 'em',
116 | min: 0,
117 | max: 20,
118 | precision: 1
119 | }),
120 | p('layoutInputHeight', {
121 | ui: 'number',
122 | unit: 'em',
123 | min: 0,
124 | max: 20,
125 | precision: 1
126 | }),
127 | p('layoutPopoverPadding', {
128 | ui: 'number',
129 | unit: 'em',
130 | min: 0,
131 | max: 20,
132 | precision: 1
133 | })
134 | ])
135 | ])
136 |
--------------------------------------------------------------------------------
/src/core/index.ts:
--------------------------------------------------------------------------------
1 | // no
2 |
--------------------------------------------------------------------------------
/src/data/BaseNode.ts:
--------------------------------------------------------------------------------
1 | import deepcopy from '../util/deepcopy'
2 |
3 | export default class BaseNode {
4 | public name!: string | null
5 | public _parent!: BaseNode | null
6 |
7 | constructor(
8 | name: string | null = null,
9 | attrs: {[s: string]: any} | null = null
10 | ) {
11 | this.name = name
12 |
13 | Object.defineProperties(this, {
14 | _parent: {
15 | writable: true,
16 | enumerable: false
17 | }
18 | })
19 |
20 | if (attrs) {
21 | this.setAttrs(attrs)
22 | }
23 | }
24 |
25 | public clone(): BaseNode {
26 | return new BaseNode(this.name, deepcopy(this.getAttrs()))
27 | }
28 |
29 | public getAttrs(): {[s: string]: any} {
30 | const attrs = Object.assign({}, this)
31 | delete attrs.name
32 | return attrs
33 | }
34 |
35 | public setAttrs(attrs: {[s: string]: any}) {
36 | const self = this as {[s: string]: any}
37 | for (const key of Object.keys(attrs)) {
38 | self[key] = attrs[key]
39 | }
40 | }
41 |
42 | public serialize() {
43 | const attrs = this.getAttrs()
44 |
45 | const obj: any[] = ['']
46 |
47 | const className = this.constructor.name
48 | if (className !== 'IndexedNode') {
49 | obj[0] += `:${className}`
50 | }
51 |
52 | if (this.name) {
53 | obj[0] += `#${this.name}`
54 | }
55 |
56 | if (Object.keys(attrs).length > 0) {
57 | obj.push(attrs)
58 | }
59 |
60 | return obj
61 | }
62 |
63 | public toJSON() {
64 | return this.serialize()
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/data/Color.ts:
--------------------------------------------------------------------------------
1 | import colorConvert from 'color-convert'
2 | import {mod, lerp, clamp} from '../math'
3 |
4 | export type ColorMode = 'rgb' | 'hsv' | 'hsl' | 'hex'
5 | export type ColorElements = string | number[]
6 |
7 | interface ColorModeInfoValue {
8 | max: number[]
9 | prefix: string[]
10 | unit: string[]
11 | }
12 |
13 | export const ColorModeInfo: {[s: string]: ColorModeInfoValue} = {
14 | hex: {max: [NaN], prefix: [''], unit: ['']},
15 | rgb: {max: [255, 255, 255], prefix: ['R', 'G', 'B'], unit: ['', '', '']},
16 | hsl: {max: [360, 100, 100], prefix: ['H', 'S', 'L'], unit: ['°', '%', '%']},
17 | hsv: {max: [360, 100, 100], prefix: ['H', 'S', 'V'], unit: ['°', '%', '%']}
18 | }
19 |
20 | export default class Color {
21 | public static cssColor(color: Color): string {
22 | return color.cssColor
23 | }
24 |
25 | public static convertMode(color: Color, mode: ColorMode) {
26 | const newColor = color.clone()
27 | return newColor.convertMode(mode)
28 | }
29 |
30 | public static adjustHSB(
31 | color: Color,
32 | hueRotate: number,
33 | saturate: number,
34 | brightness: number
35 | ) {
36 | const newColor = color.clone()
37 | return newColor.adjustHSB(hueRotate, saturate, brightness)
38 | }
39 |
40 | public mode!: ColorMode
41 |
42 | public elements!: ColorElements
43 |
44 | private _cssColor!: {value: string; hash: string}
45 |
46 | constructor(mode: ColorMode, elements: ColorElements) {
47 | this.mode = mode
48 | this.elements = elements
49 |
50 | Object.defineProperty(this, '_cssColor', {
51 | enumerable: false,
52 | writable: true,
53 | configurable: false,
54 | value: {value: '', hash: ''}
55 | })
56 | }
57 |
58 | public get cssColor(): string {
59 | const {mode, elements} = this
60 |
61 | const hash = mode + elements
62 |
63 | if (this._cssColor.hash === hash) {
64 | return this._cssColor.value
65 | }
66 |
67 | let cssColor: string
68 |
69 | if (mode === 'hex') {
70 | cssColor = elements as string
71 | } else {
72 | const [v0, v1, v2] = elements
73 | if (mode === 'rgb') {
74 | cssColor = `rgb(${v0}, ${v1}, ${v2})`
75 | } else if (mode === 'hsl') {
76 | cssColor = `hsl(${v0}, ${v1}%, ${v2}%)`
77 | } else {
78 | const [r, g, b]: number[] = colorConvert[mode].rgb(elements as [
79 | number,
80 | number,
81 | number
82 | ])
83 | cssColor = `rgb(${r}, ${g}, ${b})`
84 | }
85 | }
86 |
87 | this._cssColor.hash = hash
88 | this._cssColor.value = cssColor
89 |
90 | return cssColor
91 | }
92 |
93 | public clone(): Color {
94 | const elements = Array.isArray(this.elements)
95 | ? [...this.elements]
96 | : this.elements
97 | return new Color(this.mode, elements)
98 | }
99 |
100 | public convertMode(mode: ColorMode): Color {
101 | const {mode: originalMode, elements} = this
102 |
103 | if (originalMode === 'hex') {
104 | // @ts-ignore
105 | this.elements = colorConvert[originalMode][mode](elements)
106 | } else {
107 | // @ts-ignore
108 | this.elements = colorConvert[originalMode][mode].apply(null, elements)
109 | if (mode === 'hex') {
110 | this.elements = `#${this.elements}`
111 | }
112 | }
113 |
114 | this.mode = mode
115 |
116 | return this
117 | }
118 |
119 | public adjustHSB(hueRotate: number, saturate: number, brightness: number) {
120 | const {mode} = this
121 | const isHSB = mode === 'hsv' || mode === 'hsl'
122 |
123 | // Convert to HSV if the color is neither HSV nor HSL
124 | if (!isHSB) {
125 | this.convertMode('hsv')
126 | }
127 |
128 | const hsb = this.elements as number[]
129 |
130 | // Hue-rotate
131 | if (hueRotate % 360 !== 0) {
132 | hsb[0] = mod(hsb[0] + hueRotate, 360)
133 | }
134 |
135 | // Saturate / Brightness (%)
136 | for (let [i, inc] of [saturate, brightness].entries()) {
137 | i += 1
138 | if (inc !== 0) {
139 | if (inc < 0) {
140 | hsb[i] = lerp(0, hsb[i], clamp(inc / 100 + 1, 0, 1))
141 | } else {
142 | hsb[i] = lerp(hsb[i], 100, clamp(inc / 100, 0, 1))
143 | }
144 | }
145 | }
146 |
147 | // Convert to original color mode
148 | if (!isHSB) {
149 | this.convertMode(mode)
150 | }
151 |
152 | return this
153 | }
154 |
155 | private toJSON() {
156 | const {mode, elements} = this
157 | return [':Color', [this.mode, this.elements]]
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/data/IndexedNode.ts:
--------------------------------------------------------------------------------
1 | import {observable, reaction} from 'mobx'
2 | import BaseNode from './BaseNode'
3 | import deepcopy from '../util/deepcopy'
4 |
5 | export default class IndexedNode extends BaseNode {
6 | public children!: BaseNode[]
7 | public _namedChildren!: {[s: string]: BaseNode}
8 |
9 | constructor(
10 | name: string | null = null,
11 | attrs: {[s: string]: any} | null = null,
12 | children: BaseNode[] = []
13 | ) {
14 | super(name, attrs)
15 | this.children = children
16 |
17 | Object.defineProperties(this, {
18 | _parent: {
19 | writable: true,
20 | enumerable: false
21 | },
22 | _namedChildren: {
23 | enumerable: false,
24 | value: {}
25 | }
26 | })
27 |
28 | for (const child of this.children) {
29 | child._parent = this
30 | if (child.name) {
31 | this._namedChildren[child.name] = child
32 | }
33 | }
34 | }
35 |
36 | public clone(): IndexedNode {
37 | return new IndexedNode(
38 | this.name,
39 | deepcopy(this.getAttrs()),
40 | deepcopy(this.children)
41 | )
42 | }
43 |
44 | public getAttrs(): {[s: string]: any} {
45 | const attrs = super.getAttrs()
46 | delete attrs.children
47 | return attrs
48 | }
49 |
50 | public serialize() {
51 | const obj = super.serialize()
52 |
53 | if (this.children.length > 0) {
54 | obj.push(Array.from(this.children))
55 | }
56 |
57 | return obj
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/data/Mat2.ts:
--------------------------------------------------------------------------------
1 | export default class Mat2 extends Array {}
2 |
--------------------------------------------------------------------------------
/src/data/Mat3.ts:
--------------------------------------------------------------------------------
1 | export default class Mat3 extends Array {}
2 |
--------------------------------------------------------------------------------
/src/data/Mat4.ts:
--------------------------------------------------------------------------------
1 | export default class Mat4 extends Array {}
2 |
--------------------------------------------------------------------------------
/src/data/Schema.ts:
--------------------------------------------------------------------------------
1 | import deepmerge from 'deepmerge'
2 | import Case from 'case'
3 |
4 | import BaseNode from './BaseNode'
5 | import IndexedNode from './IndexedNode'
6 | import deepcopy from '../util/deepcopy'
7 |
8 | function mergeSchemaPair(
9 | a: Schema | SchemaGroup,
10 | b: Schema | SchemaGroup
11 | ): Schema | SchemaGroup {
12 | if (a instanceof Schema && b instanceof Schema) {
13 | // If both objects are instances of Schema, just merge the attribute.
14 | return new Schema(b.name || a.name, deepmerge(a.getAttrs(), b.getAttrs()))
15 | } else if (a instanceof SchemaGroup && b instanceof SchemaGroup) {
16 | // If both objects are instances of SchemaGroup, merge the two array of children.
17 | // The way of merge is as same as how two objects are merged when using Object.assign({}, a, b)
18 | // The order of proerties of A will be saved and the properties that only B has will be appended after them.
19 | const out = new SchemaGroup(
20 | b.name || a.name,
21 | deepmerge(a.getAttrs(), b.getAttrs()),
22 | deepcopy(a.children)
23 | )
24 |
25 | for (const childOfB of b.children) {
26 | const {name} = childOfB
27 | const childOfA = out._namedChildren[name]
28 |
29 | if (childOfA) {
30 | // out.set(name, )
31 | const index = out.children.indexOf(childOfA)
32 | const newChild = mergeSchemaPair(childOfA, childOfB)
33 | out.children.splice(index, 1, newChild)
34 | out._namedChildren[name] = newChild
35 | } else {
36 | const newChild = childOfB.clone()
37 | out.children.push(newChild)
38 | out._namedChildren[name] = newChild
39 | }
40 | }
41 | return out
42 | } else {
43 | // If one is Schema and the other is SchemaGroup, merge would fail so trhow the error.
44 | throw new Error('Cannot merge because the types of two schema do not match')
45 | }
46 | }
47 |
48 | export function mergeSchema(schemas: SchemaGroup[]): SchemaGroup {
49 | const [car, ...cdr] = schemas
50 | return cdr.reduce(
51 | (prev, current) => mergeSchemaPair(prev, current),
52 | car
53 | ) as SchemaGroup
54 | }
55 |
56 | export interface BindSchema {
57 | address: string
58 | method: string
59 | option: {[name: string]: any}
60 | }
61 |
62 | export interface ISchema {
63 | ui?: string
64 | label?: string
65 | prefix?: string
66 | unit?: string
67 | labels?: string[]
68 | values?: string[]
69 | precision?: number
70 | min?: number | number[]
71 | max?: number | number[]
72 | step?: number
73 | keepProportion?: boolean
74 | bindList?: BindSchema[]
75 | toField?: (v: any) => any
76 | toData?: (v: any) => any
77 | }
78 |
79 | export class Schema extends BaseNode implements ISchema {
80 | public name!: string
81 |
82 | public ui!: string
83 | public label?: string
84 | public prefix?: string
85 | public unit?: string
86 | public labels?: string[]
87 | public values?: string[]
88 | public precision?: number
89 | public min?: number | number[]
90 | public max?: number | number[]
91 | public step?: number
92 | public keepProportion?: boolean
93 | public bindList?: BindSchema[]
94 | public toField?: (v: any) => any
95 | public toData?: (v: any) => any
96 |
97 | constructor(name: string, schemaObj: ISchema) {
98 | super(name, schemaObj)
99 |
100 | if (!schemaObj.label) {
101 | this.label = Case.capital(name)
102 | }
103 | }
104 |
105 | public clone(): Schema {
106 | return super.clone() as Schema
107 | }
108 | }
109 |
110 | export class SchemaGroup extends IndexedNode {
111 | public name!: string
112 | public label!: string
113 | public children!: Array
114 | public _namedChildren!: {[s: string]: Schema | SchemaGroup}
115 |
116 | constructor(
117 | name: string,
118 | schemaObj: {label?: string},
119 | children: Array
120 | ) {
121 | super(name, schemaObj, children)
122 |
123 | if (!schemaObj || !schemaObj.label) {
124 | this.label = Case.capital(name)
125 | }
126 | }
127 |
128 | public clone(): SchemaGroup {
129 | return super.clone() as SchemaGroup
130 | }
131 | }
132 |
133 | export const p = (name: string, schemaObj: ISchema) =>
134 | new Schema(name, schemaObj)
135 |
136 | export const g = (
137 | name: string,
138 | schemaObj: any,
139 | children: Array
140 | ) => new SchemaGroup(name, schemaObj, children)
141 |
--------------------------------------------------------------------------------
/src/data/Time.ts:
--------------------------------------------------------------------------------
1 | export default class Time {}
2 |
--------------------------------------------------------------------------------
/src/data/Vec3.ts:
--------------------------------------------------------------------------------
1 | export default class Vec3 {
2 | public x: number
3 | public y: number
4 | public z: number
5 |
6 | constructor(x: number = 0, y?: number, z?: number) {
7 | if (y === undefined || z === undefined) {
8 | z = y = x
9 | }
10 | this.x = x
11 | this.y = y
12 | this.z = z
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/data/common.ts:
--------------------------------------------------------------------------------
1 | export const EPSILON = 0.000001
2 |
--------------------------------------------------------------------------------
/src/data/index.ts:
--------------------------------------------------------------------------------
1 | import Color from './Color'
2 |
3 | // Transform
4 | export type DataTransformType1D =
5 | | 'translateX'
6 | | 'translateY'
7 | | 'scaleX'
8 | | 'scaleY'
9 | | 'scaleUniform'
10 | | 'rotate'
11 | | 'skewX'
12 | | 'skewY'
13 |
14 | export type DataTransformType2D = 'translate' | 'scale' | 'skew'
15 |
16 | export type DataTransformTypeMatrix = 'matrix'
17 |
18 | export type DataTransformType =
19 | | DataTransformType1D
20 | | DataTransformType2D
21 | | DataTransformTypeMatrix
22 |
23 | export type DataTransformValue = number | number[]
24 |
25 | export const DataTransformType1DList = [
26 | 'translateX',
27 | 'translateY',
28 | 'scaleX',
29 | 'scaleY',
30 | 'scaleUniform',
31 | 'rotate',
32 | 'skewX',
33 | 'skewY'
34 | ]
35 |
36 | export const DataTransformType2DList = ['translate', 'scale', 'skew']
37 |
38 | export const DataTransformTypeMatrixList = ['matrix']
39 |
40 | export const DataTransformTypeList = [
41 | ...DataTransformType1DList,
42 | ...DataTransformType2DList,
43 | ...DataTransformTypeMatrixList
44 | ]
45 |
46 | export interface DataTransformStack {
47 | type: DataTransformType
48 | value: DataTransformValue
49 | active: boolean
50 | }
51 |
52 | export type DataTransform = DataTransformStack[]
53 |
54 | export interface Store {
55 | [name: string]: number | string | number[] | Color | Store
56 | }
57 |
58 | export {Color}
59 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import components from './components'
2 | import Drag from './components/common/Drag'
3 | import * as util from './util'
4 | import * as math from './math'
5 |
6 | const common = {Drag}
7 |
8 | export default {components, common, util, math}
9 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import {glMatrix} from 'gl-matrix'
4 |
5 | import router from './router'
6 |
7 | glMatrix.setMatrixArrayType(Array)
8 |
9 | Vue.config.productionTip = false
10 |
11 | new Vue({
12 | router,
13 | render: h => h(App)
14 | }).$mount('#app')
15 |
--------------------------------------------------------------------------------
/src/manager/HistoryManager.ts:
--------------------------------------------------------------------------------
1 | interface HistoryDescriptor {
2 | undo: () => void
3 | redo: () => void
4 | label?: string
5 | }
6 |
7 | class HistoryManager {
8 | private histories: HistoryDescriptor[] = []
9 | private index: number = 0
10 |
11 | public addHistory(descriptor: HistoryDescriptor) {
12 | if (this.index >= 1) {
13 | this.histories.splice(0, this.index)
14 | this.index = 0
15 | }
16 | this.histories.unshift(descriptor)
17 | }
18 |
19 | public get canUndo(): boolean {
20 | return this.index < this.histories.length
21 | }
22 |
23 | public get canRedo(): boolean {
24 | return this.index >= 1
25 | }
26 |
27 | public undo() {
28 | if (!this.canUndo) {
29 | console.log('cannot undo')
30 | return
31 | }
32 | this.histories[this.index].undo()
33 | this.index++
34 | }
35 |
36 | public redo() {
37 | if (!this.canRedo) {
38 | console.log('cannot redo')
39 | return
40 | }
41 | this.index--
42 | this.histories[this.index].redo()
43 | }
44 | }
45 |
46 | export default new HistoryManager()
47 |
--------------------------------------------------------------------------------
/src/math/index.ts:
--------------------------------------------------------------------------------
1 | function lerp(a: number, b: number, t: number) {
2 | return a + (b - a) * t
3 | }
4 |
5 | function fit(
6 | value: number,
7 | srcmin: number,
8 | srcmax: number,
9 | destmin: number,
10 | destmax: number
11 | ) {
12 | const t = (value - srcmin) / (srcmax - srcmin)
13 | return destmin + (destmax - destmin) * t
14 | }
15 |
16 | function clamp(value: number, min: number, max: number) {
17 | return min < max
18 | ? value < min
19 | ? min
20 | : value > max
21 | ? max
22 | : value
23 | : value < max
24 | ? max
25 | : value > min
26 | ? min
27 | : value
28 | }
29 |
30 | function mod(a: number, b: number): number {
31 | return ((a % b) + b) % b
32 | }
33 |
34 | function ratio(
35 | value: number,
36 | bottom: number,
37 | top: number,
38 | clamped: boolean = false
39 | ) {
40 | const t = (value - bottom) / (top - bottom)
41 | return clamped ? clamp(t, 0, 1) : t
42 | }
43 |
44 | const numberReg = /[+-]?([0-9]*[.])?[0-9]+/
45 |
46 | function parseNumber(str: string): number {
47 | // if (numberReg.test(str)) {
48 | // return parseFloat(str)
49 | // } else {
50 | // return NaN
51 | // }
52 | return parseFloat(str)
53 | }
54 |
55 | function toFixed(
56 | value: number,
57 | precision: number,
58 | omitZeros: boolean = true
59 | ): string {
60 | const fixed = (+value).toFixed(precision)
61 | return fixed === '0'
62 | ? fixed
63 | : omitZeros
64 | ? fixed.replace(/^(.+\.[1-9]*)0+$/, '$1').replace(/\.$/, '')
65 | : fixed
66 | }
67 |
68 | function toRadians(degrees: number) {
69 | return (degrees * Math.PI) / 180
70 | }
71 |
72 | function toDegrees(radians: number) {
73 | return (radians * 180) / Math.PI
74 | }
75 |
76 | function cycleMod(value: number, inc: number, max: number) {
77 | inc = (inc % max) + max
78 | return (value + inc) % max
79 | }
80 |
81 | function quantize(value: number, step: number) {
82 | return Math.round(value / step) * step
83 | }
84 |
85 | function isInteger(value: number): boolean {
86 | return Math.floor(value) - value === 0
87 | }
88 |
89 | export {
90 | lerp,
91 | fit,
92 | clamp,
93 | parseNumber,
94 | toFixed,
95 | ratio,
96 | mod,
97 | toRadians,
98 | toDegrees,
99 | cycleMod,
100 | quantize,
101 | isInteger
102 | }
103 |
--------------------------------------------------------------------------------
/src/pages/Abstract.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | クリエイターが制作ツールについて語るとき、しばしば「デジタル」と「アナログ」が対比的に取り上げられることがあります。しかし、どのような意味でその二者を区別しているかを厳密に考えている人はそう多くないでしょう。
6 |
7 | 多くの場合、その原義である「離散的」「連続的」ではなく、漠然とした感覚として、どれだけツールとの「密着感」があるかを表しているように感じられます。そして「デジタル」は素早く修正が効きやすい反面、体の出入力とアウトプットとがより密に作用しあう感覚、つまり感覚性は「アナログ」には劣るというニュアンスで説明されることもまた多いです。
8 |
9 | 僕は数年来、制作ごとにツールから作るということを自分なりに実践してきました。それはしかし、ツールを作るためのUIの部品や、設計思想から再考する必要があるのではないかと考えるようになりました。
10 |
11 | このプロジェクトでは、「デジタル」上のデザインのためのインターフェースが、その利点を活かしつつどのようにすれば「アナログ」のような感覚性を獲得できるかということについて探求します。具体的には、数値ボックスやスライダー、カラーピッカーはどのような挙動をしていると使いやすいか、環境設定画面はどのような構造をとっていると理想的か、といった、とても細かいことです。そして、この中で開発したUIコンポーネントを使って、自分の制作のための、あるいはより汎用的な目的のためのデザインツールを完成させることが最終的な目的です。
12 |
13 |
14 |
15 |
16 |
17 |
25 |
--------------------------------------------------------------------------------
/src/pages/Easing/Easing.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
49 |
50 |
53 |
--------------------------------------------------------------------------------
/src/pages/Easing/index.ts:
--------------------------------------------------------------------------------
1 | import Easing from './Easing.vue'
2 |
3 | export default Easing
4 |
--------------------------------------------------------------------------------
/src/pages/GraphicsOnLisp/index.ts:
--------------------------------------------------------------------------------
1 | import GraphicsOnLisp from './GraphicsOnLisp.vue'
2 |
3 | export default GraphicsOnLisp
4 |
--------------------------------------------------------------------------------
/src/pages/GraphicsOnLisp/parser.ts:
--------------------------------------------------------------------------------
1 | // type Atom = number | string
2 |
3 | // type Node = Atom | Atom[]
4 |
5 | // export function atom(token: string): Atom {
6 | // const val = parseFloat(token)
7 | // return isNaN(val) ? token : val
8 | // }
9 |
10 | // export function tokenize(str: string): string[] {
11 | // return str
12 | // .replace(/(\(|\))/g, ' $1 ')
13 | // .replace(/\n/g, ' ')
14 | // .split(' ')
15 | // .filter(x => x !== '')
16 | // }
17 |
18 | // export function readFrom(tokens: string[]): any {
19 | // if (tokens.length === 0) {
20 | // throw Error('unexpected EOF while reading')
21 | // }
22 |
23 | // const token: string = tokens.shift() as string
24 |
25 | // if (token === '(') {
26 | // const L = []
27 | // while (tokens[0] !== ')') {
28 | // L.push(readFrom(tokens))
29 | // }
30 | // tokens.shift()
31 | // return L
32 | // } else if (token === ')') {
33 | // throw Error('unexpected )')
34 | // } else {
35 | // return atom(token)
36 | // }
37 | // }
38 |
39 | // export function createEnv(outer: any, names: string[], values: Atom[]) {
40 | // const dict = new Map()
41 | // names.forEach((p, i) => dict.set(p, values[i]))
42 | // return {
43 | // set: (key: string, val: any) => dict.set(key, val) && null,
44 | // get: (key: string) => (dict.has(key) ? dict.get(key) : outer),
45 | // upd: (key: string, val: any) =>
46 | // dict.has(key) ? dict.set(key, val) && null : outer.upd(key, val)
47 | // }
48 | // }
49 |
50 | // export function globalEnv() {
51 | // const env = createEnv(null, [], [])
52 | // env.set('+', (xs: number[]) =>
53 | // xs.reduce((acc: number, x: number) => acc + x, 0)
54 | // )
55 | // }
56 |
57 | // function lEval(_x: any, _env: any) {
58 | // let [x, env] = [_x, _env]
59 | // for (;;) {
60 | // if (typeof x === 'string') {
61 | // // symbol
62 | // return env.get(x)
63 | // } else if (typeof x === 'number') {
64 | // // number
65 | // return x
66 | // } else if (x[0] === 'quote') {
67 | // return x.slice(1)
68 | // } else if (x[0] === 'if') {
69 | // const [, test, conseq, alt] = x
70 | // x = lEval(test, env) ? conseq : alt // tail call
71 | // } else if (x[0] === 'set!') {
72 | // const [, name, exp] = x
73 | // env.upd(name, lEval(exp, env))
74 | // return
75 | // } else if (x[0] === 'define') {
76 | // const [, name, exp] = x
77 | // env.set(name, lEval(exp, env))
78 | // return
79 | // } else if (x[0] === 'begin') {
80 | // x.slice(1, x.length - 1).map(ex => lEval(ex, env))
81 | // x = x[x.length - 1] // tail call
82 | // } else if (x[0] === 'lambda') {
83 | // const [, params, exp] = x
84 | // return {env, isUDF: true, params, exp}
85 | // } else {
86 | // // apply function
87 | // const [op, ...args] = x.map(ex => lEval(ex, env))
88 | // if (isProcedure(op)) {
89 | // // tail call
90 | // x = op.exp
91 | // env = createEnv(op.env, op.params, args)
92 | // } else {
93 | // return op(args)
94 | // }
95 | // }
96 | // }
97 | // }
98 |
--------------------------------------------------------------------------------
/src/pages/Home/PageLink.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 | {{numbering}}
11 | {{title}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
55 |
56 |
117 |
--------------------------------------------------------------------------------
/src/pages/Home/index.ts:
--------------------------------------------------------------------------------
1 | import Home from './Home.vue'
2 |
3 | export default Home
4 |
--------------------------------------------------------------------------------
/src/pages/ParameterControl/index.ts:
--------------------------------------------------------------------------------
1 | import ParameterControl from './ParameterControl.vue'
2 |
3 | export default ParameterControl
4 |
--------------------------------------------------------------------------------
/src/pages/ParameterControl/polar-disp.meta.txt:
--------------------------------------------------------------------------------
1 | {
2 | "CREDIT": "Baku Hashimoto",
3 | "CATEGORIES": ["BAKU"],
4 | "INPUTS": [
5 | {
6 | "NAME": "intensity",
7 | "LABEL": "Intensity",
8 | "TYPE": "float",
9 | "DEFAULT": 20,
10 | "MIN": 0,
11 | "MAX": 100,
12 | "UNIT": "%"
13 | },
14 | {
15 | "NAME": "iteration",
16 | "LABEL": "Iteration",
17 | "TYPE": "long",
18 | "DEFAULT": 2,
19 | "MIN": 1,
20 | "MAX": 5,
21 | "UI_TYPE": "integer"
22 | },
23 | {
24 | "NAME": "scale",
25 | "LABEL": "Scale",
26 | "TYPE": "point2D",
27 | "UI_TYPE": "scale",
28 | "DEFAULT": [0.2, 0.2]
29 | },
30 | {
31 | "NAME": "angle",
32 | "LABEL": "Angle",
33 | "TYPE": "float",
34 | "UI_TYPE": "angle"
35 | },
36 | {
37 | "NAME": "offset",
38 | "LABEL": "Offset",
39 | "TYPE": "point2D",
40 | "UNIT": "%"
41 | },
42 | {
43 | "NAME": "cropTop",
44 | "LABEL": "Crop Top",
45 | "TYPE": "float",
46 | "DEFAULT": 5,
47 | "MIN": 0,
48 | "MAX": 50,
49 | "UNIT": "%"
50 | },
51 | {
52 | "NAME": "cropRight",
53 | "LABEL": "Crop Right",
54 | "TYPE": "float",
55 | "DEFAULT": 5,
56 | "MIN": 0,
57 | "MAX": 50,
58 | "UNIT": "%"
59 | },
60 | {
61 | "NAME": "cropBottom",
62 | "LABEL": "Crop Bottom",
63 | "TYPE": "float",
64 | "DEFAULT": 5,
65 | "MIN": 0,
66 | "MAX": 50,
67 | "UNIT": "%"
68 | },
69 | {
70 | "NAME": "cropLeft",
71 | "LABEL": "Crop Left",
72 | "TYPE": "float",
73 | "DEFAULT": 5,
74 | "MIN": 0,
75 | "MAX": 50,
76 | "UNIT": "%"
77 | },
78 | {
79 | "NAME": "noiseType",
80 | "LABEL": "Noise Type",
81 | "TYPE": "long",
82 | "VALUES": [0, 1],
83 | "LABELS": ["Simplex", "Periodic"],
84 | "UI_TYPE": "mode"
85 | },
86 | {
87 | "NAME": "frameColor",
88 | "LABEL": "Frame Color",
89 | "TYPE": "color"
90 | }
91 | ],
92 | "PASSES": [{}]
93 | }
94 |
--------------------------------------------------------------------------------
/src/pages/Settings.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/pages/TransformationMatrix/Param.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{iconText}}
4 |
7 |
8 |
9 |
10 |
20 |
21 |
22 |
23 |
50 |
51 |
52 |
98 |
--------------------------------------------------------------------------------
/src/pages/TransformationMatrix/index.ts:
--------------------------------------------------------------------------------
1 | import TransformationMatrix from './TransformationMatrix.vue'
2 |
3 | export default TransformationMatrix
4 |
--------------------------------------------------------------------------------
/src/pages/TransformationMatrix/matrix-util.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/src/pages/TransformationMatrix/matrix-util.ts
--------------------------------------------------------------------------------
/src/pages/TransformationMatrix/transform-stack-store.ts:
--------------------------------------------------------------------------------
1 | import {observable, computed} from 'mobx'
2 | import {toRadians} from '../../math'
3 | import {mat2d} from 'gl-matrix'
4 | import {
5 | DataTransformValue,
6 | DataTransformStack,
7 | DataTransformType
8 | } from '../../data'
9 |
10 | export default class TransformStackStore {
11 | @observable public type!: DataTransformType
12 | @observable public value!: DataTransformValue
13 | @observable public active!: boolean
14 |
15 | constructor({type, value, active}: DataTransformStack) {
16 | this.type = type
17 | this.value = value
18 | this.active = active
19 | }
20 |
21 | @computed public get matrix(): mat2d {
22 | let type = this.type
23 | let value = this.value
24 | const out = mat2d.create()
25 |
26 | // normalize to 2d vector
27 | const isSingleDim = /(X|Y)$/.exec(type)
28 | if (isSingleDim) {
29 | type = type.substr(0, type.length - 1) as DataTransformType
30 | const ident = type.includes('scale') ? 1 : 0
31 | const newValue = [ident, ident]
32 | const dim = type.substr(-1) === 'X' ? 0 : 0
33 | newValue[dim] = value as number
34 | value = newValue
35 | } else if (type === 'scaleUniform') {
36 | type = 'scale'
37 | value = [value as number, value as number]
38 | }
39 |
40 | if (type === 'translate') {
41 | mat2d.fromTranslation(out, value as number[])
42 | } else if (type === 'rotate') {
43 | mat2d.fromRotation(out, toRadians(value as number))
44 | } else if (type === 'scale') {
45 | mat2d.fromScaling(out, value as number[])
46 | } else if (type === 'skew') {
47 | const tanx = Math.tan(toRadians((value as number[])[0]))
48 | const tany = Math.tan(toRadians((value as number[])[1]))
49 | mat2d.set(out, 1, tany, tanx, 1, 0, 0)
50 | } else if (type === 'matrix') {
51 | mat2d.copy(out, value as any)
52 | } else {
53 | mat2d.identity(out)
54 | }
55 | return out
56 | }
57 |
58 | @computed public get matrixInverse(): mat2d | null {
59 | const out = mat2d.create()
60 | return mat2d.invert(out, this.matrix) === null ? null : out
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/router.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 |
4 | import Abstract from './pages/Abstract.vue'
5 | import ComponentsList from './pages/ComponentsList.vue'
6 | import ParameterControl from './pages/ParameterControl'
7 | import TransformationMatrix from './pages/TransformationMatrix'
8 | import GraphicsOnLisp from './pages/GraphicsOnLisp'
9 | import Easing from './pages/Easing'
10 |
11 | Vue.use(Router)
12 |
13 | export default new Router({
14 | mode: 'history',
15 | base: process.env.BASE_URL,
16 | routes: [
17 | {
18 | path: '/abstract',
19 | name: 'abstract',
20 | component: Abstract
21 | },
22 | {
23 | path: '/components-list',
24 | name: 'components-list',
25 | component: ComponentsList
26 | },
27 | {
28 | path: '/parameter-control',
29 | name: 'parameter-control',
30 | component: ParameterControl
31 | },
32 | {
33 | path: '/transformation-matrix',
34 | name: 'transformation-matrix',
35 | component: TransformationMatrix
36 | },
37 | {
38 | path: '/graphics-on-lisp',
39 | name: 'graphics-on-lisp',
40 | component: GraphicsOnLisp
41 | },
42 | {
43 | path: '/easing',
44 | name: 'easing',
45 | component: Easing
46 | }
47 | ]
48 | })
49 |
--------------------------------------------------------------------------------
/src/shims-modules.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'uid' {
2 | export default function(length: number): string
3 | }
4 |
5 | declare module 'mouse-event' {
6 | export function buttons(event: MouseEvent): number
7 | }
8 |
9 | declare module 'deepcopy' {
10 | export default function(value: any): any
11 | }
12 |
--------------------------------------------------------------------------------
/src/shims-tsx.d.ts:
--------------------------------------------------------------------------------
1 | import Vue, {VNode} from 'vue'
2 |
3 | declare global {
4 | namespace JSX {
5 | // tslint:disable no-empty-interface
6 | interface Element extends VNode {}
7 | // tslint:disable no-empty-interface
8 | interface ElementClass extends Vue {}
9 | interface IntrinsicElements {
10 | [elem: string]: any
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import Vue from 'vue';
3 | export default Vue;
4 | }
5 |
--------------------------------------------------------------------------------
/src/style/article.styl:
--------------------------------------------------------------------------------
1 | ::selection
2 | background var(--color-border)
3 |
4 | .article
5 | margin 0 auto
6 | padding 3em 2em 2em
7 | max-width 45em
8 | font-size 1.5em
9 | font-family 'YakuHanMPs', 'YakuHanJPs', 'EB Garamond', Georgia, yu-mincho-pr6n, YuMincho, '游明朝', 'Yu Mincho', YuMincho, 'Hiragino Mincho ProN', serif
10 |
11 | section
12 | margin-bottom 2em
13 |
14 | em
15 | // text-decoration underline
16 | // margin 0 2px
17 | // box-shadow 0 0 0 1px var(--color-border), 0 0 0 2px white, 0 0 0 3px var(--color-border)
18 | // font-weight 500
19 | font-style italic
20 |
21 | h1, h2, h3, h4, h5, h6
22 | font-family Roboto, sans-serif
23 |
24 | h1
25 | margin-bottom 1em
26 | color transparent
27 | font-weight 500
28 | font-size 3em
29 | text-stroke 1px var(--color-text)
30 | -webkit-text-stroke 1px var(--color-text)
31 |
32 | h2
33 | margin-top 0.5em
34 | margin-bottom 0.7em
35 | // margin-bottom 1em
36 | font-weight 500
37 | font-size 1.2em
38 |
39 | p
40 | margin-bottom 1.5em
41 | line-height 1.6
42 |
43 | a
44 | color var(--color-active)
45 |
46 | &:hover, &:focus, &:active
47 | text-decoration underline
48 |
49 | [lang=en]
50 | display none
51 |
52 | .en &
53 | display block
54 |
55 | [lang=ja]
56 | display none
57 | font-size 0.95em
58 | line-height 1.8
59 |
60 | .ja &
61 | display block
62 |
63 | .outline
64 | display inline-block
65 | margin-bottom 0.1em
66 | color transparent
67 | text-stroke 1px var(--color-text)
68 | -webkit-text-stroke 1px var(--color-text)
--------------------------------------------------------------------------------
/src/style/common.styl:
--------------------------------------------------------------------------------
1 | flex-version = flex
2 |
3 | @import 'nib'
4 | @import url('https://fonts.googleapis.com/css?family=Roboto+Condensed:400,700|Roboto:300,400,500')
5 |
6 | global-reset()
7 |
8 | @import './config.styl'
9 |
10 | // Variables
11 | :root
12 | --color-active #63acf9
13 | --color-border #e0e0e0
14 | --color-border-text #bbbbbb
15 | --color-control #bbbbbb
16 | --color-control-text #999999
17 | --color-bg #f0f0f0
18 | --color-field #f9f9f9
19 | --color-text #444444
20 | --color-parameter-hover #e4e4e4
21 | --color-seek #ff3854
22 | --font-monospace 'Roboto Condensed', monospace, sans-serif
23 | --font-code 'Fira Code', monospace, sans-serif
24 | --font-normal 'Roboto', Helvetica, Arial, sans-serif
25 | --color-menu-bg #000000
26 | --color-menu-text #ffffff
27 | --color-menu-field #000000
28 | --color-menu-border #333
29 | // Layout
30 | --layout-param-height 2.8em
31 | --layout-param-field-1w 6em
32 | --layout-param-field-gap-widget 0.5em
33 | --layout-param-field-gap-box 0.3em
34 | --layout-input-height 2em
35 | --layout-popover-padding 0.5em
36 |
37 | *, ::after, ::before
38 | box-sizing border-box
39 | outline none
40 | -webkit-tap-highlight-color transparent
41 |
42 | // Reset form elements
43 | input, button, select
44 | margin 0
45 | padding 0
46 | outline none
47 | border 0
48 | background transparent
49 | color inherit
50 | font-size inherit
51 | appearance none
52 |
53 | &::-webkit-outer-spin-button, &::-webkit-inner-spin-button
54 | margin 0
55 | -webkit-appearance none
56 |
57 | html
58 | font-size var(--font-size)
59 |
60 | .ui
61 | background var(--color-bg)
62 | font-size var(--font-size)
63 | font-family var(--font-normal)
64 | user-select none
65 |
66 | // Parameter
67 | .param-field
68 |
69 | &--1w, &--2w, &--3n, &--4n
70 | margin-right var(--layout-param-field-gap-widget)
71 |
72 | &--1w
73 | width var(--layout-param-field-1w)
74 |
75 | &--2w
76 | width 'calc(%s * 2)' % var(--layout-param-field-1w)
77 |
78 | &--3n
79 | width 'calc(%s / 1.5 * 3)' % var(--layout-param-field-1w)
80 |
81 | &--4n
82 | width 'calc(%s / 1.5 * 4)' % var(--layout-param-field-1w)
83 |
84 | // SVG
85 | .svg-overlay
86 | position fixed
87 | top 0
88 | left 0
89 | z-index 2001
90 | width 100vw
91 | height 100vh
92 |
93 | .svg-ui
94 | overflow visible
95 |
96 | .svg-overlay, .svg-ui
97 | svg
98 | position absolute
99 | top 0
100 | left 0
101 | width 100%
102 | height 100%
103 |
104 | .guide
105 | stroke var(--color-border)
106 | stroke-width 1px
107 | fill none
108 |
109 | .stroke
110 | stroke var(--color-active)
111 | stroke-width 3px
112 | fill none
113 |
114 | .dashed-stroke
115 | stroke var(--color-active)
116 | stroke-width 2px
117 | stroke-dasharray 3 2
118 | fill none
119 |
120 | .narrow-stroke
121 | stroke var(--color-active)
122 | stroke-width 2px
123 | fill none
124 |
125 | .fill
126 | fill var(--color-active)
127 |
128 | .text
129 | font-weight 700
130 | font-family var(--font-monospace)
131 | pointer-events none
132 | fill var(--color-active)
133 |
--------------------------------------------------------------------------------
/src/style/config.styl:
--------------------------------------------------------------------------------
1 | $popover-arrow-size = 0.7em
2 | $border-radius = 3px
3 | $border-radius-large = 6px
4 | $color-preview-size = 60px
5 |
6 | // TODO: Fix
7 | input-border-style()
8 | height var(--layout-input-height)
9 | border 1px solid var(--color-border)
10 | border-radius $border-radius
11 | background var(--color-field)
12 |
13 | input-placement-modifier-root()
14 | z-index 1
15 |
16 | &:hover
17 | z-index 2
18 |
19 | &:active, &:focus, &.editing, &.selected, &.updating
20 | z-index 3
21 |
22 | &.left
23 | margin-right -1px
24 |
25 | &.center
26 | margin-right -1px
27 |
28 | &.top
29 | margin-bottom -1px
30 |
31 | &.middle
32 | margin-bottom -1px
33 |
34 | input-placement-modifier-border(prefix = '&', suffix = '')
35 | {prefix}.left{suffix}
36 | border-top-right-radius 0
37 | border-bottom-right-radius 0
38 |
39 | {prefix}.center{suffix}
40 | border-radius 0
41 |
42 | {prefix}.right{suffix}
43 | border-top-left-radius 0
44 | border-bottom-left-radius 0
45 |
46 | {prefix}.top{suffix}
47 | border-bottom-right-radius 0
48 | border-bottom-left-radius 0
49 |
50 | {prefix}.middle{suffix}
51 | border-radius 0
52 |
53 | {prefix}.bottom{suffix}
54 | border-top-left-radius 0
55 | border-top-right-radius 0
56 |
57 | input-border-hover-style()
58 | border-color var(--color-active)
59 |
60 | input-border-focus-style()
61 | border-color var(--color-active)
62 | box-shadow 0 0 0 1px @border-color
63 |
64 | input-field-style()
65 | padding 0 0.3em
66 | color var(--color-text)
67 | line-height calc(var(--layout-input-height) - 2px)
68 |
69 | enable-menu-color()
70 | --color-bg var(--color-menu-bg)
71 | --color-text var(--color-menu-text)
72 | --color-border var(--color-menu-border)
73 | --color-field var(--color-menu-field)
74 |
75 | color var(--color-text)
76 | background var(--color-bg)
77 |
--------------------------------------------------------------------------------
/src/util/MouseDragEvent.ts:
--------------------------------------------------------------------------------
1 | import {vec2} from 'gl-matrix'
2 |
3 | export default interface MouseDragEvent {
4 | current: vec2
5 | delta: vec2
6 | offset: vec2
7 | abort: () => void
8 | originalEvent: any
9 | }
10 |
--------------------------------------------------------------------------------
/src/util/RoteryDrag.ts:
--------------------------------------------------------------------------------
1 | import {vec2} from 'gl-matrix'
2 | import {lerp} from '../math'
3 |
4 | // Returns +1, -1, 0
5 | function isTraversedAxisMinusX(
6 | p1: ArrayLike,
7 | p2: ArrayLike
8 | ): number {
9 | // Suppose a line segment from p1 to p2.
10 | // It'd be okay to check if it intersects to the axis -X
11 | // Precisely, The axis's formula is y = lim(a -> 0) a, x < 0
12 |
13 | const isTraversedAxisX = p1[1] * p2[1] < 0 || (p1[1] === 0 && p2[1] > 0)
14 |
15 | if (isTraversedAxisX) {
16 | // calculate X coord of intersection to the axis
17 | const yabs1 = Math.abs(p1[1])
18 | const yabs2 = Math.abs(p2[1])
19 | const t = yabs1 / (yabs1 + yabs2)
20 | const intersectionX = lerp(p1[0], p2[0], t)
21 |
22 | if (intersectionX < 0) {
23 | // Traversed
24 | return Math.sign(p2[1])
25 | }
26 | }
27 |
28 | return 0
29 | }
30 |
31 | export default class RoteryDrag {
32 | public minDistance: number = 0
33 | public initialAngle!: number
34 |
35 | private baseRotation!: number
36 | private lastAngle!: number
37 | private prev: vec2 = vec2.create()
38 | private current: vec2 = vec2.create()
39 | private center: vec2 = vec2.create()
40 |
41 | public start(
42 | initialAngle: number,
43 | center: number[],
44 | position: number[]
45 | ): void {
46 | this.initialAngle = initialAngle
47 | this.lastAngle = initialAngle
48 | vec2.copy(this.center, center)
49 | vec2.sub(this.prev, position, center)
50 | this.baseRotation = Math.floor(initialAngle / 360)
51 | }
52 |
53 | public getAngle(position: number[]): number {
54 | vec2.sub(this.current, position, this.center)
55 |
56 | if (vec2.length(this.current) < this.minDistance) {
57 | return this.lastAngle
58 | }
59 |
60 | const traversed = isTraversedAxisMinusX(this.prev, this.current)
61 | this.baseRotation -= traversed
62 |
63 | const angle = (Math.atan2(this.current[1], this.current[0]) / Math.PI) * 180
64 | this.lastAngle = this.baseRotation * 360 + angle
65 |
66 | vec2.copy(this.prev, this.current)
67 |
68 | return this.lastAngle
69 | }
70 |
71 | public get radius() {
72 | return vec2.length(this.current)
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/util/constrain-value.ts:
--------------------------------------------------------------------------------
1 | import {quantize} from '../math'
2 |
3 | type ValueType = number | number[]
4 |
5 | interface ConstraintsInfo {
6 | min: ValueType
7 | max: ValueType
8 | step: number
9 | toData: (value: ValueType) => ValueType
10 | }
11 |
12 | export default function constrainValue(
13 | value: any,
14 | {min, max, step, toData}: ConstraintsInfo
15 | ): any {
16 | const isValueArray = Array.isArray(value)
17 |
18 | if (typeof min === 'boolean') {
19 | if (isValueArray) {
20 | const isMinArray = Array.isArray(min)
21 | for (let i = 0; i < value.length; i++) {
22 | value[i] = Math.max(value[i], isMinArray ? min[i] : min)
23 | }
24 | } else {
25 | value = Math.max(value, min)
26 | }
27 | }
28 |
29 | if (typeof max === 'boolean') {
30 | if (isValueArray) {
31 | const iMaxArray = Array.isArray(max)
32 | for (let i = 0; i < value.length; i++) {
33 | value[i] = Math.min(value[i], iMaxArray ? max[i] : max)
34 | }
35 | } else {
36 | value = Math.min(value, max)
37 | }
38 | }
39 |
40 | if (typeof step === 'number') {
41 | if (isValueArray) {
42 | for (let i = 0; i < value.length; i++) {
43 | value[i] = quantize(value[i], step)
44 | }
45 | } else {
46 | value = quantize(value, step)
47 | }
48 | }
49 |
50 | if (toData) {
51 | value = toData(value)
52 | }
53 |
54 | return value
55 | }
56 |
--------------------------------------------------------------------------------
/src/util/deepcopy.ts:
--------------------------------------------------------------------------------
1 | function isPlainObject(obj: any) {
2 | return obj !== null && typeof obj === 'object'
3 | }
4 |
5 | export default function deepcopy(src: any) {
6 | let dest: any
7 | if (Array.isArray(src)) {
8 | dest = src.slice(0) || []
9 | dest.forEach((n: any) => {
10 | if ((typeof n === 'object' && n !== {}) || Array.isArray(n)) {
11 | n = deepcopy(n)
12 | }
13 | })
14 | } else if (typeof src.clone === 'function') {
15 | dest = src.clone()
16 | } else if (isPlainObject(src)) {
17 | dest = Object.assign({}, src)
18 | Object.keys(dest).forEach(key => {
19 | if (isPlainObject(dest[key])) {
20 | dest[key] = deepcopy(dest[key])
21 | }
22 | })
23 | } else {
24 | dest = src
25 | }
26 | return dest
27 | }
28 |
--------------------------------------------------------------------------------
/src/util/deserialize.ts:
--------------------------------------------------------------------------------
1 | import Color from '../data/Color'
2 |
3 | const DataClass: {[s: string]: any} = {
4 | Color
5 | }
6 |
7 | export default function deserialize(text: string) {
8 | const data = JSON.parse(text)
9 |
10 | if (/^(object|array)$/.test(typeof data)) {
11 | deserializeObject(data)
12 | }
13 | return data
14 |
15 | function deserializeObject(obj: any) {
16 | const keys = Array.isArray(obj)
17 | ? Array(obj.length)
18 | .fill(0)
19 | .map((_, i) => i)
20 | : Object.keys(obj)
21 |
22 | for (const key of keys) {
23 | const value = obj[key]
24 | if (
25 | Array.isArray(value) &&
26 | typeof value[0] === 'string' &&
27 | value[0] === ':'
28 | ) {
29 | // It should be an instance of class
30 | } else if (typeof value === 'object') {
31 | if (typeof value.$type === 'string') {
32 | obj[key] = new DataClass[value.$type](...value.value)
33 | } else {
34 | deserializeObject(value)
35 | }
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/util/disable-reactive.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baku89/ui-study/99799e504df0f74ee5838e81ee5258387df2a99e/src/util/disable-reactive.ts
--------------------------------------------------------------------------------
/src/util/force-notify.ts:
--------------------------------------------------------------------------------
1 | export default function forceNotify(obj: any) {
2 | if (obj.__ob__) {
3 | obj.__ob__.dep.notify()
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/util/index.ts:
--------------------------------------------------------------------------------
1 | import mouse from 'mouse-event'
2 |
3 | import constrainValue from './constrain-value'
4 | import deserialize from './deserialize'
5 | import forceNotify from './force-notify'
6 | import RoteryDrag from './RoteryDrag'
7 | import MouseDragEvent from './MouseDragEvent'
8 | import splitToParentAndKey from './split-to-parent-and-key'
9 |
10 | function getDOMCenter(el: HTMLElement): number[] {
11 | const {top, right, bottom, left} = el.getBoundingClientRect()
12 | return [(left + right) / 2, (top + bottom) / 2]
13 | }
14 |
15 | function setButtonUnfocusableForMouse(button: HTMLElement) {
16 | button.addEventListener('mousedown', (e: MouseEvent) => {
17 | const clicked = mouse.buttons(e)
18 | if (clicked === 1) {
19 | window.addEventListener(
20 | 'mouseup',
21 | () => {
22 | button.blur()
23 | },
24 | {once: true}
25 | )
26 | }
27 | })
28 | }
29 | export {
30 | constrainValue,
31 | deserialize,
32 | forceNotify,
33 | getDOMCenter,
34 | setButtonUnfocusableForMouse,
35 | RoteryDrag,
36 | MouseDragEvent,
37 | splitToParentAndKey
38 | }
39 |
--------------------------------------------------------------------------------
/src/util/split-to-parent-and-key.ts:
--------------------------------------------------------------------------------
1 | export default function splitToParentAndKey(path: string) {
2 | const lastSlashIndex = path.lastIndexOf('/')
3 |
4 | const parent = path.substr(0, lastSlashIndex)
5 | let key: string | number = path.substr(lastSlashIndex + 1)
6 |
7 | if (/^[0-9]+$/.test(key)) {
8 | key = parseInt(key, 10)
9 | }
10 |
11 | return [parent, key]
12 | }
13 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "module": "esnext",
5 | "strict": true,
6 | "strictFunctionTypes": false,
7 | "jsx": "preserve",
8 | "importHelpers": true,
9 | "moduleResolution": "node",
10 | "experimentalDecorators": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "sourceMap": true,
14 | "declaration": true,
15 | "declarationDir": "./typings",
16 | "baseUrl": ".",
17 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"]
18 | },
19 | "files": ["node_modules/@types/webgl2/index.d.ts"],
20 | "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
21 | "exclude": ["node_modules"]
22 | }
23 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "defaultSeverity": "warning",
3 | "extends": ["tslint:recommended", "tslint-config-prettier"],
4 | "linterOptions": {
5 | "exclude": ["node_modules/**"]
6 | },
7 | "rules": {
8 | "interface-name": false,
9 | "ordered-imports": false,
10 | "object-literal-sort-keys": false,
11 | "no-consecutive-blank-lines": false,
12 | "no-console": false,
13 | "variable-name": [true, "allow-leading-underscore", "allow-pascal-case"],
14 | "one-variable-per-declaration": false,
15 | "max-classes-per-file": false
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/typings/components/ConfigProvider.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ConfigProvider extends Vue {
3 | private keySlower;
4 | private keyFaster;
5 | private keySymmetry;
6 | private keyQuantize;
7 | private keyScale;
8 | private quantizeAngles;
9 | private render;
10 | }
11 |
--------------------------------------------------------------------------------
/typings/components/InputAngle.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputAngle extends Vue {
3 | private value;
4 | private isDragging;
5 | private dragFrom;
6 | private dragTo;
7 | private roteryDrag;
8 | private readonly quantizeAngles;
9 | private readonly keyQuantize;
10 | private created;
11 | private mounted;
12 | private onDragstart;
13 | private onDrag;
14 | private onDragend;
15 | }
16 |
--------------------------------------------------------------------------------
/typings/components/InputButton.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputButton extends Vue {
3 | private label;
4 | private icon;
5 | private iconPosition;
6 | private mounted;
7 | private readonly onlyIcon;
8 | }
9 |
--------------------------------------------------------------------------------
/typings/components/InputCheckbox.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputCheckbox extends Vue {
3 | private value;
4 | private label;
5 | private id;
6 | }
7 |
--------------------------------------------------------------------------------
/typings/components/InputCodeEditor/InputCodeEditor.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputCodeEditor extends Vue {
3 | private value;
4 | private lang;
5 | private editor;
6 | private mounted;
7 | private beforeDestroy;
8 | private onValueChanged;
9 | private onLangChanged;
10 | }
11 |
--------------------------------------------------------------------------------
/typings/components/InputCodeEditor/index.d.ts:
--------------------------------------------------------------------------------
1 | import InputCodeEditor from './InputCodeEditor.vue';
2 | export default InputCodeEditor;
3 |
--------------------------------------------------------------------------------
/typings/components/InputColor/InputColor.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputColor extends Vue {
3 | private value;
4 | private showLabel;
5 | private readonly hasAlpha;
6 | private readonly isHex;
7 | private validateColorHex;
8 | private onUpdateElement;
9 | }
10 |
--------------------------------------------------------------------------------
/typings/components/InputColor/InputColorElement.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | import { DataColorMode, DataColorModeInfo } from '../../data';
3 | export default class InputColorElement extends Vue {
4 | private color;
5 | private varying;
6 | private isEditing;
7 | private isDragging;
8 | private slitMaxY;
9 | private slitMinY;
10 | private slitLeft;
11 | private previewY;
12 | private updatedRecently;
13 | private updatedTimer;
14 | private readonly keyFaster;
15 | readonly mode: DataColorMode;
16 | readonly element: number;
17 | readonly cssColor: string;
18 | readonly slitStyles: {
19 | left: string;
20 | top: string;
21 | height: string;
22 | };
23 | readonly previewStyles: {
24 | background: string;
25 | left: string;
26 | top: string;
27 | };
28 | readonly info: DataColorModeInfo;
29 | private onChange;
30 | private onKeydown;
31 | private onClick;
32 | private onDragstart;
33 | private onDrag;
34 | private onDragend;
35 | private onColorChanged;
36 | }
37 |
--------------------------------------------------------------------------------
/typings/components/InputColor/index.d.ts:
--------------------------------------------------------------------------------
1 | import InputColor from './InputColor.vue';
2 | export default InputColor;
3 |
--------------------------------------------------------------------------------
/typings/components/InputColorButton.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | import { DataColorMode, DataColorElements } from '../data';
3 | export default class InputColorButton extends Vue {
4 | private value;
5 | private isPopoverOpen;
6 | readonly mode: DataColorMode;
7 | readonly elements: DataColorElements;
8 | readonly cssColor: string;
9 | readonly previewStyles: object;
10 | readonly hsl: number[];
11 | private onChangeMode;
12 | private onInput;
13 | }
14 |
--------------------------------------------------------------------------------
/typings/components/InputColorPicker.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputColorPicker extends Vue {
3 | private value;
4 | private isDraggingSV;
5 | private isDraggingHue;
6 | private readonly mode;
7 | private readonly elements;
8 | private readonly hsv;
9 | private readonly cssColor;
10 | private readonly SVPreviewStyles;
11 | private readonly HuePreviewStyles;
12 | private readonly gradientPaletteColor;
13 | private onDragSV;
14 | private onDragHue;
15 | private emitNewValue;
16 | }
17 |
--------------------------------------------------------------------------------
/typings/components/InputDropdown.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputDropdown extends Vue {
3 | private value;
4 | private values;
5 | private labels;
6 | private theme;
7 | private onChange;
8 | }
9 |
--------------------------------------------------------------------------------
/typings/components/InputIconAction/InputIconAction.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputIconAction extends Vue {
3 | private items;
4 | private src;
5 | private isPopoverOpen;
6 | private onClick;
7 | }
8 |
--------------------------------------------------------------------------------
/typings/components/InputIconAction/index.d.ts:
--------------------------------------------------------------------------------
1 | import InputIconAction from './InputIconAction.vue';
2 | export default InputIconAction;
3 |
--------------------------------------------------------------------------------
/typings/components/InputIconButton.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputIconButton extends Vue {
3 | private src;
4 | private mounted;
5 | }
6 |
--------------------------------------------------------------------------------
/typings/components/InputIconToggle.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputIconToggle extends Vue {
3 | private value;
4 | private srcOn;
5 | private srcOff;
6 | private mounted;
7 | }
8 |
--------------------------------------------------------------------------------
/typings/components/InputMatrix.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputMatrix extends Vue {
3 | private value;
4 | private columns;
5 | private rows;
6 | private direction;
7 | private precision;
8 | private min;
9 | private max;
10 | private labels;
11 | private unit;
12 | private readonly elmAttrs;
13 | private onInput;
14 | }
15 |
--------------------------------------------------------------------------------
/typings/components/InputMode.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputMode extends Vue {
3 | private value;
4 | private values;
5 | private labels;
6 | private id;
7 | private onClick;
8 | }
9 |
--------------------------------------------------------------------------------
/typings/components/InputNumber.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputNumber extends Vue {
3 | isSelected: boolean;
4 | private value;
5 | private precision;
6 | private label;
7 | private unit;
8 | private min;
9 | private max;
10 | private step;
11 | private isEditing;
12 | private isDragging;
13 | private dragFrom;
14 | private dragTo;
15 | private dragMinX;
16 | private dragMaxX;
17 | private shouldOmitZero;
18 | private updatedRecently;
19 | private updatedTimer;
20 | private readonly SelectionManager;
21 | private readonly dragSpeed;
22 | private readonly keyFaster;
23 | private readonly keySlower;
24 | private readonly displayValue;
25 | private readonly hasMin;
26 | private readonly hasMax;
27 | private readonly hasStep;
28 | private onChange;
29 | private updateValue;
30 | private onClick;
31 | private onFocus;
32 | private onKeydown;
33 | private onDragstart;
34 | private onDrag;
35 | private onDragend;
36 | private onValueChanged;
37 | }
38 |
--------------------------------------------------------------------------------
/typings/components/InputPoint.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputPoint extends Vue {
3 | private value;
4 | private knobOffset;
5 | private isDragging;
6 | private dragFrom;
7 | private dragTo;
8 | private readonly keyFaster;
9 | private readonly keySlower;
10 | private ui;
11 | private onKeydown;
12 | private onKeyup;
13 | private onDragstart;
14 | private onDrag;
15 | private onDragend;
16 | }
17 |
--------------------------------------------------------------------------------
/typings/components/InputRange.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputRange extends Vue {
3 | private value;
4 | private min;
5 | private max;
6 | private step;
7 | private readonly keySymmetry;
8 | private readonly keySlower;
9 | private hoverTarget;
10 | private dragMode;
11 | private dragStartValue;
12 | readonly lower: number;
13 | readonly upper: number;
14 | readonly barStyles: {
15 | left: string;
16 | right: string;
17 | };
18 | readonly firstStyles: {
19 | left: string;
20 | };
21 | readonly secondStyles: {
22 | left: string;
23 | };
24 | private onMousemove;
25 | private onMouseleave;
26 | private onDragstart;
27 | private onDrag;
28 | private onDragend;
29 | }
30 |
--------------------------------------------------------------------------------
/typings/components/InputSlider.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputSlider extends Vue {
3 | private value;
4 | private min;
5 | private max;
6 | private step;
7 | private readonly keySlower;
8 | private dragStartValue;
9 | private isDragging;
10 | private readonly percent;
11 | private readonly accumStyles;
12 | private readonly knobStyles;
13 | private readonly isExceeded;
14 | private onDragstart;
15 | private onDrag;
16 | private onDragend;
17 | }
18 |
--------------------------------------------------------------------------------
/typings/components/InputString.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputString extends Vue {
3 | private value;
4 | private validator;
5 | readonly inputListeners: Record & {
6 | change: () => void;
7 | };
8 | private onChange;
9 | }
10 |
--------------------------------------------------------------------------------
/typings/components/InputTime/InputTime.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputTime extends Vue {
3 | private value;
4 | private min;
5 | private max;
6 | private readonly fps;
7 | private readonly dragSpeed;
8 | private readonly keyFaster;
9 | private readonly keySlower;
10 | private smpte;
11 | private frames;
12 | private dropFrameSeparator;
13 | private seconds;
14 | private minutes;
15 | private hours;
16 | private isEditing;
17 | private isDragging;
18 | private activePartIndex;
19 | private dragFrom;
20 | private dragTo;
21 | private dragMinX;
22 | private dragMaxX;
23 | private timecode;
24 | private readonly hasMin;
25 | private readonly hasMax;
26 | private created;
27 | private onValueChanged;
28 | private onChange;
29 | private onKeydown;
30 | private onMouseenterPart;
31 | private onMouseleavePart;
32 | private onDragstart;
33 | private onDrag;
34 | private onDragend;
35 | private onClick;
36 | private setSelectionByPartIndex;
37 | }
38 |
--------------------------------------------------------------------------------
/typings/components/InputTime/index.d.ts:
--------------------------------------------------------------------------------
1 | import InputTime from './InputTime.vue';
2 | export default InputTime;
3 |
--------------------------------------------------------------------------------
/typings/components/InputVector.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class InputVector extends Vue {
3 | private value;
4 | private precision;
5 | private min;
6 | private max;
7 | private step;
8 | private labels;
9 | private unit;
10 | private onInput;
11 | }
12 |
--------------------------------------------------------------------------------
/typings/components/ParamFieldAffine.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ParamFieldAffine extends Vue {
3 | private value;
4 | private precision;
5 | private dragSpeed;
6 | private onInput;
7 | }
8 |
--------------------------------------------------------------------------------
/typings/components/ParamFieldAngle.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ParamFieldAngle extends Vue {
3 | private value;
4 | private precision;
5 | private label;
6 | private onInput;
7 | }
8 |
--------------------------------------------------------------------------------
/typings/components/ParamFieldColor.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ParamFieldColor extends Vue {
3 | private value;
4 | private onInput;
5 | }
6 |
--------------------------------------------------------------------------------
/typings/components/ParamFieldNumber.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ParamFieldNumber extends Vue {
3 | }
4 |
--------------------------------------------------------------------------------
/typings/components/ParamFieldPoint.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ParamFieldPoint extends Vue {
3 | private value;
4 | private precision;
5 | private label;
6 | private unit;
7 | private keepProportion;
8 | private onInput;
9 | }
10 |
--------------------------------------------------------------------------------
/typings/components/ParamFieldRange.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ParamFieldRange extends Vue {
3 | private value;
4 | private min;
5 | private max;
6 | private precision;
7 | private labels;
8 | private unit;
9 | private onInputVector;
10 | private onInput;
11 | }
12 |
--------------------------------------------------------------------------------
/typings/components/ParamFieldScale.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ParamFieldScale extends Vue {
3 | private value;
4 | private min;
5 | private max;
6 | private precision;
7 | private labels;
8 | private keepProportion;
9 | private internalKeepProportion;
10 | private created;
11 | private readonly _keepProportion;
12 | private onInput;
13 | private onChangeKeepProportion;
14 | }
15 |
--------------------------------------------------------------------------------
/typings/components/ParamFieldSeed.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ParamFieldSeed extends Vue {
3 | private value;
4 | private min;
5 | private max;
6 | private step;
7 | private preision;
8 | private onInput;
9 | private generateRandomSeed;
10 | }
11 |
--------------------------------------------------------------------------------
/typings/components/ParamFieldSlider.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ParamFieldSlider extends Vue {
3 | private value;
4 | private min;
5 | private max;
6 | private step;
7 | private precision;
8 | private label;
9 | private unit;
10 | private onInput;
11 | }
12 |
--------------------------------------------------------------------------------
/typings/components/Parameter.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class Parameter extends Vue {
3 | private label;
4 | }
5 |
--------------------------------------------------------------------------------
/typings/components/SelectionManager.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class SelectionManager extends Vue {
3 | SelectionManager: this;
4 | private items;
5 | private dragStartValues;
6 | private dragMode;
7 | add(item: any): void;
8 | private mounted;
9 | private beforeDestroy;
10 | private readonly showControl;
11 | private deselectAll;
12 | private onDragstart;
13 | private onDrag;
14 | private onDragend;
15 | private deselectOnClickOutside;
16 | }
17 |
--------------------------------------------------------------------------------
/typings/components/Timeline/Timeline.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class Timeline extends Vue {
3 | private time;
4 | private min;
5 | private max;
6 | private autoScroll;
7 | private readonly keyScale;
8 | private displayRange;
9 | private readonly keySlower;
10 | private dragStartTime;
11 | private created;
12 | private mounted;
13 | private readonly knobOverflow;
14 | private readonly knobStyles;
15 | private onDragstart;
16 | private onDrag;
17 | private onUpdateDisplayRange;
18 | private onTimeChanged;
19 | private scrollToTime;
20 | }
21 |
--------------------------------------------------------------------------------
/typings/components/Timeline/TimelineSeekbarScale.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class TimelineSeekbarScale extends Vue {
3 | private displayRange;
4 | private readonly fps;
5 | private scales;
6 | private mounted;
7 | private updateScale;
8 | }
9 |
--------------------------------------------------------------------------------
/typings/components/Timeline/index.d.ts:
--------------------------------------------------------------------------------
1 | import Timeline from './Timeline.vue';
2 | export default Timeline;
3 |
--------------------------------------------------------------------------------
/typings/components/TimelineColor.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class TimelineColor extends Vue {
3 | private value;
4 | private displayRange;
5 | private ctx;
6 | renderColors(): void;
7 | private mounted;
8 | private beforeDestroy;
9 | }
10 |
--------------------------------------------------------------------------------
/typings/components/common/ButtonWrapper.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class ButtonWrapper extends Vue {
3 | private mounted;
4 | private initEventHandlers;
5 | private render;
6 | }
7 |
--------------------------------------------------------------------------------
/typings/components/common/Drag.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class Drag extends Vue {
3 | private measure;
4 | private coordinate;
5 | private detectDirection;
6 | private minDragDistance;
7 | private clamp;
8 | private box;
9 | private dragStarted;
10 | private origin;
11 | private current;
12 | private prev;
13 | private delta;
14 | private absOrigin;
15 | private absCurrent;
16 | private absPrev;
17 | private created;
18 | private mounted;
19 | private beforeDestroy;
20 | private readonly boxElement;
21 | private onMousedown;
22 | private onKeyToggle;
23 | private onMousemove;
24 | private onMouseup;
25 | private quitDrag;
26 | private setAbsCoordByMouseEvent;
27 | private toSpecifiedCoord;
28 | private render;
29 | }
30 |
--------------------------------------------------------------------------------
/typings/components/common/GradientPalette/GradientPalette.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class GradientPalette extends Vue {
3 | private color;
4 | private varyings;
5 | private ctx;
6 | private canvas;
7 | private mounted;
8 | private onColorChanged;
9 | private onVaryingsChanged;
10 | private renderPad;
11 | }
12 |
--------------------------------------------------------------------------------
/typings/components/common/GradientPalette/index.d.ts:
--------------------------------------------------------------------------------
1 | import GradientPalette from './GradientPalette.vue';
2 | export default GradientPalette;
3 |
--------------------------------------------------------------------------------
/typings/components/common/Icon.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class Icon extends Vue {
3 | private src;
4 | private tag;
5 | private size;
6 | private render;
7 | }
8 |
--------------------------------------------------------------------------------
/typings/components/common/Menu/Menu.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class Menu extends Vue {
3 | private items;
4 | private filterText;
5 | private readonly isFiltering;
6 | private readonly numValues;
7 | private readonly flattenedItems;
8 | private readonly filteredItems;
9 | private mounted;
10 | private beforeDestroy;
11 | private onKeydown;
12 | private onInputFilterText;
13 | private onKeydownFilterText;
14 | }
15 |
--------------------------------------------------------------------------------
/typings/components/common/Menu/MenuItem.d.ts:
--------------------------------------------------------------------------------
1 | export default interface MenuItem {
2 | value: string | number | symbol;
3 | label: string;
4 | shortLabel?: string;
5 | icon?: string;
6 | type?: 'submenu' | 'compact';
7 | submenu?: MenuItem[];
8 | }
9 |
--------------------------------------------------------------------------------
/typings/components/common/Menu/Submenu.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class Submenu extends Vue {
3 | private items;
4 | private type;
5 | private hasParent;
6 | private selectedIndex;
7 | private isSubSelected;
8 | setSelectedIndex(index: number | null): void;
9 | private onItemsChanged;
10 | private liClasses;
11 | private onHoverItem;
12 | private mounted;
13 | private beforeDestroy;
14 | private onKeydown;
15 | private selectNeighbour;
16 | }
17 |
--------------------------------------------------------------------------------
/typings/components/common/Menu/index.d.ts:
--------------------------------------------------------------------------------
1 | import Menu from './Menu.vue';
2 | export default Menu;
3 |
--------------------------------------------------------------------------------
/typings/components/common/Popover.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class Popover extends Vue {
3 | private active;
4 | private placement;
5 | private popperInstance;
6 | private originalParentEl;
7 | setReference(el: Element): void;
8 | private mounted;
9 | private onActiveChanged;
10 | private setOriginalParent;
11 | private killPopper;
12 | private bindPopper;
13 | private createPopper;
14 | private resetPopper;
15 | }
16 |
--------------------------------------------------------------------------------
/typings/components/common/Portal.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class Portal extends Vue {
3 | private originalParentEl;
4 | private attachToParent;
5 | private target;
6 | private mounted;
7 | private beforeDestroy;
8 | private render;
9 | private onTargetChanged;
10 | private killGhostElement;
11 | private initDestroy;
12 | private destroyElement;
13 | private changeParentEl;
14 | }
15 |
--------------------------------------------------------------------------------
/typings/components/common/SvgArcArrow.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | export default class SvgArcArrow extends Vue {
3 | private center;
4 | private radius;
5 | private start;
6 | private end;
7 | readonly diff: number;
8 | readonly startRadians: number;
9 | readonly endRadians: number;
10 | readonly x2: number;
11 | readonly y2: number;
12 | readonly d: string;
13 | readonly willShowTip: boolean;
14 | readonly tipTransform: string;
15 | }
16 |
--------------------------------------------------------------------------------
/typings/components/common/SvgArrow.vue.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator';
2 | import { vec2 } from 'gl-matrix';
3 | export default class SvgArrow extends Vue {
4 | private from;
5 | private to;
6 | private _sub;
7 | private _lineTo;
8 | private _normalized;
9 | private created;
10 | readonly lineTo: vec2;
11 | readonly sub: vec2;
12 | readonly willShowTip: boolean;
13 | readonly tipTransform: string;
14 | }
15 |
--------------------------------------------------------------------------------
/typings/components/index.d.ts:
--------------------------------------------------------------------------------
1 | import ConfigProvider from './ConfigProvider';
2 | import InputAngle from './InputAngle.vue';
3 | import InputButton from './InputButton.vue';
4 | import InputCodeEditor from './InputCodeEditor';
5 | import InputCheckbox from './InputCheckbox.vue';
6 | import InputColor from './InputColor';
7 | import InputColorButton from './InputColorButton.vue';
8 | import InputDropdown from './InputDropdown.vue';
9 | import InputIconAction from './InputIconAction';
10 | import InputIconButton from './InputIconButton.vue';
11 | import InputIconToggle from './InputIconToggle.vue';
12 | import InputMatrix from './InputMatrix.vue';
13 | import InputMode from './InputMode.vue';
14 | import InputNumber from './InputNumber.vue';
15 | import InputPoint from './InputPoint.vue';
16 | import InputRange from './InputRange.vue';
17 | import InputSlider from './InputSlider.vue';
18 | import InputString from './InputString.vue';
19 | import InputTime from './InputTime';
20 | import InputVector from './InputVector.vue';
21 | import Parameter from './Parameter.vue';
22 | import ParamFieldAffine from './ParamFieldAffine.vue';
23 | import ParamFieldAngle from './ParamFieldAngle.vue';
24 | import ParamFieldColor from './ParamFieldColor.vue';
25 | import ParamFieldNumber from './ParamFieldNumber.vue';
26 | import ParamFieldPoint from './ParamFieldPoint.vue';
27 | import ParamFieldRange from './ParamFieldRange.vue';
28 | import ParamFieldScale from './ParamFieldScale.vue';
29 | import ParamFieldSeed from './ParamFieldSeed.vue';
30 | import ParamFieldSlider from './ParamFieldSlider.vue';
31 | import SelectionManager from './SelectionManager.vue';
32 | import Timeline from './Timeline';
33 | import TimelineColor from './TimelineColor.vue';
34 | declare const _default: {
35 | ConfigProvider: typeof ConfigProvider;
36 | InputAngle: typeof InputAngle;
37 | InputButton: typeof InputButton;
38 | InputCodeEditor: typeof InputCodeEditor;
39 | InputCheckbox: typeof InputCheckbox;
40 | InputColor: typeof InputColor;
41 | InputColorButton: typeof InputColorButton;
42 | InputDropdown: typeof InputDropdown;
43 | InputIconAction: typeof InputIconAction;
44 | InputIconButton: typeof InputIconButton;
45 | InputIconToggle: typeof InputIconToggle;
46 | InputMatrix: typeof InputMatrix;
47 | InputMode: typeof InputMode;
48 | InputNumber: typeof InputNumber;
49 | InputPoint: typeof InputPoint;
50 | InputRange: typeof InputRange;
51 | InputSlider: typeof InputSlider;
52 | InputString: typeof InputString;
53 | InputTime: typeof InputTime;
54 | InputVector: typeof InputVector;
55 | Parameter: typeof Parameter;
56 | ParamFieldAffine: typeof ParamFieldAffine;
57 | ParamFieldAngle: typeof ParamFieldAngle;
58 | ParamFieldColor: typeof ParamFieldColor;
59 | ParamFieldNumber: typeof ParamFieldNumber;
60 | ParamFieldPoint: typeof ParamFieldPoint;
61 | ParamFieldRange: typeof ParamFieldRange;
62 | ParamFieldSeed: typeof ParamFieldSeed;
63 | ParamFieldScale: typeof ParamFieldScale;
64 | ParamFieldSlider: typeof ParamFieldSlider;
65 | SelectionManager: typeof SelectionManager;
66 | Timeline: typeof Timeline;
67 | TimelineColor: typeof TimelineColor;
68 | };
69 | export default _default;
70 |
--------------------------------------------------------------------------------
/typings/data/index.d.ts:
--------------------------------------------------------------------------------
1 | declare type DataColorMode = 'hex' | 'hexa' | 'rgb' | 'rgba' | 'hsl' | 'hsla' | 'hsv' | 'hsva';
2 | declare type DataColorElements = string | number[] | [string, number];
3 | declare type DataColor = [DataColorMode, DataColorElements];
4 | interface DataColorModeInfo {
5 | max: number[];
6 | label: string[];
7 | unit: string[];
8 | }
9 | declare const DataColorInfo: Map;
10 | declare type DataTransformType1D = 'translateX' | 'translateY' | 'scaleX' | 'scaleY' | 'scaleUniform' | 'rotate' | 'skewX' | 'skewY';
11 | declare type DataTransformType2D = 'translate' | 'scale' | 'skew';
12 | declare type DataTransformTypeMatrix = 'matrix';
13 | declare type DataTransformType = DataTransformType1D | DataTransformType2D | DataTransformTypeMatrix;
14 | declare type DataTransformValue = number | number[];
15 | declare const DataTransformType1DList: string[];
16 | declare const DataTransformType2DList: string[];
17 | declare const DataTransformTypeMatrixList: string[];
18 | declare const DataTransformTypeList: string[];
19 | interface DataTransformStack {
20 | type: DataTransformType;
21 | value: DataTransformValue;
22 | active: boolean;
23 | }
24 | declare type DataTransform = DataTransformStack[];
25 | export { DataColorMode, DataColorElements, DataColor, DataColorModeInfo, DataColorInfo, DataTransform, DataTransformType, DataTransformValue, DataTransformType1DList, DataTransformType2DList, DataTransformTypeMatrixList, DataTransformTypeList, DataTransformStack };
26 |
--------------------------------------------------------------------------------
/typings/index.d.ts:
--------------------------------------------------------------------------------
1 | import Drag from './components/common/Drag';
2 | import * as util from './util';
3 | import * as math from './math';
4 | declare const _default: {
5 | components: {
6 | ConfigProvider: typeof import("./components/ConfigProvider").default;
7 | InputAngle: typeof import("./components/InputAngle.vue").default;
8 | InputButton: typeof import("./components/InputButton.vue").default;
9 | InputCodeEditor: typeof import("./components/InputCodeEditor").default;
10 | InputCheckbox: typeof import("./components/InputCheckbox.vue").default;
11 | InputColor: typeof import("./components/InputColor").default;
12 | InputColorButton: typeof import("./components/InputColorButton.vue").default;
13 | InputDropdown: typeof import("./components/InputDropdown.vue").default;
14 | InputIconAction: typeof import("./components/InputIconAction").default;
15 | InputIconButton: typeof import("./components/InputIconButton.vue").default;
16 | InputIconToggle: typeof import("./components/InputIconToggle.vue").default;
17 | InputMatrix: typeof import("./components/InputMatrix.vue").default;
18 | InputMode: typeof import("./components/InputMode.vue").default;
19 | InputNumber: typeof import("./components/InputNumber.vue").default;
20 | InputPoint: typeof import("./components/InputPoint.vue").default;
21 | InputRange: typeof import("./components/InputRange.vue").default;
22 | InputSlider: typeof import("./components/InputSlider.vue").default;
23 | InputString: typeof import("./components/InputString.vue").default;
24 | InputTime: typeof import("./components/InputTime").default;
25 | InputVector: typeof import("./components/InputVector.vue").default;
26 | Parameter: typeof import("./components/Parameter.vue").default;
27 | ParamFieldAffine: typeof import("./components/ParamFieldAffine.vue").default;
28 | ParamFieldAngle: typeof import("./components/ParamFieldAngle.vue").default;
29 | ParamFieldColor: typeof import("./components/ParamFieldColor.vue").default;
30 | ParamFieldNumber: typeof import("./components/ParamFieldNumber.vue").default;
31 | ParamFieldPoint: typeof import("./components/ParamFieldPoint.vue").default;
32 | ParamFieldRange: typeof import("./components/ParamFieldRange.vue").default;
33 | ParamFieldSeed: typeof import("./components/ParamFieldSeed.vue").default;
34 | ParamFieldScale: typeof import("./components/ParamFieldScale.vue").default;
35 | ParamFieldSlider: typeof import("./components/ParamFieldSlider.vue").default;
36 | SelectionManager: typeof import("./components/SelectionManager.vue").default;
37 | Timeline: typeof import("./components/Timeline").default;
38 | TimelineColor: typeof import("./components/TimelineColor.vue").default;
39 | };
40 | common: {
41 | Drag: typeof Drag;
42 | };
43 | util: typeof util;
44 | math: typeof math;
45 | };
46 | export default _default;
47 |
--------------------------------------------------------------------------------
/typings/math/index.d.ts:
--------------------------------------------------------------------------------
1 | declare function lerp(a: number, b: number, t: number): number;
2 | declare function clamp(value: number, min: number, max: number): number;
3 | declare function mod(a: number, b: number): number;
4 | declare function ratio(value: number, bottom: number, top: number, clamped?: boolean): number;
5 | declare function parseNumber(str: string): number;
6 | declare function toFixed(value: number, precision: number, omitZeros?: boolean): string;
7 | declare function toRadians(degrees: number): number;
8 | declare function toDegrees(radians: number): number;
9 | declare function cycleMod(value: number, inc: number, max: number): number;
10 | declare function quantize(value: number, step: number): number;
11 | declare function isInteger(value: number): boolean;
12 | export { lerp, clamp, parseNumber, toFixed, ratio, mod, toRadians, toDegrees, cycleMod, quantize, isInteger };
13 |
--------------------------------------------------------------------------------
/typings/util/RoteryDrag.d.ts:
--------------------------------------------------------------------------------
1 | export default class RoteryDrag {
2 | minDistance: number;
3 | initialAngle: number;
4 | private baseRotation;
5 | private lastAngle;
6 | private prev;
7 | private current;
8 | private center;
9 | start(initialAngle: number, center: number[], position: number[]): void;
10 | getAngle(position: number[]): number;
11 | readonly radius: number;
12 | }
13 |
--------------------------------------------------------------------------------
/typings/util/Timecode.d.ts:
--------------------------------------------------------------------------------
1 | export default class Timecode {
2 | static formatSimple(frameCount: number, frameRate: number): string;
3 | frameRate: number;
4 | readonly dropFrame: boolean;
5 | frameCount: number;
6 | frames: number;
7 | readonly framesText: string;
8 | seconds: number;
9 | readonly secondsText: string;
10 | minutes: number;
11 | readonly minutesText: string;
12 | hours: number;
13 | readonly hoursText: string;
14 | smpte: string;
15 | private _frameRate;
16 | private _dropFrame;
17 | private _frameCount;
18 | private _hours;
19 | private _minutes;
20 | private _seconds;
21 | private _frames;
22 | private _hoursText;
23 | private _minutesText;
24 | private _secondsText;
25 | private _framesText;
26 | constructor(frameCount?: number, frameRate?: number);
27 | private validateFrameRate;
28 | private updateSMTPE;
29 | }
30 |
--------------------------------------------------------------------------------
/typings/util/index.d.ts:
--------------------------------------------------------------------------------
1 | import RoteryDrag from './RoteryDrag';
2 | import keypressed from './keypressed';
3 | import { DataColor, DataColorMode, DataColorElements } from '../data';
4 | declare function getDOMCenter(el: HTMLElement): number[];
5 | declare function setButtonUnfocusableForMouse(button: HTMLElement): void;
6 | declare function toCSSColor(color: DataColor): string;
7 | declare function convertColorElements(from: DataColorMode, to: DataColorMode, elements: DataColorElements): DataColorElements;
8 | export { getDOMCenter, setButtonUnfocusableForMouse, toCSSColor, convertColorElements, RoteryDrag, keypressed };
9 |
--------------------------------------------------------------------------------
/typings/util/keypressed.d.ts:
--------------------------------------------------------------------------------
1 | declare function keypressed(key: string): boolean;
2 | export default keypressed;
3 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | // resolve: { alias: { mobx: __dirname + "/node_modules/mobx/lib/mobx.es6.js" }}
2 |
3 | module.exports = {
4 | css: {
5 | loaderOptions: {
6 | stylus: {
7 | use: [require('autoprefixer-stylus')(), require('nib')()]
8 | }
9 | }
10 | },
11 | configureWebpack: config => {
12 | if (process.env.NODE_ENV === 'production') {
13 | config.module.rules.forEach(rule => {
14 | if (rule.use) {
15 | let idx = rule.use.findIndex(w => w.loader === 'thread-loader')
16 | if (idx !== -1) rule.use.splice(idx, 1)
17 | }
18 | })
19 | }
20 | },
21 | chainWebpack: config => {
22 | config.resolve.extensions.prepend('.vue')
23 |
24 | config.module
25 | .rule('raw')
26 | .test(/\.(vert|frag|glsl)$/)
27 | .use('raw-loader')
28 | .loader('raw-loader')
29 |
30 | if (process.env.NODE_ENV === 'production') {
31 | // disable cache (not sure if this is actually useful...)
32 | config.module.rule('ts').uses.delete('cache-loader')
33 |
34 | config.module
35 | .rule('ts')
36 | .use('ts-loader')
37 | .loader('ts-loader')
38 | .tap(opts => {
39 | opts.transpileOnly = false
40 | opts.happyPackMode = false
41 | return opts
42 | })
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------