All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
0.13.0 - 2026-03-18
Movie#play()optiononDraw()(#266).
- The type for
KeyFrame.valuehas been updated fromunknown[][]to(number|T|Interpolate)[][](#259).
- Shader effects producing solid black output in browsers whose GLSL linker does not assign
a_VertexPositionto attribute location 0 (e.g., Firefox on macOS).
- Bump ejs from 3.1.8 to 3.1.10 (#271).
- Bump follow-redirects from 1.15.4 to 1.15.6 (#267).
- Bump braces from 3.0.2 to 3.0.3 (#274).
- Bump socket.io from 4.6.1 to 4.7.5 (#277).
- Bump js-yaml from 4.1.0 to 4.1.1 (#309).
- Bump @rollup/plugin-eslint from 8.0.2 to 9.2.0 (#309).
- Bump validator from 13.11.0 to 13.15.20 (#308).
- Bump pbkdf2 from 3.1.2 to 3.1.5 (#307).
- Bump cipher-base from 1.0.4 to 1.0.6 (#305).
- Bump rollup from 1.32.1 to 2.79.2 (#300).
- Bump elliptic from 6.5.4 to 6.6.1 (#299).
- Bump ws, socket.io-adapter (#281).
- Bump cookie, socket.io (#283).
- Bump body-parser from 1.20.1 to 1.20.3 (#285).
- Bump shipjs from 0.26.3 to 0.27.0 (#314).
- Bump basic-ftp from 5.0.4 to 5.2.0 (#320).
0.12.1 - 2024-02-19
- Importing etro in the client-side code of a NextJS project causing a "module not found" error (#243).
- Keyframes with values that are not numbers no longer result in type mismatches.
TypeError: this.data is undefinedwhen applying aTransformeffect with a dynamic matrix.
0.12.0 - 2024-01-15
strokeoption forTextlayer (#239).
- Bump @babel/traverse from 7.18.13 to 7.23.2 (#244).
- Bump browserify-sign from 4.2.1 to 4.2.2 (#245).
- Bump follow-redirects from 1.14.9 to 1.15.4 (#247).
- Bump gitmoji-cli from 8.4.0 to 9.0.0.
0.11.0 - 2023-08-05
durationoption forMovie#play(#208).
- Audio and video layers going silent after the first time recording the movie (#106).
Failed to set the 'currentTime' property on 'HTMLMediaElement'error when seeking audio and video layers (#227).- Seeking while playing not updating the movie's current time (#233).
- Bump word-wrap from 1.2.3 to 1.2.5 (#222).
0.10.1 - 2023-07-16
- Bump engine.io and socket.io.
- Bump socket.io-parser from 4.2.1 to 4.2.3.
0.10.0 - 2023-04-18
Movie#stream()to stream the movie to aMediaStream.- New
onStartoption forMovie#play()andMovie#record(). - Image, audio and video layers'
sourceproperties now accept urls (#153). - Movies, layers and effects have a new
readygetter, indicating if they are ready to play. - Layers and effects now have an async
whenReadymethod. Movie#seek()method.- Layers have new
seek()andprogress()methods. onceoption forsubscribe.
- The (deprecated)
'movie.pause'event is now published every time playback stops, regardless of the reason. sourceproperties ofImage,AudioandVideohave been retyped toHTMLImageElement,HTMLAudioElementandHTMLVideoElementrespectively.
etro.applyOptions()andEtroObject#getDefaultOptions()are deprecated. Instead, set each option in the constructor (#131).- The
Movie#currentTimesetter is deprecated. UseMovie#seek()instead. Movie#setCurrentTime()is deprecated. Instead, callseek()andrefresh()separately.- The
'movie.seek'event is deprecated. Override theseek()method on layers instead. - The
'movie.timeupdate'event is deprecated. Override theprogress()method on layers instead. - The
'movie.loadeddata'event is deprecated. - The
'movie.play'event is deprecated. Provide theonStartoption toplay(),stream()orrecord()instead. - The
'movie.pause'event is deprecated. Wait forplay(),stream()orrecord()to resolve instead. - The
'movie.record'event is deprecated. Provide theonStartoption torecord()instead. - The
'movie.recordended'event is deprecated. Wait forrecord()to resolve instead. - The
'movie.ended'event is deprecated.
Movie#autoRefresh(see #130).changeevents (see #130).watchPublic()andpublicExcludes(see #130).
Movie#currentTimeis now reset to 0 when the movie ends.Movie#play()andMovie#record()now wait until all resources are loaded before starting.Movie#pause()no longer stops inactive layers (#203).- Array methods like
unshiftforetro.layer.Visual#effectsandetro.effect.Stack#effectswork properly. AudioSource#playbackRateis now optional.durationoption forAudioandVideolayers is now optional.Videoconstructor now accepts missing options.
0.9.1 - 2022-09-18
- Update color types from
stringtoColor(#135). ImageandVideoclasses now include missing properties.Movie#currentTimeno longer exceeds the stop time.
0.9.0 - 2022-07-17
- Methods in the
Baseeffect now acceptBaselayers instead ofVisuallayers.
- Layers no longer trigger infinite loops when their active states change (#127).
- Add missing
VisualSourceoptions toImagelayer (#128). - Layers are now stopped when recording ends.
stop()is no longer called on inactive layers.- Movies no longer publish
'movie.ended'when done recording. AudioandVideolayers not detaching properly.- When done playing or recording, movies only reset their time if they're in repeat mode.
- The
timeupdateevent is no longer fired whencurrentTimeremains the same (due toperformance.now()rounding).
0.8.5 - 2022-03-06
vd.effect.Base- All visual effects now inherit fromvd.effect.Visualinstead.
- Movie constructor throwing
Can't find variable: AudioContexton WebKit browsers.
0.8.4 - 2022-02-23
- Major memory leak.
Movie#play()not resolving.Movie#pausedset to false after done playing or recording.- Movies'
currentTimebeing off by a fraction of a second a few frames after playing. - Movies'
currentTimesetter not respectingautoRefresh.
0.8.3 - 2022-01-18
- Recording not respecting the
typeoption. - Effects throwing 'empty canvas' errors when the target's width or height is 0.
0.8.2 - 2021-07-08
GaussianBlureffect throwing aTypeErrorwhen applied to a movie or layer (the problem persisted).- Ignore layers and effects removed with
delete.
0.8.1 - 2021-04-20
sourceStartTimegetting ignored on'movie.seek'.- Calling methods like
unshiftonMovie#layersandMovie#effects. GaussianBlureffect throwing aTypeErrorwhen applied to a movie or layer.- Issues with audio and video layers re-attaching to a movie.
0.8.0 - 2021-04-11
- Type declarations.
durationoption forMovie#record, to only record a subsection of the movie.'movie.recordended'event. This does not affect the behavior of'movie.ended'.- Grayscale effect.
etro.event.unsubscribeto remove event listeners.- Image and video layers'
destX,destY,destWidthanddestHeight.- Previously
imageX,imageY,imageWidth,imageHeight, ... - Allows for rotating these layers without cropping out parts.
- Previously
- All constructor arguments are now supplied through an
optionsobject. - Now
Movie#recordalso accepts its arguments through anoptionsobject. - Keyframes are now entered as
new etro.KeyFrame([time1, val1, interp], [time2, val2]) - Rename
clip*tosource*for image layers.clipXis nowsourceX, etc.
- Rename
imagetosourcefor image layers. - Rename
sourcetoaudioNodeandmediatosourcefor audio and video layers.- And
mediaStartTimetosourceStartTime
- And
- For image and video layers,
widthnow defaults todestWidth, which defaults tosourceWidth, which defaults to the width of the image or video. - The
movie.audiodestinationupdateevent is now published on the movie instead of each layer. - The movie's
audioContextoption is nowactx(to match the property).
etro.mapPixels- useetro.effect.Shaderinstead, because it supports hardware-accelerationaudioContextoption forMovie- useactxinstead.
- Video files for examples (can now be downloaded with
npm run assets).
- Browsers that do not implement
AudioContextare now supported. - Movie not rendering with no layers.
- Issues with modifying
Movie#layersandMovie#effects. - Layers no longer error on 'movie.seek' event.
- Property filters'
thisis now set to the owner of the property. - Visual layers'
widthandheightproperty filters now default to the movie's width and height. - Visual layers'
borderproperty not being processed correctly. - Effects' and layers'
attach()anddetach()methods not being called when replaced by another effect or layer.
0.7.0 - 2020-12-17
- Importing with CommonJS syntax.
- MIME type option for
record.
- Movies are no longer hidden and silent when exporting.
- Media layers' audio nodes can now be reconnected to other audio nodes.
refreshcan be called when the movie is playing or recording to force render.
- Image layers'
imageX,imageY,imageWidthandimageHeightproperties. Every image is now rendered over its entire layer. - Video layers'
mediaX,mediaY,mediaWidthandmediaHeightproperties. Every video is now rendered over its entire layer.
- Fix recording with only video or only audio.
- Video layers'
clipWidthandclipHeightare no longer treated as invalid options. - Image layers'
clipWidthandclipHeightare no longer set in the constructor, so if theclipWidthoption is not supplied and the layer'swidthchangesclipWidthuses the newwidth. - Video and image layers'
widthandheightdefault to theirclipWidthandclipHeightrespectively. - Elliptical mask effect throwing
TypeError: path.split is not a function. - In shader effects, textures whose dimensions are not powers of two accept interpolation filters.
- No longer ignore video layers'
mediaWidthoption. - Treat layers'
enabledproperty as dynamic (allowing for keyframes and functions). - Make each media layer's duration depend on its playback rate.
- Update vulnerable dependencies.
0.6.0 - 2019-12-26
- Add API documentation.
- Support enabling and disabling layers and effects.
- Implement more movie events (movie.play, movie.record, movie.pause, movie.change.duration).
- Implement property filters.
- Implement property caching.
- Media layer supports media whose duration changes.
- Add unimplemented
etro.Fontproperties. - Add example that uses a live stream (the webcam).
- Add layer
startandstopmethods. - Add layer and effect
attachanddetachmethods. - Make some properties public (
_getDefaultOptions,_publicExcludes,layer.Base#_render,event._publish,layer.Base#_render,event._publish,layer.Visual#_doRender). - Change
etro.val(property, element, time)→etro.val(element, path, time). - Make event properties specific to event type
- layer.attach|detach:
source→effectTarget - effect.attach|detach:
source→effectTarget - movie.change.layer.add|remove:
source→layer - movie.change.effect.add|remove:
source→effect
- layer.attach|detach:
- Media current time is no longer reset every time it's played.
- Fix Gaussian blur effect throwing error.
- Custom textures work for shader effects.
- Fix undefined behavior with shader effects that output transparency.
- Use
sourceTextureOptionsin shader effects. - Recursive property changes now emit events with
etro.watchPublic. - Public properties set to keyframes are treated as keyframes.
- Update event names in examples.
0.5.0 - 2019-10-09
- Movies and layers auto-refresh.
- Rewrite event system.
- Events propogate up.
- Event names are organized into groups.
- Update IIFE global export from
mvtoetro. - Fix recording audio.
- Fix recording movies without audio in Chrome.
- Fix effects for movies.
0.4.0 - 2019-08-18
- WebGL fragment shader effects, with which you can re-render a layer or movie with a GLSL fragment shader.
- New
initialRefreshmovie option that can prevent rendering on init.
- Most visual effects now use GLSL.
- New
elementargument passed to function properties to see which Etro object the property belongs to.
0.3.0 - 2018-12-11
- Function properties.
- Dynamic properties that call a function every time they're queried.
- Null or undefined layer dimensions default to the width or height of the movie.
- Movie "end" event is now called "ended".
- Volume, speed and muted properties. These will most likely be added as separate audio effects in the future.
- Bug with layer options
0.2.0 - 2018-10-14
- Keyframes
- Works with any value type in pretty much every built-in component property.
- Number and objects, including colors and fonts, can interpolate.
- Custom interpolation option.
- Elliptical mask effect.
- Many small improvements.
- Movies
- Timeline
- Playing
- Exporting
- Layers
- Base layers
- Text layers
- Image layers
- Audio layers
- Video layers
- Effects
- Transparency
- Brightness
- Contrast
- Channels
- Gaussian blur
- Transform