etro 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/nodejs.yml +3 -1
- package/CHANGELOG.md +9 -1
- package/CODE_OF_CONDUCT.md +5 -5
- package/CONTRIBUTING.md +22 -72
- package/README.md +1 -1
- package/dist/effect/base.d.ts +14 -1
- package/dist/etro-cjs.js +156 -213
- package/dist/etro-iife.js +156 -213
- package/dist/layer/base.d.ts +13 -0
- package/eslint.conf.js +2 -1
- package/eslint.test-conf.js +1 -0
- package/examples/application/readme-screenshot.html +4 -8
- package/examples/application/video-player.html +3 -4
- package/examples/introduction/effects.html +23 -4
- package/karma.conf.js +4 -2
- package/package.json +4 -1
- package/scripts/gen-effect-samples.html +0 -3
- package/src/effect/base.ts +29 -10
- package/src/effect/gaussian-blur.ts +10 -10
- package/src/effect/pixelate.ts +1 -2
- package/src/effect/shader.ts +18 -22
- package/src/effect/stack.ts +5 -2
- package/src/effect/transform.ts +13 -14
- package/src/event.ts +8 -14
- package/src/layer/audio-source.ts +16 -14
- package/src/layer/audio.ts +1 -2
- package/src/layer/base.ts +26 -7
- package/src/layer/visual.ts +5 -6
- package/src/movie.ts +41 -49
- package/src/util.ts +50 -57
- package/docs/effect.js.html +0 -1215
- package/docs/event.js.html +0 -145
- package/docs/index.html +0 -81
- package/docs/index.js.html +0 -92
- package/docs/layer.js.html +0 -888
- package/docs/module-effect-GaussianBlurComponent.html +0 -345
- package/docs/module-effect.Brightness.html +0 -339
- package/docs/module-effect.Channels.html +0 -319
- package/docs/module-effect.ChromaKey.html +0 -611
- package/docs/module-effect.Contrast.html +0 -339
- package/docs/module-effect.EllipticalMask.html +0 -200
- package/docs/module-effect.GaussianBlur.html +0 -202
- package/docs/module-effect.GaussianBlurHorizontal.html +0 -242
- package/docs/module-effect.GaussianBlurVertical.html +0 -242
- package/docs/module-effect.Pixelate.html +0 -330
- package/docs/module-effect.Shader.html +0 -1227
- package/docs/module-effect.Stack.html +0 -406
- package/docs/module-effect.Transform.Matrix.html +0 -193
- package/docs/module-effect.Transform.html +0 -1174
- package/docs/module-effect.html +0 -148
- package/docs/module-event.html +0 -473
- package/docs/module-index.html +0 -186
- package/docs/module-layer-Media.html +0 -1116
- package/docs/module-layer-MediaMixin.html +0 -164
- package/docs/module-layer.Audio.html +0 -1188
- package/docs/module-layer.Base.html +0 -629
- package/docs/module-layer.Image.html +0 -1421
- package/docs/module-layer.Text.html +0 -1731
- package/docs/module-layer.Video.html +0 -1938
- package/docs/module-layer.Visual.html +0 -1698
- package/docs/module-layer.html +0 -137
- package/docs/module-movie.html +0 -3118
- package/docs/module-util.Color.html +0 -702
- package/docs/module-util.Font.html +0 -395
- package/docs/module-util.html +0 -845
- package/docs/movie.js.html +0 -689
- package/docs/scripts/collapse.js +0 -20
- package/docs/scripts/linenumber.js +0 -25
- package/docs/scripts/nav.js +0 -12
- package/docs/scripts/polyfill.js +0 -4
- package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/docs/scripts/prettify/lang-css.js +0 -2
- package/docs/scripts/prettify/prettify.js +0 -28
- package/docs/scripts/search.js +0 -83
- package/docs/styles/jsdoc.css +0 -671
- package/docs/styles/prettify.css +0 -79
- package/docs/util.js.html +0 -503
- package/spec/assets/effect/gaussian-blur-horizontal.png +0 -0
- package/spec/assets/effect/gaussian-blur-vertical.png +0 -0
- package/spec/assets/effect/grayscale.png +0 -0
- package/spec/assets/effect/original.png +0 -0
- package/spec/assets/effect/pixelate.png +0 -0
- package/spec/assets/effect/transform/multiply.png +0 -0
- package/spec/assets/effect/transform/rotate.png +0 -0
- package/spec/assets/effect/transform/scale-fraction.png +0 -0
- package/spec/assets/effect/transform/scale.png +0 -0
- package/spec/assets/effect/transform/translate-fraction.png +0 -0
- package/spec/assets/effect/transform/translate.png +0 -0
- package/spec/assets/layer/audio.wav +0 -0
- package/spec/assets/layer/image.jpg +0 -0
- package/spec/effect.spec.js +0 -421
- package/spec/event.spec.js +0 -39
- package/spec/layer.spec.js +0 -307
- package/spec/movie.spec.js +0 -346
- package/spec/util.spec.js +0 -294
package/dist/layer/base.d.ts
CHANGED
|
@@ -36,7 +36,20 @@ declare class Base implements EtroObject {
|
|
|
36
36
|
* movie's timeline
|
|
37
37
|
*/
|
|
38
38
|
constructor(options: BaseOptions);
|
|
39
|
+
/**
|
|
40
|
+
* Attaches this layer to `movie` if not already attached.
|
|
41
|
+
* @ignore
|
|
42
|
+
*/
|
|
43
|
+
tryAttach(movie: Movie): void;
|
|
39
44
|
attach(movie: Movie): void;
|
|
45
|
+
/**
|
|
46
|
+
* Dettaches this layer from its movie if the number of times `tryDetach` has
|
|
47
|
+
* been called (including this call) equals the number of times `tryAttach`
|
|
48
|
+
* has been called.
|
|
49
|
+
*
|
|
50
|
+
* @ignore
|
|
51
|
+
*/
|
|
52
|
+
tryDetach(): void;
|
|
40
53
|
detach(): void;
|
|
41
54
|
/**
|
|
42
55
|
* Called when the layer is activated
|
package/eslint.conf.js
CHANGED
package/eslint.test-conf.js
CHANGED
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
document.body.appendChild(canvas)
|
|
16
16
|
movie = new etro.Movie({ canvas })
|
|
17
17
|
etro.event.subscribe(movie, 'movie.timeupdate', () => {
|
|
18
|
-
if (movie.currentTime >= 11)
|
|
18
|
+
if (movie.currentTime >= 11)
|
|
19
19
|
movie.pause()
|
|
20
|
-
}
|
|
21
20
|
})
|
|
22
21
|
|
|
23
22
|
sample = document.createElement('video')
|
|
@@ -32,15 +31,14 @@
|
|
|
32
31
|
const width = movie.width / cols; const height = movie.height / rows
|
|
33
32
|
let numbLoaded = 0
|
|
34
33
|
|
|
35
|
-
for (let y = 0; y < movie.height; y += height)
|
|
34
|
+
for (let y = 0; y < movie.height; y += height)
|
|
36
35
|
for (let x = 0; x < movie.width; x += width) {
|
|
37
36
|
const video = document.createElement('video')
|
|
38
37
|
video.src = '../assets/desert.mp4'
|
|
39
|
-
if (x * y)
|
|
38
|
+
if (x * y)
|
|
40
39
|
video.onplay = event => {
|
|
41
40
|
console.log(event)
|
|
42
41
|
}
|
|
43
|
-
}
|
|
44
42
|
|
|
45
43
|
video.onloadedmetadata = () => {
|
|
46
44
|
const layer = new etro.layer.Video({
|
|
@@ -54,12 +52,10 @@
|
|
|
54
52
|
movie.addLayer(layer)
|
|
55
53
|
numbLoaded++
|
|
56
54
|
|
|
57
|
-
if (numbLoaded === rows * cols)
|
|
55
|
+
if (numbLoaded === rows * cols)
|
|
58
56
|
end()
|
|
59
|
-
}
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
|
-
}
|
|
63
59
|
}
|
|
64
60
|
|
|
65
61
|
const end = () => {
|
|
@@ -83,14 +83,13 @@
|
|
|
83
83
|
canvas.addEventListener('click', controls.playPause.click) // FIXME: isn"t firing
|
|
84
84
|
document.body.addEventListener('keyup', event => {
|
|
85
85
|
const key = event.which || event.keyCode || 0
|
|
86
|
-
if (key === 32)
|
|
86
|
+
if (key === 32)
|
|
87
87
|
controls.playPause.click()
|
|
88
|
-
|
|
88
|
+
// spacebar
|
|
89
89
|
})
|
|
90
90
|
etro.event.subscribe(movie, 'movie.ended', event => {
|
|
91
|
-
if (!event.repeat)
|
|
91
|
+
if (!event.repeat)
|
|
92
92
|
controls.playPause.className = 'play'
|
|
93
|
-
}
|
|
94
93
|
})
|
|
95
94
|
|
|
96
95
|
controls.progressBar.min = 0
|
|
@@ -26,13 +26,18 @@
|
|
|
26
26
|
// create a transparent blue 500x200 at (50, 20) that starts at time 1 and lasts 2 seconds
|
|
27
27
|
.addLayer(
|
|
28
28
|
new etro.layer.Image({ startTime: 2, duration: 2, source: image }).addEffect(
|
|
29
|
-
new etro.effect.GaussianBlur(3)
|
|
29
|
+
new etro.effect.GaussianBlur({ radius: 3 })
|
|
30
30
|
)
|
|
31
31
|
)
|
|
32
32
|
.addLayer(
|
|
33
33
|
new etro.layer.Image({ startTime: 4, duration: 2, source: image }).addEffect(
|
|
34
34
|
// you can also use keyframes for almost any property in Etro
|
|
35
|
-
new etro.effect.Channels({
|
|
35
|
+
new etro.effect.Channels({
|
|
36
|
+
factors: new etro.KeyFrame(
|
|
37
|
+
[0, { r: 2, g: 0.5 }],
|
|
38
|
+
[2, { r: 0.5, g: 2 }]
|
|
39
|
+
)
|
|
40
|
+
})
|
|
36
41
|
)
|
|
37
42
|
)
|
|
38
43
|
.addLayer(
|
|
@@ -44,14 +49,28 @@
|
|
|
44
49
|
width: movie.width,
|
|
45
50
|
height: movie.height
|
|
46
51
|
}).addEffect(
|
|
47
|
-
new etro.effect.Transform(
|
|
52
|
+
new etro.effect.Transform({
|
|
53
|
+
matrix: new etro.effect.Transform.Matrix().rotate(Math.PI / 6) // 30d
|
|
54
|
+
})
|
|
48
55
|
)
|
|
49
56
|
)
|
|
50
57
|
.addLayer(
|
|
51
58
|
new etro.layer.Image({ startTime: 8, duration: 2, source: image }).addEffect(
|
|
52
|
-
new etro.effect.EllipticalMask(
|
|
59
|
+
new etro.effect.EllipticalMask({
|
|
60
|
+
x: image.width / 2,
|
|
61
|
+
y: image.height / 2,
|
|
62
|
+
radiusX: image.width / 2,
|
|
63
|
+
radiusY: image.height / 2
|
|
64
|
+
})
|
|
53
65
|
)
|
|
54
66
|
)
|
|
67
|
+
// .addEffect(new etro.effect.GaussianBlur({ radius: 5 }))
|
|
68
|
+
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
// console.log(movie.layers[1].effects[0].effects[1].shape)
|
|
71
|
+
}, 3100)
|
|
72
|
+
|
|
73
|
+
movie
|
|
55
74
|
.play()
|
|
56
75
|
}
|
|
57
76
|
</script>
|
package/karma.conf.js
CHANGED
|
@@ -9,12 +9,14 @@ module.exports = function (config) {
|
|
|
9
9
|
|
|
10
10
|
// frameworks to use
|
|
11
11
|
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
|
12
|
-
frameworks: ['jasmine'],
|
|
12
|
+
frameworks: ['jasmine', 'requirejs', 'es6-shim'],
|
|
13
13
|
|
|
14
14
|
// list of files / patterns to load in the browser
|
|
15
15
|
files: [
|
|
16
16
|
'dist/etro-iife.js',
|
|
17
|
-
'spec/*.spec.js',
|
|
17
|
+
{ pattern: 'spec/*.spec.js', included: false },
|
|
18
|
+
{ pattern: 'node_modules/resemblejs/*.js', included: false },
|
|
19
|
+
'spec/main.js',
|
|
18
20
|
{ pattern: 'spec/assets/**/*', included: false }
|
|
19
21
|
],
|
|
20
22
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "etro",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "An extendable video-editing framework for the browser and Node",
|
|
5
5
|
"browser": "dist/etro-cjs.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -32,9 +32,12 @@
|
|
|
32
32
|
"jsdoc-export-default-interop": "^0.3.1",
|
|
33
33
|
"karma": "^6.1.1",
|
|
34
34
|
"karma-chrome-launcher": "^3.1.0",
|
|
35
|
+
"karma-es6-shim": "^1.0.0",
|
|
35
36
|
"karma-jasmine": "^2.0.1",
|
|
37
|
+
"karma-requirejs": "^1.1.0",
|
|
36
38
|
"karma-super-dots-reporter": "^0.2.0",
|
|
37
39
|
"puppeteer": "^2.0.0",
|
|
40
|
+
"resemblejs": "^3.2.5",
|
|
38
41
|
"rollup": "^1.19.4",
|
|
39
42
|
"rollup-plugin-cleaner": "^1.0.0",
|
|
40
43
|
"rollup-plugin-eslint": "^7.0.0",
|
|
@@ -74,9 +74,6 @@
|
|
|
74
74
|
'transform/translate.png': new etro.effect.Transform({
|
|
75
75
|
matrix: new etro.effect.Transform.Matrix().translate(-3, 5)
|
|
76
76
|
}),
|
|
77
|
-
'transform/translate-fraction.png': new etro.effect.Transform({
|
|
78
|
-
matrix: new etro.effect.Transform.Matrix().translate(0.5, 0.5)
|
|
79
|
-
}),
|
|
80
77
|
'transform/scale.png': new etro.effect.Transform({
|
|
81
78
|
matrix: new etro.effect.Transform.Matrix().scale(2, 2)
|
|
82
79
|
}),
|
package/src/effect/base.ts
CHANGED
|
@@ -31,9 +31,9 @@ export class Base implements BaseObject {
|
|
|
31
31
|
|
|
32
32
|
// Propogate up to target
|
|
33
33
|
subscribe(newThis, 'effect.change.modify', event => {
|
|
34
|
-
if (!newThis._target)
|
|
34
|
+
if (!newThis._target)
|
|
35
35
|
return
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
const type = `${newThis._target.type}.change.effect.modify`
|
|
38
38
|
publish(newThis._target, type, { ...event, target: newThis._target, source: newThis, type })
|
|
39
39
|
})
|
|
@@ -41,22 +41,41 @@ export class Base implements BaseObject {
|
|
|
41
41
|
return newThis
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Attaches this effect to `target` if not already attached.
|
|
46
|
+
* @ignore
|
|
47
|
+
*/
|
|
48
|
+
tryAttach (target: Movie | Visual): void {
|
|
49
|
+
if (this._occurrenceCount === 0)
|
|
50
|
+
this.attach(target)
|
|
51
|
+
|
|
45
52
|
this._occurrenceCount++
|
|
46
|
-
this._target = target
|
|
47
53
|
}
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
attach (movie: Movie | Visual): void {
|
|
56
|
+
this._target = movie
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Dettaches this effect from its target if the number of times `tryDetach`
|
|
61
|
+
* has been called (including this call) equals the number of times
|
|
62
|
+
* `tryAttach` has been called.
|
|
63
|
+
*
|
|
64
|
+
* @ignore
|
|
65
|
+
*/
|
|
66
|
+
tryDetach (): void {
|
|
67
|
+
if (this._target === null)
|
|
51
68
|
throw new Error('No movie to detach from')
|
|
52
|
-
}
|
|
53
69
|
|
|
54
70
|
this._occurrenceCount--
|
|
55
71
|
// If this effect occurs in another place in the containing array, do not
|
|
56
72
|
// unset _target. (For calling `unshift` on the `layers` proxy)
|
|
57
|
-
if (this._occurrenceCount === 0)
|
|
58
|
-
this.
|
|
59
|
-
|
|
73
|
+
if (this._occurrenceCount === 0)
|
|
74
|
+
this.detach()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
detach (): void {
|
|
78
|
+
this._target = null
|
|
60
79
|
}
|
|
61
80
|
|
|
62
81
|
// subclasses must implement apply
|
|
@@ -63,12 +63,12 @@ class GaussianBlurComponent extends Shader {
|
|
|
63
63
|
|
|
64
64
|
apply (target: Movie | Visual, reltime: number): void {
|
|
65
65
|
const radiusVal = val(this, 'radius', reltime)
|
|
66
|
-
if (radiusVal !== this._radiusCache)
|
|
66
|
+
if (radiusVal !== this._radiusCache)
|
|
67
67
|
// Regenerate gaussian distribution canvas.
|
|
68
68
|
this.shape = GaussianBlurComponent._render1DKernel(
|
|
69
69
|
GaussianBlurComponent._gen1DKernel(radiusVal)
|
|
70
70
|
)
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
this._radiusCache = radiusVal
|
|
73
73
|
|
|
74
74
|
super.apply(target, reltime)
|
|
@@ -106,28 +106,28 @@ class GaussianBlurComponent extends Shader {
|
|
|
106
106
|
const pascal = GaussianBlurComponent._genPascalRow(2 * radius + 1)
|
|
107
107
|
// don't use `reduce` and `map` (overhead?)
|
|
108
108
|
let sum = 0
|
|
109
|
-
for (let i = 0; i < pascal.length; i++)
|
|
109
|
+
for (let i = 0; i < pascal.length; i++)
|
|
110
110
|
sum += pascal[i]
|
|
111
|
-
|
|
112
|
-
for (let i = 0; i < pascal.length; i++)
|
|
111
|
+
|
|
112
|
+
for (let i = 0; i < pascal.length; i++)
|
|
113
113
|
pascal[i] /= sum
|
|
114
|
-
|
|
114
|
+
|
|
115
115
|
return pascal
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
private static _genPascalRow (index: number): number[] {
|
|
119
|
-
if (index < 0)
|
|
119
|
+
if (index < 0)
|
|
120
120
|
throw new Error(`Invalid index ${index}`)
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
let currRow = [1]
|
|
123
123
|
for (let i = 1; i < index; i++) {
|
|
124
124
|
const nextRow = []
|
|
125
125
|
nextRow.length = currRow.length + 1
|
|
126
126
|
// edges are always 1's
|
|
127
127
|
nextRow[0] = nextRow[nextRow.length - 1] = 1
|
|
128
|
-
for (let j = 1; j < nextRow.length - 1; j++)
|
|
128
|
+
for (let j = 1; j < nextRow.length - 1; j++)
|
|
129
129
|
nextRow[j] = currRow[j - 1] + currRow[j]
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
currRow = nextRow
|
|
132
132
|
}
|
|
133
133
|
return currRow
|
package/src/effect/pixelate.ts
CHANGED
|
@@ -50,9 +50,8 @@ export class Pixelate extends Shader {
|
|
|
50
50
|
|
|
51
51
|
apply (target: Movie | Visual, reltime: number): void {
|
|
52
52
|
const ps = val(this, 'pixelSize', reltime)
|
|
53
|
-
if (ps % 1 !== 0 || ps < 0)
|
|
53
|
+
if (ps % 1 !== 0 || ps < 0)
|
|
54
54
|
throw new Error('Pixel size must be a nonnegative integer')
|
|
55
|
-
}
|
|
56
55
|
|
|
57
56
|
super.apply(target, reltime)
|
|
58
57
|
}
|
package/src/effect/shader.ts
CHANGED
|
@@ -117,9 +117,9 @@ export class Shader extends Base {
|
|
|
117
117
|
private _initGl () {
|
|
118
118
|
this._canvas = document.createElement('canvas')
|
|
119
119
|
const gl = this._canvas.getContext('webgl')
|
|
120
|
-
if (gl === null)
|
|
120
|
+
if (gl === null)
|
|
121
121
|
throw new Error('Unable to initialize WebGL. Your browser or machine may not support it.')
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
this._gl = gl
|
|
124
124
|
return gl
|
|
125
125
|
}
|
|
@@ -127,9 +127,9 @@ export class Shader extends Base {
|
|
|
127
127
|
private _initTextures (userUniforms, userTextures, sourceTextureOptions) {
|
|
128
128
|
const gl = this._gl
|
|
129
129
|
const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS)
|
|
130
|
-
if (userTextures.length > maxTextures)
|
|
130
|
+
if (userTextures.length > maxTextures)
|
|
131
131
|
console.warn('Too many textures!')
|
|
132
|
-
|
|
132
|
+
|
|
133
133
|
this._userTextures = {}
|
|
134
134
|
for (const name in userTextures) {
|
|
135
135
|
const userOptions: TextureOptions = userTextures[name]
|
|
@@ -143,9 +143,9 @@ export class Shader extends Base {
|
|
|
143
143
|
* textures, without having to define multiple properties in the effect
|
|
144
144
|
* object.
|
|
145
145
|
*/
|
|
146
|
-
if (userUniforms[name])
|
|
146
|
+
if (userUniforms[name])
|
|
147
147
|
throw new Error(`Texture - uniform naming conflict: ${name}!`)
|
|
148
|
-
|
|
148
|
+
|
|
149
149
|
// Add this as a "user uniform".
|
|
150
150
|
userUniforms[name] = '1i' // texture pointer
|
|
151
151
|
}
|
|
@@ -309,14 +309,12 @@ export class Shader extends Base {
|
|
|
309
309
|
|
|
310
310
|
// Tell the shader we bound the texture to texture unit 0.
|
|
311
311
|
// All base (Shader class) uniforms are optional.
|
|
312
|
-
if (this._uniformLocations.source)
|
|
312
|
+
if (this._uniformLocations.source)
|
|
313
313
|
gl.uniform1i(this._uniformLocations.source, 0)
|
|
314
|
-
}
|
|
315
314
|
|
|
316
315
|
// All base (Shader class) uniforms are optional.
|
|
317
|
-
if (this._uniformLocations.size)
|
|
316
|
+
if (this._uniformLocations.size)
|
|
318
317
|
gl.uniform2iv(this._uniformLocations.size, [target.canvas.width, target.canvas.height])
|
|
319
|
-
}
|
|
320
318
|
|
|
321
319
|
for (const unprefixed in this._userUniforms) {
|
|
322
320
|
const options = this._userUniforms[unprefixed] as UniformOptions
|
|
@@ -371,43 +369,41 @@ export class Shader extends Base {
|
|
|
371
369
|
let i = 0
|
|
372
370
|
for (const name in this._userTextures) {
|
|
373
371
|
const testValue = val(this, name, reltime)
|
|
374
|
-
if (value === testValue)
|
|
372
|
+
if (value === testValue)
|
|
375
373
|
value = Shader.INTERNAL_TEXTURE_UNITS + i // after the internal texture units
|
|
376
|
-
|
|
374
|
+
|
|
377
375
|
i++
|
|
378
376
|
}
|
|
379
377
|
}
|
|
380
378
|
|
|
381
379
|
if (outputType === '3fv') {
|
|
382
380
|
// allow 4-component vectors; TODO: why?
|
|
383
|
-
if (Array.isArray(value) && (value.length === 3 || value.length === 4))
|
|
381
|
+
if (Array.isArray(value) && (value.length === 3 || value.length === 4))
|
|
384
382
|
return value
|
|
385
|
-
|
|
383
|
+
|
|
386
384
|
// kind of loose so this can be changed if needed
|
|
387
|
-
if (typeof value === 'object')
|
|
385
|
+
if (typeof value === 'object')
|
|
388
386
|
return [
|
|
389
387
|
value.r !== undefined ? value.r : def,
|
|
390
388
|
value.g !== undefined ? value.g : def,
|
|
391
389
|
value.b !== undefined ? value.b : def
|
|
392
390
|
]
|
|
393
|
-
}
|
|
394
391
|
|
|
395
392
|
throw new Error(`Invalid type: ${outputType} or value: ${value}`)
|
|
396
393
|
}
|
|
397
394
|
|
|
398
395
|
if (outputType === '4fv') {
|
|
399
|
-
if (Array.isArray(value) && value.length === 4)
|
|
396
|
+
if (Array.isArray(value) && value.length === 4)
|
|
400
397
|
return value
|
|
401
|
-
|
|
398
|
+
|
|
402
399
|
// kind of loose so this can be changed if needed
|
|
403
|
-
if (typeof value === 'object')
|
|
400
|
+
if (typeof value === 'object')
|
|
404
401
|
return [
|
|
405
402
|
value.r !== undefined ? value.r : def,
|
|
406
403
|
value.g !== undefined ? value.g : def,
|
|
407
404
|
value.b !== undefined ? value.b : def,
|
|
408
405
|
value.a !== undefined ? value.a : def
|
|
409
406
|
]
|
|
410
|
-
}
|
|
411
407
|
|
|
412
408
|
throw new Error(`Invalid type: ${outputType} or value: ${value}`)
|
|
413
409
|
}
|
|
@@ -513,9 +509,9 @@ export class Shader extends Base {
|
|
|
513
509
|
} else {
|
|
514
510
|
// No, it's not a power of 2. Turn off mips and set
|
|
515
511
|
// wrapping to clamp to edge
|
|
516
|
-
if (wrapS !== gl.CLAMP_TO_EDGE || wrapT !== gl.CLAMP_TO_EDGE)
|
|
512
|
+
if (wrapS !== gl.CLAMP_TO_EDGE || wrapT !== gl.CLAMP_TO_EDGE)
|
|
517
513
|
console.warn('Wrap mode is not CLAMP_TO_EDGE for a non-power-of-two texture. Defaulting to CLAMP_TO_EDGE')
|
|
518
|
-
|
|
514
|
+
|
|
519
515
|
gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
|
520
516
|
gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
|
|
521
517
|
}
|
package/src/effect/stack.ts
CHANGED
|
@@ -19,6 +19,7 @@ export class Stack extends Base {
|
|
|
19
19
|
super()
|
|
20
20
|
|
|
21
21
|
this._effectsBack = []
|
|
22
|
+
// TODO: Throw 'change' events in handlers
|
|
22
23
|
this.effects = new Proxy(this._effectsBack, {
|
|
23
24
|
deleteProperty: function (target: Base[], property: number | string): boolean {
|
|
24
25
|
const value = target[property]
|
|
@@ -29,9 +30,9 @@ export class Stack extends Base {
|
|
|
29
30
|
set: function (target: Base[], property: number | string, value: Base): boolean {
|
|
30
31
|
// TODO: make sure type check works
|
|
31
32
|
if (!isNaN(Number(property))) { // if property is a number (index)
|
|
32
|
-
if (target[property])
|
|
33
|
+
if (target[property])
|
|
33
34
|
target[property].detach() // Detach old effect from movie
|
|
34
|
-
|
|
35
|
+
|
|
35
36
|
value.attach(this._target) // Attach effect to movie
|
|
36
37
|
}
|
|
37
38
|
target[property] = value
|
|
@@ -39,6 +40,8 @@ export class Stack extends Base {
|
|
|
39
40
|
}
|
|
40
41
|
})
|
|
41
42
|
options.effects.forEach(effect => this.effects.push(effect))
|
|
43
|
+
|
|
44
|
+
// TODO: Propogate 'change' events from children up
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
attach (movie: Movie): void {
|
package/src/effect/transform.ts
CHANGED
|
@@ -36,12 +36,12 @@ class Transform extends Base {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
apply (target: Movie | Visual, reltime: number): void {
|
|
39
|
-
if (target.canvas.width !== this._tmpCanvas.width)
|
|
39
|
+
if (target.canvas.width !== this._tmpCanvas.width)
|
|
40
40
|
this._tmpCanvas.width = target.canvas.width
|
|
41
|
-
|
|
42
|
-
if (target.canvas.height !== this._tmpCanvas.height)
|
|
41
|
+
|
|
42
|
+
if (target.canvas.height !== this._tmpCanvas.height)
|
|
43
43
|
this._tmpCanvas.height = target.canvas.height
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
// Use data, since that's the underlying storage
|
|
46
46
|
this._tmpMatrix.data = val(this, 'matrix.data', reltime)
|
|
47
47
|
|
|
@@ -81,9 +81,8 @@ namespace Transform { // eslint-disable-line @typescript-eslint/no-namespace
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
identity (): Matrix {
|
|
84
|
-
for (let i = 0; i < this.data.length; i++)
|
|
84
|
+
for (let i = 0; i < this.data.length; i++)
|
|
85
85
|
this.data[i] = Matrix.IDENTITY.data[i]
|
|
86
|
-
}
|
|
87
86
|
|
|
88
87
|
return this
|
|
89
88
|
}
|
|
@@ -94,9 +93,9 @@ namespace Transform { // eslint-disable-line @typescript-eslint/no-namespace
|
|
|
94
93
|
* @param [val]
|
|
95
94
|
*/
|
|
96
95
|
cell (x: number, y: number, val?: number): number {
|
|
97
|
-
if (val !== undefined)
|
|
96
|
+
if (val !== undefined)
|
|
98
97
|
this.data[3 * y + x] = val
|
|
99
|
-
|
|
98
|
+
|
|
100
99
|
return this.data[3 * y + x]
|
|
101
100
|
}
|
|
102
101
|
|
|
@@ -131,19 +130,19 @@ namespace Transform { // eslint-disable-line @typescript-eslint/no-namespace
|
|
|
131
130
|
*/
|
|
132
131
|
multiply (other: Matrix): Matrix {
|
|
133
132
|
// copy to temporary matrix to avoid modifying `this` while reading from it
|
|
134
|
-
for (let x = 0; x < 3; x++)
|
|
133
|
+
for (let x = 0; x < 3; x++)
|
|
135
134
|
for (let y = 0; y < 3; y++) {
|
|
136
135
|
let sum = 0
|
|
137
|
-
for (let i = 0; i < 3; i++)
|
|
136
|
+
for (let i = 0; i < 3; i++)
|
|
138
137
|
sum += this.cell(x, i) * other.cell(i, y)
|
|
139
|
-
|
|
138
|
+
|
|
140
139
|
Matrix._TMP_MATRIX.cell(x, y, sum)
|
|
141
140
|
}
|
|
142
|
-
|
|
141
|
+
|
|
143
142
|
// copy data from TMP_MATRIX to this
|
|
144
|
-
for (let i = 0; i < Matrix._TMP_MATRIX.data.length; i++)
|
|
143
|
+
for (let i = 0; i < Matrix._TMP_MATRIX.data.length; i++)
|
|
145
144
|
this.data[i] = Matrix._TMP_MATRIX.data[i]
|
|
146
|
-
|
|
145
|
+
|
|
147
146
|
return this
|
|
148
147
|
}
|
|
149
148
|
|
package/src/event.ts
CHANGED
|
@@ -21,15 +21,13 @@ class TypeId {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
contains (other) {
|
|
24
|
-
if (other._parts.length > this._parts.length)
|
|
24
|
+
if (other._parts.length > this._parts.length)
|
|
25
25
|
return false
|
|
26
|
-
}
|
|
27
26
|
|
|
28
|
-
for (let i = 0; i < other._parts.length; i++)
|
|
29
|
-
if (other._parts[i] !== this._parts[i])
|
|
27
|
+
for (let i = 0; i < other._parts.length; i++)
|
|
28
|
+
if (other._parts[i] !== this._parts[i])
|
|
30
29
|
return false
|
|
31
|
-
|
|
32
|
-
}
|
|
30
|
+
|
|
33
31
|
return true
|
|
34
32
|
}
|
|
35
33
|
|
|
@@ -47,9 +45,8 @@ class TypeId {
|
|
|
47
45
|
* @param listener
|
|
48
46
|
*/
|
|
49
47
|
export function subscribe (target: EtroObject, type: string, listener: <T extends Event>(T) => void): void {
|
|
50
|
-
if (!listeners.has(target))
|
|
48
|
+
if (!listeners.has(target))
|
|
51
49
|
listeners.set(target, [])
|
|
52
|
-
}
|
|
53
50
|
|
|
54
51
|
listeners.get(target).push(
|
|
55
52
|
{ type: new TypeId(type), listener }
|
|
@@ -67,9 +64,8 @@ export function subscribe (target: EtroObject, type: string, listener: <T extend
|
|
|
67
64
|
export function unsubscribe (target: EtroObject, listener: <T extends Event>(T) => void): void {
|
|
68
65
|
// Make sure `listener` has been added with `subscribe`.
|
|
69
66
|
if (!listeners.has(target) ||
|
|
70
|
-
!listeners.get(target).map(pair => pair.listener).includes(listener))
|
|
67
|
+
!listeners.get(target).map(pair => pair.listener).includes(listener))
|
|
71
68
|
throw new Error('No matching event listener to remove')
|
|
72
|
-
}
|
|
73
69
|
|
|
74
70
|
const removed = listeners.get(target)
|
|
75
71
|
.filter(pair => pair.listener !== listener)
|
|
@@ -90,18 +86,16 @@ export function publish (target: EtroObject, type: string, event: Record<string,
|
|
|
90
86
|
|
|
91
87
|
const t = new TypeId(type)
|
|
92
88
|
|
|
93
|
-
if (!listeners.has(target))
|
|
89
|
+
if (!listeners.has(target))
|
|
94
90
|
// No event fired
|
|
95
91
|
return null
|
|
96
|
-
}
|
|
97
92
|
|
|
98
93
|
// Call event listeners for this event.
|
|
99
94
|
const listenersForType = []
|
|
100
95
|
for (let i = 0; i < listeners.get(target).length; i++) {
|
|
101
96
|
const item = listeners.get(target)[i]
|
|
102
|
-
if (t.contains(item.type))
|
|
97
|
+
if (t.contains(item.type))
|
|
103
98
|
listenersForType.push(item.listener)
|
|
104
|
-
}
|
|
105
99
|
}
|
|
106
100
|
|
|
107
101
|
for (let i = 0; i < listenersForType.length; i++) {
|