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.
Files changed (95) hide show
  1. package/.github/workflows/nodejs.yml +3 -1
  2. package/CHANGELOG.md +9 -1
  3. package/CODE_OF_CONDUCT.md +5 -5
  4. package/CONTRIBUTING.md +22 -72
  5. package/README.md +1 -1
  6. package/dist/effect/base.d.ts +14 -1
  7. package/dist/etro-cjs.js +156 -213
  8. package/dist/etro-iife.js +156 -213
  9. package/dist/layer/base.d.ts +13 -0
  10. package/eslint.conf.js +2 -1
  11. package/eslint.test-conf.js +1 -0
  12. package/examples/application/readme-screenshot.html +4 -8
  13. package/examples/application/video-player.html +3 -4
  14. package/examples/introduction/effects.html +23 -4
  15. package/karma.conf.js +4 -2
  16. package/package.json +4 -1
  17. package/scripts/gen-effect-samples.html +0 -3
  18. package/src/effect/base.ts +29 -10
  19. package/src/effect/gaussian-blur.ts +10 -10
  20. package/src/effect/pixelate.ts +1 -2
  21. package/src/effect/shader.ts +18 -22
  22. package/src/effect/stack.ts +5 -2
  23. package/src/effect/transform.ts +13 -14
  24. package/src/event.ts +8 -14
  25. package/src/layer/audio-source.ts +16 -14
  26. package/src/layer/audio.ts +1 -2
  27. package/src/layer/base.ts +26 -7
  28. package/src/layer/visual.ts +5 -6
  29. package/src/movie.ts +41 -49
  30. package/src/util.ts +50 -57
  31. package/docs/effect.js.html +0 -1215
  32. package/docs/event.js.html +0 -145
  33. package/docs/index.html +0 -81
  34. package/docs/index.js.html +0 -92
  35. package/docs/layer.js.html +0 -888
  36. package/docs/module-effect-GaussianBlurComponent.html +0 -345
  37. package/docs/module-effect.Brightness.html +0 -339
  38. package/docs/module-effect.Channels.html +0 -319
  39. package/docs/module-effect.ChromaKey.html +0 -611
  40. package/docs/module-effect.Contrast.html +0 -339
  41. package/docs/module-effect.EllipticalMask.html +0 -200
  42. package/docs/module-effect.GaussianBlur.html +0 -202
  43. package/docs/module-effect.GaussianBlurHorizontal.html +0 -242
  44. package/docs/module-effect.GaussianBlurVertical.html +0 -242
  45. package/docs/module-effect.Pixelate.html +0 -330
  46. package/docs/module-effect.Shader.html +0 -1227
  47. package/docs/module-effect.Stack.html +0 -406
  48. package/docs/module-effect.Transform.Matrix.html +0 -193
  49. package/docs/module-effect.Transform.html +0 -1174
  50. package/docs/module-effect.html +0 -148
  51. package/docs/module-event.html +0 -473
  52. package/docs/module-index.html +0 -186
  53. package/docs/module-layer-Media.html +0 -1116
  54. package/docs/module-layer-MediaMixin.html +0 -164
  55. package/docs/module-layer.Audio.html +0 -1188
  56. package/docs/module-layer.Base.html +0 -629
  57. package/docs/module-layer.Image.html +0 -1421
  58. package/docs/module-layer.Text.html +0 -1731
  59. package/docs/module-layer.Video.html +0 -1938
  60. package/docs/module-layer.Visual.html +0 -1698
  61. package/docs/module-layer.html +0 -137
  62. package/docs/module-movie.html +0 -3118
  63. package/docs/module-util.Color.html +0 -702
  64. package/docs/module-util.Font.html +0 -395
  65. package/docs/module-util.html +0 -845
  66. package/docs/movie.js.html +0 -689
  67. package/docs/scripts/collapse.js +0 -20
  68. package/docs/scripts/linenumber.js +0 -25
  69. package/docs/scripts/nav.js +0 -12
  70. package/docs/scripts/polyfill.js +0 -4
  71. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
  72. package/docs/scripts/prettify/lang-css.js +0 -2
  73. package/docs/scripts/prettify/prettify.js +0 -28
  74. package/docs/scripts/search.js +0 -83
  75. package/docs/styles/jsdoc.css +0 -671
  76. package/docs/styles/prettify.css +0 -79
  77. package/docs/util.js.html +0 -503
  78. package/spec/assets/effect/gaussian-blur-horizontal.png +0 -0
  79. package/spec/assets/effect/gaussian-blur-vertical.png +0 -0
  80. package/spec/assets/effect/grayscale.png +0 -0
  81. package/spec/assets/effect/original.png +0 -0
  82. package/spec/assets/effect/pixelate.png +0 -0
  83. package/spec/assets/effect/transform/multiply.png +0 -0
  84. package/spec/assets/effect/transform/rotate.png +0 -0
  85. package/spec/assets/effect/transform/scale-fraction.png +0 -0
  86. package/spec/assets/effect/transform/scale.png +0 -0
  87. package/spec/assets/effect/transform/translate-fraction.png +0 -0
  88. package/spec/assets/effect/transform/translate.png +0 -0
  89. package/spec/assets/layer/audio.wav +0 -0
  90. package/spec/assets/layer/image.jpg +0 -0
  91. package/spec/effect.spec.js +0 -421
  92. package/spec/event.spec.js +0 -39
  93. package/spec/layer.spec.js +0 -307
  94. package/spec/movie.spec.js +0 -346
  95. package/spec/util.spec.js +0 -294
@@ -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
@@ -15,6 +15,7 @@ module.exports = {
15
15
  sourceType: 'module'
16
16
  },
17
17
  rules: {
18
- 'brace-style': ['error', '1tbs', { allowSingleLine: false }]
18
+ 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
19
+ curly: ['error', 'multi', 'consistent']
19
20
  },
20
21
  }
@@ -1,4 +1,5 @@
1
1
  const conf = require('./eslint.conf.js')
2
2
  conf.env.jasmine = true
3
+ conf.globals.define = 'readonly'
3
4
  conf.globals.etro = 'readonly'
4
5
  module.exports = conf
@@ -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
- } // spacebar
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({ 0: { r: 2, g: 0.5 }, 2: { r: 0.5, g: 2 } })
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(new etro.effect.Transform.Matrix().rotate(Math.PI / 6)) // 30d
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(image.width / 2, image.height / 2, image.width / 2, image.height / 2)
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.0",
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
  }),
@@ -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
- attach (target: Movie | Visual): void {
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
- detach (): void {
50
- if (this._target === null) {
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._target = null
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
@@ -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
  }
@@ -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
  }
@@ -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 {
@@ -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++) {