etro 0.8.5 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/nodejs.yml +1 -1
- package/CHANGELOG.md +27 -0
- package/CONTRIBUTING.md +13 -26
- package/README.md +8 -15
- package/dist/effect/base.d.ts +5 -5
- package/dist/effect/visual.d.ts +11 -0
- package/dist/etro-cjs.js +84 -53
- package/dist/etro-iife.js +84 -53
- package/dist/layer/image.d.ts +2 -2
- package/dist/layer/text.d.ts +3 -3
- package/dist/layer/visual-source.d.ts +18 -3
- package/dist/layer/visual.d.ts +5 -5
- package/dist/movie.d.ts +13 -4
- package/dist/object.d.ts +5 -1
- package/dist/util.d.ts +2 -0
- package/eslint.conf.js +2 -0
- package/eslint.test-conf.js +1 -2
- package/karma.conf.js +17 -8
- package/package.json +19 -19
- package/scripts/gen-effect-samples.html +24 -0
- package/scripts/save-effect-samples.js +1 -1
- package/src/effect/base.ts +6 -6
- package/src/effect/stack.ts +2 -2
- package/src/effect/transform.ts +2 -2
- package/src/effect/visual.ts +16 -1
- package/src/layer/audio-source.ts +4 -1
- package/src/layer/base.ts +3 -2
- package/src/layer/image.ts +3 -3
- package/src/layer/text.ts +4 -4
- package/src/layer/visual-source.ts +27 -7
- package/src/layer/visual.ts +7 -7
- package/src/movie.ts +55 -37
- package/src/object.ts +5 -1
- package/src/util.ts +2 -0
- package/tsconfig.json +3 -1
- package/examples/application/readme-screenshot.html +0 -85
- package/examples/application/video-player.html +0 -130
- package/examples/application/webcam.html +0 -28
- package/examples/introduction/audio.html +0 -64
- package/examples/introduction/effects.html +0 -79
- package/examples/introduction/export.html +0 -83
- package/examples/introduction/functions.html +0 -37
- package/examples/introduction/hello-world1.html +0 -37
- package/examples/introduction/hello-world2.html +0 -32
- package/examples/introduction/keyframes.html +0 -79
- package/examples/introduction/media.html +0 -63
- package/examples/introduction/text.html +0 -31
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [0.9.1] - 2022-09-18
|
|
9
|
+
### Fixed
|
|
10
|
+
- Update color types from `string` to `Color` ([#135](https://github.com/etro-js/etro/pull/135)).
|
|
11
|
+
- `Image` and `Video` classes now include missing properties.
|
|
12
|
+
- `Movie#currentTime` no longer exceeds the stop time.
|
|
13
|
+
|
|
14
|
+
## [0.9.0] - 2022-07-17
|
|
15
|
+
### Changed
|
|
16
|
+
- Methods in the `Base` effect now accept `Base` layers instead of `Visual` layers.
|
|
17
|
+
|
|
18
|
+
### Deprecated
|
|
19
|
+
- `autoRefresh` option ([#130](https://github.com/etro-js/etro/issues/130)).
|
|
20
|
+
- `publicExcludes` ([#130](https://github.com/etro-js/etro/issues/130)).
|
|
21
|
+
- All `change` events ([#130](https://github.com/etro-js/etro/issues/130)).
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- Layers no longer trigger infinite loops when their active states change ([#127](https://github.com/etro-js/etro/issues/127)).
|
|
25
|
+
- Add missing `VisualSource` options to `Image` layer ([#128](https://github.com/etro-js/etro/pull/128)).
|
|
26
|
+
- Layers are now stopped when recording ends.
|
|
27
|
+
- `stop()` is no longer called on inactive layers.
|
|
28
|
+
- Movies no longer publish `'movie.ended'` when done recording.
|
|
29
|
+
- `Audio` and `Video` layers not detaching properly.
|
|
30
|
+
- When done playing or recording, movies only reset their time if they're in repeat mode.
|
|
31
|
+
- The `timeupdate` event is no longer fired when `currentTime` remains the same (due to `performance.now()` rounding).
|
|
32
|
+
|
|
8
33
|
## [0.8.5] - 2022-03-06
|
|
9
34
|
### Deprecated
|
|
10
35
|
- `vd.effect.Base` - All visual effects now inherit from `vd.effect.Visual` instead.
|
|
@@ -208,6 +233,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
208
233
|
- Gaussian blur
|
|
209
234
|
- Transform
|
|
210
235
|
|
|
236
|
+
[0.9.1]: https://github.com/etro-js/etro/compare/v0.9.0...v0.9.1
|
|
237
|
+
[0.9.0]: https://github.com/etro-js/etro/compare/v0.8.5...v0.9.0
|
|
211
238
|
[0.8.5]: https://github.com/etro-js/etro/compare/v0.8.4...v0.8.5
|
|
212
239
|
[0.8.4]: https://github.com/etro-js/etro/compare/v0.8.3...v0.8.4
|
|
213
240
|
[0.8.3]: https://github.com/etro-js/etro/compare/v0.8.2...v0.8.3
|
package/CONTRIBUTING.md
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
Thank you for considering contributing to Etro! There are many ways you can contribute to Etro, like creating issues for features or bugs, improving the docs or wiki, or writing the
|
|
5
|
+
Thank you for considering contributing to Etro! There are many ways you can contribute to Etro, like creating issues for features or bugs, improving the docs or wiki, or writing the code for the library. This page covers how to make changes to the repository files (either code or jsdocs).
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[Join our Discord](https://discord.gg/myrBsQ8Cht)
|
|
8
8
|
|
|
9
9
|
## Setting up your local environment
|
|
10
10
|
|
|
11
11
|
#### Step 0: Dependencies
|
|
12
12
|
|
|
13
|
-
- You will need Git, Node, NPM (at least 7.x) and
|
|
13
|
+
- You will need Git, Node, NPM (at least 7.x) and Firefox (for headless functional testing) installed.
|
|
14
14
|
|
|
15
15
|
#### Step 1: Fork
|
|
16
16
|
|
|
@@ -27,9 +27,9 @@ Thank you for considering contributing to Etro! There are many ways you can cont
|
|
|
27
27
|
|
|
28
28
|
#### Step 2: Code
|
|
29
29
|
|
|
30
|
-
- Make some changes
|
|
31
|
-
- If you are writing code, the linter uses [StandardJS](https://standardjs.com/rules.html) for style conventions
|
|
32
|
-
- When you're ready to submit
|
|
30
|
+
- Make some changes
|
|
31
|
+
- If you are writing code, the linter uses [StandardJS](https://standardjs.com/rules.html) for style conventions
|
|
32
|
+
- When you're ready to submit, first run
|
|
33
33
|
|
|
34
34
|
```
|
|
35
35
|
npm run lint
|
|
@@ -40,12 +40,11 @@ Thank you for considering contributing to Etro! There are many ways you can cont
|
|
|
40
40
|
to lint the code, generate the [dist](dist) files and run unit tests on them. It may be helpful to put these commands in a pre-commit hook.
|
|
41
41
|
|
|
42
42
|
- Commit your changes
|
|
43
|
-
- Please avoid squashing all your commits into one; we try to keep atomic commits.
|
|
44
43
|
- Please follow these commit message guidelines:
|
|
45
|
-
- Optionally, prefix each commit message with [an appropriate emoji](https://gitmoji.dev)
|
|
44
|
+
- Optionally, prefix each commit message with [an appropriate emoji](https://gitmoji.dev), such as `:bug:` for fixes.
|
|
46
45
|
- Write in the imperative tense
|
|
47
46
|
- Wrap lines after 72 characters (for Vim add `filetype indent plugin on` to ~/.vimrc, it's enabled by default in Atom).
|
|
48
|
-
-
|
|
47
|
+
- Format:
|
|
49
48
|
|
|
50
49
|
```
|
|
51
50
|
:emoji: One-liner
|
|
@@ -57,19 +56,18 @@ Thank you for considering contributing to Etro! There are many ways you can cont
|
|
|
57
56
|
|
|
58
57
|
#### Step 3: Push
|
|
59
58
|
|
|
60
|
-
- First, rebase (
|
|
59
|
+
- First, rebase (please avoid merging) to integrate your work with any new changes in the main repository
|
|
61
60
|
|
|
62
61
|
```
|
|
63
62
|
git fetch upstream
|
|
64
63
|
git rebase upstream/master
|
|
65
64
|
```
|
|
66
65
|
|
|
67
|
-
- Push to
|
|
66
|
+
- Push to the fork
|
|
68
67
|
|
|
69
68
|
#### Step 4: Pull request
|
|
70
69
|
|
|
71
|
-
- Open a pull request from
|
|
72
|
-
- In the PR title, include **fixes ###** for bugs and **resolves ###** for feature requests
|
|
70
|
+
- Open a pull request from the branch in your fork to the main repository
|
|
73
71
|
- If you changed any core functionality, make sure you explain your motives for those changes
|
|
74
72
|
|
|
75
73
|
#### Step 5: Feedback
|
|
@@ -80,20 +78,9 @@ Thank you for considering contributing to Etro! There are many ways you can cont
|
|
|
80
78
|
|
|
81
79
|
### Etro Overview
|
|
82
80
|
|
|
83
|
-
|
|
81
|
+
Check out [the overview guide](https://etrojs.dev/docs/overview) for usage information
|
|
84
82
|
|
|
85
|
-
###
|
|
86
|
-
|
|
87
|
-
* `etro.Movie` - the movie
|
|
88
|
-
* `etro.layer.*` - all layers
|
|
89
|
-
* `etro.effect.*` - all (visual) effects
|
|
90
|
-
- `etro.event.publish` - emit an event
|
|
91
|
-
- `etro.event.subscribe` - add an event listener
|
|
92
|
-
- `etro.*` - other utility classes and methods (see **src/util.ts**)
|
|
93
|
-
|
|
94
|
-
### Etro concepts
|
|
95
|
-
|
|
96
|
-
#### Pub/sub system
|
|
83
|
+
### Pub/sub system
|
|
97
84
|
|
|
98
85
|
Events emitted by Etro objects use a [pub/sub system](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern). To emit an event, use `event.publish(target, type, event)`. For instance,
|
|
99
86
|
|
package/README.md
CHANGED
|
@@ -3,14 +3,12 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/etro)
|
|
4
4
|
[](https://actions-badge.atrox.dev/etro-js/etro/goto)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
Etro is a typescript framework for programmatically editing videos. It lets you
|
|
7
|
+
composite layers and add filters (effects). Etro comes shipped with text, video,
|
|
8
|
+
audio and image layers, along with a bunch of GLSL effects. You can also define
|
|
9
|
+
your own layers and effects with javascript and GLSL.
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
GUI-based video-editing software, it lets you composite layers and add effects.
|
|
11
|
-
Etro comes shipped with text, video, audio and image layers, along with a bunch
|
|
12
|
-
of GLSL effects. You can also define your own layers and effects with javascript
|
|
13
|
-
and GLSL.
|
|
11
|
+
[Join our Discord](https://discord.gg/myrBsQ8Cht)
|
|
14
12
|
|
|
15
13
|
## Features
|
|
16
14
|
|
|
@@ -72,16 +70,11 @@ To use Etro in Node, see the [wrapper](https://github.com/etro-js/etro-node):
|
|
|
72
70
|
|
|
73
71
|
## Running the Examples
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
npm run assets
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Then, start the development server (only used for convience while developing;
|
|
82
|
-
you don't need a server to use Etro):
|
|
73
|
+
Start the development server (only used for convience while developing; you
|
|
74
|
+
don't need a server to use Etro):
|
|
83
75
|
|
|
84
76
|
```
|
|
77
|
+
npm i
|
|
85
78
|
npm start
|
|
86
79
|
```
|
|
87
80
|
|
package/dist/effect/base.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Movie } from '../movie';
|
|
2
|
-
import {
|
|
2
|
+
import { Base as BaseLayer } from '../layer/index';
|
|
3
3
|
import BaseObject from '../object';
|
|
4
4
|
/**
|
|
5
5
|
* @deprecated All visual effects now inherit from `Visual` instead
|
|
@@ -21,8 +21,8 @@ export declare class Base implements BaseObject {
|
|
|
21
21
|
* Attaches this effect to `target` if not already attached.
|
|
22
22
|
* @ignore
|
|
23
23
|
*/
|
|
24
|
-
tryAttach(target: Movie |
|
|
25
|
-
attach(movie: Movie |
|
|
24
|
+
tryAttach(target: Movie | BaseLayer): void;
|
|
25
|
+
attach(movie: Movie | BaseLayer): void;
|
|
26
26
|
/**
|
|
27
27
|
* Dettaches this effect from its target if the number of times `tryDetach`
|
|
28
28
|
* has been called (including this call) equals the number of times
|
|
@@ -40,12 +40,12 @@ export declare class Base implements BaseObject {
|
|
|
40
40
|
* (will soon be replaced with an instance getter)
|
|
41
41
|
* @abstract
|
|
42
42
|
*/
|
|
43
|
-
apply(target: Movie |
|
|
43
|
+
apply(target: Movie | BaseLayer, reltime: number): void;
|
|
44
44
|
/**
|
|
45
45
|
* The current time of the target
|
|
46
46
|
*/
|
|
47
47
|
get currentTime(): number;
|
|
48
|
-
get parent(): Movie |
|
|
48
|
+
get parent(): Movie | BaseLayer;
|
|
49
49
|
get movie(): Movie;
|
|
50
50
|
getDefaultOptions(): Record<string, unknown>;
|
|
51
51
|
}
|
package/dist/effect/visual.d.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
import { Movie } from '../movie';
|
|
2
|
+
import { Visual as VisualLayer } from '../layer/index';
|
|
1
3
|
import { Base } from './base';
|
|
2
4
|
/**
|
|
3
5
|
* Modifies the visual contents of a layer.
|
|
4
6
|
*/
|
|
5
7
|
export declare class Visual extends Base {
|
|
8
|
+
/**
|
|
9
|
+
* Apply this effect to a target at the given time
|
|
10
|
+
*
|
|
11
|
+
* @param target
|
|
12
|
+
* @param reltime - the movie's current time relative to the layer
|
|
13
|
+
* (will soon be replaced with an instance getter)
|
|
14
|
+
* @abstract
|
|
15
|
+
*/
|
|
16
|
+
apply(target: Movie | VisualLayer, reltime: number): void;
|
|
6
17
|
}
|
package/dist/etro-cjs.js
CHANGED
|
@@ -125,6 +125,7 @@ function publish(target, type, event) {
|
|
|
125
125
|
var listeners = new WeakMap();
|
|
126
126
|
|
|
127
127
|
var event = /*#__PURE__*/Object.freeze({
|
|
128
|
+
__proto__: null,
|
|
128
129
|
subscribe: subscribe,
|
|
129
130
|
unsubscribe: unsubscribe,
|
|
130
131
|
publish: publish
|
|
@@ -374,7 +375,7 @@ var Color = /** @class */ (function () {
|
|
|
374
375
|
* Converts to a CSS color
|
|
375
376
|
*/
|
|
376
377
|
Color.prototype.toString = function () {
|
|
377
|
-
return "rgba("
|
|
378
|
+
return "rgba(".concat(this.r, ", ").concat(this.g, ", ").concat(this.b, ", ").concat(this.a, ")");
|
|
378
379
|
};
|
|
379
380
|
return Color;
|
|
380
381
|
}());
|
|
@@ -433,7 +434,7 @@ var Font = /** @class */ (function () {
|
|
|
433
434
|
s += this.weight + ' ';
|
|
434
435
|
if (this.stretch !== 'normal')
|
|
435
436
|
s += this.stretch + ' ';
|
|
436
|
-
s += ""
|
|
437
|
+
s += "".concat(this.size).concat(this.sizeUnit, " ");
|
|
437
438
|
if (this.lineHeight !== 'normal')
|
|
438
439
|
s += this.lineHeight + ' ';
|
|
439
440
|
s += this.family;
|
|
@@ -450,7 +451,7 @@ var parseFontEl = document.createElement('div');
|
|
|
450
451
|
*/
|
|
451
452
|
function parseFont(str) {
|
|
452
453
|
// Assign css string to html element
|
|
453
|
-
parseFontEl.setAttribute('style', "font: "
|
|
454
|
+
parseFontEl.setAttribute('style', "font: ".concat(str));
|
|
454
455
|
var _a = parseFontEl.style, fontSize = _a.fontSize, fontFamily = _a.fontFamily, fontStyle = _a.fontStyle, fontVariant = _a.fontVariant, fontWeight = _a.fontWeight, lineHeight = _a.lineHeight;
|
|
455
456
|
parseFontEl.removeAttribute('style');
|
|
456
457
|
var size = parseFloat(fontSize);
|
|
@@ -485,6 +486,8 @@ function mapPixels(mapper, canvas, ctx, x, y, width, height, flush) {
|
|
|
485
486
|
* <p>Must be called before any watchable properties are set, and only once in
|
|
486
487
|
* the prototype chain.
|
|
487
488
|
*
|
|
489
|
+
* @deprecated Will be removed in the future (see issue #130)
|
|
490
|
+
*
|
|
488
491
|
* @param target - object to watch
|
|
489
492
|
*/
|
|
490
493
|
function watchPublic(target) {
|
|
@@ -493,7 +496,7 @@ function watchPublic(target) {
|
|
|
493
496
|
};
|
|
494
497
|
var callback = function (prop, val, receiver) {
|
|
495
498
|
// Public API property updated, emit 'modify' event.
|
|
496
|
-
publish(proxy, target.type
|
|
499
|
+
publish(proxy, "".concat(target.type, ".change.modify"), { property: getPath(receiver, prop), newValue: val });
|
|
497
500
|
};
|
|
498
501
|
var canWatch = function (receiver, prop) { return !prop.startsWith('_') &&
|
|
499
502
|
(receiver.publicExcludes === undefined || !receiver.publicExcludes.includes(prop)); };
|
|
@@ -618,7 +621,10 @@ function AudioSourceMixin(superclass) {
|
|
|
618
621
|
this.audioNode.connect(movie.actx.destination);
|
|
619
622
|
};
|
|
620
623
|
MixedAudioSource.prototype.detach = function () {
|
|
621
|
-
|
|
624
|
+
// Cache dest before super.detach() unsets this.movie
|
|
625
|
+
var dest = this.movie.actx.destination;
|
|
626
|
+
_super.prototype.detach.call(this);
|
|
627
|
+
this.audioNode.disconnect(dest);
|
|
622
628
|
};
|
|
623
629
|
MixedAudioSource.prototype.start = function () {
|
|
624
630
|
this.source.currentTime = this.currentTime + this.sourceStartTime;
|
|
@@ -727,7 +733,7 @@ var Base = /** @class */ (function () {
|
|
|
727
733
|
// Propogate up to target
|
|
728
734
|
subscribe(newThis, 'layer.change', function (event) {
|
|
729
735
|
var typeOfChange = event.type.substring(event.type.lastIndexOf('.') + 1);
|
|
730
|
-
var type = "movie.change.layer."
|
|
736
|
+
var type = "movie.change.layer.".concat(typeOfChange);
|
|
731
737
|
publish(newThis._movie, type, __assign(__assign({}, event), { target: newThis._movie, type: type }));
|
|
732
738
|
});
|
|
733
739
|
return newThis;
|
|
@@ -800,7 +806,8 @@ var Base = /** @class */ (function () {
|
|
|
800
806
|
* The current time of the movie relative to this layer
|
|
801
807
|
*/
|
|
802
808
|
get: function () {
|
|
803
|
-
return this._movie
|
|
809
|
+
return this._movie
|
|
810
|
+
? this._movie.currentTime - this.startTime
|
|
804
811
|
: undefined;
|
|
805
812
|
},
|
|
806
813
|
enumerable: false,
|
|
@@ -836,7 +843,7 @@ var Base = /** @class */ (function () {
|
|
|
836
843
|
// id for events (independent of instance, but easy to access when on prototype
|
|
837
844
|
// chain)
|
|
838
845
|
Base.prototype.type = 'layer';
|
|
839
|
-
Base.prototype.publicExcludes = [];
|
|
846
|
+
Base.prototype.publicExcludes = ['active'];
|
|
840
847
|
Base.prototype.propertyFilters = {};
|
|
841
848
|
|
|
842
849
|
// TODO: rename to something more consistent with the naming convention of Visual and VisualSourceMixin
|
|
@@ -981,13 +988,13 @@ var Visual = /** @class */ (function (_super) {
|
|
|
981
988
|
height: null,
|
|
982
989
|
/**
|
|
983
990
|
* @name module:layer.Visual#background
|
|
984
|
-
* @desc The
|
|
991
|
+
* @desc The color code for the background, or <code>null</code> for
|
|
985
992
|
* transparency
|
|
986
993
|
*/
|
|
987
994
|
background: null,
|
|
988
995
|
/**
|
|
989
996
|
* @name module:layer.Visual#border
|
|
990
|
-
* @desc The
|
|
997
|
+
* @desc The border style, or <code>null</code> for no border
|
|
991
998
|
*/
|
|
992
999
|
border: null,
|
|
993
1000
|
/**
|
|
@@ -1062,19 +1069,23 @@ function VisualSourceMixin(superclass) {
|
|
|
1062
1069
|
// instead. (TODO: fact check)
|
|
1063
1070
|
/* eslint-disable eqeqeq */
|
|
1064
1071
|
return destWidth != undefined
|
|
1065
|
-
? destWidth
|
|
1072
|
+
? destWidth
|
|
1073
|
+
: val(this, 'sourceWidth', this.currentTime);
|
|
1066
1074
|
}, destHeight: function (destHeight) {
|
|
1067
1075
|
/* eslint-disable eqeqeq */
|
|
1068
1076
|
return destHeight != undefined
|
|
1069
|
-
? destHeight
|
|
1077
|
+
? destHeight
|
|
1078
|
+
: val(this, 'sourceHeight', this.currentTime);
|
|
1070
1079
|
}, width: function (width) {
|
|
1071
1080
|
/* eslint-disable eqeqeq */
|
|
1072
1081
|
return width != undefined
|
|
1073
|
-
? width
|
|
1082
|
+
? width
|
|
1083
|
+
: val(this, 'destWidth', this.currentTime);
|
|
1074
1084
|
}, height: function (height) {
|
|
1075
1085
|
/* eslint-disable eqeqeq */
|
|
1076
1086
|
return height != undefined
|
|
1077
|
-
? height
|
|
1087
|
+
? height
|
|
1088
|
+
: val(this, 'destHeight', this.currentTime);
|
|
1078
1089
|
} });
|
|
1079
1090
|
return MixedVisualSource;
|
|
1080
1091
|
}
|
|
@@ -1146,7 +1157,7 @@ var Text = /** @class */ (function (_super) {
|
|
|
1146
1157
|
return metrics;
|
|
1147
1158
|
} */
|
|
1148
1159
|
Text.prototype.getDefaultOptions = function () {
|
|
1149
|
-
return __assign(__assign({}, Visual.prototype.getDefaultOptions()), { background: null, text: undefined, font: '10px sans-serif', color: '#fff', textX: 0, textY: 0, maxWidth: null, textAlign: 'start', textBaseline: 'top', textDirection: 'ltr' });
|
|
1160
|
+
return __assign(__assign({}, Visual.prototype.getDefaultOptions()), { background: null, text: undefined, font: '10px sans-serif', color: parseColor('#fff'), textX: 0, textY: 0, maxWidth: null, textAlign: 'start', textBaseline: 'top', textDirection: 'ltr' });
|
|
1150
1161
|
};
|
|
1151
1162
|
return Text;
|
|
1152
1163
|
}(Visual));
|
|
@@ -1170,6 +1181,7 @@ var Video = /** @class */ (function (_super) {
|
|
|
1170
1181
|
*/
|
|
1171
1182
|
|
|
1172
1183
|
var index = /*#__PURE__*/Object.freeze({
|
|
1184
|
+
__proto__: null,
|
|
1173
1185
|
AudioSourceMixin: AudioSourceMixin,
|
|
1174
1186
|
Audio: Audio,
|
|
1175
1187
|
Base: Base,
|
|
@@ -1193,7 +1205,7 @@ var Base$1 = /** @class */ (function () {
|
|
|
1193
1205
|
subscribe(newThis, 'effect.change.modify', function (event) {
|
|
1194
1206
|
if (!newThis._target)
|
|
1195
1207
|
return;
|
|
1196
|
-
var type = newThis._target.type
|
|
1208
|
+
var type = "".concat(newThis._target.type, ".change.effect.modify");
|
|
1197
1209
|
publish(newThis._target, type, __assign(__assign({}, event), { target: newThis._target, source: newThis, type: type }));
|
|
1198
1210
|
});
|
|
1199
1211
|
return newThis;
|
|
@@ -1282,6 +1294,18 @@ var Visual$1 = /** @class */ (function (_super) {
|
|
|
1282
1294
|
function Visual() {
|
|
1283
1295
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
1284
1296
|
}
|
|
1297
|
+
// subclasses must implement apply
|
|
1298
|
+
/**
|
|
1299
|
+
* Apply this effect to a target at the given time
|
|
1300
|
+
*
|
|
1301
|
+
* @param target
|
|
1302
|
+
* @param reltime - the movie's current time relative to the layer
|
|
1303
|
+
* (will soon be replaced with an instance getter)
|
|
1304
|
+
* @abstract
|
|
1305
|
+
*/
|
|
1306
|
+
Visual.prototype.apply = function (target, reltime) {
|
|
1307
|
+
_super.prototype.apply.call(this, target, reltime);
|
|
1308
|
+
};
|
|
1285
1309
|
return Visual;
|
|
1286
1310
|
}(Base$1));
|
|
1287
1311
|
|
|
@@ -1341,7 +1365,7 @@ var Shader = /** @class */ (function (_super) {
|
|
|
1341
1365
|
* object.
|
|
1342
1366
|
*/
|
|
1343
1367
|
if (userUniforms[name_1])
|
|
1344
|
-
throw new Error("Texture - uniform naming conflict: "
|
|
1368
|
+
throw new Error("Texture - uniform naming conflict: ".concat(name_1, "!"));
|
|
1345
1369
|
// Add this as a "user uniform".
|
|
1346
1370
|
userUniforms[name_1] = '1i'; // texture pointer
|
|
1347
1371
|
}
|
|
@@ -1550,7 +1574,7 @@ var Shader = /** @class */ (function (_super) {
|
|
|
1550
1574
|
value.g !== undefined ? value.g : def,
|
|
1551
1575
|
value.b !== undefined ? value.b : def
|
|
1552
1576
|
];
|
|
1553
|
-
throw new Error("Invalid type: "
|
|
1577
|
+
throw new Error("Invalid type: ".concat(outputType, " or value: ").concat(value));
|
|
1554
1578
|
}
|
|
1555
1579
|
if (outputType === '4fv') {
|
|
1556
1580
|
if (Array.isArray(value) && value.length === 4)
|
|
@@ -1563,7 +1587,7 @@ var Shader = /** @class */ (function (_super) {
|
|
|
1563
1587
|
value.b !== undefined ? value.b : def,
|
|
1564
1588
|
value.a !== undefined ? value.a : def
|
|
1565
1589
|
];
|
|
1566
|
-
throw new Error("Invalid type: "
|
|
1590
|
+
throw new Error("Invalid type: ".concat(outputType, " or value: ").concat(value));
|
|
1567
1591
|
}
|
|
1568
1592
|
return value;
|
|
1569
1593
|
};
|
|
@@ -2040,7 +2064,7 @@ var GaussianBlurComponent = /** @class */ (function (_super) {
|
|
|
2040
2064
|
};
|
|
2041
2065
|
GaussianBlurComponent._genPascalRow = function (index) {
|
|
2042
2066
|
if (index < 0)
|
|
2043
|
-
throw new Error("Invalid index "
|
|
2067
|
+
throw new Error("Invalid index ".concat(index));
|
|
2044
2068
|
var currRow = [1];
|
|
2045
2069
|
for (var i = 1; i < index; i++) {
|
|
2046
2070
|
var nextRow = [];
|
|
@@ -2312,16 +2336,17 @@ var Transform = /** @class */ (function (_super) {
|
|
|
2312
2336
|
*/
|
|
2313
2337
|
|
|
2314
2338
|
var index$1 = /*#__PURE__*/Object.freeze({
|
|
2315
|
-
|
|
2316
|
-
GaussianBlurHorizontal: GaussianBlurHorizontal,
|
|
2317
|
-
GaussianBlurVertical: GaussianBlurVertical,
|
|
2339
|
+
__proto__: null,
|
|
2318
2340
|
Base: Base$1,
|
|
2341
|
+
Brightness: Brightness,
|
|
2319
2342
|
Channels: Channels,
|
|
2320
2343
|
ChromaKey: ChromaKey,
|
|
2321
2344
|
Contrast: Contrast,
|
|
2322
2345
|
EllipticalMaskOptions: EllipticalMaskOptions,
|
|
2323
2346
|
EllipticalMask: EllipticalMask,
|
|
2324
|
-
|
|
2347
|
+
GaussianBlur: GaussianBlur,
|
|
2348
|
+
GaussianBlurHorizontal: GaussianBlurHorizontal,
|
|
2349
|
+
GaussianBlurVertical: GaussianBlurVertical,
|
|
2325
2350
|
Grayscale: Grayscale,
|
|
2326
2351
|
Pixelate: Pixelate,
|
|
2327
2352
|
Shader: Shader,
|
|
@@ -2343,8 +2368,6 @@ var MovieOptions = /** @class */ (function () {
|
|
|
2343
2368
|
*
|
|
2344
2369
|
* Implements a pub/sub system.
|
|
2345
2370
|
*/
|
|
2346
|
-
// TODO: Implement event "durationchange", and more
|
|
2347
|
-
// TODO: Add width and height options
|
|
2348
2371
|
// TODO: Make record option to make recording video output to the user while
|
|
2349
2372
|
// it's recording
|
|
2350
2373
|
// TODO: rename renderingFrame -> refreshing
|
|
@@ -2614,19 +2637,28 @@ var Movie = /** @class */ (function () {
|
|
|
2614
2637
|
done();
|
|
2615
2638
|
return;
|
|
2616
2639
|
}
|
|
2617
|
-
this.
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2640
|
+
var end = this.recording ? this._recordEndTime : this.duration;
|
|
2641
|
+
this._updateCurrentTime(timestamp, end);
|
|
2642
|
+
// TODO: Is calling duration every frame bad for performance? (remember,
|
|
2643
|
+
// it's calling Array.reduce)
|
|
2644
|
+
if (this.currentTime === end) {
|
|
2645
|
+
if (this.recording)
|
|
2646
|
+
publish(this, 'movie.recordended', { movie: this });
|
|
2647
|
+
if (this.currentTime === this.duration)
|
|
2648
|
+
publish(this, 'movie.ended', { movie: this, repeat: this.repeat });
|
|
2649
|
+
// TODO: only reset currentTime if repeating
|
|
2650
|
+
if (this.repeat) {
|
|
2651
|
+
// Don't use setter, which publishes 'movie.seek'. Instead, update the
|
|
2652
|
+
// value and publish a 'movie.timeupdate' event.
|
|
2653
|
+
this._currentTime = 0;
|
|
2654
|
+
publish(this, 'movie.timeupdate', { movie: this });
|
|
2655
|
+
}
|
|
2626
2656
|
this._lastPlayed = performance.now();
|
|
2627
2657
|
this._lastPlayedOffset = 0; // this.currentTime
|
|
2628
2658
|
this._renderingFrame = false;
|
|
2629
|
-
if (
|
|
2659
|
+
// Stop playback or recording if done (except if it's playing and repeat
|
|
2660
|
+
// is true)
|
|
2661
|
+
if (!(!this.recording && this.repeat)) {
|
|
2630
2662
|
this._paused = true;
|
|
2631
2663
|
this._ended = true;
|
|
2632
2664
|
// Deactivate all layers
|
|
@@ -2635,22 +2667,15 @@ var Movie = /** @class */ (function () {
|
|
|
2635
2667
|
var layer = this.layers[i];
|
|
2636
2668
|
// A layer that has been deleted before layers.length has been updated
|
|
2637
2669
|
// (see the layers proxy in the constructor).
|
|
2638
|
-
if (!layer)
|
|
2670
|
+
if (!layer || !layer.active)
|
|
2639
2671
|
continue;
|
|
2640
2672
|
layer.stop();
|
|
2641
2673
|
layer.active = false;
|
|
2642
2674
|
}
|
|
2675
|
+
if (done)
|
|
2676
|
+
done();
|
|
2677
|
+
return;
|
|
2643
2678
|
}
|
|
2644
|
-
publish(this, 'movie.ended', { movie: this, repeat: this.repeat });
|
|
2645
|
-
// TODO: only reset currentTime if repeating
|
|
2646
|
-
this._currentTime = 0; // don't use setter
|
|
2647
|
-
publish(this, 'movie.timeupdate', { movie: this });
|
|
2648
|
-
}
|
|
2649
|
-
// Stop playback or recording if done
|
|
2650
|
-
if (recordingEnded || (ended && !this.repeat)) {
|
|
2651
|
-
if (done)
|
|
2652
|
-
done();
|
|
2653
|
-
return;
|
|
2654
2679
|
}
|
|
2655
2680
|
// Do render
|
|
2656
2681
|
this._renderBackground(timestamp);
|
|
@@ -2672,16 +2697,21 @@ var Movie = /** @class */ (function () {
|
|
|
2672
2697
|
_this._render(repeat, undefined, done);
|
|
2673
2698
|
}); // TODO: research performance cost
|
|
2674
2699
|
};
|
|
2675
|
-
Movie.prototype._updateCurrentTime = function (
|
|
2700
|
+
Movie.prototype._updateCurrentTime = function (timestampMs, end) {
|
|
2676
2701
|
// If we're only instant-rendering (current frame only), it doens't matter
|
|
2677
2702
|
// if it's paused or not.
|
|
2678
2703
|
if (!this._renderingFrame) {
|
|
2679
2704
|
// if ((timestamp - this._lastUpdate) >= this._updateInterval) {
|
|
2680
|
-
var sinceLastPlayed = (
|
|
2681
|
-
|
|
2682
|
-
|
|
2705
|
+
var sinceLastPlayed = (timestampMs - this._lastPlayed) / 1000;
|
|
2706
|
+
var currentTime = this._lastPlayedOffset + sinceLastPlayed; // don't use setter
|
|
2707
|
+
if (this.currentTime !== currentTime) {
|
|
2708
|
+
this._currentTime = currentTime;
|
|
2709
|
+
publish(this, 'movie.timeupdate', { movie: this });
|
|
2710
|
+
}
|
|
2683
2711
|
// this._lastUpdate = timestamp;
|
|
2684
2712
|
// }
|
|
2713
|
+
if (this.currentTime > end)
|
|
2714
|
+
this.currentTime = end;
|
|
2685
2715
|
}
|
|
2686
2716
|
};
|
|
2687
2717
|
Movie.prototype._renderBackground = function (timestamp) {
|
|
@@ -2948,9 +2978,9 @@ var Movie = /** @class */ (function () {
|
|
|
2948
2978
|
canvas: undefined,
|
|
2949
2979
|
/**
|
|
2950
2980
|
* @name module:movie#background
|
|
2951
|
-
* @desc The
|
|
2981
|
+
* @desc The color for the background, or <code>null</code> for transparency
|
|
2952
2982
|
*/
|
|
2953
|
-
background: '#000',
|
|
2983
|
+
background: parseColor('#000'),
|
|
2954
2984
|
/**
|
|
2955
2985
|
* @name module:movie#repeat
|
|
2956
2986
|
*/
|
|
@@ -2978,6 +3008,7 @@ Movie.prototype.propertyFilters = {};
|
|
|
2978
3008
|
*/
|
|
2979
3009
|
|
|
2980
3010
|
var etro = /*#__PURE__*/Object.freeze({
|
|
3011
|
+
__proto__: null,
|
|
2981
3012
|
layer: index,
|
|
2982
3013
|
effect: index$1,
|
|
2983
3014
|
event: event,
|