etro 0.12.1 → 0.14.0
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/dependabot.yml +6 -0
- package/.github/scripts/update-changelog.js +72 -0
- package/.github/workflows/dependabot-changelog.yml +57 -0
- package/.github/workflows/nodejs.yml +6 -2
- package/.github/workflows/shipjs-trigger.yml +2 -1
- package/.husky/pre-commit +1 -1
- package/AGENTS.md +106 -0
- package/CHANGELOG.md +46 -0
- package/CONTRIBUTING.md +5 -5
- package/README.md +8 -7
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/base.css +224 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/block-navigation.js +87 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/favicon.png +0 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/index.html +161 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/prettify.css +1 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/prettify.js +2 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/sorter.js +196 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/custom-array.ts.html +214 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/base.ts.html +481 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/brightness.ts.html +214 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/channels.ts.html +235 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/chroma-key.ts.html +331 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/contrast.ts.html +211 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/elliptical-mask.ts.html +310 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/gaussian-blur.ts.html +796 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/grayscale.ts.html +187 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/index.html +311 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/index.ts.html +154 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/pixelate.ts.html +259 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/shader.ts.html +1774 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/stack.ts.html +358 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/transform.ts.html +685 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/effect/visual.ts.html +148 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/etro.ts.html +163 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/event.ts.html +691 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/index.html +176 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/index.ts.html +109 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/layer/audio-source.ts.html +835 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/layer/audio.ts.html +241 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/layer/base.ts.html +826 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/layer/image.ts.html +181 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/layer/index.html +236 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/layer/index.ts.html +124 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/layer/text.ts.html +658 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/layer/video.ts.html +211 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/layer/visual-source.ts.html +721 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/layer/visual.ts.html +760 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/movie/effects.ts.html +163 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/movie/index.html +161 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/movie/index.ts.html +88 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/movie/layers.ts.html +163 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/movie/movie.ts.html +3037 -0
- package/coverage/Chrome Headless 148.0.0.0 (Mac OS 10.15.7)/html/src/util.ts.html +1765 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/base.css +224 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/block-navigation.js +87 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/favicon.png +0 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/index.html +161 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/prettify.css +1 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/prettify.js +2 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/sort-arrow-sprite.png +0 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/sorter.js +196 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/custom-array.ts.html +214 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/base.ts.html +481 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/brightness.ts.html +214 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/channels.ts.html +235 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/chroma-key.ts.html +331 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/contrast.ts.html +211 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/elliptical-mask.ts.html +310 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/gaussian-blur.ts.html +796 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/grayscale.ts.html +187 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/index.html +311 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/index.ts.html +154 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/pixelate.ts.html +259 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/shader.ts.html +1774 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/stack.ts.html +358 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/transform.ts.html +685 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/effect/visual.ts.html +148 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/etro.ts.html +163 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/event.ts.html +691 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/index.html +176 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/index.ts.html +109 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/layer/audio-source.ts.html +835 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/layer/audio.ts.html +241 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/layer/base.ts.html +826 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/layer/image.ts.html +181 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/layer/index.html +236 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/layer/index.ts.html +124 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/layer/text.ts.html +658 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/layer/video.ts.html +211 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/layer/visual-source.ts.html +721 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/layer/visual.ts.html +760 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/movie/effects.ts.html +163 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/movie/index.html +161 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/movie/index.ts.html +88 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/movie/layers.ts.html +163 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/movie/movie.ts.html +3037 -0
- package/coverage/Firefox 151.0 (Mac OS 10.15)/html/src/util.ts.html +1765 -0
- package/dist/custom-array.d.ts +10 -10
- package/dist/effect/base.d.ts +61 -60
- package/dist/effect/brightness.d.ts +16 -16
- package/dist/effect/channels.d.ts +23 -23
- package/dist/effect/chroma-key.d.ts +23 -23
- package/dist/effect/contrast.d.ts +15 -15
- package/dist/effect/elliptical-mask.d.ts +31 -31
- package/dist/effect/gaussian-blur.d.ts +60 -60
- package/dist/effect/grayscale.d.ts +7 -7
- package/dist/effect/index.d.ts +16 -16
- package/dist/effect/pixelate.d.ts +18 -18
- package/dist/effect/shader.d.ts +109 -109
- package/dist/effect/stack.d.ts +27 -27
- package/dist/effect/transform.d.ts +73 -73
- package/dist/effect/visual.d.ts +17 -17
- package/dist/etro-cjs.js +3601 -3556
- package/dist/etro-iife.js +3602 -3557
- package/dist/etro.d.ts +7 -7
- package/dist/event.d.ts +40 -40
- package/dist/index.d.ts +6 -6
- package/dist/layer/audio-source.d.ts +28 -28
- package/dist/layer/audio.d.ts +27 -27
- package/dist/layer/base.d.ts +129 -128
- package/dist/layer/image.d.ts +20 -20
- package/dist/layer/index.d.ts +11 -11
- package/dist/layer/text.d.ts +78 -78
- package/dist/layer/video.d.ts +23 -23
- package/dist/layer/visual-source.d.ts +47 -47
- package/dist/layer/visual.d.ts +62 -62
- package/dist/movie/effects.d.ts +6 -6
- package/dist/movie/index.d.ts +1 -1
- package/dist/movie/layers.d.ts +6 -6
- package/dist/movie/movie.d.ts +280 -277
- package/dist/object.d.ts +19 -19
- package/dist/util.d.ts +128 -121
- package/karma.conf.js +70 -3
- package/package.json +14 -17
- package/ship.config.js +9 -11
- package/src/effect/base.ts +16 -0
- package/src/effect/shader.ts +1 -1
- package/src/layer/base.ts +19 -1
- package/src/movie/movie.ts +123 -8
- package/src/util.ts +116 -3
- package/tsconfig.json +3 -2
- package/.husky/commit-msg +0 -4
- package/.husky/prepare-commit-msg +0 -11
- package/commitlint.config.ts +0 -39
package/src/movie/movie.ts
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { publish, deprecate } from '../event'
|
|
6
|
-
import { Dynamic, val, clearCachedValues, applyOptions, Color, parseColor } from '../util'
|
|
6
|
+
import { Dynamic, val, clearCachedValues, applyOptions, Color, parseColor, serializeProperty, deserializeProperty } from '../util'
|
|
7
7
|
import { Base as BaseLayer, Audio as AudioLayer, Video as VideoLayer, Visual } from '../layer/index' // `Media` mixins
|
|
8
8
|
import { Base as BaseEffect } from '../effect/index'
|
|
9
|
+
import * as Layers from '../layer/index'
|
|
10
|
+
import * as Effects from '../effect/index'
|
|
9
11
|
import { MovieEffects } from './effects'
|
|
10
12
|
import { MovieLayers } from './layers'
|
|
11
13
|
|
|
@@ -124,12 +126,13 @@ export class Movie {
|
|
|
124
126
|
* Plays the movie
|
|
125
127
|
*
|
|
126
128
|
* @param [options]
|
|
129
|
+
* @param [options.onDraw] Called when the current frame is drawn to the canvas
|
|
127
130
|
* @param [options.onStart] Called when the movie starts playing
|
|
128
131
|
* @param [options.duration] The duration of the movie to play in seconds
|
|
129
|
-
*
|
|
130
132
|
* @return Fulfilled when the movie is done playing, never fails
|
|
131
133
|
*/
|
|
132
134
|
async play (options: {
|
|
135
|
+
onDraw?: () => void,
|
|
133
136
|
onStart?: () => void,
|
|
134
137
|
duration?: number,
|
|
135
138
|
} = {}): Promise<void> {
|
|
@@ -152,7 +155,7 @@ export class Movie {
|
|
|
152
155
|
await new Promise<void>(resolve => {
|
|
153
156
|
if (!this.renderingFrame) {
|
|
154
157
|
// Not rendering (and not playing), so play.
|
|
155
|
-
this._render(undefined, resolve)
|
|
158
|
+
this._render(undefined, resolve, options.onDraw)
|
|
156
159
|
}
|
|
157
160
|
|
|
158
161
|
// Stop rendering frame if currently doing so, because playing has higher
|
|
@@ -181,7 +184,7 @@ export class Movie {
|
|
|
181
184
|
* Streams the movie to a MediaStream
|
|
182
185
|
*
|
|
183
186
|
* @param options Options for the stream
|
|
184
|
-
* @param options.frameRate The frame rate of the stream's video
|
|
187
|
+
* @param options.frameRate The maximum frame rate of the stream's video
|
|
185
188
|
* @param options.duration The duration of the stream in seconds
|
|
186
189
|
* @param options.video Whether to stream video. Defaults to true.
|
|
187
190
|
* @param options.audio Whether to stream audio. Defaults to true.
|
|
@@ -264,7 +267,7 @@ export class Movie {
|
|
|
264
267
|
* Plays the movie in the background and records it
|
|
265
268
|
*
|
|
266
269
|
* @param options
|
|
267
|
-
* @param [options.frameRate] -
|
|
270
|
+
* @param [options.frameRate] - Maximum video frame rate (fps)
|
|
268
271
|
* @param [options.video=true] - whether to include video in recording
|
|
269
272
|
* @param [options.audio=true] - whether to include audio in recording
|
|
270
273
|
* @param [options.mediaRecorderOptions=undefined] - Options to pass to the
|
|
@@ -399,10 +402,10 @@ export class Movie {
|
|
|
399
402
|
* Processes one frame of the movie and draws it to the canvas
|
|
400
403
|
*
|
|
401
404
|
* @param [timestamp=performance.now()]
|
|
402
|
-
* @param [done=undefined] - Called when done playing or when the current
|
|
403
|
-
* frame is
|
|
405
|
+
* @param [done=undefined] - Called when done playing or when the current frame is loaded
|
|
406
|
+
* @param [onFrameRender=undefined] - Called when the current frame is rendered
|
|
404
407
|
*/
|
|
405
|
-
private _render (timestamp = performance.now(), done = undefined) {
|
|
408
|
+
private _render (timestamp = performance.now(), done = undefined, onFrameRender = undefined) {
|
|
406
409
|
clearCachedValues(this)
|
|
407
410
|
|
|
408
411
|
if (!this.rendering) {
|
|
@@ -482,6 +485,7 @@ export class Movie {
|
|
|
482
485
|
this._renderBackground(timestamp)
|
|
483
486
|
this._renderLayers()
|
|
484
487
|
this._applyEffects()
|
|
488
|
+
onFrameRender?.()
|
|
485
489
|
} else {
|
|
486
490
|
// If we are recording, pause the media recorder until the movie is
|
|
487
491
|
// ready.
|
|
@@ -852,6 +856,117 @@ export class Movie {
|
|
|
852
856
|
repeat: false
|
|
853
857
|
}
|
|
854
858
|
}
|
|
859
|
+
|
|
860
|
+
toJSON (): object {
|
|
861
|
+
return {
|
|
862
|
+
type: 'movie',
|
|
863
|
+
canvas: this.canvas ? { width: this.canvas.width, height: this.canvas.height } : undefined,
|
|
864
|
+
background: serializeProperty(this.background),
|
|
865
|
+
repeat: this.repeat,
|
|
866
|
+
layers: this.layers.map(layer => (layer as any).toJSON()),
|
|
867
|
+
effects: this.effects.map(effect => (effect as any).toJSON())
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
static fromJSON (json: any, canvas?: HTMLCanvasElement, actx?: AudioContext): Movie {
|
|
872
|
+
if (!canvas) {
|
|
873
|
+
canvas = document.createElement('canvas')
|
|
874
|
+
if (json.canvas) {
|
|
875
|
+
canvas.width = json.canvas.width
|
|
876
|
+
canvas.height = json.canvas.height
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
const options: any = {
|
|
880
|
+
canvas,
|
|
881
|
+
actx,
|
|
882
|
+
background: deserializeProperty(json.background),
|
|
883
|
+
repeat: json.repeat
|
|
884
|
+
}
|
|
885
|
+
const movie = new Movie(options)
|
|
886
|
+
|
|
887
|
+
const deserializeEffect = (effectJson: any): any => {
|
|
888
|
+
const type = effectJson.type.replace('effect.', '')
|
|
889
|
+
const EffectClass = (Effects as any)[type]
|
|
890
|
+
if (!EffectClass) {
|
|
891
|
+
throw new Error(`Unknown effect type: ${type}`)
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
const effectOptions: any = {}
|
|
895
|
+
const defaultOptions = EffectClass.prototype.getDefaultOptions ? EffectClass.prototype.getDefaultOptions() : {}
|
|
896
|
+
|
|
897
|
+
for (const key in effectJson) {
|
|
898
|
+
if (key !== 'type' && key !== 'effects') {
|
|
899
|
+
if (key in defaultOptions) {
|
|
900
|
+
effectOptions[key] = deserializeProperty(effectJson[key])
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
if (effectJson.effects) {
|
|
906
|
+
effectOptions.effects = effectJson.effects.map((subEffectJson: any) => deserializeEffect(subEffectJson))
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
const effect = new EffectClass(effectOptions)
|
|
910
|
+
for (const key in effectJson) {
|
|
911
|
+
if (key !== 'type' && key !== 'effects' && !(key in defaultOptions)) {
|
|
912
|
+
effect[key] = deserializeProperty(effectJson[key])
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
return effect
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
const deserializeLayer = (layerJson: any): any => {
|
|
919
|
+
const type = layerJson.type.replace('layer.', '')
|
|
920
|
+
const LayerClass = (Layers as any)[type]
|
|
921
|
+
if (!LayerClass) {
|
|
922
|
+
throw new Error(`Unknown layer type: ${type}`)
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
const layerOptions: any = {}
|
|
926
|
+
const defaultOptions = LayerClass.prototype.getDefaultOptions ? LayerClass.prototype.getDefaultOptions() : {}
|
|
927
|
+
if (!('startTime' in defaultOptions)) {
|
|
928
|
+
defaultOptions.startTime = undefined
|
|
929
|
+
}
|
|
930
|
+
if (!('duration' in defaultOptions)) {
|
|
931
|
+
defaultOptions.duration = undefined
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
for (const key in layerJson) {
|
|
935
|
+
if (key !== 'type' && key !== 'effects') {
|
|
936
|
+
if (key in defaultOptions) {
|
|
937
|
+
layerOptions[key] = deserializeProperty(layerJson[key])
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
const layer = new LayerClass(layerOptions)
|
|
943
|
+
for (const key in layerJson) {
|
|
944
|
+
if (key !== 'type' && key !== 'effects' && !(key in defaultOptions)) {
|
|
945
|
+
layer[key] = deserializeProperty(layerJson[key])
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
if (layerJson.effects) {
|
|
949
|
+
for (const effectJson of layerJson.effects) {
|
|
950
|
+
layer.addEffect(deserializeEffect(effectJson))
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
return layer
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
if (json.layers) {
|
|
957
|
+
for (const layerJson of json.layers) {
|
|
958
|
+
movie.addLayer(deserializeLayer(layerJson))
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
if (json.effects) {
|
|
963
|
+
for (const effectJson of json.effects) {
|
|
964
|
+
movie.addEffect(deserializeEffect(effectJson))
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
return movie
|
|
969
|
+
}
|
|
855
970
|
}
|
|
856
971
|
|
|
857
972
|
// Id for events
|
package/src/util.ts
CHANGED
|
@@ -91,6 +91,13 @@ export function clearCachedValues (movie: Movie): void {
|
|
|
91
91
|
valCache.delete(movie)
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
type Interpolate = <U = number | object>(
|
|
95
|
+
startValue: U,
|
|
96
|
+
endValue: U,
|
|
97
|
+
percentProgress: number,
|
|
98
|
+
interpolationKeys: string[]
|
|
99
|
+
) => U
|
|
100
|
+
|
|
94
101
|
/**
|
|
95
102
|
* A keyframe set.
|
|
96
103
|
*
|
|
@@ -101,7 +108,7 @@ export function clearCachedValues (movie: Movie): void {
|
|
|
101
108
|
* TypeScript users need to specify the type of the value as a type parameter.
|
|
102
109
|
*/
|
|
103
110
|
export class KeyFrame<T> {
|
|
104
|
-
value:
|
|
111
|
+
value: (number|T|Interpolate)[][]
|
|
105
112
|
/** Keys to interpolate, or all keys if undefined */
|
|
106
113
|
interpolationKeys: string[]
|
|
107
114
|
|
|
@@ -115,6 +122,25 @@ export class KeyFrame<T> {
|
|
|
115
122
|
return this
|
|
116
123
|
}
|
|
117
124
|
|
|
125
|
+
toJSON (): object {
|
|
126
|
+
return {
|
|
127
|
+
type: 'KeyFrame',
|
|
128
|
+
value: this.value.map(point => {
|
|
129
|
+
const out: any[] = [point[0], serializeProperty(point[1])]
|
|
130
|
+
if (point.length === 3) {
|
|
131
|
+
const interp = point[2] as Interpolate
|
|
132
|
+
if (interp === linearInterp) {
|
|
133
|
+
out.push('linear')
|
|
134
|
+
} else if (interp === cosineInterp) {
|
|
135
|
+
out.push('cosine')
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return out
|
|
139
|
+
}),
|
|
140
|
+
interpolationKeys: this.interpolationKeys
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
118
144
|
evaluate (time: number): T {
|
|
119
145
|
if (this.value.length === 0) {
|
|
120
146
|
throw new Error('Empty keyframe')
|
|
@@ -133,8 +159,10 @@ export class KeyFrame<T> {
|
|
|
133
159
|
for (let i = 0; i < this.value.length; i++) {
|
|
134
160
|
const startTime = this.value[i][0] as number
|
|
135
161
|
const startValue = this.value[i][1] as T
|
|
136
|
-
|
|
137
|
-
|
|
162
|
+
const interpolate =
|
|
163
|
+
this.value[i].length === 3
|
|
164
|
+
? (this.value[i][2] as Interpolate)
|
|
165
|
+
: linearInterp
|
|
138
166
|
if (i + 1 < this.value.length) {
|
|
139
167
|
const endTime = this.value[i + 1][0] as number
|
|
140
168
|
const endValue = this.value[i + 1][1] as T
|
|
@@ -313,6 +341,10 @@ export class Color {
|
|
|
313
341
|
toString (): string {
|
|
314
342
|
return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a})`
|
|
315
343
|
}
|
|
344
|
+
|
|
345
|
+
toJSON (): object {
|
|
346
|
+
return { type: 'Color', r: this.r, g: this.g, b: this.b, a: this.a }
|
|
347
|
+
}
|
|
316
348
|
}
|
|
317
349
|
|
|
318
350
|
const parseColorCanvas = document.createElement('canvas')
|
|
@@ -389,6 +421,20 @@ export class Font {
|
|
|
389
421
|
|
|
390
422
|
return s
|
|
391
423
|
}
|
|
424
|
+
|
|
425
|
+
toJSON (): object {
|
|
426
|
+
return {
|
|
427
|
+
type: 'Font',
|
|
428
|
+
size: this.size,
|
|
429
|
+
sizeUnit: this.sizeUnit,
|
|
430
|
+
family: this.family,
|
|
431
|
+
style: this.style,
|
|
432
|
+
variant: this.variant,
|
|
433
|
+
weight: this.weight,
|
|
434
|
+
stretch: this.stretch,
|
|
435
|
+
lineHeight: this.lineHeight
|
|
436
|
+
}
|
|
437
|
+
}
|
|
392
438
|
}
|
|
393
439
|
|
|
394
440
|
const parseFontEl = document.createElement('div')
|
|
@@ -445,3 +491,70 @@ export function mapPixels (
|
|
|
445
491
|
ctx.putImageData(frame, x, y)
|
|
446
492
|
}
|
|
447
493
|
}
|
|
494
|
+
|
|
495
|
+
export function serializeProperty (val: any): any {
|
|
496
|
+
if (val && typeof val === 'object') {
|
|
497
|
+
if (typeof val.toJSON === 'function') {
|
|
498
|
+
return val.toJSON()
|
|
499
|
+
}
|
|
500
|
+
if (Array.isArray(val)) {
|
|
501
|
+
return val.map(serializeProperty)
|
|
502
|
+
}
|
|
503
|
+
if (val instanceof HTMLImageElement || val instanceof HTMLVideoElement || val instanceof HTMLAudioElement) {
|
|
504
|
+
// It's a DOM element serving as a media source
|
|
505
|
+
return val.getAttribute('src') || val.src
|
|
506
|
+
}
|
|
507
|
+
// plain object
|
|
508
|
+
if (val.constructor === Object) {
|
|
509
|
+
const out: any = {}
|
|
510
|
+
for (const k in val) {
|
|
511
|
+
if (Object.prototype.hasOwnProperty.call(val, k)) {
|
|
512
|
+
out[k] = serializeProperty(val[k])
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return out
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return val
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
export function deserializeProperty (val: any): any {
|
|
522
|
+
if (val && typeof val === 'object') {
|
|
523
|
+
if (Array.isArray(val)) {
|
|
524
|
+
return val.map(deserializeProperty)
|
|
525
|
+
}
|
|
526
|
+
if (val.type === 'Color') {
|
|
527
|
+
return new Color(val.r, val.g, val.b, val.a)
|
|
528
|
+
}
|
|
529
|
+
if (val.type === 'Font') {
|
|
530
|
+
return new Font(val.size, val.sizeUnit, val.family, val.style, val.variant, val.weight, val.stretch, val.lineHeight)
|
|
531
|
+
}
|
|
532
|
+
if (val.type === 'KeyFrame') {
|
|
533
|
+
const kf = new KeyFrame()
|
|
534
|
+
kf.value = val.value.map((point: any[]) => {
|
|
535
|
+
const out: any[] = [point[0], deserializeProperty(point[1])]
|
|
536
|
+
if (point.length === 3) {
|
|
537
|
+
if (point[2] === 'linear') {
|
|
538
|
+
out.push(linearInterp)
|
|
539
|
+
} else if (point[2] === 'cosine') {
|
|
540
|
+
out.push(cosineInterp)
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return out
|
|
544
|
+
})
|
|
545
|
+
kf.interpolationKeys = val.interpolationKeys
|
|
546
|
+
return kf
|
|
547
|
+
}
|
|
548
|
+
// plain object
|
|
549
|
+
if (val.constructor === Object) {
|
|
550
|
+
const out: any = {}
|
|
551
|
+
for (const k in val) {
|
|
552
|
+
if (Object.prototype.hasOwnProperty.call(val, k)) {
|
|
553
|
+
out[k] = deserializeProperty(val[k])
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return out
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
return val
|
|
560
|
+
}
|
package/tsconfig.json
CHANGED
package/.husky/commit-msg
DELETED
package/commitlint.config.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type {UserConfig} from '@commitlint/types';
|
|
2
|
-
import { RuleConfigSeverity } from "@commitlint/types";
|
|
3
|
-
|
|
4
|
-
const Configuration: UserConfig = {
|
|
5
|
-
/*
|
|
6
|
-
* Resolve and load @commitlint/format from node_modules.
|
|
7
|
-
* Referenced package must be installed
|
|
8
|
-
*/
|
|
9
|
-
formatter: '@commitlint/format',
|
|
10
|
-
/*
|
|
11
|
-
* Any rules defined here will override the default ones
|
|
12
|
-
*/
|
|
13
|
-
rules: {
|
|
14
|
-
'header-max-length': [RuleConfigSeverity.Error, 'always', 72],
|
|
15
|
-
'body-max-line-length': [RuleConfigSeverity.Error, 'always', 72],
|
|
16
|
-
},
|
|
17
|
-
/*
|
|
18
|
-
* Functions that return true if commitlint should ignore the given message.
|
|
19
|
-
*/
|
|
20
|
-
ignores: [(commit) => commit === ''],
|
|
21
|
-
/*
|
|
22
|
-
* Whether commitlint uses the default ignore rules.
|
|
23
|
-
*/
|
|
24
|
-
defaultIgnores: true,
|
|
25
|
-
/*
|
|
26
|
-
* Custom URL to show upon failure
|
|
27
|
-
*/
|
|
28
|
-
helpUrl:
|
|
29
|
-
'https://github.com/conventional-changelog/commitlint/#what-is-commitlint',
|
|
30
|
-
/*
|
|
31
|
-
* Custom prompt configs
|
|
32
|
-
*/
|
|
33
|
-
prompt: {
|
|
34
|
-
messages: {},
|
|
35
|
-
questions: {},
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
module.exports = Configuration;
|