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.
Files changed (47) hide show
  1. package/.github/workflows/nodejs.yml +1 -1
  2. package/CHANGELOG.md +27 -0
  3. package/CONTRIBUTING.md +13 -26
  4. package/README.md +8 -15
  5. package/dist/effect/base.d.ts +5 -5
  6. package/dist/effect/visual.d.ts +11 -0
  7. package/dist/etro-cjs.js +84 -53
  8. package/dist/etro-iife.js +84 -53
  9. package/dist/layer/image.d.ts +2 -2
  10. package/dist/layer/text.d.ts +3 -3
  11. package/dist/layer/visual-source.d.ts +18 -3
  12. package/dist/layer/visual.d.ts +5 -5
  13. package/dist/movie.d.ts +13 -4
  14. package/dist/object.d.ts +5 -1
  15. package/dist/util.d.ts +2 -0
  16. package/eslint.conf.js +2 -0
  17. package/eslint.test-conf.js +1 -2
  18. package/karma.conf.js +17 -8
  19. package/package.json +19 -19
  20. package/scripts/gen-effect-samples.html +24 -0
  21. package/scripts/save-effect-samples.js +1 -1
  22. package/src/effect/base.ts +6 -6
  23. package/src/effect/stack.ts +2 -2
  24. package/src/effect/transform.ts +2 -2
  25. package/src/effect/visual.ts +16 -1
  26. package/src/layer/audio-source.ts +4 -1
  27. package/src/layer/base.ts +3 -2
  28. package/src/layer/image.ts +3 -3
  29. package/src/layer/text.ts +4 -4
  30. package/src/layer/visual-source.ts +27 -7
  31. package/src/layer/visual.ts +7 -7
  32. package/src/movie.ts +55 -37
  33. package/src/object.ts +5 -1
  34. package/src/util.ts +2 -0
  35. package/tsconfig.json +3 -1
  36. package/examples/application/readme-screenshot.html +0 -85
  37. package/examples/application/video-player.html +0 -130
  38. package/examples/application/webcam.html +0 -28
  39. package/examples/introduction/audio.html +0 -64
  40. package/examples/introduction/effects.html +0 -79
  41. package/examples/introduction/export.html +0 -83
  42. package/examples/introduction/functions.html +0 -37
  43. package/examples/introduction/hello-world1.html +0 -37
  44. package/examples/introduction/hello-world2.html +0 -32
  45. package/examples/introduction/keyframes.html +0 -79
  46. package/examples/introduction/media.html +0 -63
  47. package/examples/introduction/text.html +0 -31
package/dist/etro-iife.js CHANGED
@@ -126,6 +126,7 @@ var etro = (function () {
126
126
  var listeners = new WeakMap();
127
127
 
128
128
  var event = /*#__PURE__*/Object.freeze({
129
+ __proto__: null,
129
130
  subscribe: subscribe,
130
131
  unsubscribe: unsubscribe,
131
132
  publish: publish
@@ -375,7 +376,7 @@ var etro = (function () {
375
376
  * Converts to a CSS color
376
377
  */
377
378
  Color.prototype.toString = function () {
378
- return "rgba(" + this.r + ", " + this.g + ", " + this.b + ", " + this.a + ")";
379
+ return "rgba(".concat(this.r, ", ").concat(this.g, ", ").concat(this.b, ", ").concat(this.a, ")");
379
380
  };
380
381
  return Color;
381
382
  }());
@@ -434,7 +435,7 @@ var etro = (function () {
434
435
  s += this.weight + ' ';
435
436
  if (this.stretch !== 'normal')
436
437
  s += this.stretch + ' ';
437
- s += "" + this.size + this.sizeUnit + " ";
438
+ s += "".concat(this.size).concat(this.sizeUnit, " ");
438
439
  if (this.lineHeight !== 'normal')
439
440
  s += this.lineHeight + ' ';
440
441
  s += this.family;
@@ -451,7 +452,7 @@ var etro = (function () {
451
452
  */
452
453
  function parseFont(str) {
453
454
  // Assign css string to html element
454
- parseFontEl.setAttribute('style', "font: " + str);
455
+ parseFontEl.setAttribute('style', "font: ".concat(str));
455
456
  var _a = parseFontEl.style, fontSize = _a.fontSize, fontFamily = _a.fontFamily, fontStyle = _a.fontStyle, fontVariant = _a.fontVariant, fontWeight = _a.fontWeight, lineHeight = _a.lineHeight;
456
457
  parseFontEl.removeAttribute('style');
457
458
  var size = parseFloat(fontSize);
@@ -486,6 +487,8 @@ var etro = (function () {
486
487
  * <p>Must be called before any watchable properties are set, and only once in
487
488
  * the prototype chain.
488
489
  *
490
+ * @deprecated Will be removed in the future (see issue #130)
491
+ *
489
492
  * @param target - object to watch
490
493
  */
491
494
  function watchPublic(target) {
@@ -494,7 +497,7 @@ var etro = (function () {
494
497
  };
495
498
  var callback = function (prop, val, receiver) {
496
499
  // Public API property updated, emit 'modify' event.
497
- publish(proxy, target.type + ".change.modify", { property: getPath(receiver, prop), newValue: val });
500
+ publish(proxy, "".concat(target.type, ".change.modify"), { property: getPath(receiver, prop), newValue: val });
498
501
  };
499
502
  var canWatch = function (receiver, prop) { return !prop.startsWith('_') &&
500
503
  (receiver.publicExcludes === undefined || !receiver.publicExcludes.includes(prop)); };
@@ -619,7 +622,10 @@ var etro = (function () {
619
622
  this.audioNode.connect(movie.actx.destination);
620
623
  };
621
624
  MixedAudioSource.prototype.detach = function () {
622
- this.audioNode.disconnect(this.movie.actx.destination);
625
+ // Cache dest before super.detach() unsets this.movie
626
+ var dest = this.movie.actx.destination;
627
+ _super.prototype.detach.call(this);
628
+ this.audioNode.disconnect(dest);
623
629
  };
624
630
  MixedAudioSource.prototype.start = function () {
625
631
  this.source.currentTime = this.currentTime + this.sourceStartTime;
@@ -728,7 +734,7 @@ var etro = (function () {
728
734
  // Propogate up to target
729
735
  subscribe(newThis, 'layer.change', function (event) {
730
736
  var typeOfChange = event.type.substring(event.type.lastIndexOf('.') + 1);
731
- var type = "movie.change.layer." + typeOfChange;
737
+ var type = "movie.change.layer.".concat(typeOfChange);
732
738
  publish(newThis._movie, type, __assign(__assign({}, event), { target: newThis._movie, type: type }));
733
739
  });
734
740
  return newThis;
@@ -801,7 +807,8 @@ var etro = (function () {
801
807
  * The current time of the movie relative to this layer
802
808
  */
803
809
  get: function () {
804
- return this._movie ? this._movie.currentTime - this.startTime
810
+ return this._movie
811
+ ? this._movie.currentTime - this.startTime
805
812
  : undefined;
806
813
  },
807
814
  enumerable: false,
@@ -837,7 +844,7 @@ var etro = (function () {
837
844
  // id for events (independent of instance, but easy to access when on prototype
838
845
  // chain)
839
846
  Base.prototype.type = 'layer';
840
- Base.prototype.publicExcludes = [];
847
+ Base.prototype.publicExcludes = ['active'];
841
848
  Base.prototype.propertyFilters = {};
842
849
 
843
850
  // TODO: rename to something more consistent with the naming convention of Visual and VisualSourceMixin
@@ -982,13 +989,13 @@ var etro = (function () {
982
989
  height: null,
983
990
  /**
984
991
  * @name module:layer.Visual#background
985
- * @desc The CSS color code for the background, or <code>null</code> for
992
+ * @desc The color code for the background, or <code>null</code> for
986
993
  * transparency
987
994
  */
988
995
  background: null,
989
996
  /**
990
997
  * @name module:layer.Visual#border
991
- * @desc The CSS border style, or <code>null</code> for no border
998
+ * @desc The border style, or <code>null</code> for no border
992
999
  */
993
1000
  border: null,
994
1001
  /**
@@ -1063,19 +1070,23 @@ var etro = (function () {
1063
1070
  // instead. (TODO: fact check)
1064
1071
  /* eslint-disable eqeqeq */
1065
1072
  return destWidth != undefined
1066
- ? destWidth : val(this, 'sourceWidth', this.currentTime);
1073
+ ? destWidth
1074
+ : val(this, 'sourceWidth', this.currentTime);
1067
1075
  }, destHeight: function (destHeight) {
1068
1076
  /* eslint-disable eqeqeq */
1069
1077
  return destHeight != undefined
1070
- ? destHeight : val(this, 'sourceHeight', this.currentTime);
1078
+ ? destHeight
1079
+ : val(this, 'sourceHeight', this.currentTime);
1071
1080
  }, width: function (width) {
1072
1081
  /* eslint-disable eqeqeq */
1073
1082
  return width != undefined
1074
- ? width : val(this, 'destWidth', this.currentTime);
1083
+ ? width
1084
+ : val(this, 'destWidth', this.currentTime);
1075
1085
  }, height: function (height) {
1076
1086
  /* eslint-disable eqeqeq */
1077
1087
  return height != undefined
1078
- ? height : val(this, 'destHeight', this.currentTime);
1088
+ ? height
1089
+ : val(this, 'destHeight', this.currentTime);
1079
1090
  } });
1080
1091
  return MixedVisualSource;
1081
1092
  }
@@ -1147,7 +1158,7 @@ var etro = (function () {
1147
1158
  return metrics;
1148
1159
  } */
1149
1160
  Text.prototype.getDefaultOptions = function () {
1150
- 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' });
1161
+ 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' });
1151
1162
  };
1152
1163
  return Text;
1153
1164
  }(Visual));
@@ -1171,6 +1182,7 @@ var etro = (function () {
1171
1182
  */
1172
1183
 
1173
1184
  var index = /*#__PURE__*/Object.freeze({
1185
+ __proto__: null,
1174
1186
  AudioSourceMixin: AudioSourceMixin,
1175
1187
  Audio: Audio,
1176
1188
  Base: Base,
@@ -1194,7 +1206,7 @@ var etro = (function () {
1194
1206
  subscribe(newThis, 'effect.change.modify', function (event) {
1195
1207
  if (!newThis._target)
1196
1208
  return;
1197
- var type = newThis._target.type + ".change.effect.modify";
1209
+ var type = "".concat(newThis._target.type, ".change.effect.modify");
1198
1210
  publish(newThis._target, type, __assign(__assign({}, event), { target: newThis._target, source: newThis, type: type }));
1199
1211
  });
1200
1212
  return newThis;
@@ -1283,6 +1295,18 @@ var etro = (function () {
1283
1295
  function Visual() {
1284
1296
  return _super !== null && _super.apply(this, arguments) || this;
1285
1297
  }
1298
+ // subclasses must implement apply
1299
+ /**
1300
+ * Apply this effect to a target at the given time
1301
+ *
1302
+ * @param target
1303
+ * @param reltime - the movie's current time relative to the layer
1304
+ * (will soon be replaced with an instance getter)
1305
+ * @abstract
1306
+ */
1307
+ Visual.prototype.apply = function (target, reltime) {
1308
+ _super.prototype.apply.call(this, target, reltime);
1309
+ };
1286
1310
  return Visual;
1287
1311
  }(Base$1));
1288
1312
 
@@ -1342,7 +1366,7 @@ var etro = (function () {
1342
1366
  * object.
1343
1367
  */
1344
1368
  if (userUniforms[name_1])
1345
- throw new Error("Texture - uniform naming conflict: " + name_1 + "!");
1369
+ throw new Error("Texture - uniform naming conflict: ".concat(name_1, "!"));
1346
1370
  // Add this as a "user uniform".
1347
1371
  userUniforms[name_1] = '1i'; // texture pointer
1348
1372
  }
@@ -1551,7 +1575,7 @@ var etro = (function () {
1551
1575
  value.g !== undefined ? value.g : def,
1552
1576
  value.b !== undefined ? value.b : def
1553
1577
  ];
1554
- throw new Error("Invalid type: " + outputType + " or value: " + value);
1578
+ throw new Error("Invalid type: ".concat(outputType, " or value: ").concat(value));
1555
1579
  }
1556
1580
  if (outputType === '4fv') {
1557
1581
  if (Array.isArray(value) && value.length === 4)
@@ -1564,7 +1588,7 @@ var etro = (function () {
1564
1588
  value.b !== undefined ? value.b : def,
1565
1589
  value.a !== undefined ? value.a : def
1566
1590
  ];
1567
- throw new Error("Invalid type: " + outputType + " or value: " + value);
1591
+ throw new Error("Invalid type: ".concat(outputType, " or value: ").concat(value));
1568
1592
  }
1569
1593
  return value;
1570
1594
  };
@@ -2041,7 +2065,7 @@ var etro = (function () {
2041
2065
  };
2042
2066
  GaussianBlurComponent._genPascalRow = function (index) {
2043
2067
  if (index < 0)
2044
- throw new Error("Invalid index " + index);
2068
+ throw new Error("Invalid index ".concat(index));
2045
2069
  var currRow = [1];
2046
2070
  for (var i = 1; i < index; i++) {
2047
2071
  var nextRow = [];
@@ -2313,16 +2337,17 @@ var etro = (function () {
2313
2337
  */
2314
2338
 
2315
2339
  var index$1 = /*#__PURE__*/Object.freeze({
2316
- GaussianBlur: GaussianBlur,
2317
- GaussianBlurHorizontal: GaussianBlurHorizontal,
2318
- GaussianBlurVertical: GaussianBlurVertical,
2340
+ __proto__: null,
2319
2341
  Base: Base$1,
2342
+ Brightness: Brightness,
2320
2343
  Channels: Channels,
2321
2344
  ChromaKey: ChromaKey,
2322
2345
  Contrast: Contrast,
2323
2346
  EllipticalMaskOptions: EllipticalMaskOptions,
2324
2347
  EllipticalMask: EllipticalMask,
2325
- Brightness: Brightness,
2348
+ GaussianBlur: GaussianBlur,
2349
+ GaussianBlurHorizontal: GaussianBlurHorizontal,
2350
+ GaussianBlurVertical: GaussianBlurVertical,
2326
2351
  Grayscale: Grayscale,
2327
2352
  Pixelate: Pixelate,
2328
2353
  Shader: Shader,
@@ -2344,8 +2369,6 @@ var etro = (function () {
2344
2369
  *
2345
2370
  * Implements a pub/sub system.
2346
2371
  */
2347
- // TODO: Implement event "durationchange", and more
2348
- // TODO: Add width and height options
2349
2372
  // TODO: Make record option to make recording video output to the user while
2350
2373
  // it's recording
2351
2374
  // TODO: rename renderingFrame -> refreshing
@@ -2615,19 +2638,28 @@ var etro = (function () {
2615
2638
  done();
2616
2639
  return;
2617
2640
  }
2618
- this._updateCurrentTime(timestamp);
2619
- var recordingEnd = this.recording ? this._recordEndTime : this.duration;
2620
- var recordingEnded = this.currentTime > recordingEnd;
2621
- if (recordingEnded)
2622
- publish(this, 'movie.recordended', { movie: this });
2623
- // Bad for performance? (remember, it's calling Array.reduce)
2624
- var end = this.duration;
2625
- var ended = this.currentTime > end;
2626
- if (ended) {
2641
+ var end = this.recording ? this._recordEndTime : this.duration;
2642
+ this._updateCurrentTime(timestamp, end);
2643
+ // TODO: Is calling duration every frame bad for performance? (remember,
2644
+ // it's calling Array.reduce)
2645
+ if (this.currentTime === end) {
2646
+ if (this.recording)
2647
+ publish(this, 'movie.recordended', { movie: this });
2648
+ if (this.currentTime === this.duration)
2649
+ publish(this, 'movie.ended', { movie: this, repeat: this.repeat });
2650
+ // TODO: only reset currentTime if repeating
2651
+ if (this.repeat) {
2652
+ // Don't use setter, which publishes 'movie.seek'. Instead, update the
2653
+ // value and publish a 'movie.timeupdate' event.
2654
+ this._currentTime = 0;
2655
+ publish(this, 'movie.timeupdate', { movie: this });
2656
+ }
2627
2657
  this._lastPlayed = performance.now();
2628
2658
  this._lastPlayedOffset = 0; // this.currentTime
2629
2659
  this._renderingFrame = false;
2630
- if (!this.repeat || this.recording) {
2660
+ // Stop playback or recording if done (except if it's playing and repeat
2661
+ // is true)
2662
+ if (!(!this.recording && this.repeat)) {
2631
2663
  this._paused = true;
2632
2664
  this._ended = true;
2633
2665
  // Deactivate all layers
@@ -2636,22 +2668,15 @@ var etro = (function () {
2636
2668
  var layer = this.layers[i];
2637
2669
  // A layer that has been deleted before layers.length has been updated
2638
2670
  // (see the layers proxy in the constructor).
2639
- if (!layer)
2671
+ if (!layer || !layer.active)
2640
2672
  continue;
2641
2673
  layer.stop();
2642
2674
  layer.active = false;
2643
2675
  }
2676
+ if (done)
2677
+ done();
2678
+ return;
2644
2679
  }
2645
- publish(this, 'movie.ended', { movie: this, repeat: this.repeat });
2646
- // TODO: only reset currentTime if repeating
2647
- this._currentTime = 0; // don't use setter
2648
- publish(this, 'movie.timeupdate', { movie: this });
2649
- }
2650
- // Stop playback or recording if done
2651
- if (recordingEnded || (ended && !this.repeat)) {
2652
- if (done)
2653
- done();
2654
- return;
2655
2680
  }
2656
2681
  // Do render
2657
2682
  this._renderBackground(timestamp);
@@ -2673,16 +2698,21 @@ var etro = (function () {
2673
2698
  _this._render(repeat, undefined, done);
2674
2699
  }); // TODO: research performance cost
2675
2700
  };
2676
- Movie.prototype._updateCurrentTime = function (timestamp) {
2701
+ Movie.prototype._updateCurrentTime = function (timestampMs, end) {
2677
2702
  // If we're only instant-rendering (current frame only), it doens't matter
2678
2703
  // if it's paused or not.
2679
2704
  if (!this._renderingFrame) {
2680
2705
  // if ((timestamp - this._lastUpdate) >= this._updateInterval) {
2681
- var sinceLastPlayed = (timestamp - this._lastPlayed) / 1000;
2682
- this._currentTime = this._lastPlayedOffset + sinceLastPlayed; // don't use setter
2683
- publish(this, 'movie.timeupdate', { movie: this });
2706
+ var sinceLastPlayed = (timestampMs - this._lastPlayed) / 1000;
2707
+ var currentTime = this._lastPlayedOffset + sinceLastPlayed; // don't use setter
2708
+ if (this.currentTime !== currentTime) {
2709
+ this._currentTime = currentTime;
2710
+ publish(this, 'movie.timeupdate', { movie: this });
2711
+ }
2684
2712
  // this._lastUpdate = timestamp;
2685
2713
  // }
2714
+ if (this.currentTime > end)
2715
+ this.currentTime = end;
2686
2716
  }
2687
2717
  };
2688
2718
  Movie.prototype._renderBackground = function (timestamp) {
@@ -2949,9 +2979,9 @@ var etro = (function () {
2949
2979
  canvas: undefined,
2950
2980
  /**
2951
2981
  * @name module:movie#background
2952
- * @desc The css color for the background, or <code>null</code> for transparency
2982
+ * @desc The color for the background, or <code>null</code> for transparency
2953
2983
  */
2954
- background: '#000',
2984
+ background: parseColor('#000'),
2955
2985
  /**
2956
2986
  * @name module:movie#repeat
2957
2987
  */
@@ -2979,6 +3009,7 @@ var etro = (function () {
2979
3009
  */
2980
3010
 
2981
3011
  var etro = /*#__PURE__*/Object.freeze({
3012
+ __proto__: null,
2982
3013
  layer: index,
2983
3014
  effect: index$1,
2984
3015
  event: event,
@@ -1,5 +1,5 @@
1
- import { VisualOptions } from './visual';
2
- declare type ImageOptions = VisualOptions;
1
+ import { VisualSourceOptions } from './visual-source';
2
+ declare type ImageOptions = VisualSourceOptions;
3
3
  declare const Image_base: new (...args: unknown[]) => import("./visual-source").VisualSource;
4
4
  declare class Image extends Image_base {
5
5
  }
@@ -1,9 +1,9 @@
1
- import { Dynamic } from '../util';
1
+ import { Dynamic, Color } from '../util';
2
2
  import { Visual, VisualOptions } from './visual';
3
3
  interface TextOptions extends VisualOptions {
4
4
  text: Dynamic<string>;
5
5
  font?: Dynamic<string>;
6
- color?: Dynamic<string>;
6
+ color?: Dynamic<Color>;
7
7
  /** The text's horizontal offset from the layer */
8
8
  textX?: Dynamic<number>;
9
9
  /** The text's vertical offset from the layer */
@@ -27,7 +27,7 @@ interface TextOptions extends VisualOptions {
27
27
  declare class Text extends Visual {
28
28
  text: Dynamic<string>;
29
29
  font: Dynamic<string>;
30
- color: Dynamic<string>;
30
+ color: Dynamic<Color>;
31
31
  /** The text's horizontal offset from the layer */
32
32
  textX: Dynamic<number>;
33
33
  /** The text's vertical offset from the layer */
@@ -1,9 +1,24 @@
1
1
  import { Dynamic } from '../util';
2
- import { Base, BaseOptions } from './base';
3
2
  import { Visual, VisualOptions } from './visual';
4
3
  declare type Constructor<T> = new (...args: unknown[]) => T;
5
- interface VisualSource extends Base {
4
+ interface VisualSource extends Visual {
6
5
  readonly source: HTMLImageElement | HTMLVideoElement;
6
+ /** What part of {@link source} to render */
7
+ sourceX: Dynamic<number>;
8
+ /** What part of {@link source} to render */
9
+ sourceY: Dynamic<number>;
10
+ /** What part of {@link source} to render, or undefined for the entire width */
11
+ sourceWidth: Dynamic<number>;
12
+ /** What part of {@link source} to render, or undefined for the entire height */
13
+ sourceHeight: Dynamic<number>;
14
+ /** Where to render {@link source} onto the layer */
15
+ destX: Dynamic<number>;
16
+ /** Where to render {@link source} onto the layer */
17
+ destY: Dynamic<number>;
18
+ /** Where to render {@link source} onto the layer, or undefined to fill the layer's width */
19
+ destWidth: Dynamic<number>;
20
+ /** Where to render {@link source} onto the layer, or undefined to fill the layer's height */
21
+ destHeight: Dynamic<number>;
7
22
  }
8
23
  interface VisualSourceOptions extends VisualOptions {
9
24
  source: HTMLImageElement | HTMLVideoElement;
@@ -28,5 +43,5 @@ interface VisualSourceOptions extends VisualOptions {
28
43
  * A layer that gets its image data from an HTML image or video element
29
44
  * @mixin VisualSourceMixin
30
45
  */
31
- declare function VisualSourceMixin<OptionsSuperclass extends BaseOptions>(superclass: Constructor<Visual>): Constructor<VisualSource>;
46
+ declare function VisualSourceMixin<OptionsSuperclass extends VisualOptions>(superclass: Constructor<Visual>): Constructor<VisualSource>;
32
47
  export { VisualSource, VisualSourceOptions, VisualSourceMixin };
@@ -1,4 +1,4 @@
1
- import { Dynamic } from '../util';
1
+ import { Dynamic, Color } from '../util';
2
2
  import { Base, BaseOptions } from './base';
3
3
  import { Visual as VisualEffect } from '../effect/visual';
4
4
  interface VisualOptions extends BaseOptions {
@@ -6,9 +6,9 @@ interface VisualOptions extends BaseOptions {
6
6
  y?: Dynamic<number>;
7
7
  width?: Dynamic<number>;
8
8
  height?: Dynamic<number>;
9
- background?: Dynamic<string>;
9
+ background?: Dynamic<Color>;
10
10
  border?: Dynamic<{
11
- color: string;
11
+ color: Color;
12
12
  thickness?: number;
13
13
  }>;
14
14
  opacity?: Dynamic<number>;
@@ -19,9 +19,9 @@ declare class Visual extends Base {
19
19
  y: Dynamic<number>;
20
20
  width: Dynamic<number>;
21
21
  height: Dynamic<number>;
22
- background: Dynamic<string>;
22
+ background: Dynamic<Color>;
23
23
  border: Dynamic<{
24
- color: string;
24
+ color: Color;
25
25
  thickness: number;
26
26
  }>;
27
27
  opacity: Dynamic<number>;
package/dist/movie.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @module movie
3
3
  */
4
- import { Dynamic } from './util';
4
+ import { Dynamic, Color } from './util';
5
5
  import { Base as BaseLayer } from './layer/index';
6
6
  import { Base as BaseEffect } from './effect/index';
7
7
  declare global {
@@ -20,7 +20,7 @@ export declare class MovieOptions {
20
20
  /** @deprecated Use <code>actx</code> instead */
21
21
  audioContext?: AudioContext;
22
22
  /** The background color of the movie as a cSS string */
23
- background?: Dynamic<string>;
23
+ background?: Dynamic<Color>;
24
24
  repeat?: boolean;
25
25
  /** Call `refresh` when the user changes a property on the movie or any of its layers or effects */
26
26
  autoRefresh?: boolean;
@@ -32,13 +32,22 @@ export declare class MovieOptions {
32
32
  */
33
33
  export declare class Movie {
34
34
  type: string;
35
+ /**
36
+ * @deprecated Auto-refresh will be removed in the future (see issue #130).
37
+ */
35
38
  publicExcludes: string[];
36
39
  propertyFilters: Record<string, <T>(value: T) => T>;
37
40
  repeat: boolean;
38
- /** Call `refresh` when the user changes a property on the movie or any of its layers or effects */
41
+ /**
42
+ * Call `refresh` when the user changes a property on the movie or any of its
43
+ * layers or effects
44
+ *
45
+ * @deprecated Auto-refresh will be removed in the future. If you want to
46
+ * refresh the canvas, call `refresh`. See issue #130.
47
+ */
39
48
  autoRefresh: boolean;
40
49
  /** The background color of the movie as a cSS string */
41
- background: Dynamic<string>;
50
+ background: Dynamic<Color>;
42
51
  /** The audio context to which audio output is sent during playback */
43
52
  readonly actx: AudioContext;
44
53
  readonly effects: BaseEffect[];
package/dist/object.d.ts CHANGED
@@ -3,7 +3,11 @@ import { Movie } from './movie';
3
3
  export default interface EtroObject {
4
4
  /** Used in etro internals */
5
5
  type: string;
6
- /** Which properties to not watch for changes, for `Movie#autoRefresh` */
6
+ /**
7
+ * Which properties to not watch for changes, for `Movie#autoRefresh`
8
+ *
9
+ * @deprecated `Movie#autoRefresh` is deprecated
10
+ */
7
11
  publicExcludes: string[];
8
12
  /** Map of property name to function to run on result of `val` */
9
13
  propertyFilters: Record<string, <T>(value: T) => T>;
package/dist/util.d.ts CHANGED
@@ -120,6 +120,8 @@ export declare function mapPixels(mapper: (pixels: Uint8ClampedArray, i: number)
120
120
  * <p>Must be called before any watchable properties are set, and only once in
121
121
  * the prototype chain.
122
122
  *
123
+ * @deprecated Will be removed in the future (see issue #130)
124
+ *
123
125
  * @param target - object to watch
124
126
  */
125
127
  export declare function watchPublic(target: EtroObject): EtroObject;
package/eslint.conf.js CHANGED
@@ -10,7 +10,9 @@ module.exports = {
10
10
  Atomics: 'readonly',
11
11
  SharedArrayBuffer: 'readonly'
12
12
  },
13
+ parser: '@typescript-eslint/parser',
13
14
  parserOptions: {
15
+ // requireConfigFile: false,
14
16
  ecmaVersion: 2018,
15
17
  sourceType: 'module'
16
18
  },
@@ -1,5 +1,4 @@
1
1
  const conf = require('./eslint.conf.js')
2
2
  conf.env.jasmine = true
3
- conf.globals.define = 'readonly'
4
- conf.globals.etro = 'readonly'
3
+
5
4
  module.exports = conf
package/karma.conf.js CHANGED
@@ -11,15 +11,13 @@ module.exports = function (config) {
11
11
 
12
12
  // frameworks to use
13
13
  // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
14
- frameworks: ['jasmine', 'requirejs', 'es6-shim'],
14
+ frameworks: ['jasmine', 'karma-typescript'],
15
15
 
16
16
  // list of files / patterns to load in the browser
17
17
  files: [
18
- 'dist/etro-iife.js',
19
- { pattern: 'spec/*.spec.js', included: false },
20
- { pattern: 'node_modules/resemblejs/*.js', included: false },
21
- 'spec/main.js',
22
- { pattern: 'spec/assets/**/*', included: false }
18
+ 'src/**/*.ts',
19
+ 'spec/**/*.ts',
20
+ { pattern: 'spec/integration/assets/**/*', included: false }
23
21
  ],
24
22
 
25
23
  // list of files / patterns to exclude
@@ -29,12 +27,13 @@ module.exports = function (config) {
29
27
  // preprocess matching files before serving them to the browser
30
28
  // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
31
29
  preprocessors: {
30
+ '**/*.ts': ['karma-typescript']
32
31
  },
33
32
 
34
33
  // test results reporter to use
35
34
  // possible values: 'dots', 'progress'
36
35
  // available reporters: https://npmjs.org/browse/keyword/karma-reporter
37
- reporters: ['dots'],
36
+ reporters: ['dots', 'karma-typescript'],
38
37
 
39
38
  // web server port
40
39
  port: 9876,
@@ -67,12 +66,22 @@ module.exports = function (config) {
67
66
  captureConsole: true
68
67
  },
69
68
 
69
+ browserConsoleLogOptions: {
70
+ level: 'log'
71
+ },
72
+
70
73
  // Continuous Integration mode
71
74
  // if true, Karma captures browsers, runs the tests and exits
72
75
  singleRun: true,
73
76
 
74
77
  // Concurrency level
75
78
  // how many browser should be started simultaneous
76
- concurrency: Infinity
79
+ concurrency: Infinity,
80
+
81
+ client: {
82
+ jasmine: {
83
+ timeoutInterval: 10000
84
+ }
85
+ }
77
86
  })
78
87
  }