W3C home > Mailing lists > Public > public-fx@w3.org > October to December 2015

Javascript properties and Houdini types

From: Kevin Doughty <socallednonflipped@gmail.com>
Date: Sun, 29 Nov 2015 19:25:05 -0500
Message-ID: <CAAbwtRwau8_s2HUrE0O=NnZ9tkRckwoCJuivubN+iW0O=ngZ1Q@mail.gmail.com>
To: public-fx@w3.org, public-houdini@w3.org
I would like to animate arbitrary properties of Javascript objects. I find
Houdini Properties and Values to be really compelling, and would like to be
able to trigger animations of non-CSS properties using something similar to
the apply function. I envision Object.defineProperty as a possible place to
declare transitions of Javascript property values. I saw one comment in an
early Houdini draft that suggested it could be a place to trigger CSS
animations, and I hope this is revisited.


I have a Javascript framework loosely based on Core Animation. It is meant
for use with code that depends on DOM diffing with a render function. The
primary difference of other animation techniques is the easy access to
specified vs. animated values. I achieve this by making copies of the
Javascript object whose properties are to be interpolated, and compositing
the values onto the new object. Then the render function is bound to the
copy, so the same code is provided animated values. This is very similar to
behavior of Core Animation model and presentation layers. Core Animation
has a third private layer, the render tree, which I do not consider because
of Javascript’s single threaded nature.


One problem I fear is the community making decisions about the future of
Javascript is concerned with language and syntax, and does not consider
animation. Conversely, the community making decisions about the future of
animation are focused solely on CSS and SVG properties, but they ignore the
numerous frameworks that use DOM diffing and animate by rAF with a render
function.


This gap needs to be bridged. Along with those DOM diffing frameworks,
there are plenty of other uses, for example animating canvas and webGL
(vertices at least) with a unified animation API.


My goal is discrete app state. This is partially accomplished by relative
additive animation. Along with this, animations that rely on imperative
function calls in completion handlers must be avoided. The reason for this
is to prevent indeterminate state between animation start and stop. When
interrupting, all possibilities must be known and reasoned about, which is
undesirable. Thus the need to do everything at once, at the start of an
animation.


I will give two common examples of where completion handlers are typically
used but could be avoided. The first is simpler, fading out an element but
not removing it, merely setting display:none. This is a place where many
might make the lazy choice to depend on a callback. Web Animations in some
form or other would allow for a constant animation on the property display
to animate from “block” to “block”, which would bring the element back for
the duration of an opacity fade.


The more complicated example is animating insertion and removal children.
It would require a new Houdini Properties and Values type. I see you have
arrays, which seem to be for ordering transform functions. I would want
arrays for animating arrays of number types, like points on a canvas or
webGL vertices. But I propose a new animatable type, for mathematical sets.
Because they are unordered, their contents would not be individually
interpolatable like arrays. Instead, they would discretely animate their
contents from one state to another, behaving like Web-Animations
non-numeric values.


If you animate children as sets then you can avoid completion handers. Of
course the animation is additive and relative, you should know I would be
advocating this by now. The only requirement is that elements must be
sortable, with the limitation that data sets must be reasonably small.


Take for instance animating form children A-B-C-D to A-B-D. Element C will
be removed. Old minus new, A-B-C-D minus A-B-D leaves C. Then when added
back to the underlying, non-animated value of A-B-D, results in A-B-D-C
which must then be sorted. An opacity animation would fade out while the
children set animation would keep the child being removed in place until
the animation is completed. Bringing an element back from A-B-D to A-B-C-D
does not require any work. Subtraction results in an empty set. The element
is added instantly and that is all you need to do, other than run an
opacity fade or other animation. Like the display:none example this avoids
race conditions and corruption of state entirely, albeit in simple cases.


I have some example code. The first shows what I’ve just described, in
three columns. On the left are buttons to trigger insertion and removal.
The middle column shows the display:none technique. The right column shows
removal of children.

http://codepen.io/kvndy/pen/avedLe/?editors=001


The second is a case for interpolating arrays of numbers for canvas
drawing. The render function is provided with an array of numbers with the
animations already composited. This is opposed to animation techniques in
frameworks like React which require manual conversion / function calls to
get the animated value. They may argue that those calls are trivial, to
which I would reply that DOM manipulation is also trivial. If they go
through the trouble of making a declarative render function then animated
values should be provided automatically, otherwise their render function is
not so declarative. Thus the render function here just needs to loop
through points and plot them.

http://codepen.io/kvndy/pen/KdrWKN?editors=001


I make arbitrary decisions in my animation code to provide composited
presentation values to the render function, which would need to be a
decision made by authors of Javascript frameworks. But having a way to
automatically composite values from animations from one Javascript object
into another, easily accessed and using the same animation API that backs
CSS, would be a revolution for the web.


Thanks for considering this proposal.
Received on Monday, 30 November 2015 00:25:37 UTC

This archive was generated by hypermail 2.3.1 : Monday, 30 November 2015 00:25:37 UTC