etro 0.7.0 → 0.8.2

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 (158) hide show
  1. package/.github/workflows/nodejs.yml +4 -2
  2. package/.github/workflows/shipjs-trigger.yml +29 -0
  3. package/CHANGELOG.md +73 -12
  4. package/CODE_OF_CONDUCT.md +5 -5
  5. package/CONTRIBUTING.md +31 -77
  6. package/README.md +81 -26
  7. package/dist/effect/base.d.ts +51 -0
  8. package/dist/effect/brightness.d.ts +16 -0
  9. package/dist/effect/channels.d.ts +23 -0
  10. package/dist/effect/chroma-key.d.ts +23 -0
  11. package/dist/effect/contrast.d.ts +15 -0
  12. package/dist/effect/elliptical-mask.d.ts +31 -0
  13. package/dist/effect/gaussian-blur.d.ts +60 -0
  14. package/dist/effect/grayscale.d.ts +7 -0
  15. package/dist/effect/index.d.ts +15 -0
  16. package/dist/effect/pixelate.d.ts +18 -0
  17. package/dist/effect/shader.d.ts +99 -0
  18. package/dist/effect/stack.d.ts +23 -0
  19. package/dist/effect/transform.d.ts +73 -0
  20. package/dist/etro-cjs.js +9287 -3331
  21. package/dist/etro-iife.js +9229 -3273
  22. package/dist/etro.d.ts +7 -0
  23. package/dist/event.d.ts +35 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/layer/audio-source.d.ts +24 -0
  26. package/dist/layer/audio.d.ts +14 -0
  27. package/dist/layer/base.d.ts +82 -0
  28. package/dist/layer/image.d.ts +6 -0
  29. package/dist/layer/index.d.ts +11 -0
  30. package/dist/layer/text.d.ts +60 -0
  31. package/dist/layer/video.d.ts +11 -0
  32. package/dist/layer/visual-source.d.ts +32 -0
  33. package/dist/layer/visual.d.ts +58 -0
  34. package/dist/movie.d.ts +192 -0
  35. package/dist/object.d.ts +12 -0
  36. package/dist/util.d.ts +125 -0
  37. package/eslint.conf.js +2 -9
  38. package/eslint.example-conf.js +9 -0
  39. package/eslint.test-conf.js +1 -0
  40. package/eslint.typescript-conf.js +5 -0
  41. package/examples/application/readme-screenshot.html +16 -17
  42. package/examples/application/video-player.html +10 -11
  43. package/examples/application/webcam.html +6 -6
  44. package/examples/introduction/audio.html +30 -18
  45. package/examples/introduction/effects.html +37 -14
  46. package/examples/introduction/export.html +32 -25
  47. package/examples/introduction/functions.html +6 -4
  48. package/examples/introduction/hello-world1.html +9 -5
  49. package/examples/introduction/hello-world2.html +5 -5
  50. package/examples/introduction/keyframes.html +35 -23
  51. package/examples/introduction/media.html +26 -18
  52. package/examples/introduction/text.html +9 -5
  53. package/karma.conf.js +5 -3
  54. package/package.json +36 -14
  55. package/rollup.config.js +15 -4
  56. package/scripts/gen-effect-samples.html +26 -25
  57. package/scripts/save-effect-samples.js +14 -15
  58. package/ship.config.js +80 -0
  59. package/src/effect/base.ts +115 -0
  60. package/src/effect/brightness.ts +43 -0
  61. package/src/effect/channels.ts +50 -0
  62. package/src/effect/chroma-key.ts +82 -0
  63. package/src/effect/contrast.ts +42 -0
  64. package/src/effect/elliptical-mask.ts +75 -0
  65. package/src/effect/gaussian-blur.ts +232 -0
  66. package/src/effect/grayscale.ts +34 -0
  67. package/src/effect/index.ts +22 -0
  68. package/src/effect/pixelate.ts +58 -0
  69. package/src/effect/shader.ts +557 -0
  70. package/src/effect/stack.ts +78 -0
  71. package/src/effect/transform.ts +193 -0
  72. package/src/etro.ts +26 -0
  73. package/src/event.ts +112 -0
  74. package/src/index.ts +8 -0
  75. package/src/layer/audio-source.ts +219 -0
  76. package/src/layer/audio.ts +34 -0
  77. package/src/layer/base.ts +175 -0
  78. package/src/layer/image.ts +8 -0
  79. package/src/layer/index.ts +13 -0
  80. package/src/layer/text.ts +138 -0
  81. package/src/layer/video.ts +15 -0
  82. package/src/layer/visual-source.ts +150 -0
  83. package/src/layer/visual.ts +197 -0
  84. package/src/movie.ts +707 -0
  85. package/src/object.ts +14 -0
  86. package/src/util.ts +466 -0
  87. package/tsconfig.json +8 -0
  88. package/docs/effect.js.html +0 -1215
  89. package/docs/event.js.html +0 -145
  90. package/docs/index.html +0 -81
  91. package/docs/index.js.html +0 -92
  92. package/docs/layer.js.html +0 -888
  93. package/docs/module-effect-GaussianBlurComponent.html +0 -345
  94. package/docs/module-effect.Brightness.html +0 -339
  95. package/docs/module-effect.Channels.html +0 -319
  96. package/docs/module-effect.ChromaKey.html +0 -611
  97. package/docs/module-effect.Contrast.html +0 -339
  98. package/docs/module-effect.EllipticalMask.html +0 -200
  99. package/docs/module-effect.GaussianBlur.html +0 -202
  100. package/docs/module-effect.GaussianBlurHorizontal.html +0 -242
  101. package/docs/module-effect.GaussianBlurVertical.html +0 -242
  102. package/docs/module-effect.Pixelate.html +0 -330
  103. package/docs/module-effect.Shader.html +0 -1227
  104. package/docs/module-effect.Stack.html +0 -406
  105. package/docs/module-effect.Transform.Matrix.html +0 -193
  106. package/docs/module-effect.Transform.html +0 -1174
  107. package/docs/module-effect.html +0 -148
  108. package/docs/module-event.html +0 -473
  109. package/docs/module-index.html +0 -186
  110. package/docs/module-layer-Media.html +0 -1116
  111. package/docs/module-layer-MediaMixin.html +0 -164
  112. package/docs/module-layer.Audio.html +0 -1188
  113. package/docs/module-layer.Base.html +0 -629
  114. package/docs/module-layer.Image.html +0 -1421
  115. package/docs/module-layer.Text.html +0 -1731
  116. package/docs/module-layer.Video.html +0 -1938
  117. package/docs/module-layer.Visual.html +0 -1698
  118. package/docs/module-layer.html +0 -137
  119. package/docs/module-movie.html +0 -3118
  120. package/docs/module-util.Color.html +0 -702
  121. package/docs/module-util.Font.html +0 -395
  122. package/docs/module-util.html +0 -845
  123. package/docs/movie.js.html +0 -689
  124. package/docs/scripts/collapse.js +0 -20
  125. package/docs/scripts/linenumber.js +0 -25
  126. package/docs/scripts/nav.js +0 -12
  127. package/docs/scripts/polyfill.js +0 -4
  128. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
  129. package/docs/scripts/prettify/lang-css.js +0 -2
  130. package/docs/scripts/prettify/prettify.js +0 -28
  131. package/docs/scripts/search.js +0 -83
  132. package/docs/styles/jsdoc.css +0 -671
  133. package/docs/styles/prettify.css +0 -79
  134. package/docs/util.js.html +0 -503
  135. package/screenshots/2019-08-17_0.png +0 -0
  136. package/spec/assets/effect/gaussian-blur-horizontal.png +0 -0
  137. package/spec/assets/effect/gaussian-blur-vertical.png +0 -0
  138. package/spec/assets/effect/original.png +0 -0
  139. package/spec/assets/effect/pixelate.png +0 -0
  140. package/spec/assets/effect/transform/multiply.png +0 -0
  141. package/spec/assets/effect/transform/rotate.png +0 -0
  142. package/spec/assets/effect/transform/scale-fraction.png +0 -0
  143. package/spec/assets/effect/transform/scale.png +0 -0
  144. package/spec/assets/effect/transform/translate-fraction.png +0 -0
  145. package/spec/assets/effect/transform/translate.png +0 -0
  146. package/spec/assets/layer/audio.wav +0 -0
  147. package/spec/assets/layer/image.jpg +0 -0
  148. package/spec/effect.spec.js +0 -352
  149. package/spec/event.spec.js +0 -25
  150. package/spec/layer.spec.js +0 -150
  151. package/spec/movie.spec.js +0 -162
  152. package/spec/util.spec.js +0 -285
  153. package/src/effect.js +0 -1268
  154. package/src/event.js +0 -78
  155. package/src/index.js +0 -23
  156. package/src/layer.js +0 -897
  157. package/src/movie.js +0 -637
  158. package/src/util.js +0 -505
@@ -2,10 +2,10 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Keyframes 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,7 +15,7 @@
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
@@ -23,42 +23,54 @@
23
23
  // Keyframes let you make a dynamic property that interpolates.
24
24
  // For instance, you can set a layer's opacity to decrease over time, effectively making it fade out
25
25
  // Numbers and objects interpolate (animate smoothly)
26
- .addLayer(new etro.layer.Visual(0, 3, {
26
+ .addLayer(new etro.layer.Visual({
27
+ startTime: 0,
28
+ duration: 3,
27
29
  // omitting width or height sets the respective element to fill the screen
28
30
  background: 'green',
29
31
  // opacity=1 @ 0s (relative to the layer) -> opacity=0 @ 1s (relative to the layer)
30
- opacity: { 0: 1, 3: 0 }
32
+ opacity: new etro.KeyFrame([0, 1], [3, 0])
31
33
  }))
32
34
  // Because strings don't interpolate, you need to convert colors and fonts to objects
33
35
  // for a smooth effect (which will then be automatically `.toString()`ed when set on the canvas
34
36
  // context).
35
- .addLayer(new etro.layer.Visual(3, 3, {
36
- background: { 0: etro.parseColor('red'), 3: new etro.Color(0, 0, 255) }
37
+ .addLayer(new etro.layer.Visual({
38
+ startTime: 3,
39
+ duration: 3,
40
+ background: new etro.KeyFrame([0, etro.parseColor('red')], [3, new etro.Color(0, 0, 255)])
37
41
  }))
38
42
  // You can use other types in keyframes, but they will be used sequentially without interpolation
39
- .addLayer(new etro.layer.Text(6, 3, { 0: 'Hello ...', 1.5: '...world' }))
43
+ .addLayer(new etro.layer.Text({
44
+ startTime: 6,
45
+ duration: 3,
46
+ text: new etro.KeyFrame([0, 'Hello ...'], [1.5, '...world'])
47
+ }))
40
48
 
41
49
  // When interpolating, you can specify how the keyframes will be interpolated
42
- .addLayer(new etro.layer.Visual(9, 3, {
43
- width: { 0: movie.width, 3: 0, interpolate: etro.linearInterp }, // (obviously) linear
44
- height: { 0: movie.height, 3: 0, interpolate: etro.cosineInterp }, // curved
50
+ .addLayer(new etro.layer.Visual({
51
+ startTime: 9,
52
+ duration: 3,
53
+ width: new etro.KeyFrame([0, movie.width, etro.linearInterp], [3, 0]), // (obviously) linear
54
+ height: new etro.KeyFrame([0, movie.height, etro.linearInterp], [3, 0]), // (obviously) linear
45
55
  background: 'blue'
46
56
  }))
47
57
 
48
58
  // Of course, you can have more than two keyframes
49
- .addLayer(new etro.layer.Text(12, 6, 'Etro', {
50
- background: {
51
- 0: etro.parseColor('#0ff'),
52
- 2: etro.parseColor('#ff0'),
53
- 4: etro.parseColor('#f0f'),
54
- 6: etro.parseColor('#fff')
55
- },
59
+ .addLayer(new etro.layer.Text({
60
+ text: 'Etro',
61
+ startTime: 12,
62
+ duration: 6,
63
+ background: new etro.KeyFrame(
64
+ [0, etro.parseColor('#0ff')],
65
+ [2, etro.parseColor('#ff0')],
66
+ [4, etro.parseColor('#f0f')],
67
+ [6, etro.parseColor('#fff')]
68
+ ),
56
69
  // let's just add another property (fonts can be parsed into objects just like colors)
57
- font: {
58
- 0: etro.parseFont('28px monospace'),
59
- 6: etro.parseFont('36px monospace'),
60
- interpolate: etro.cosineInterp
61
- }
70
+ font: new etro.KeyFrame(
71
+ [0, etro.parseFont('28px monospace'), etro.cosineInterp],
72
+ [6, etro.parseFont('36px monospace')]
73
+ )
62
74
  }))
63
75
  .play()
64
76
  }
@@ -2,14 +2,18 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Media in Etro</title>
5
+ <script src="../../dist/etro-iife.js"></script>
5
6
  <style> img, video {display: none;} </style>
6
7
  </head>
7
8
  <body>
8
- <script type="module">
9
- import etro from '../../src/index.js'
10
-
11
- let movie
12
- window.addEventListener('load', () => {
9
+ <img src="../assets/lake.jpg"/>
10
+ <video src="../assets/desert.mp4"></video>
11
+ <audio src="../assets/strings.wav"></audio>
12
+ <button>Start</button>
13
+ <script>
14
+ const button = document.querySelector('button')
15
+ button.addEventListener('click', () => {
16
+ button.disabled = true
13
17
  const canvas = document.createElement('canvas')
14
18
  canvas.width = 600
15
19
  canvas.height = 400
@@ -19,37 +23,41 @@
19
23
  })
20
24
 
21
25
  const initMovie = canvas => {
22
- movie = new etro.Movie(canvas)
26
+ const movie = new etro.Movie({ canvas })
23
27
  const video = document.querySelector('video')
24
28
  movie.width = video.videoWidth
25
29
  movie.height = video.videoHeight
26
30
  movie
27
- .addLayer(new etro.layer.Image(0, 3, document.querySelector('img'), {
31
+ .addLayer(new etro.layer.Image({
32
+ startTime: 0,
33
+ duration: 3,
34
+ source: document.querySelector('img'),
28
35
  // crop @ (150, 150) extending (200, 200)
29
- clipX: 100,
30
- clipY: 100,
36
+ sourceX: 100,
37
+ sourceY: 100,
38
+ sourceWidth: 400,
39
+ sourceHeight: 400,
31
40
  x: 100,
32
41
  y: 100,
33
- clipWidth: 400,
34
- clipHeight: 400,
35
42
  width: 400,
36
43
  height: 400
37
44
  }))
38
- .addLayer(new etro.layer.Video(3, video, {
45
+ .addLayer(new etro.layer.Video({
46
+ source: video,
47
+ startTime: 3,
39
48
  // trim video to only include 3 seconds starting 2 minutes into the video in the video
40
- mediaStartTime: 120,
49
+ sourceStartTime: 5,
41
50
  duration: 3
42
51
  }))
43
- .addLayer(new etro.layer.Audio(6, document.querySelector('audio'), {
44
- mediaStartTime: 9, // start audio at 9s
52
+ .addLayer(new etro.layer.Audio({
53
+ startTime: 6,
54
+ source: document.querySelector('audio'),
55
+ sourceStartTime: 9, // start audio at 9s
45
56
  duration: 3 // last 3s
46
57
  // volume: 0.25 // 25% of default volume (same as setting volume attribute on audio element)
47
58
  }))
48
59
  .play()
49
60
  }
50
61
  </script>
51
- <img src="../assets/sample.jpg"/>
52
- <video src="../assets/sample.ogv"></video>
53
- <audio src="../assets/sample.wav"></audio>
54
62
  </body>
55
63
  </html>
@@ -2,10 +2,10 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Text 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')
@@ -17,9 +17,13 @@
17
17
  })
18
18
 
19
19
  const initMovie = canvas => {
20
- movie = new etro.Movie(canvas)
21
- movie.addLayer(new etro.layer.Text(0, 4, 'Hello world', {
22
- font: '24px monospace', color: 'blue'
20
+ movie = new etro.Movie({ canvas })
21
+ movie.addLayer(new etro.layer.Text({
22
+ startTime: 0,
23
+ duration: 4,
24
+ text: 'Hello world',
25
+ font: '24px monospace',
26
+ color: 'blue'
23
27
  })).play()
24
28
  }
25
29
  </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
 
@@ -30,7 +32,7 @@ module.exports = function (config) {
30
32
  // test results reporter to use
31
33
  // possible values: 'dots', 'progress'
32
34
  // available reporters: https://npmjs.org/browse/keyword/karma-reporter
33
- reporters: ['progress'],
35
+ reporters: ['dots'],
34
36
 
35
37
  // web server port
36
38
  port: 9876,
package/package.json CHANGED
@@ -1,16 +1,21 @@
1
1
  {
2
2
  "name": "etro",
3
- "version": "0.7.0",
4
- "description": "A flexible video-editing library for the browser",
5
- "main": "dist/etro-cjs.js",
6
- "browser": "src/index.js",
3
+ "version": "0.8.2",
4
+ "description": "An extendable video-editing framework for the browser and Node",
5
+ "browser": "dist/etro-cjs.js",
6
+ "types": "dist/index.d.ts",
7
7
  "directories": {
8
8
  "doc": "docs",
9
9
  "example": "examples",
10
10
  "test": "spec"
11
11
  },
12
- "dependencies": {},
12
+ "dependencies": {
13
+ "standardized-audio-context": "^25.1.13"
14
+ },
13
15
  "devDependencies": {
16
+ "@types/dom-mediacapture-record": "^1.0.7",
17
+ "@typescript-eslint/eslint-plugin": "^4.15.2",
18
+ "@typescript-eslint/parser": "^4.15.2",
14
19
  "docdash": "^1.1.1",
15
20
  "ecstatic": ">=4.1.3",
16
21
  "eslint": "^6.5.1",
@@ -25,36 +30,53 @@
25
30
  "jasmine": "^3.4.0",
26
31
  "jsdoc": "^3.6.3",
27
32
  "jsdoc-export-default-interop": "^0.3.1",
28
- "karma": "^5.0.5",
33
+ "karma": "^6.1.1",
29
34
  "karma-chrome-launcher": "^3.1.0",
35
+ "karma-es6-shim": "^1.0.0",
30
36
  "karma-jasmine": "^2.0.1",
37
+ "karma-requirejs": "^1.1.0",
38
+ "karma-super-dots-reporter": "^0.2.0",
39
+ "keep-a-changelog": "^0.10.4",
31
40
  "puppeteer": "^2.0.0",
41
+ "resemblejs": "^3.2.5",
32
42
  "rollup": "^1.19.4",
43
+ "rollup-plugin-cleaner": "^1.0.0",
33
44
  "rollup-plugin-eslint": "^7.0.0",
34
45
  "rollup-plugin-node-resolve": "^5.2.0",
35
- "rollup-plugin-uglify-es": "^0.0.1"
46
+ "rollup-plugin-typescript2": "^0.29.0",
47
+ "rollup-plugin-uglify-es": "^0.0.1",
48
+ "shipjs": "0.23.3",
49
+ "typedoc": "^0.20.34",
50
+ "typescript": "^4.1.3"
36
51
  },
37
52
  "scripts": {
38
53
  "build": "rollup -c",
39
- "doc": "rm -rf docs && npx jsdoc -r src -d docs -t node_modules/docdash",
54
+ "doc": "rm -rf docs && npx typedoc src/etro.ts --excludePrivate --readme none --theme minimal",
55
+ "assets": "git fetch origin example-assets:example-assets && git cherry-pick example-assets && git reset --soft HEAD^ && git reset HEAD examples/assets",
40
56
  "effects": "node scripts/save-effect-samples.js",
41
- "fix:main": "eslint -c eslint.conf.js --fix --ext .js,.html src examples",
42
- "fix:test": "eslint -c eslint.test-conf.js --fix spec",
43
- "lint": "npm run --silent lint:main && npm run --silent lint:test",
44
- "lint:main": "eslint -c eslint.conf.js --ext .js,.html src examples",
57
+ "lint": "npm run --silent lint:main && npm run --silent lint:test && npm run --silent lint:examples",
58
+ "lint:main": "eslint -c eslint.typescript-conf.js --ext .ts src",
45
59
  "lint:test": "eslint -c eslint.test-conf.js spec",
60
+ "lint:examples": "eslint -c eslint.example-conf.js --ext .html examples",
46
61
  "start": "http-server",
47
- "test": "karma start"
62
+ "test": "karma start",
63
+ "release": "shipjs prepare"
48
64
  },
49
65
  "repository": {
50
66
  "type": "git",
51
67
  "url": "git+https://github.com/etro-js/etro.git"
52
68
  },
53
69
  "keywords": [
70
+ "video",
71
+ "audio",
72
+ "blob",
54
73
  "video-editing",
55
74
  "video-editor",
75
+ "video-manipulation",
56
76
  "browser",
57
- "api-driven"
77
+ "nodejs",
78
+ "api-driven",
79
+ "etro"
58
80
  ],
59
81
  "author": "Caleb Sacks (https://calebsacks.me)",
60
82
  "license": "GPL-3.0",
package/rollup.config.js CHANGED
@@ -1,17 +1,28 @@
1
1
  // import uglify from "rollup-plugin-uglify-es";
2
+ import cleaner from 'rollup-plugin-cleaner'
2
3
  import resolve from 'rollup-plugin-node-resolve'
4
+ import typescript from 'rollup-plugin-typescript2'
3
5
 
4
6
  export default [
5
7
  // iife bundle
6
8
  {
7
- input: 'src/index.js',
9
+ input: 'src/index.ts',
8
10
  output: { file: 'dist/etro-iife.js', format: 'iife', name: 'etro' },
9
- plugins: [resolve()]
11
+ plugins: [
12
+ cleaner({
13
+ targets: ['dist']
14
+ }),
15
+ typescript(),
16
+ resolve()
17
+ ]
10
18
  },
11
19
  {
12
- input: 'src/index.js',
20
+ input: 'src/index.ts',
13
21
  output: { file: 'dist/etro-cjs.js', format: 'cjs' },
14
- plugins: [resolve()]
22
+ plugins: [
23
+ typescript(),
24
+ resolve()
25
+ ]
15
26
  }
16
27
  // // es6 module bundle
17
28
  // {
@@ -50,12 +50,14 @@
50
50
  buffer.height = original.height
51
51
  const ctx = buffer.getContext('2d')
52
52
  ctx.drawImage(original, 0, 0)
53
-
54
- // do effect
55
- effect.apply({
53
+ const movie = {
56
54
  canvas: buffer, cctx: ctx,
57
55
  width: original.width, height: original.height
58
- })
56
+ }
57
+ // for util.cache()
58
+ effect._target = { movie }
59
+ // Run effect
60
+ effect.apply(movie)
59
61
 
60
62
  save(buffer, path)
61
63
  }
@@ -65,34 +67,33 @@
65
67
  save(original, 'original.png')
66
68
 
67
69
  const samples = {
68
- 'gaussian-blur-horizontal.png': new etro.effect.GaussianBlurHorizontal(5),
69
- 'gaussian-blur-vertical.png': new etro.effect.GaussianBlurVertical(5),
70
- 'pixelate.png': new etro.effect.Pixelate(3),
71
- 'transform/translate.png': new etro.effect.Transform(
72
- new etro.effect.Transform.Matrix().translate(-3, 5)
73
- ),
74
- 'transform/translate-fraction.png': new etro.effect.Transform(
75
- new etro.effect.Transform.Matrix().translate(0.5, 0.5)
76
- ),
77
- 'transform/scale.png': new etro.effect.Transform(
78
- new etro.effect.Transform.Matrix().scale(2, 2)
79
- ),
80
- 'transform/scale-fraction.png': new etro.effect.Transform(
81
- new etro.effect.Transform.Matrix().scale(0.5, 0.5)
82
- ),
83
- 'transform/rotate.png': new etro.effect.Transform(
84
- new etro.effect.Transform.Matrix().rotate(Math.PI / 6)
85
- ),
86
- 'transform/multiply.png': new etro.effect.Transform(
87
- new etro.effect.Transform.Matrix().scale(2, 2)
70
+ 'gaussian-blur-horizontal.png': new etro.effect.GaussianBlurHorizontal({ radius: 5 }),
71
+ 'gaussian-blur-vertical.png': new etro.effect.GaussianBlurVertical({ radius: 5 }),
72
+ 'grayscale.png': new etro.effect.Grayscale(),
73
+ 'pixelate.png': new etro.effect.Pixelate({ pixelSize: 3 }),
74
+ 'transform/translate.png': new etro.effect.Transform({
75
+ matrix: new etro.effect.Transform.Matrix().translate(-3, 5)
76
+ }),
77
+ 'transform/scale.png': new etro.effect.Transform({
78
+ matrix: new etro.effect.Transform.Matrix().scale(2, 2)
79
+ }),
80
+ 'transform/scale-fraction.png': new etro.effect.Transform({
81
+ matrix: new etro.effect.Transform.Matrix().scale(0.5, 0.5)
82
+ }),
83
+ 'transform/rotate.png': new etro.effect.Transform({
84
+ matrix: new etro.effect.Transform.Matrix().rotate(Math.PI / 6)
85
+ }),
86
+ 'transform/multiply.png': new etro.effect.Transform({
87
+ matrix: new etro.effect.Transform.Matrix().scale(2, 2)
88
88
  .multiply(new etro.effect.Transform.Matrix().translate(-3, 5))
89
- )
89
+ })
90
90
  }
91
91
 
92
92
  for (let path in samples) {
93
93
  const effect = samples[path]
94
94
  saveSample(original, effect, path)
95
95
  }
96
+ window.done = true
96
97
  }
97
98
  </script>
98
99
  </body>
@@ -23,21 +23,20 @@ function createDirs(filePath) {
23
23
  const browser = await puppeteer.launch()
24
24
  const page = await browser.newPage()
25
25
 
26
- page.on('load', async () => {
27
- // console.log(await page.$$('p'));
28
- const items = await page.$$eval('p', elems => elems.map(p => {
29
- return { data: p.innerHTML, path: p.dataset.path }
30
- }))
26
+ await page.goto(`file://${__dirname}/gen-effect-samples.html`)
27
+ await page.waitForFunction(() => window.done);
28
+
29
+ const items = await page.$$eval('p', elems => elems.map(p => {
30
+ return { data: p.innerHTML, path: p.dataset.path }
31
+ }))
31
32
 
32
- items.forEach(item => {
33
- // remove prefix and save to png
34
- const buffer = Buffer.from(item.data.replace(/^data:image\/png;base64,/, ''), 'base64')
35
- console.log(`writing ${item.path} ...`)
36
- const path = projectDir + '/spec/assets/effect/' + item.path
37
- createDirs(path)
38
- fs.writeFileSync(path, buffer)
39
- })
40
- await browser.close()
33
+ items.forEach(item => {
34
+ // remove prefix and save to png
35
+ const buffer = Buffer.from(item.data.replace(/^data:image\/png;base64,/, ''), 'base64')
36
+ console.log(`writing ${item.path} ...`)
37
+ const path = projectDir + '/spec/assets/effect/' + item.path
38
+ createDirs(path)
39
+ fs.writeFileSync(path, buffer)
41
40
  })
42
- await page.goto(`file://${__dirname}/gen-effect-samples.html`)
41
+ await browser.close()
43
42
  })()
package/ship.config.js ADDED
@@ -0,0 +1,80 @@
1
+ const { parser } = require('keep-a-changelog')
2
+ const fs = require('fs')
3
+ const semver = require('semver')
4
+
5
+ module.exports = {
6
+ updateChangelog: false,
7
+ formatCommitMessage: ({ version }) => `Release v${version}`,
8
+ formatPullRequestTitle: ({ version }) => `Release v${version}`,
9
+ getNextVersion: ({ currentVersion, dir }) => {
10
+ const changelog = new Changelog(`${dir}/CHANGELOG.md`)
11
+ return changelog.nextVersion(currentVersion)
12
+ },
13
+ versionUpdated: async ({ version, _releaseType, dir, _exec }) => {
14
+ const parsedVersion = semver.parse(version)
15
+ if (parsedVersion.prerelease.length)
16
+ return
17
+
18
+ // Release 'Unreleased' section in changelog
19
+ const changelogFile = `${dir}/CHANGELOG.md`
20
+ const oldChangelog = fs.readFileSync(changelogFile, 'utf8')
21
+ const parsed = parser(oldChangelog)
22
+ const release = parsed.findRelease() // get 'Unreleased' section
23
+ release.setVersion(version) // release
24
+ release.setDate(new Date()) // today
25
+ const newChangelog = parsed.toString()
26
+ fs.writeFileSync(changelogFile, newChangelog, 'utf8')
27
+ }
28
+ }
29
+
30
+ class Changelog {
31
+ constructor (path) {
32
+ const data = fs.readFileSync(path, 'utf8')
33
+ const lines = data.split(/\r?\n/)
34
+ const headings = []
35
+ let unreleased = false
36
+
37
+ this.releaseTag = 'latest'
38
+ lines.every((line) => {
39
+ if (line.startsWith('## [Unreleased]')) {
40
+ unreleased = true
41
+ const tagMatch = line.match(/## \[Unreleased\]\[(.*)\]/)
42
+ if (tagMatch)
43
+ this.releaseTag = tagMatch[1].trim()
44
+ } else if (line.startsWith('## ')) {
45
+ return false
46
+ }
47
+
48
+ if (unreleased)
49
+ if (line.startsWith('### ')) {
50
+ headings.push(line.match(/### (.*)/)[1].trim())
51
+ }
52
+
53
+ return true
54
+ })
55
+
56
+ if (headings.includes('Changed'))
57
+ this.releaseType = 'major'
58
+ else if (headings.includes('Added'))
59
+ this.releaseType = 'minor'
60
+ else
61
+ this.releaseType = 'patch'
62
+ }
63
+
64
+ nextVersion (version) {
65
+ const parsedVersion = semver.parse(version)
66
+
67
+ if (this.releaseTag !== 'latest')
68
+ if (parsedVersion.prerelease.length) {
69
+ parsedVersion.inc('prerelease', this.releaseTag)
70
+ } else {
71
+ parsedVersion.inc(this.releaseType)
72
+ parsedVersion.prerelease = [this.releaseTag, 0]
73
+ parsedVersion.format()
74
+ }
75
+ else
76
+ parsedVersion.inc(this.releaseType)
77
+
78
+ return parsedVersion.version
79
+ }
80
+ }
@@ -0,0 +1,115 @@
1
+ import { watchPublic } from '../util'
2
+ import { publish, subscribe } from '../event'
3
+ import { Movie } from '../movie'
4
+ import { Visual } from '../layer/index'
5
+ import BaseObject from '../object'
6
+
7
+ /**
8
+ * Modifies the visual contents of a layer.
9
+ */
10
+ export class Base implements BaseObject {
11
+ type: string
12
+ publicExcludes: string[]
13
+ propertyFilters: Record<string, <T>(value: T) => T>
14
+
15
+ enabled: boolean
16
+
17
+ private _target: Movie | Visual
18
+ /**
19
+ * The number of times this effect has been attached to a target minus the
20
+ * number of times it's been detached. (Used for the target's array proxy with
21
+ * `unshift`)
22
+ */
23
+ private _occurrenceCount: number
24
+
25
+ constructor () {
26
+ const newThis = watchPublic(this) as Base // proxy that will be returned by constructor
27
+
28
+ newThis.enabled = true
29
+ newThis._occurrenceCount = 0
30
+ newThis._target = null
31
+
32
+ // Propogate up to target
33
+ subscribe(newThis, 'effect.change.modify', event => {
34
+ if (!newThis._target)
35
+ return
36
+
37
+ const type = `${newThis._target.type}.change.effect.modify`
38
+ publish(newThis._target, type, { ...event, target: newThis._target, source: newThis, type })
39
+ })
40
+
41
+ return newThis
42
+ }
43
+
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
+
52
+ this._occurrenceCount++
53
+ }
54
+
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)
68
+ throw new Error('No movie to detach from')
69
+
70
+ this._occurrenceCount--
71
+ // If this effect occurs in another place in the containing array, do not
72
+ // unset _target. (For calling `unshift` on the `layers` proxy)
73
+ if (this._occurrenceCount === 0)
74
+ this.detach()
75
+ }
76
+
77
+ detach (): void {
78
+ this._target = null
79
+ }
80
+
81
+ // subclasses must implement apply
82
+ /**
83
+ * Apply this effect to a target at the given time
84
+ *
85
+ * @param target
86
+ * @param reltime - the movie's current time relative to the layer
87
+ * (will soon be replaced with an instance getter)
88
+ * @abstract
89
+ */
90
+ apply (target: Movie | Visual, reltime: number): void {} // eslint-disable-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
91
+
92
+ /**
93
+ * The current time of the target
94
+ */
95
+ get currentTime (): number {
96
+ return this._target ? this._target.currentTime : undefined
97
+ }
98
+
99
+ get parent (): Movie | Visual {
100
+ return this._target
101
+ }
102
+
103
+ get movie (): Movie {
104
+ return this._target ? this._target.movie : undefined
105
+ }
106
+
107
+ getDefaultOptions (): Record<string, unknown> {
108
+ return {}
109
+ }
110
+ }
111
+ // id for events (independent of instance, but easy to access when on prototype
112
+ // chain)
113
+ Base.prototype.type = 'effect'
114
+ Base.prototype.publicExcludes = []
115
+ Base.prototype.propertyFilters = {}