etro 0.6.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 (157) hide show
  1. package/.github/workflows/nodejs.yml +4 -2
  2. package/CHANGELOG.md +85 -4
  3. package/CODE_OF_CONDUCT.md +5 -5
  4. package/CONTRIBUTING.md +33 -79
  5. package/README.md +93 -26
  6. package/dist/effect/base.d.ts +51 -0
  7. package/dist/effect/brightness.d.ts +16 -0
  8. package/dist/effect/channels.d.ts +23 -0
  9. package/dist/effect/chroma-key.d.ts +23 -0
  10. package/dist/effect/contrast.d.ts +15 -0
  11. package/dist/effect/elliptical-mask.d.ts +31 -0
  12. package/dist/effect/gaussian-blur.d.ts +60 -0
  13. package/dist/effect/grayscale.d.ts +7 -0
  14. package/dist/effect/index.d.ts +15 -0
  15. package/dist/effect/pixelate.d.ts +18 -0
  16. package/dist/effect/shader.d.ts +99 -0
  17. package/dist/effect/stack.d.ts +23 -0
  18. package/dist/effect/transform.d.ts +73 -0
  19. package/dist/etro-cjs.js +9387 -0
  20. package/dist/etro-iife.js +9390 -0
  21. package/dist/etro.d.ts +7 -0
  22. package/dist/event.d.ts +35 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/layer/audio-source.d.ts +24 -0
  25. package/dist/layer/audio.d.ts +14 -0
  26. package/dist/layer/base.d.ts +82 -0
  27. package/dist/layer/image.d.ts +6 -0
  28. package/dist/layer/index.d.ts +11 -0
  29. package/dist/layer/text.d.ts +60 -0
  30. package/dist/layer/video.d.ts +11 -0
  31. package/dist/layer/visual-source.d.ts +32 -0
  32. package/dist/layer/visual.d.ts +58 -0
  33. package/dist/movie.d.ts +192 -0
  34. package/dist/object.d.ts +12 -0
  35. package/dist/util.d.ts +125 -0
  36. package/eslint.conf.js +2 -9
  37. package/eslint.example-conf.js +9 -0
  38. package/eslint.test-conf.js +1 -0
  39. package/eslint.typescript-conf.js +5 -0
  40. package/examples/application/readme-screenshot.html +16 -17
  41. package/examples/application/video-player.html +10 -11
  42. package/examples/application/webcam.html +6 -6
  43. package/examples/introduction/audio.html +30 -18
  44. package/examples/introduction/effects.html +37 -14
  45. package/examples/introduction/export.html +40 -27
  46. package/examples/introduction/functions.html +6 -4
  47. package/examples/introduction/hello-world1.html +9 -5
  48. package/examples/introduction/hello-world2.html +5 -5
  49. package/examples/introduction/keyframes.html +35 -23
  50. package/examples/introduction/media.html +26 -18
  51. package/examples/introduction/text.html +9 -5
  52. package/karma.conf.js +6 -4
  53. package/package.json +34 -13
  54. package/rollup.config.js +19 -3
  55. package/scripts/gen-effect-samples.html +27 -26
  56. package/scripts/save-effect-samples.js +14 -15
  57. package/src/effect/base.ts +115 -0
  58. package/src/effect/brightness.ts +43 -0
  59. package/src/effect/channels.ts +50 -0
  60. package/src/effect/chroma-key.ts +82 -0
  61. package/src/effect/contrast.ts +42 -0
  62. package/src/effect/elliptical-mask.ts +75 -0
  63. package/src/effect/gaussian-blur.ts +232 -0
  64. package/src/effect/grayscale.ts +34 -0
  65. package/src/effect/index.ts +22 -0
  66. package/src/effect/pixelate.ts +58 -0
  67. package/src/effect/shader.ts +557 -0
  68. package/src/effect/stack.ts +77 -0
  69. package/src/effect/transform.ts +193 -0
  70. package/src/etro.ts +26 -0
  71. package/src/event.ts +112 -0
  72. package/src/index.ts +8 -0
  73. package/src/layer/audio-source.ts +219 -0
  74. package/src/layer/audio.ts +34 -0
  75. package/src/layer/base.ts +175 -0
  76. package/src/layer/image.ts +8 -0
  77. package/src/layer/index.ts +13 -0
  78. package/src/layer/text.ts +138 -0
  79. package/src/layer/video.ts +15 -0
  80. package/src/layer/visual-source.ts +150 -0
  81. package/src/layer/visual.ts +197 -0
  82. package/src/movie.ts +701 -0
  83. package/src/object.ts +14 -0
  84. package/src/util.ts +466 -0
  85. package/tsconfig.json +8 -0
  86. package/dist/etro.js +0 -3397
  87. package/docs/effect.js.html +0 -1215
  88. package/docs/event.js.html +0 -145
  89. package/docs/index.html +0 -81
  90. package/docs/index.js.html +0 -92
  91. package/docs/layer.js.html +0 -888
  92. package/docs/module-effect-GaussianBlurComponent.html +0 -345
  93. package/docs/module-effect.Brightness.html +0 -339
  94. package/docs/module-effect.Channels.html +0 -319
  95. package/docs/module-effect.ChromaKey.html +0 -611
  96. package/docs/module-effect.Contrast.html +0 -339
  97. package/docs/module-effect.EllipticalMask.html +0 -200
  98. package/docs/module-effect.GaussianBlur.html +0 -202
  99. package/docs/module-effect.GaussianBlurHorizontal.html +0 -242
  100. package/docs/module-effect.GaussianBlurVertical.html +0 -242
  101. package/docs/module-effect.Pixelate.html +0 -330
  102. package/docs/module-effect.Shader.html +0 -1227
  103. package/docs/module-effect.Stack.html +0 -406
  104. package/docs/module-effect.Transform.Matrix.html +0 -193
  105. package/docs/module-effect.Transform.html +0 -1174
  106. package/docs/module-effect.html +0 -148
  107. package/docs/module-event.html +0 -473
  108. package/docs/module-index.html +0 -186
  109. package/docs/module-layer-Media.html +0 -1116
  110. package/docs/module-layer-MediaMixin.html +0 -164
  111. package/docs/module-layer.Audio.html +0 -1188
  112. package/docs/module-layer.Base.html +0 -629
  113. package/docs/module-layer.Image.html +0 -1421
  114. package/docs/module-layer.Text.html +0 -1731
  115. package/docs/module-layer.Video.html +0 -1938
  116. package/docs/module-layer.Visual.html +0 -1698
  117. package/docs/module-layer.html +0 -137
  118. package/docs/module-movie.html +0 -3118
  119. package/docs/module-util.Color.html +0 -702
  120. package/docs/module-util.Font.html +0 -395
  121. package/docs/module-util.html +0 -845
  122. package/docs/movie.js.html +0 -689
  123. package/docs/scripts/collapse.js +0 -20
  124. package/docs/scripts/linenumber.js +0 -25
  125. package/docs/scripts/nav.js +0 -12
  126. package/docs/scripts/polyfill.js +0 -4
  127. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
  128. package/docs/scripts/prettify/lang-css.js +0 -2
  129. package/docs/scripts/prettify/prettify.js +0 -28
  130. package/docs/scripts/search.js +0 -83
  131. package/docs/styles/jsdoc.css +0 -671
  132. package/docs/styles/prettify.css +0 -79
  133. package/docs/util.js.html +0 -503
  134. package/screenshots/2019-08-17_0.png +0 -0
  135. package/spec/assets/effect/gaussian-blur-horizontal.png +0 -0
  136. package/spec/assets/effect/gaussian-blur-vertical.png +0 -0
  137. package/spec/assets/effect/original.png +0 -0
  138. package/spec/assets/effect/pixelate.png +0 -0
  139. package/spec/assets/effect/transform/multiply.png +0 -0
  140. package/spec/assets/effect/transform/rotate.png +0 -0
  141. package/spec/assets/effect/transform/scale-fraction.png +0 -0
  142. package/spec/assets/effect/transform/scale.png +0 -0
  143. package/spec/assets/effect/transform/translate-fraction.png +0 -0
  144. package/spec/assets/effect/transform/translate.png +0 -0
  145. package/spec/assets/layer/audio.wav +0 -0
  146. package/spec/assets/layer/image.jpg +0 -0
  147. package/spec/effect.spec.js +0 -352
  148. package/spec/event.spec.js +0 -25
  149. package/spec/layer.spec.js +0 -128
  150. package/spec/movie.spec.js +0 -154
  151. package/spec/util.spec.js +0 -285
  152. package/src/effect.js +0 -1265
  153. package/src/event.js +0 -78
  154. package/src/index.js +0 -23
  155. package/src/layer.js +0 -875
  156. package/src/movie.js +0 -636
  157. package/src/util.js +0 -487
package/eslint.conf.js CHANGED
@@ -14,15 +14,8 @@ module.exports = {
14
14
  ecmaVersion: 2018,
15
15
  sourceType: 'module'
16
16
  },
17
- plugins: [
18
- 'html'
19
- ],
20
17
  rules: {
21
- 'brace-style': ['error', '1tbs', { allowSingleLine: false }]
18
+ 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
19
+ curly: ['error', 'multi', 'consistent']
22
20
  },
23
- settings: {
24
- html: {
25
- indent: '+2'
26
- }
27
- }
28
21
  }
@@ -0,0 +1,9 @@
1
+ const conf = require('./eslint.conf.js')
2
+ conf.globals.etro = 'readonly'
3
+ conf.plugins = ['html']
4
+ conf.settings = {
5
+ html: {
6
+ indent: '+2'
7
+ }
8
+ }
9
+ module.exports = conf
@@ -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
@@ -0,0 +1,5 @@
1
+ const conf = require('./eslint.conf.js')
2
+ conf.extends.push('plugin:@typescript-eslint/recommended')
3
+ conf.parser = '@typescript-eslint/parser'
4
+ conf.plugins = ['@typescript-eslint']
5
+ module.exports = conf
@@ -3,25 +3,24 @@
3
3
  <html>
4
4
  <head>
5
5
  <title>Fun with Etro</title>
6
+ <script src="../../dist/etro-iife.js"></script>
6
7
  </head>
7
8
  <body>
8
- <script type="module">
9
- import etro from '../../src/index.js'
9
+ <script>
10
10
  const cols = 2; const rows = 2
11
11
  let movie, sample
12
12
 
13
13
  const begin = () => {
14
14
  const canvas = document.createElement('canvas')
15
15
  document.body.appendChild(canvas)
16
- movie = new etro.Movie(canvas)
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')
24
- sample.src = '../assets/sample.ogv'
23
+ sample.src = '../assets/desert.mp4'
25
24
 
26
25
  sample.onloadedmetadata = addLayers
27
26
  }
@@ -32,20 +31,19 @@
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
- video.src = '../assets/sample.ogv'
39
- if (x * y) {
37
+ video.src = '../assets/desert.mp4'
38
+ if (x * y)
40
39
  video.onplay = event => {
41
40
  console.log(event)
42
41
  }
43
- }
44
42
 
45
43
  video.onloadedmetadata = () => {
46
- const layer = new etro.layer.Video(0, video, {
47
- x: x, y: y, width: width, height: height
48
- // mediaStartTime: 0
44
+ const layer = new etro.layer.Video({
45
+ startTime: 0, source: video, x, y, width, height
46
+ // sourceStartTime: 0
49
47
  }).addEffect(new etro.effect.Channels({
50
48
  r: 0.5 + Math.random() * 0.5,
51
49
  g: 0.5 + Math.random() * 0.5,
@@ -54,17 +52,18 @@
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 = () => {
66
62
  movie
67
- .addLayer(new etro.layer.Text(0, sample.duration, 'etro', {
63
+ .addLayer(new etro.layer.Text({
64
+ startTime: 0,
65
+ duration: sample.duration,
66
+ text: 'etro',
68
67
  width: movie.width / 2,
69
68
  height: movie.height / 2,
70
69
  x: movie.width / 4,
@@ -2,6 +2,7 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Video player in Etro</title>
5
+ <script src="../../dist/etro-iife.js"></script>
5
6
  <style>
6
7
  body {
7
8
  background: #333;
@@ -58,9 +59,7 @@
58
59
  </style>
59
60
  </head>
60
61
  <body>
61
- <script type="module">
62
- import etro from '../../src/index.js'
63
-
62
+ <script>
64
63
  window.addEventListener('load', () => {
65
64
  const canvas = document.getElementById('output')
66
65
 
@@ -69,7 +68,7 @@
69
68
  progressBar: document.getElementById('progress')
70
69
  }
71
70
 
72
- const movie = new etro.Movie(canvas, { repeat: true })
71
+ const movie = new etro.Movie({ canvas, repeat: true })
73
72
 
74
73
  // FIXME: resetting to beginning every time paused and played
75
74
  controls.playPause.onclick = event => {
@@ -84,14 +83,13 @@
84
83
  canvas.addEventListener('click', controls.playPause.click) // FIXME: isn"t firing
85
84
  document.body.addEventListener('keyup', event => {
86
85
  const key = event.which || event.keyCode || 0
87
- if (key === 32) {
86
+ if (key === 32)
88
87
  controls.playPause.click()
89
- } // spacebar
88
+ // spacebar
90
89
  })
91
90
  etro.event.subscribe(movie, 'movie.ended', event => {
92
- if (!event.repeat) {
91
+ if (!event.repeat)
93
92
  controls.playPause.className = 'play'
94
- }
95
93
  })
96
94
 
97
95
  controls.progressBar.min = 0
@@ -103,6 +101,7 @@
103
101
  controls.progressBar.value = 0 // just for sure, it's weird
104
102
  controls.progressBar.addEventListener('input', () => {
105
103
  movie.currentTime = 1 * controls.progressBar.value
104
+ movie.refresh()
106
105
  })
107
106
  etro.event.subscribe(movie, 'movie.timeupdate', () => {
108
107
  controls.progressBar.value = movie.currentTime
@@ -114,15 +113,15 @@
114
113
 
115
114
  // For simplicity, only use one layer
116
115
  movie.addLayer(
117
- new etro.layer.Video(0, video)
116
+ new etro.layer.Video({ startTime: 0, source: video })
118
117
  )
119
118
 
120
119
  controls.progressBar.max = movie.duration
121
120
  })
122
121
  </script>
123
122
  <div id="container">
124
- <video src="../assets/sample.ogv"></video>
125
- <img src="../assets/sample.jpg"/>
123
+ <video src="../assets/desert.mp4"></video>
124
+ <img src="../assets/lake.jpg"/>
126
125
  <canvas id="output"></canvas><br>
127
126
  <button id="pause-play" class="play"><!-- styled --></button>
128
127
  <input id="progress" type="range" value="0"/>
@@ -2,13 +2,12 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>getUserMedia()</title>
5
+ <script src="../../dist/etro-iife.js"></script>
5
6
  </head>
6
7
  <body>
7
8
  <video style="display:none"></video>
8
9
  <canvas></canvas>
9
- <script type="module">
10
- import etro from '../../src/index.js'
11
-
10
+ <script>
12
11
  const video = document.querySelector('video')
13
12
  navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
14
13
  video.srcObject = stream
@@ -19,9 +18,10 @@
19
18
  }
20
19
  })
21
20
 
22
- const movie = new etro.Movie(document.querySelector('canvas'))
23
- .addLayer(new etro.layer.Visual(0, Infinity, { background: 'black' }))
24
- .addLayer(new etro.layer.Video(0, video)
21
+ const canvas = document.querySelector('canvas')
22
+ const movie = new etro.Movie({ canvas })
23
+ .addLayer(new etro.layer.Visual({ startTime: 0, duration: Infinity, background: 'black' }))
24
+ .addLayer(new etro.layer.Video({ startTime: 0, source: video })
25
25
  .addEffect(new etro.effect.ChromaKey(etro.parseColor('black'), 100)))
26
26
  </script>
27
27
  </body>
@@ -2,19 +2,26 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Manipulating Audio in Etro</title>
5
+ <script src="../../dist/etro-iife.js"></script>
5
6
  </head>
6
7
  <body>
7
- <script type="module">
8
- import etro from '../../src/index.js'
9
- let movie
10
-
11
- const initMovie = () => {
8
+ <script>
9
+ const start = () => {
10
+ button.disabled = true
12
11
  // initialize movie
13
- movie = new etro.Movie(document.createElement('canvas'))
12
+ const canvas = document.createElement('canvas')
13
+ const movie = new etro.Movie({ canvas })
14
14
  // initialize layers (all with durations clipped to 5 seconds)
15
- const layer1 = new etro.layer.Audio(0, document.getElementById('layer1'), { duration: 5 })
16
- const layer2 = new etro.layer.Audio(layer1.duration, document.getElementById('layer2'), { duration: 5 })
17
- const layer3 = new etro.layer.Audio(layer2.startTime + layer2.duration, document.getElementById('layer3'), { duration: 5 })
15
+ const audio1 = document.getElementById('layer1')
16
+ const audio2 = document.getElementById('layer2')
17
+ const audio3 = document.getElementById('layer3')
18
+ const layer1 = new etro.layer.Audio({ startTime: 0, source: audio1, duration: 5 })
19
+ const layer2 = new etro.layer.Audio({ startTime: layer1.duration, source: audio2, duration: 5 })
20
+ const layer3 = new etro.layer.Audio({
21
+ startTime: layer2.startTime + layer2.duration,
22
+ source: audio3,
23
+ duration: 5
24
+ })
18
25
 
19
26
  /*
20
27
  Once a media layer is added to the movie, it will automatically be connected to the movie's `actx`
@@ -24,29 +31,34 @@
24
31
  // movie.layers.push.apply(movie.layers, [layer1, layer2, layer3])
25
32
  movie.layers.push(layer1, layer2, layer3)
26
33
 
27
- // Now, disconnect the layers from the audio node graph and reconnect them with intermediate audio
34
+ // Now, disconnect the layers from the audio node graph and reconnect them with intersourcete audio
28
35
  // effect nodes.
29
36
 
30
- layer1.source.disconnect(movie.actx.destination)
37
+ layer1.audioNode.disconnect(movie.actx.destination)
31
38
  const muter = movie.actx.createGain()
32
39
  muter.gain.value = 0
33
- layer1.source.connect(muter).connect(movie.actx.destination)
40
+ layer1.audioNode.connect(muter).connect(movie.actx.destination)
34
41
 
35
- layer2.source.disconnect(movie.actx.destination)
42
+ layer2.audioNode.disconnect(movie.actx.destination)
36
43
  const panner = movie.actx.createStereoPanner()
37
44
  panner.pan.value = +1 // completely to the right
38
- layer2.source.connect(panner).connect(movie.actx.destination)
45
+ layer2.audioNode.connect(panner).connect(movie.actx.destination)
39
46
 
40
47
  // Manipulating the audio graph is not always necessary
41
48
  layer3.playbackRate = 2 // double the speed
42
49
 
50
+ etro.event.subscribe(movie, 'movie.ended', () => {
51
+ button.disabled = false
52
+ })
43
53
  movie.play()
44
54
  }
45
55
 
46
- window.addEventListener('load', initMovie)
56
+ const button = document.querySelector('button')
57
+ button.addEventListener('click', start)
47
58
  </script>
48
- <audio id="layer1" src="../assets/sample.wav"></audio>
49
- <audio id="layer2" src="../assets/sample.wav"></audio>
50
- <audio id="layer3" src="../assets/sample.wav"></audio>
59
+ <button>Start</button>
60
+ <audio id="layer1" src="../assets/strings.wav"></audio>
61
+ <audio id="layer2" src="../assets/strings.wav"></audio>
62
+ <audio id="layer3" src="../assets/strings.wav"></audio>
51
63
  </body>
52
64
  </html>
@@ -2,10 +2,10 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Effects in Etro</title>
5
+ <script src="../../dist/etro-iife.js"></script>
5
6
  </head>
6
7
  <body>
7
- <script type="module">
8
- import etro from '../../src/index.js'
8
+ <script>
9
9
  let movie
10
10
  window.addEventListener('load', () => {
11
11
  const canvas = document.createElement('canvas')
@@ -15,42 +15,65 @@
15
15
  })
16
16
 
17
17
  const initMovie = canvas => {
18
- movie = new etro.Movie(canvas)
18
+ movie = new etro.Movie({ canvas })
19
19
 
20
20
  const image = document.querySelector('img')
21
21
  canvas.width = image.width
22
22
  canvas.height = image.height
23
23
  // create a red 400x400 rectangle that starts at time 0 and lasts 2 seconds
24
24
  movie
25
- .addLayer(new etro.layer.Image(0, 2, image))
25
+ .addLayer(new etro.layer.Image({ startTime: 0, duration: 2, source: image }))
26
26
  // create a transparent blue 500x200 at (50, 20) that starts at time 1 and lasts 2 seconds
27
27
  .addLayer(
28
- new etro.layer.Image(2, 2, image).addEffect(
29
- new etro.effect.GaussianBlur(3)
28
+ new etro.layer.Image({ startTime: 2, duration: 2, source: image }).addEffect(
29
+ new etro.effect.GaussianBlur({ radius: 3 })
30
30
  )
31
31
  )
32
32
  .addLayer(
33
- new etro.layer.Image(4, 2, image).addEffect(
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(
39
- new etro.layer.Image(6, 2, image, {
44
+ new etro.layer.Image({
45
+ startTime: 6,
46
+ duration: 2,
47
+ source: image,
40
48
  // allow rotated image to fill entire screen by setting the size of the layer, which is not the image
41
- width: movie.width, height: movie.height
49
+ width: movie.width,
50
+ height: movie.height
42
51
  }).addEffect(
43
- 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
+ })
44
55
  )
45
56
  )
46
57
  .addLayer(
47
- new etro.layer.Image(8, 2, image).addEffect(
48
- new etro.effect.EllipticalMask(image.width / 2, image.height / 2, image.width / 2, image.height / 2)
58
+ new etro.layer.Image({ startTime: 8, duration: 2, source: image }).addEffect(
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
+ })
49
65
  )
50
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
51
74
  .play()
52
75
  }
53
76
  </script>
54
- <img src="../assets/sample.jpg" style="display: none;"/>
77
+ <img src="../assets/lake.jpg" style="display: none;"/>
55
78
  </body>
56
79
  </html>
@@ -2,13 +2,25 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Media in Etro</title>
5
+ <script src="../../dist/etro-iife.js"></script>
5
6
  </head>
6
7
  <body>
7
- <script type="module">
8
+ <div id="input">
9
+ <img src="../assets/lake.jpg" style="display:none"/>
10
+ <video src="../assets/desert.mp4" style="display:none"></video>
11
+ <audio src="../assets/strings.wav" style="display:none"></audio>
12
+ </div>
13
+ <div id="output">
14
+ <video controls></video><br>
15
+ </div>
16
+ <button>Record</button>
17
+
18
+ <script>
8
19
  // TODO: test audio output on a device that actually has drivers
9
- import etro from '../../src/index.js'
10
20
  let movie
11
- window.addEventListener('load', () => {
21
+ const btn = document.querySelector('button')
22
+ btn.addEventListener('click', () => {
23
+ btn.disabled = true
12
24
  const canvas = document.createElement('canvas')
13
25
  canvas.width = 600
14
26
  canvas.height = 400
@@ -18,53 +30,54 @@
18
30
  })
19
31
 
20
32
  const initMovie = canvas => {
21
- movie = new etro.Movie(canvas)
33
+ movie = new etro.Movie({ canvas })
22
34
  const video = document.querySelector('#input video')
23
35
  movie.width = video.videoWidth
24
36
  movie.height = video.videoHeight
25
37
  movie
26
- .addLayer(new etro.layer.Image(0, 3, document.querySelector('#input img'), {
38
+ .addLayer(new etro.layer.Image({
39
+ startTime: 0,
40
+ duration: 3,
41
+ source: document.querySelector('#input img'),
27
42
  // crop @ (150, 150) extending (200, 200)
28
- clipX: 100,
29
- clipY: 100,
43
+ sourceX: 100,
44
+ sourceY: 100,
45
+ sourceWidth: 400,
46
+ sourceHeight: 400,
30
47
  x: 100,
31
48
  y: 100,
32
- clipWidth: 400,
33
- clipHeight: 400,
34
- width: 400,
35
- height: 400
49
+ destWidth: 400,
50
+ destHeight: 400
36
51
  }))
37
- .addLayer(new etro.layer.Video(3, video, {
52
+ .addLayer(new etro.layer.Video({
53
+ startTime: 3,
54
+ source: video,
38
55
  // trim video to only include 3 seconds starting 2 minutes into the video in the video
39
- mediaStartTime: 120,
56
+ sourceStartTime: 5,
40
57
  duration: 3
41
58
  }))
42
- .addLayer(new etro.layer.Audio(6, document.querySelector('#input audio'), {
43
- mediaStartTime: 9, // start audio at 9s
59
+ .addLayer(new etro.layer.Audio({
60
+ startTime: 6,
61
+ source: document.querySelector('#input audio'),
62
+ sourceStartTime: 9, // start audio at 9s
44
63
  duration: 3 // last 3s
45
64
  // volume: 0.25 // 25% of default volume (same as setting volume attribute on audio element)
46
65
  }))
47
66
 
48
- .record(25)
67
+ .record({ frameRate: 25 })
49
68
  .then(blob => {
50
69
  const video = document.querySelector('#output video')
51
70
  video.src = URL.createObjectURL(blob)
52
- document.querySelector('p').innerHTML = 'Done'
53
71
  })
54
72
  .catch(error => {
55
73
  throw error
56
74
  })
75
+
76
+ window.addEventListener('unload', () => {
77
+ const video = document.querySelector('#output video')
78
+ URL.revokeObjectURL(video.src)
79
+ })
57
80
  }
58
81
  </script>
59
- <div id="input">
60
- <img src="../assets/sample.jpg" style="display:none"/>
61
- <video src="../assets/sample.ogv" style="display:none"></video>
62
- <audio src="../assets/sample.wav" style="display:none"></audio>
63
- </div>
64
- <div id="output">
65
- <video controls></video><br>
66
- </div>
67
-
68
- <p>Recording</p>
69
82
  </body>
70
83
  </html>
@@ -2,10 +2,10 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Functions in Etro</title>
5
+ <script src="../../dist/etro-iife.js"></script>
5
6
  </head>
6
7
  <body>
7
- <script type="module">
8
- import etro from '../../src/index.js'
8
+ <script>
9
9
  let movie
10
10
  window.addEventListener('load', () => {
11
11
  const canvas = document.createElement('canvas')
@@ -15,14 +15,16 @@
15
15
  })
16
16
 
17
17
  const initMovie = canvas => {
18
- movie = new etro.Movie(canvas)
18
+ movie = new etro.Movie({ canvas })
19
19
 
20
20
  canvas.width = canvas.height = 400
21
21
  movie
22
22
  // Functions are callbacks that are called every time a property value is queried.
23
23
  // For instance, you can set a layer's opacity to the function `Math.random`, which will make the
24
24
  // layer's opacity randomized each animation frame.
25
- .addLayer(new etro.layer.Visual(0, 3, {
25
+ .addLayer(new etro.layer.Visual({
26
+ startTime: 0,
27
+ duration: 3,
26
28
  // omitting width or height sets the respective element to fill the screen
27
29
  background: 'green',
28
30
 
@@ -2,23 +2,27 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Hello World in Etro</title>
5
+ <script src="../../dist/etro-iife.js"></script>
5
6
  </head>
6
7
  <body>
7
- <script type="module">
8
- import etro from '../../src/index.js'
8
+ <script>
9
9
  window.addEventListener('load', () => {
10
10
  const canvas = document.createElement('canvas')
11
11
  canvas.width = 600
12
12
  canvas.height = 400
13
13
  document.body.appendChild(canvas)
14
14
 
15
- new etro.Movie(canvas)
15
+ new etro.Movie({ canvas })
16
16
  // create a red rectangle that starts at time 0 and lasts 4 seconds and fills the entire screen
17
- .addLayer(new etro.layer.Visual(0, 4, {
17
+ .addLayer(new etro.layer.Visual({
18
+ startTime: 0,
19
+ duration: 4,
18
20
  background: 'red'
19
21
  }))
20
22
  // create a transparent blue 500x200 at (50, 20) that starts at time 1 and lasts 2 seconds
21
- .addLayer(new etro.layer.Visual(1, 2, {
23
+ .addLayer(new etro.layer.Visual({
24
+ startTime: 1,
25
+ duration: 2,
22
26
  background: '#0000ff80',
23
27
  border: { color: '#00f', thickness: 4 },
24
28
  width: 500,
@@ -2,24 +2,24 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Hello World in Etro</title>
5
+ <script src="../../dist/etro-iife.js"></script>
5
6
  </head>
6
7
  <body>
7
- <script type="module">
8
- import etro from '../../src/index.js'
8
+ <script>
9
9
  window.addEventListener('load', () => {
10
10
  const canvas = document.createElement('canvas')
11
11
  document.body.appendChild(canvas)
12
12
 
13
13
  const video = document.createElement('video')
14
- video.src = '../assets/sample.ogv'
14
+ video.src = '../assets/desert.mp4'
15
15
 
16
16
  video.onloadeddata = () => {
17
17
  canvas.width = video.videoWidth // you could also do movie.width = video.videoWidth;
18
18
  canvas.height = video.videoHeight
19
- const movie = new etro.Movie(canvas)
19
+ const movie = new etro.Movie({ canvas })
20
20
  movie
21
21
  // add a video layer at 0s in the timeline
22
- .addLayer(new etro.layer.Video(0, video))
22
+ .addLayer(new etro.layer.Video({ startTime: 0, source: video }))
23
23
  .play()
24
24
 
25
25
  // FOR TESTING issue#8 (don't delete):