SVG F2F Auckland 2011
snapshotTime
) — are there other use cases? An animation debugger perhaps such as Firebug plugin?The semantic argument is probably valid but few concrete use cases makes it hard to develop specs based on this criteria alone.
Sometimes you can't/don't want to allow scripts. For example,
SVG is gradually penetrating deeper into the Web platform.
From an implementation point of view:
From an authoring point of view:
begin="a.begin"
vs begin="a.beginEvent"
<animate id="a" dur="5s" end="elem.mouseout" .../> <animate id="b" begin="a.end+1s" ... /> <animate id="c" begin="b.begin+3s" ... />
We'd like to distinguish between A running to completion (→ B and C should play) and A being cancelled via mouseout (→ B and C should not play).
<animate begin="5s" id="a" ... /> <animate begin="a.begin+2s" ... /> <animate begin="a.begin+1s" ... />
becomes:
<par begin="5s"> <animate id="a" ... /> <animate begin="2s" ... /> <animate begin="1s" ... /> </par>
SMIL 3.0 has three types of time container:
<par>
- "parallel" — elements play at the same time, e.g.
<par begin="5s"> <animate id="a" ... /> --> starts at t=5s <animate begin="2s" ... /> --> starts at t=7s <animate begin="1s" ... /> --> starts at t=6s </par>
<animation>
<seq>
- "sequence" — elements play one after another, e.g.
<seq begin="5s"> <animate dur="2s" ... /> --> starts at t=5s <animate dur="3s" ... /> --> starts at t=7s (5s + 2s dur) <animate begin="1s" dur="2s" ... /> --> starts at t=11s (7s + 3s dur + 1s offset) </seq>
Unlike <par>, children of a <seq> can only have a single non-negative offset as a begin value. i.e. you can't use event-based timing, wallclock timing, etc. inside a <seq>.
<excl>
- "exclusive"? — only one element can play at a time. Starting one element stops all others. e.g.
<excl> <animate begin="buttonA.click" ... /> <animate begin="buttonB.click" ... /> <animate begin="buttonC.click" ... /> </excl>
Containers can be nested. For example,
<seq> <!-- Phase 1 of animation --> <par> <animate /> <animate /> </par> <!-- Phase 2 --> <par> <animate /> <animate /> </par> </seq>
Applying to syncbase timing:
<animate begin="5s" id="a" ... /> <animate begin="a.end+1s" id="b" ... /> <animate begin="b.begin+2s" ... />
becomes:
<seq begin="5s"> <animate id="a" ... /> <par begin="1s"> <animate id="b" ... /> <animate begin="2s" ... /> </par> </seq>
<seq>
-style containers are just 1-to-1
a.begin
vs a.beginEvent
animation-name
in CSS Animations.
Challenge 1: There are some syncbase arrangements which can't be realised with these containers as specified.
e.g.
<animate id="a" ... /> <animate begin="a.end-1s"/>
We'd like to write:
<seq> <animate id="a" ... /> <animate begin="-1s"/> </seq>
But SMIL doesn't allow negative offset times for <seq> children.
e.g. (2)
<animate id="a" begin="b.end; click" restart="whenNotActive" ... /> <animate id="b" begin="a.end; click" restart="whenNotActive" ... />
A regular ping-pong arrangement is easy:
<seq repeatDur="indefinite"> <animate/> <animate/> </seq>
But in this case we want to be able to start the animation mid-way. We'd like to do:
<seq repeatDur="indefinite"> <animate begin="id1.click" .../> <animate begin="id2.click" .../> </seq>
But again, <seq> children can't have event-based begin conditions.
We could:
Challenge 2: Migration path. How can we drop syncbase timing without anyone noticing?
One possibility:
<excl>
(for now)
endsync
, fillDefault
, restartDefault
etc.
Don't necessarily need <par>
and <seq>
elements. SMIL also allows adding a timeContainer
attribute to existing elements. e.g.
<g timeContainer="par"> <animate ... /> </g>
<animation>
already offers a new <par>
time container—perhaps we could extend that
<animate>
element is removed whilst in play and later rebound what animation state is preserved?
<svg>
element is removed and rebound what state is preserved? What events get dispatched?
fill
attribute to 'freeze'
after an animation has finished
Compare:
<rect width="100" height="50"> <animate attributeName="width" calcMode="discrete" begin="0s" dur="2s" to="300" fill="freeze"/> </rect>
and:
<rect height="50"> <animate attributeName="width" calcMode="discrete" begin="0s" dur="2s" from="100" to="300" fill="freeze"/> </rect>
(Test URL: https://bug544855.bugzilla.mozilla.org/attachment.cgi?id=493392)
Test http://dev.w3.org/SVG/profiles/1.2T/test/svg/animate-elem-227-t.svg still mandates the wrong behaviour.
Make discrete to-animation set the animation value to the base value for half the duration and then the to-value for the remainder of the duration.
i.e. <animate calcMode="discrete" to="<value>" .../>
is equivalent to:<animate calcMode="discrete" from="<underlying-value>" to="<value>" .../>
Opera and WebKit already do this.
To-animation behaves differently when frozen to when active. According to SMIL:
A frozen to animation takes on the value at the time it is frozen, masking further changes in the underlying value. This matches the dominance of the to value at the end of the simple duration. Even if other, lower priority animations are active while a to animation is frozen, the value does not change.
Proposal: Adopt Opera's behaviour
Specifically, the following piece of pseudocode from SMIL 3.0 5.4.5 End of an interval:
// Events leave the end open-ended. If there are other conditions // that have not yet generated instances, they must be unresolved. if endHasEventConditions() OR if the instance list is empty tempEnd = UNRESOLVED; // if all ends are before the begin, bad interval else return FAILURE;
The presence of a single end time / end instance changes the behaviour considerably. e.g.
<animate begin="1s; 3s" ... /> → 2 intervals <animate begin="1s; 3s" end="2s" .../> → 1 interval
Even with beginElement
you can't restart the second one after t=2s.
It also contributes to a problem with reset behaviour.
I think we want to change this pseudocode:
// Events leave the end open-ended. If there are other conditions // that have not yet generated instances, they must be unresolved. if endHasEventConditions() OR if the instance list is empty tempEnd = UNRESOLVED; // if all ends are before the begin, bad interval else return FAILURE;
To simply:
tempEnd = UNRESOLVED;
But rather than hacking the pseudocode, it would be enough simply to say,
In SVG, theend
attribute is always considered to include the'indefinite'
value as the last item in the list of end times, whether it is explicitly specified or not.
That seems to be what Opera and WebKit do anyway.
It doesn't seem to help with actual use cases: https://lists.w3.org/Archives/Public/www-smil/2010AprJun/0006.html.
Proposal: Deprecate/remove wallclock timing
I don't think anyone's using this so could we get away with just dropping it?
I don't think they're currently used, but they may actually become useful if we go with time containers (and phase out syncbase timing). e.g. repeat-to-fill
<par max="10s"> <animate repeatDur="indefinite" ... /> </par>
Let's wait to see if min/max are useful in combination with time containers.
Many issues, e.g.:
transform
attribute refers to a transform list but animateTransform only operates on a single transform object
<animateTransform>
element?
<animateTransform>
elements just get post-multiplied to that one?
<animateTransform>
? Just define the additional type
attribute on <animate>
? Or change the syntax of <animateTransform>
values to include the transform type?
<animateMotion>
and <animateTransform>
?
The swelling button use case.
autoReverse
however but it will reverse as soon as the active duration is reached.
e.g. Introduce a container level attribute reverse
that takes a begin-value-list
, e.g.
<par begin="mouseover" reverse="mouseout"> <animate ... /> </par>
end
is confusing. Is it useful to distinguish the two? i.e. a list of times/conditions that will cause the animation to reverse, and a parallel list that will cause it to stop it in its tracks?
reverse="auto"
value to match SMIL's autoReverse
, i.e. reverse as soon as the group reaches its active end.
Lots of issues:
keySplines
, does the reverse transition → ease-in or an ease-out?
animation-direction="alternate"
makes ease-in become ease-out).
SMIL animations are re-usable or scalable. They have a single target:
This means:
animation-name
For example,
As it happens, SMIL Timesheets provides CSS selectors to specify animation targets.
<timesheet> <seq> <item select="#Slide1" dur="5s" /> <item select="#Slide2" dur="5s" /> <item select="#Slide3" dur="5s" /> </seq> </timesheet>
which can also be written:
<timesheet> <seq> <item select=".Slide" dur="5s"/> </seq> </timesheet>
SMIL Timesheets introduces <item>
which behaves like an animation, applying the appropriate timeAction
to the target.
<timesheet> <seq> <item select=".Slide" dur="15s"> <par> <item select=".Bullet" beginInc="3s"> <animate select=".Bullet" attributeType="CSS" attributeName="margin-left" values="200;0" dur="1s" /> </item> </par> </item> </seq> </timesheet>
beginInc
<par> <item select=".Bullet" beginInc="1s" /> </par>
Increments the begin time of each of the elements, but the first one, by the defined value.
index()
function
e.g.
<defs> <!-- This animation is used on-demand like a filter --> <par id="hoverAnim"> <animate select="text:first-child" ... /> <animate select="rect" attributeName="fill" ... /> </par> </defs> <g style="animation-name:'hoverAnim'">...</g> <!-- This animation is automatically applied --> <par select=".className"> ... </par>
<item>
attributeName
→attr
), dropping features (attributeType
, syncbase timing etc.), greater simplifications, aligning better with CSS