Start reworking Animation values/effects section

Fri, 15 Mar 2013 15:17:54 +0900

author
Brian Birtles <birtles@gmail.com>
date
Fri, 15 Mar 2013 15:17:54 +0900
changeset 749
382bb806622e
parent 748
5a64938d0a49
child 750
3047a7fb9f03

Start reworking Animation values/effects section

web-anim/index.html file | annotate | diff | comparison | revisions
     1.1 --- a/web-anim/index.html	Thu Mar 14 21:41:18 2013 -0700
     1.2 +++ b/web-anim/index.html	Fri Mar 15 15:17:54 2013 +0900
     1.3 @@ -2550,16 +2550,17 @@
     1.4        <h2>Animations</h2>
     1.5        <p>
     1.6          <dfn title="animation">Animations</dfn> are a kind of <a>timed item</a>
     1.7 -        that apply an animation effect to a target element or pseudo-element
     1.8 -        such as <code>::before</code> and <code>::first-line</code> [[!SELECT]].
     1.9 +        that apply an <a>animation effect</a> to a target element or
    1.10 +        pseudo-element such as <code>::before</code> and
    1.11 +        <code>::first-line</code> [[!SELECT]].
    1.12        </p>
    1.13        <section>
    1.14          <h3>Calculating the time fraction</h3>
    1.15          <p>
    1.16            Before passing the <a>transformed time</a> of an <a>animation</a> to
    1.17 -          its animation effect we must convert it to a <em>time fraction</em>.
    1.18 -          The <dfn>time fraction</dfn> of a <a>timed item</a> is calculated
    1.19 -          according to the following steps:
    1.20 +          its <a>animation effect</a> we must convert it to a <em>time
    1.21 +          fraction</em>.  The <dfn>time fraction</dfn> of a <a>timed item</a> is
    1.22 +          calculated according to the following steps:
    1.23          </p>
    1.24          <dl class="switch">
    1.25            <dt>
    1.26 @@ -2604,716 +2605,133 @@
    1.27        </section>
    1.28      </section>
    1.29  
    1.30 +    <section class="informative">
    1.31 +      <h2>Overview of the animation model</h2>
    1.32 +      <p>
    1.33 +        The Web Animations <em>animation model</em> takes the <a
    1.34 +        title="time fraction">time fractions</a> produced by the <em>timing
    1.35 +        model</em> for a given <a>animation</a> and applies it as the input to
    1.36 +        an <a>animation effect</a> defined for the <a>animation</a>.
    1.37 +        The output of each <em>animation effect</em> is then combined using
    1.38 +        a global animation stack before being applied to the target properties
    1.39 +        (see <a href="#combining-animations" class="sectionRef"></a>).
    1.40 +      </p>
    1.41 +      <p>
    1.42 +        In order to support <a>accumulation</a> behavior the animation model
    1.43 +        also requires the timing model to supply an <a>animation</a>'s
    1.44 +        <a>current iteration</a> along with its <a>time fraction</a>.
    1.45 +      </p>
    1.46 +    </section>
    1.47 +
    1.48      <section>
    1.49 -      <h2>Animation values</h2>
    1.50 -      <div class="informative">
    1.51 +      <h2>Animation effects</h2>
    1.52 +      <p>
    1.53 +        An <dfn>animation effect</dfn> takes a <a>time fraction</a> and uses it
    1.54 +        to calculate an <a>animation value</a> for its target property.
    1.55 +        Each <a>animation</a> may have at most one <a>animation effect</a>
    1.56 +        associated with it.
    1.57 +      </p>
    1.58 +      <p class="issue">
    1.59 +        We will probably lift this restriction and allow animations to have
    1.60 +        multiple effects.
    1.61 +      </p>
    1.62 +      <p>
    1.63 +        Since the result of an <a>animation effect</a> is based on the
    1.64 +        <a>time fraction</a> it is updated whenever the timing model is <a
    1.65 +        title="sampling">sampled</a>.
    1.66 +        Note that changes to the timing model caused by using the <a
    1.67 +        href="#script-interface">programming interface</a> do not cause the
    1.68 +        animation model to be updated as described in <a
    1.69 +        href="#interaction-with-script" class="sectionRef"></a>.
    1.70 +      </p>
    1.71 +      <section>
    1.72 +        <h3>Accumulating animation values</h3>
    1.73          <p>
    1.74 -          The Web Animations <em>animation model</em> takes the <a
    1.75 -          title="time fraction">time fractions</a> produced by the <em>timing
    1.76 -          model</em> for a given <a>Animation</a> and applies it as the input to
    1.77 -          the <em>animation effect</em> defined for the <a>Animation</a> object.
    1.78 -          The output of each <em>animation effect</em> is then combined using
    1.79 -          a global animation stack before being applied to the target property
    1.80 -          (see <a href="#combining-animations" class="sectionRef"></a>).
    1.81 +          <a title="animation effect">Animation effects</a> may be defined such
    1.82 +          that as the <a>animation</a> with which they are associated is
    1.83 +          repeated the <a>animation value</a> produced builds on the value
    1.84 +          produced by previous iterations.
    1.85 +          This behavior is called <dfn>accumulation</dfn>.
    1.86          </p>
    1.87          <p>
    1.88 -          The entry-point to the <em>animation model</em> is the
    1.89 -          <a>AnimationEffect</a> or <a>CustomAnimationEffect</a> object
    1.90 -          associated with each <a>Animation</a>.
    1.91 -          These objects describe how animation values should be calculated for
    1.92 -          the <a>Animation</a> for any given time.
    1.93 -          <a>AnimationEffect</a> serves as an abstract interface of which
    1.94 -          several concrete subclasses are provided.
    1.95 -        </p>
    1.96 -      </div>
    1.97 -      <section>
    1.98 -        <h3>The <code>AnimationEffect</code> interface</h3>
    1.99 -        <dl title="interface AnimationEffect" class="idl">
   1.100 -          <dt>attribute CompositeOperation operation</dt>
   1.101 +          The <a>accumulation</a> behavior of an <a>animation effect</a> is
   1.102 +          specified by the <a>animation effect</a>'s <dfn>accumulation
   1.103 +          operation</dfn> property.
   1.104 +          The <a>accumulation operation</a> property takes one of the following
   1.105 +          two values.
   1.106 +        </p>
   1.107 +        <dl>
   1.108 +          <dt><dfn
   1.109 +            title="accumulation operation accumulate">accumulate</dfn></dt>
   1.110            <dd>
   1.111              <p>
   1.112 -              The operation used to composite this animation with the stack, as 
   1.113 -              specified by one of the <a>CompositeOperation</a> enumeration
   1.114 -              values.
   1.115 -            </p>
   1.116 -            <p>
   1.117 -              This value defaults to <code>"replace"</code>
   1.118 +              The <a>animation value</a> for the <a>animation effect</a> is
   1.119 +              added to the final <a>animation value</a> of the previous
   1.120 +              iteration.
   1.121 +            </p>
   1.122 +            <p class="issue">
   1.123 +              Should this be called <code>linear</code>?
   1.124 +              The only other sort of values I can imagine being used here would
   1.125 +              be things like <code>exponential</code> etc.
   1.126              </p>
   1.127            </dd>
   1.128 -          <dt>attribute CompositeOperation accumulateOperation</dt>
   1.129 +          <dt><dfn
   1.130 +            title="accumulation operation none">none</dfn></dt>
   1.131            <dd>
   1.132 -            <p>
   1.133 -              The operation used to composite each iteration of this animation
   1.134 -              with the result of compositing the previous animation, as
   1.135 -              specified by one of the <a>CompositeOperation</a> constants
   1.136 -              defined in this interface.
   1.137 -            </p>
   1.138 -            <p>
   1.139 -              This value defaults to <code>"replace"</code>.
   1.140 -            </p>
   1.141 -          </dd>
   1.142 -          <dt>AnimationEffect clone ()</dt>
   1.143 -          <dd>
   1.144 -            <p>
   1.145 -              Creates and returns a new object of the same type as this object's
   1.146 -              most-derived interface such that it will produce the same output
   1.147 -              as this object.
   1.148 -            </p>
   1.149 -            <p class="todo">
   1.150 -              We either need a more rigorous definition here or (probably
   1.151 -              better) a sets of steps on a per-subclass basis.
   1.152 -            </p>
   1.153 -          </dd>
   1.154 -          <dt>static AnimationEffect? createFromProperties ()</dt>
   1.155 -          <dd>
   1.156 -            <p>
   1.157 -              Creates an <a>AnimationEffect</a> representing the passed-in
   1.158 -              collection of properties.
   1.159 -            </p>
   1.160 -            <div class="note">
   1.161 -              <p>
   1.162 -                Note that this method requires handling the passed in parameter
   1.163 -                in a manner not yet supported by Web IDL and hence this method
   1.164 -                is ECMAScript-specific.
   1.165 -              </p>
   1.166 -              <p>
   1.167 -                Since accessing the properties of an ECMAScript user object can
   1.168 -                have side effects, the manner in which these properties is
   1.169 -                accessed is important.
   1.170 -                In light of this consideration the following procedure has the
   1.171 -                following properties:
   1.172 -              </p>
   1.173 -              <ul>
   1.174 -                <li>Every property is read only once.</li>
   1.175 -                <li>Properties are read in a well-defined order.</li>
   1.176 -                <li>Properties corresponding to unsupported target properties or
   1.177 -                    attributes are not read.</li>
   1.178 -              </ul>
   1.179 -            </div>
   1.180 -            <p>
   1.181 -              The interpretation of the passed-in <code>properties</code> object
   1.182 -              can be described in three parts.
   1.183 -            </p>
   1.184 -            <p><strong>Part 1 &ndash; Determine the set of
   1.185 -               animation properties</strong></p>
   1.186 -            <ol>
   1.187 -              <li>Create a list, <var>supported properties</var>, of property
   1.188 -                  names and attribute names that can be animated by the
   1.189 -                  implementation.</li>
   1.190 -              <li>Let <var>animation properties</var> be an empty sequence.</li>
   1.191 -              <li>Iterate through the properties of <code>properties</code>. For
   1.192 -                  each <var>property</var> in <code>properties</code>, if
   1.193 -                  <var>property</var> also exists in <var>supported
   1.194 -                  properties</var> based on a case-sensitive comparison, append
   1.195 -                  <var>property</var> to <var>animation properties</var>.
   1.196 -                  <p class="note">
   1.197 -                    Whilst the iteration order for properties of an ECMAScript
   1.198 -                    object is implementation-dependent, the order here is not
   1.199 -                    significant to the outcome as <var>animation
   1.200 -                    properties</var> will be sorted before being iterated over.
   1.201 -                  </p>
   1.202 -                  <p class="issue">
   1.203 -                    How do we handle <code>operation</code> and
   1.204 -                    <code>compositeOperation</code>? We'd like to be able to
   1.205 -                    list them in the same property bag but that would mean we
   1.206 -                    could never animate properties of the same name.
   1.207 -                  </p>
   1.208 -              </li>
   1.209 -            </ol>
   1.210 -            <p><strong>Part 2 &ndash; Create the <a>AnimationEffect</a>
   1.211 -               objects</strong></p>
   1.212 -            <p>
   1.213 -              The <a>AnimationEffect</a> object produced depends on the length
   1.214 -              of <var>animation properties</var> as follows:
   1.215 -            </p>
   1.216 -            <dl class="switch">
   1.217 -              <dt>If <var>animation properties</var> is of zero length,</dt>
   1.218 -              <dd>
   1.219 -                return <code>null</code>.
   1.220 -                <div class="note">
   1.221 -                  <p>
   1.222 -                    This behavior of returning <code>null</code> allows
   1.223 -                    alternative animation effects to be provided based on the
   1.224 -                    capabilities of the user agent as follows:
   1.225 -                  </p>
   1.226 -                  <pre class="example sh_javascript">
   1.227 -elem.animate(
   1.228 -  AnimationEffect.createFromProperties({ transform: 'translate(-100px)' }) ||
   1.229 -  AnimationEffect.createFromProperties({ top: '-100px' }),
   1.230 -  3);
   1.231 -                  </pre>
   1.232 -                </div>
   1.233 -              </dd>
   1.234 -              <dt>If <var>animation properties</var> has only one element,</dt>
   1.235 -              <dd>
   1.236 -                <ol>
   1.237 -                  <li>Let <var>name</var> be the value of the element
   1.238 -                      in <var>animation properties</var>.</li>
   1.239 -                  <li>Let <var>value</var> be the value of
   1.240 -                      <code>properties.<var>name</var></code>.</li>
   1.241 -                  <li>Return a new <a>KeyframeAnimationEffect</a> object
   1.242 -                      according to the steps in part 3 below based on
   1.243 -                      <var>name</var> and <var>value</var>.</li>
   1.244 -                </ol>
   1.245 -              </dd>
   1.246 -              <dt>Otherwise,</dt>
   1.247 -              <dd>
   1.248 -                <ol>
   1.249 -                  <li>Let <var>group</var> be a newly constructed
   1.250 -                      <a>GroupedAnimationEffect</a>.</li>
   1.251 -                  <li>Sort <var>animation properties</var> lexicographically by
   1.252 -                      the Unicode codepoints that define each property
   1.253 -                      name.</li>
   1.254 -                  <li>For user agents that support both a prefixed and an
   1.255 -                      unprefixed version of some CSS properties, remove all
   1.256 -                      prefixed properties from <var>animation properties</var>
   1.257 -                      where the corresponding unprefixed version is also
   1.258 -                      present.</li>
   1.259 -                  <li>Iterate through <var>animation properties</var>. For each
   1.260 -                      <var>name</var> in <var>animation properties</var>:
   1.261 -                    <ol>
   1.262 -                      <li>Let <var>value</var> be the value of
   1.263 -                          <code>properties.<var>name</var></code>.</li>
   1.264 -                      <li>Create a new <a>KeyframeAnimationEffect</a>,
   1.265 -                          <var>effect</var> object according to the steps in
   1.266 -                          part 3 below based on <var>name</var> and
   1.267 -                          <var>value</var>.</li>
   1.268 -                      <li>Append <var>effect</var> to <var>group</var>.
   1.269 -                    </ol>
   1.270 -                  </li>
   1.271 -                  <li>Return <var>group</var>.
   1.272 -                </ol>
   1.273 -              </dd>
   1.274 -            </dl>
   1.275 -            <p><strong>Part 3 &ndash; Create each
   1.276 -               <a>KeyframeAnimationEffect</a> object</strong></p>
   1.277 -            <p>
   1.278 -              Based on a given <var>name</var> and <var>value</var>, a new
   1.279 -              <a>KeyframeAnimationEffect</a> is created as follows:
   1.280 -            </p>
   1.281 -            <dl class="switch">
   1.282 -              <dt>If <var>value</var> is not of type <code>(DOMString or
   1.283 -              sequence&lt;(<a>KeyframeDictionary</a> or
   1.284 -              DOMString)&gt;)</code>,</dt>
   1.285 -              <dd>
   1.286 -                Throw a <code>TypeError</code> as defined by [[!ECMA-262]].
   1.287 -              </dd>
   1.288 -              <dt>Otherwise,</dt>
   1.289 -              <dd>
   1.290 -                Construct a new <a>KeyframeAnimationEffect</a> by calling
   1.291 -                <code>KeyframeAnimationEffect(<var>name</var>,
   1.292 -                <var>value</var>)</code>.
   1.293 -              </dd>
   1.294 -            </dl>
   1.295 -            <dl class="parameters">
   1.296 -              <dt>object properties</dt>
   1.297 -              <dd>
   1.298 -                An object whose object properties represent the CSS properties
   1.299 -                or element attributes to be animated.
   1.300 -                The values corresponding to these properties are the animation
   1.301 -                values to be applied as described above.
   1.302 -              </dd>
   1.303 -            </dl>
   1.304 +            The <a>animation value</a> for the <a>animation effect</a> is
   1.305 +            calculated independently of the <a>current iteration</a>.
   1.306            </dd>
   1.307          </dl>
   1.308 -        <div class="annotation">
   1.309 -          In future, we may expose <code>any sample (double?  timeFraction,
   1.310 -          double currentIteration, AnimationTarget? target, any
   1.311 -          underlyingValue)</code> so that the animation effects can be driven
   1.312 -          apart from the timing model.
   1.313 -          Also, doing so would allow us to do real native custom animation
   1.314 -          effects if we decide to go in that direction
   1.315 -          (see annotation in <a href="#custom-animation-effects"
   1.316 -          class="sectionRef"></a>).
   1.317 -        </div>
   1.318 +        <p class="issue">
   1.319 +          Does accumulation actually make sense for path animations or should we
   1.320 +          define this as a property of key frame animations effects only?
   1.321 +        </p>
   1.322        </section>
   1.323        <section>
   1.324 -        <h3>The <code>CompositeOperation</code> enumeration</h3>
   1.325 -        <dl title="enum CompositeOperation" class="idl">
   1.326 -          <dt>replace</dt>
   1.327 +        <h3>Calculating the animation value</h3>
   1.328 +        <p>
   1.329 +          The <a>animation value</a> of an <a>animation effect</a> for a given
   1.330 +          <a>time fraction</a> and <a>current iteration</a> is produced by first
   1.331 +          calculating the value independently of any <a>accumulation</a>
   1.332 +          behavior.
   1.333 +          This initial value is called the <dfn>iteration value</dfn> and is
   1.334 +          defined for each concrete type of <a>animation effect</a>.
   1.335 +        </p>
   1.336 +        <p>
   1.337 +          Having calculated an <a>iteration value</a> for an <a>animation
   1.338 +          effect</a>, the <dfn>animation value</dfn> is as follows:
   1.339 +        </p>
   1.340 +        <dl class="switch">
   1.341 +          <dt>If <a>accumulation operation</a> is <a
   1.342 +            title="accumulation operation none">none</a>,</dt>
   1.343            <dd>
   1.344 -            The animation should replace the value it is composited with.
   1.345 +            Return the <a>iteration value</a>.
   1.346            </dd>
   1.347 -          <dt>accumulate</dt>
   1.348 +          <dt>Otherwise,</dt>
   1.349            <dd>
   1.350 -            The animation should add to the value it is composited with.
   1.351 -            The meaning of addition is dependent on the type of animation.
   1.352 -          </dd>
   1.353 -          <dt>merge</dt>
   1.354 -          <dd>
   1.355 -            The animation should merge with the value it is composited with.
   1.356 -            The meaning of merge is dependent on the type of animation.
   1.357 -            The duration of the merge is the calculated animation duration
   1.358 -            of the <code>AnimationTemplate</code> containing this
   1.359 -            <code>AnimationEffect</code>.
   1.360 +            <ol>
   1.361 +              <li>Let <var>last value</var> be the result of evaluating
   1.362 +                  the <a>iteration value</a> of the <a>animation effect</a>
   1.363 +                  with a <a>time fraction</a> of 1.</li>
   1.364 +              <li>Let <var>previous iteration value</var> be the result of
   1.365 +                  adding <var>last value</var> to itself <a>current
   1.366 +                  iteration</a> times.
   1.367 +              <li>Return the result of adding together <var>previous iteration
   1.368 +                  value</var> and the current <a>iteration value</a> of the
   1.369 +                  <a>animation value</a> (that is, the <a>iteration value</a>
   1.370 +                  calculated for the current <a>time fraction</a>).</li>
   1.371 +            </ol>
   1.372            </dd>
   1.373          </dl>
   1.374 -      </section>
   1.375 -      <section>
   1.376 -        <h3>The <code>KeyframeAnimationEffect</code> interface</h3>
   1.377 -        <dl title="interface KeyframeAnimationEffect : AnimationEffect"
   1.378 -          class="idl">
   1.379 -          <dt>Constructor (DOMString property,
   1.380 -      (DOMString or sequence&lt;(KeyframeDictionary or DOMString)&gt;) frames,
   1.381 -      optional CompositeOperation operation = "replace",
   1.382 -      optional CompositeOperation compositeOperation = "replace")</dt>
   1.383 -          <dd>
   1.384 -            <p>
   1.385 -              Creates a new <a>KeyframeAnimationEffect</a> object for the
   1.386 -              specified property from the given list of keyframes.
   1.387 -            </p>
   1.388 -            <p>
   1.389 -              The list of keyframes may be a sequence of
   1.390 -              <a>KeyframeDictionary</a> dictionaries, a sequence of
   1.391 -              <code>DOMString</code>s, a combination of both, or
   1.392 -              a single <code>DOMString</code>.
   1.393 -            </p>
   1.394 -            <p>
   1.395 -              <code>DOMString</code>s are used to create keyframes with an
   1.396 -              offset of 1.
   1.397 -              When the list of keyframes is a sequence consisting entirely of
   1.398 -              <code>DOMString</code>s the offsets of the newly created
   1.399 -              <a>Keyframe</a>s are distributed evenly from 0 to 1.
   1.400 -            </p>
   1.401 -            <p>
   1.402 -              The <var>property</var>, <var>operation</var> and
   1.403 -              <var>compositeOperation</var> arguments are assigned to the
   1.404 -              attributes of the same names.
   1.405 -            </p>
   1.406 -            <p>
   1.407 -              The <var>frames</var> argument is processed as follows:
   1.408 -            </p>
   1.409 -            <ol>
   1.410 -              <li>Let <var>effect</var> be the
   1.411 -                  <a>KeyframeAnimationEffect</a> currently under construction.
   1.412 -              </li>
   1.413 -              <li>
   1.414 -                <p>
   1.415 -                  The processing of <var>frames</var> depends on its type as
   1.416 -                  follows:
   1.417 -                </p>
   1.418 -                <dl class="switch">
   1.419 -                  <dt>If <var>frames</var> is a <code>DOMString</code>,</dt>
   1.420 -                  <dd>
   1.421 -                    <ol>
   1.422 -                      <li>
   1.423 -                        Let <var>frame</var> be a new <a>Keyframe</a>
   1.424 -                        constructed from a <a>KeyframeDictionary</a> whose
   1.425 -                        <code>value</code> member is set to
   1.426 -                        <var>frames</var> and whose other members are set
   1.427 -                        to their default values.
   1.428 -                      </li>
   1.429 -                      <li>
   1.430 -                        Call
   1.431 -                <code><var>effect</var>.frames.add(<var>frame</var>)</code>.
   1.432 -                      </li>
   1.433 -                    </ol>
   1.434 -                  </dd>
   1.435 -                  <dt>If <var>frames</var> is a sequence of <code>(DOMString
   1.436 -                      or <a>KeyframeDictionary</a>)</code>,</dt>
   1.437 -                  <dd>
   1.438 -                    <ol>
   1.439 -                      <li>Set a flag <var>all strings</var> to
   1.440 -                          <code>true</code>.</li>
   1.441 -                      <li>
   1.442 -                        For each <var>item</var> in <var>frames</var>:
   1.443 -                        <ol>
   1.444 -                          <li>
   1.445 -                            <dl class="switch">
   1.446 -                              <dt>If <var>item</var> is
   1.447 -                                  a <code>DOMString</code>,</dt>
   1.448 -                              <dd>
   1.449 -                                Let <var>frame</var> be a new <a>Keyframe</a>
   1.450 -                                constructed from a <a>KeyframeDictionary</a>
   1.451 -                                whose <code>value</code> member is set to
   1.452 -                                <var>item</var> and whose other members are
   1.453 -                                set to their default values.
   1.454 -                              </dd>
   1.455 -                              <dt>Otherwise (<var>item</var> is
   1.456 -                                  a <a>KeyframeDictionary</a>),</dt>
   1.457 -                              <dd>
   1.458 -                                <ol>
   1.459 -                                  <li>
   1.460 -                                    Let <var>frame</var> be a new
   1.461 -                                    <a>Keyframe</a> constructed by calling
   1.462 -                                    <code>Keyframe(<var>item</var>)</code>.
   1.463 -                                  </li>
   1.464 -                                  <li>
   1.465 -                                    Set <var>all strings</var> to
   1.466 -                                    <code>false</code>.
   1.467 -                                  </li>
   1.468 -                                </ol>
   1.469 -                              </dd>
   1.470 -                            </dl>
   1.471 -                          </li>
   1.472 -                          <li>
   1.473 -                            Call
   1.474 -                <code><var>effect</var>.frames.add(<var>frame</var>)</code>.
   1.475 -                          </li>
   1.476 -                        </ol>
   1.477 -                      </li>
   1.478 -                      <li>If flag <var>all strings</var> is
   1.479 -                          <code>true</code> call
   1.480 -                        <code><var>effect</var>.frames.distribute()</code>.
   1.481 -                      </li>
   1.482 -                    </ol>
   1.483 -                  </dd>
   1.484 -                </dl>
   1.485 -              </li>
   1.486 -            </ol>
   1.487 -          </dd>
   1.488 -          <dt>attribute DOMString property</dt>
   1.489 -          <dd>
   1.490 -            The name of the target property or attribute.
   1.491 -          </dd>
   1.492 -          <dt>readonly attribute KeyframeList frames</dt>
   1.493 -          <dd>
   1.494 -            The series of values that make up this effect sorted by their
   1.495 -            offset within the iteration duration of the animation.
   1.496 -          </dd>
   1.497 -        </dl>
   1.498 -      </section>
   1.499 -      <section>
   1.500 -        <h3>The <code>KeyframeList</code> interface</h3>
   1.501 -        <p>
   1.502 -          The <a>KeyframeList</a> object is a collection of <a>Keyframe</a>
   1.503 -          objects sorted by the offset of each <a>Keyframe</a>.
   1.504 -        </p>
   1.505 -        <dl title="interface KeyframeList" class="idl">
   1.506 -          <dt>readonly attribute unsigned long length</dt>
   1.507 -          <dd>
   1.508 -            The number of frames in the list.
   1.509 -          </dd>
   1.510 -          <dt>void clear ()</dt>
   1.511 -          <dd>
   1.512 -            Removes all frames from this list.
   1.513 -          </dd>
   1.514 -          <dt>getter Keyframe? (unsigned long index)</dt>
   1.515 -          <dd>
   1.516 -            Returns the frame at <code>index</code> if it exists or
   1.517 -            <code>null</code> otherwise.
   1.518 -          </dd>
   1.519 -          <dt>Keyframe add((Keyframe or KeyframeDictionary) frame)</dt>
   1.520 -          <dd>
   1.521 -            <p>
   1.522 -              Adds <var>frame</var> to the list such that the list remains
   1.523 -              sorted by the offset of the frames.
   1.524 -            </p>
   1.525 -            <p>
   1.526 -              If <var>frame</var> is of type <a>KeyframeDictionary</a> then
   1.527 -              a <a>Keyframe</a> object is first constructed by calling
   1.528 -              <code>Keyframe(<var>frame</var>)</code> before adding the
   1.529 -              newly constructed <a>Keyframe</a> to the list.
   1.530 -            </p>
   1.531 -            <p>
   1.532 -              If there already exists a frame in this list with offset
   1.533 -              <code><var>frame</var>.offset</code>, the newly added
   1.534 -              <var>frame</var> will appear in the list <em>after</em> the
   1.535 -              already existing frames in the list with the same offset.
   1.536 -            </p>
   1.537 -            <p>
   1.538 -              If <var>frame</var> is already part of another <a>KeyframeList</a>
   1.539 -              it is first removed from that list before being added to this
   1.540 -              list.
   1.541 -            </p>
   1.542 -            <p>
   1.543 -              Exceptions:
   1.544 -            </p>
   1.545 -            <dl class="exceptions">
   1.546 -              <dt>DOMException of type <code>IndexSizeError</code></dt>
   1.547 -              <dd>
   1.548 -                Raised if <var>frame</var> is a <a>KeyframeDictionary</a> whose
   1.549 -                offset is outside the range [0,1] or missing.
   1.550 -              </dd>
   1.551 -            </dl>
   1.552 -          </dd>
   1.553 -          <dt>Keyframe? remove(unsigned long index)</dt>
   1.554 -          <dd>
   1.555 -            Removes the frame at position <var>index</var> and returns it.
   1.556 -            If index is outside the range [0, length), then <code>null</code> is
   1.557 -            returned.
   1.558 -          </dd>
   1.559 -          <dt>long indexOf(Keyframe frame)</dt>
   1.560 -          <dd>
   1.561 -            Returns the index of <var>frame</var> within the list. If
   1.562 -            <var>frame</var> is not a member of the list, returns
   1.563 -            <code>-1</code>.
   1.564 -          </dd>
   1.565 -          <dt>KeyframeList distribute()</dt>
   1.566 -          <dd>
   1.567 -            <p>
   1.568 -              Adjusts the offsets of the frames in the list such that the
   1.569 -              offsets are spaced equidistantly whilst maintaining their current
   1.570 -              order and such that the first frame (when there are multiple
   1.571 -              frames) has offset 0 and the last frame (if any) has offset 1.
   1.572 -            </p>
   1.573 -            <p>
   1.574 -              For <var>frame</var> at position <var>i</var> in the list where
   1.575 -              0 &le; <var>i</var> &lt; <code>length</code>, an offset will be
   1.576 -                assigned equal to <code>i / (length - 1)</code> unless
   1.577 -                <code>length</code> is 1 in which case it will be given offset
   1.578 -                1.
   1.579 -            </p>
   1.580 -            <p>
   1.581 -              After applying the changes, this list is returned.
   1.582 -            </p>
   1.583 -          </dd>
   1.584 -        </dl>
   1.585 -        <div class="annotation">
   1.586 -          <p>
   1.587 -            The following changes for making keyframes easier to work with in
   1.588 -            future have been proposed:
   1.589 -          </p>
   1.590 -          <pre class="example sh_javascript">
   1.591 -// Currently you have to do this
   1.592 -effect.frames.add({ property: 'left', offset: 0.3, value: '100px' }); 
   1.593 -
   1.594 -// It would be nice if you could also do this
   1.595 -effect.frames.add(0.3, 'left', '100px');
   1.596 -
   1.597 -// Also, fetching by offset would be good
   1.598 -
   1.599 -// Returns the last frame with offset 0.3 if there is one.
   1.600 -// If there is none, does the interpolation and returns a new frame? 
   1.601 -var frame = effect.frames['0.3']; 
   1.602 -          </pre>
   1.603 -        </div>
   1.604 -      </section>
   1.605 -      <section>
   1.606 -        <h3>The <code>Keyframe</code> interface</h3>
   1.607 -        <p>
   1.608 -          A <a>Keyframe</a> represents a moment within an animation that has
   1.609 -          a specified value to be applied to the target property or attribute.
   1.610 -          In between such moments values may be interpolated or filled based on
   1.611 -          the <a>TimingFunction</a> specified on the <a>TimedItem</a> where the
   1.612 -          <a>Keyframe</a> is used, or on the previous <a>Keyframe</a>.
   1.613 -        </p>
   1.614 -        <div class="issue">
   1.615 -          <p>
   1.616 -            Currently a <a>Keyframe</a> can only target a single property which
   1.617 -            is defined on the <a>KeyframeAnimationEffect</a>.
   1.618 -            This is different to CSS.
   1.619 -            Is this something we want to change?
   1.620 -            It would complicate the API, of course, but is it worth it?
   1.621 -          </p>
   1.622 -        </div>
   1.623 -        <p>
   1.624 -          <dl title="interface Keyframe" class="idl">
   1.625 -            <dt>Constructor (KeyframeDictionary dictionary)</dt>
   1.626 -            <dd>
   1.627 -              <p>
   1.628 -                Creates a new <a>Keyframe</a> object using the parameters
   1.629 -                specified in <var>dictionary</var>.
   1.630 -              </p>
   1.631 -              <p>
   1.632 -                <code><var>dictionary</var>.offset</code> is clamped to the
   1.633 -                range [0, 1] before setting.
   1.634 -              </p>
   1.635 -            </dd>
   1.636 -            <dt>attribute DOMString value</dt>
   1.637 -            <dd>
   1.638 -              The value to assign to the target attribute or property at the
   1.639 -              given offset.
   1.640 -            </dd>
   1.641 -            <dt>attribute double offset</dt>
   1.642 -            <dd>
   1.643 -              <p>
   1.644 -                A value between 0 and 1 inclusive representing the offset
   1.645 -                within the iteration duration of the animation where this value
   1.646 -                should appear.
   1.647 -              </p>
   1.648 -              <p>
   1.649 -                If this keyframe belongs to a <a>KeyframeList</a>, changes to
   1.650 -                this value cause the <a>KeyframeList</a> to be immediately
   1.651 -                re-sorted using a stable sort such that all children are ordered
   1.652 -                by their offset but children with identical offsets retain their
   1.653 -                relative position in the list.
   1.654 -              </p>
   1.655 -              <p>
   1.656 -                Exceptions:
   1.657 -              </p>
   1.658 -              <dl class="exceptions">
   1.659 -                <dt>DOMException of type <code>IndexSizeError</code></dt>
   1.660 -                <dd>
   1.661 -                  Raised on setting a value outside the range [0,1].
   1.662 -                </dd>
   1.663 -              </dl>
   1.664 -            </dd>
   1.665 -            <dt>attribute TimingFunction? timingFunction</dt>
   1.666 -            <dd>
   1.667 -              <p>
   1.668 -                The timing function to apply between this keyframe and the
   1.669 -                next keyframe in any <a>KeyframeList</a> in which this object
   1.670 -                appears.
   1.671 -              </p>
   1.672 -              <p>
   1.673 -                May be <code>null</code> in which case linear interpolation will
   1.674 -                be used.
   1.675 -              </p>
   1.676 -            </dd>
   1.677 -          </dl>
   1.678 -        </p>
   1.679 -      </section>
   1.680 -      <section>
   1.681 -        <h3>The <code>KeyframeDictionary</code> dictionary</h3>
   1.682 -        <p>
   1.683 -          To simplify creation of <a>Keyframe</a> objects
   1.684 -          a <code>KeyframeDictionary</code> can be used.
   1.685 -        </p>
   1.686 -        <p>
   1.687 -          The members of the dictionary correspond to attributes in the
   1.688 -          <a>Keyframe</a> interface which provides a more complete description
   1.689 -          of their meaning and usage.
   1.690 -        </p>
   1.691 -        <dl title="dictionary KeyframeDictionary" class="idl">
   1.692 -          <dt>DOMString value = ""</dt>
   1.693 -          <dd>
   1.694 -            The value to assign to the target attribute or property at the given
   1.695 -            offset.
   1.696 -          </dd>
   1.697 -          <dt>double offset = 1</dt>
   1.698 -          <dd>
   1.699 -            A value between 0 and 1 (inclusive) representing the offset within
   1.700 -            the iteration duration of the animation where this value should
   1.701 -            appear.
   1.702 -          </dd>
   1.703 -          <dt>TimingFunction? timingFunction = null</dt>
   1.704 -          <dd>
   1.705 -            The timing function to apply between this keyframe and the
   1.706 -            next keyframe in any <a>KeyframeList</a> in which this object
   1.707 -            appears.
   1.708 -          </dd>
   1.709 -        </dl>
   1.710 -      </section>
   1.711 -      <section>
   1.712 -        <h3>The <code>PathAnimationEffect</code> interface</h3>
   1.713 -        <dl title="[Constructor] interface PathAnimationEffect
   1.714 -          : AnimationEffect" class="idl">
   1.715 -          <dt>attribute SVGPathSegList segments</dt>
   1.716 -          <dd>
   1.717 -            The list of segments that make up this path.
   1.718 -          </dd>
   1.719 -          <dt>attribute boolean rotate</dt>
   1.720 -          <dd>
   1.721 -            True if objects animating along this path should be rotated
   1.722 -            such that their positive x axis is aligned with the direction of
   1.723 -            movement along the path.
   1.724 -          </dd>
   1.725 -        </dl>
   1.726 -      </section>
   1.727 -      <section>
   1.728 -        <h3>The <code>GroupedAnimationEffect</code> interface</h3>
   1.729 -        <p>
   1.730 -          The <code>GroupedAnimationEffect</code> interface represents a
   1.731 -          set of animation effects that share the same
   1.732 -          <code>AnimationTemplate</code> parent.
   1.733 +        <p class="issue">
   1.734 +          This definition relies on the final value of <a
   1.735 +          title="timing function">timing functions</a> being 1.
   1.736          </p>
   1.737          <p class="todo">
   1.738 -          If the group contains multiple effects that target the same property
   1.739 -          does order in the group matter? If so, we need to add a means for
   1.740 -          re-ordering the group other than popping and pushing. For example,
   1.741 -          <code>insertBefore</code>.
   1.742 -        </p>
   1.743 -        <dl title="interface GroupedAnimationEffect : AnimationEffect"
   1.744 -          class="idl">
   1.745 -          <dt>Constructor (object properties)</dt>
   1.746 -          <dd>
   1.747 -            <p class="todo">
   1.748 -              TBD whilst we decide whether we need this interface or whether we
   1.749 -              can merge it with <a>KeyframeAnimationEffect</a> somehow.
   1.750 -            </p>
   1.751 -          </dd>
   1.752 -          <dt>readonly attribute unsigned long length</dt>
   1.753 -          <dd>
   1.754 -            The number of animation effects in the group.
   1.755 -          </dd>
   1.756 -          <dt>void clear()</dt>
   1.757 -          <dd>
   1.758 -            Removes all effects from this group.
   1.759 -          </dd>
   1.760 -          <dt>getter AnimationEffect? (unsigned long index)</dt>
   1.761 -          <dd>
   1.762 -            Returns the effect at <var>index</var> if it exists, or
   1.763 -            <code>null</code> otherwise.
   1.764 -          </dd>
   1.765 -          <dt>AnimationEffect add(AnimationEffect effect)</dt>
   1.766 -          <dd>
   1.767 -            <p>
   1.768 -              Appends <code>effect</code> to the end of the group such that
   1.769 -              <code>group.indexOf(<var>effect</var>)</code> equals
   1.770 -              <code>group.length - 1</code>.
   1.771 -            </p>
   1.772 -            <p class="todo">
   1.773 -              I'm assuming that <a>AnimationEffect</a>s can be shared amongst
   1.774 -              animations and groups.
   1.775 -              Or does <var>effect</var> need to be removed from any previous
   1.776 -              <a>AnimationEffect</a>s or <a>Animation</a>s first?
   1.777 -            </p>
   1.778 -          </dd>
   1.779 -          <dt>AnimationEffect? remove(unsigned long index)</dt>
   1.780 -          <dd>
   1.781 -            Removes the effect at <code>index</code> and returns it. If
   1.782 -            <var>index</var> is outside the range [0, <code>length</code>), then
   1.783 -            <code>null</code> is returned.
   1.784 -          </dd>
   1.785 -          <dt>long indexOf(AnimationEffect effect)</dt>
   1.786 -          <dd>
   1.787 -            Returns the index of <var>effect</var> within the group.
   1.788 -            If <var>effect</var> is not a member of the group, returns
   1.789 -            <code>-1</code>.
   1.790 -          </dd>
   1.791 -        </dl>
   1.792 -      </section>
   1.793 -      <section>
   1.794 -        <h3>Calculating animation values</h3>
   1.795 -        <div class="todo">
   1.796 -          This section needs more detail on when sampling is done.
   1.797 -          It also needs to be specified that an <a>Animation</a> with
   1.798 -          a <code>null</code> <a>AnimationEffect</a> still fires events.
   1.799 -        </div>
   1.800 -        <section>
   1.801 -          <h4>Calculating the animation value from an iteration value</h4>
   1.802 -          <p>
   1.803 -            If the <a>current iteration</a> is zero, or the 
   1.804 -            <var>accumulateOperation</var> is
   1.805 -            <code>"replace"</code>, then the 
   1.806 -            <var>animation value</var> is simply the iteration value, as
   1.807 -            defined below.
   1.808 -          </p>
   1.809 -          <p>
   1.810 -            When the animation time equals the iteration duration for the 
   1.811 -            first time for an animation, the current 
   1.812 -            <var>animation value</var> should be retained as the
   1.813 -            <var>end value</var> for the animation.
   1.814 -          </p>
   1.815 -          <p class="todo">
   1.816 -            Need to revise this definition since we can't assume the time at
   1.817 -            the end of the first iteration will be visited (we might be
   1.818 -            playing backwards, or have a <var>iteration start</var> greater
   1.819 -            than 1).
   1.820 -          </p>
   1.821 -          <p>
   1.822 -            If the <a>current iteration</a> is not zero and the
   1.823 -            <var>accumulateOperation</var> is
   1.824 -            <code>"accumulate"</code> then the 
   1.825 -            <var>animation value</var> is the <var>end value</var> accumulated
   1.826 -            <a>current iteration</a> times, with the 
   1.827 -            <var>iteration value</var> accumulated on top.
   1.828 -          </p>
   1.829 -          <p>
   1.830 -            If the <a>current iteration</a> is not zero and the
   1.831 -            <var>accumulateOperation</var> is
   1.832 -            <code>"merge"</code> then the
   1.833 -            <var>animation balue</var> is the <var>end value</var> merged
   1.834 -            with the <var>iteration value</var>, with an interpolation
   1.835 -            parameter equal to the current <var>time fraction</var>
   1.836 -          </p>
   1.837 -          <p class="todo">
   1.838 -            Need to review the following algorithms to check they still make
   1.839 -            sense now that the iteration fraction is not necessarily in the
   1.840 -            range [0, 1].
   1.841 -          </p>
   1.842 -        </section>
   1.843 +          This definition relies on the concept of addition being defined for
   1.844 +          all animation effects.
   1.845 +          Need to point to where this is defined.
   1.846 +        </p>
   1.847          <section>              
   1.848            <h4>Calculating the iteration value for a 
   1.849              <code>KeyframeAnimationEffect</code></h4>
   1.850 @@ -5483,6 +4901,650 @@
   1.851          </div>
   1.852        </section>
   1.853        <section>
   1.854 +        <h3>The <code>AnimationEffect</code> interface</h3>
   1.855 +        <p>
   1.856 +          <a title="animation effect">Animation effects</a> are represented by
   1.857 +          the <code>AnimationEffect</code> interface.
   1.858 +          <a>AnimationEffect</a> is an abstract interface of which several
   1.859 +          concrete subinterfaces are provided.
   1.860 +        </p>
   1.861 +        <dl title="interface AnimationEffect" class="idl">
   1.862 +          <dt>attribute CompositeOperation operation</dt>
   1.863 +          <dd>
   1.864 +            <p>
   1.865 +              The operation used to composite this animation with the stack, as 
   1.866 +              specified by one of the <a>CompositeOperation</a> enumeration
   1.867 +              values.
   1.868 +            </p>
   1.869 +            <p>
   1.870 +              This value defaults to <code>"replace"</code>
   1.871 +            </p>
   1.872 +          </dd>
   1.873 +          <dt>attribute CompositeOperation accumulateOperation</dt>
   1.874 +          <dd>
   1.875 +            <p>
   1.876 +              The operation used to composite each iteration of this animation
   1.877 +              with the result of compositing the previous animation, as
   1.878 +              specified by one of the <a>CompositeOperation</a> constants
   1.879 +              defined in this interface.
   1.880 +            </p>
   1.881 +            <p>
   1.882 +              This value defaults to <code>"replace"</code>.
   1.883 +            </p>
   1.884 +          </dd>
   1.885 +          <dt>AnimationEffect clone ()</dt>
   1.886 +          <dd>
   1.887 +            <p>
   1.888 +              Creates and returns a new object of the same type as this object's
   1.889 +              most-derived interface such that it will produce the same output
   1.890 +              as this object.
   1.891 +            </p>
   1.892 +            <p class="todo">
   1.893 +              We either need a more rigorous definition here or (probably
   1.894 +              better) a sets of steps on a per-subclass basis.
   1.895 +            </p>
   1.896 +          </dd>
   1.897 +          <dt>static AnimationEffect? createFromProperties ()</dt>
   1.898 +          <dd>
   1.899 +            <p>
   1.900 +              Creates an <a>AnimationEffect</a> representing the passed-in
   1.901 +              collection of properties.
   1.902 +            </p>
   1.903 +            <div class="note">
   1.904 +              <p>
   1.905 +                Note that this method requires handling the passed in parameter
   1.906 +                in a manner not yet supported by Web IDL and hence this method
   1.907 +                is ECMAScript-specific.
   1.908 +              </p>
   1.909 +              <p>
   1.910 +                Since accessing the properties of an ECMAScript user object can
   1.911 +                have side effects, the manner in which these properties is
   1.912 +                accessed is important.
   1.913 +                In light of this consideration the following procedure has the
   1.914 +                following properties:
   1.915 +              </p>
   1.916 +              <ul>
   1.917 +                <li>Every property is read only once.</li>
   1.918 +                <li>Properties are read in a well-defined order.</li>
   1.919 +                <li>Properties corresponding to unsupported target properties or
   1.920 +                    attributes are not read.</li>
   1.921 +              </ul>
   1.922 +            </div>
   1.923 +            <p>
   1.924 +              The interpretation of the passed-in <code>properties</code> object
   1.925 +              can be described in three parts.
   1.926 +            </p>
   1.927 +            <p><strong>Part 1 &ndash; Determine the set of
   1.928 +               animation properties</strong></p>
   1.929 +            <ol>
   1.930 +              <li>Create a list, <var>supported properties</var>, of property
   1.931 +                  names and attribute names that can be animated by the
   1.932 +                  implementation.</li>
   1.933 +              <li>Let <var>animation properties</var> be an empty sequence.</li>
   1.934 +              <li>Iterate through the properties of <code>properties</code>. For
   1.935 +                  each <var>property</var> in <code>properties</code>, if
   1.936 +                  <var>property</var> also exists in <var>supported
   1.937 +                  properties</var> based on a case-sensitive comparison, append
   1.938 +                  <var>property</var> to <var>animation properties</var>.
   1.939 +                  <p class="note">
   1.940 +                    Whilst the iteration order for properties of an ECMAScript
   1.941 +                    object is implementation-dependent, the order here is not
   1.942 +                    significant to the outcome as <var>animation
   1.943 +                    properties</var> will be sorted before being iterated over.
   1.944 +                  </p>
   1.945 +                  <p class="issue">
   1.946 +                    How do we handle <code>operation</code> and
   1.947 +                    <code>compositeOperation</code>? We'd like to be able to
   1.948 +                    list them in the same property bag but that would mean we
   1.949 +                    could never animate properties of the same name.
   1.950 +                  </p>
   1.951 +              </li>
   1.952 +            </ol>
   1.953 +            <p><strong>Part 2 &ndash; Create the <a>AnimationEffect</a>
   1.954 +               objects</strong></p>
   1.955 +            <p>
   1.956 +              The <a>AnimationEffect</a> object produced depends on the length
   1.957 +              of <var>animation properties</var> as follows:
   1.958 +            </p>
   1.959 +            <dl class="switch">
   1.960 +              <dt>If <var>animation properties</var> is of zero length,</dt>
   1.961 +              <dd>
   1.962 +                return <code>null</code>.
   1.963 +                <div class="note">
   1.964 +                  <p>
   1.965 +                    This behavior of returning <code>null</code> allows
   1.966 +                    alternative animation effects to be provided based on the
   1.967 +                    capabilities of the user agent as follows:
   1.968 +                  </p>
   1.969 +                  <pre class="example sh_javascript">
   1.970 +elem.animate(
   1.971 +  AnimationEffect.createFromProperties({ transform: 'translate(-100px)' }) ||
   1.972 +  AnimationEffect.createFromProperties({ top: '-100px' }),
   1.973 +  3);
   1.974 +                  </pre>
   1.975 +                </div>
   1.976 +              </dd>
   1.977 +              <dt>If <var>animation properties</var> has only one element,</dt>
   1.978 +              <dd>
   1.979 +                <ol>
   1.980 +                  <li>Let <var>name</var> be the value of the element
   1.981 +                      in <var>animation properties</var>.</li>
   1.982 +                  <li>Let <var>value</var> be the value of
   1.983 +                      <code>properties.<var>name</var></code>.</li>
   1.984 +                  <li>Return a new <a>KeyframeAnimationEffect</a> object
   1.985 +                      according to the steps in part 3 below based on
   1.986 +                      <var>name</var> and <var>value</var>.</li>
   1.987 +                </ol>
   1.988 +              </dd>
   1.989 +              <dt>Otherwise,</dt>
   1.990 +              <dd>
   1.991 +                <ol>
   1.992 +                  <li>Let <var>group</var> be a newly constructed
   1.993 +                      <a>GroupedAnimationEffect</a>.</li>
   1.994 +                  <li>Sort <var>animation properties</var> lexicographically by
   1.995 +                      the Unicode codepoints that define each property
   1.996 +                      name.</li>
   1.997 +                  <li>For user agents that support both a prefixed and an
   1.998 +                      unprefixed version of some CSS properties, remove all
   1.999 +                      prefixed properties from <var>animation properties</var>
  1.1000 +                      where the corresponding unprefixed version is also
  1.1001 +                      present.</li>
  1.1002 +                  <li>Iterate through <var>animation properties</var>. For each
  1.1003 +                      <var>name</var> in <var>animation properties</var>:
  1.1004 +                    <ol>
  1.1005 +                      <li>Let <var>value</var> be the value of
  1.1006 +                          <code>properties.<var>name</var></code>.</li>
  1.1007 +                      <li>Create a new <a>KeyframeAnimationEffect</a>,
  1.1008 +                          <var>effect</var> object according to the steps in
  1.1009 +                          part 3 below based on <var>name</var> and
  1.1010 +                          <var>value</var>.</li>
  1.1011 +                      <li>Append <var>effect</var> to <var>group</var>.
  1.1012 +                    </ol>
  1.1013 +                  </li>
  1.1014 +                  <li>Return <var>group</var>.
  1.1015 +                </ol>
  1.1016 +              </dd>
  1.1017 +            </dl>
  1.1018 +            <p><strong>Part 3 &ndash; Create each
  1.1019 +               <a>KeyframeAnimationEffect</a> object</strong></p>
  1.1020 +            <p>
  1.1021 +              Based on a given <var>name</var> and <var>value</var>, a new
  1.1022 +              <a>KeyframeAnimationEffect</a> is created as follows:
  1.1023 +            </p>
  1.1024 +            <dl class="switch">
  1.1025 +              <dt>If <var>value</var> is not of type <code>(DOMString or
  1.1026 +              sequence&lt;(<a>KeyframeDictionary</a> or
  1.1027 +              DOMString)&gt;)</code>,</dt>
  1.1028 +              <dd>
  1.1029 +                Throw a <code>TypeError</code> as defined by [[!ECMA-262]].
  1.1030 +              </dd>
  1.1031 +              <dt>Otherwise,</dt>
  1.1032 +              <dd>
  1.1033 +                Construct a new <a>KeyframeAnimationEffect</a> by calling
  1.1034 +                <code>KeyframeAnimationEffect(<var>name</var>,
  1.1035 +                <var>value</var>)</code>.
  1.1036 +              </dd>
  1.1037 +            </dl>
  1.1038 +            <dl class="parameters">
  1.1039 +              <dt>object properties</dt>
  1.1040 +              <dd>
  1.1041 +                An object whose object properties represent the CSS properties
  1.1042 +                or element attributes to be animated.
  1.1043 +                The values corresponding to these properties are the animation
  1.1044 +                values to be applied as described above.
  1.1045 +              </dd>
  1.1046 +            </dl>
  1.1047 +          </dd>
  1.1048 +        </dl>
  1.1049 +        <div class="annotation">
  1.1050 +          In future, we may expose <code>any sample (double?  timeFraction,
  1.1051 +          double currentIteration, AnimationTarget? target, any
  1.1052 +          underlyingValue)</code> so that the animation effects can be driven
  1.1053 +          apart from the timing model.
  1.1054 +          Also, doing so would allow us to do real native custom animation
  1.1055 +          effects if we decide to go in that direction
  1.1056 +          (see annotation in <a href="#custom-animation-effects"
  1.1057 +          class="sectionRef"></a>).
  1.1058 +        </div>
  1.1059 +      </section>
  1.1060 +      <section>
  1.1061 +        <h3>The <code>CompositeOperation</code> enumeration</h3>
  1.1062 +        <dl title="enum CompositeOperation" class="idl">
  1.1063 +          <dt>replace</dt>
  1.1064 +          <dd>
  1.1065 +            The animation should replace the value it is composited with.
  1.1066 +          </dd>
  1.1067 +          <dt>accumulate</dt>
  1.1068 +          <dd>
  1.1069 +            The animation should add to the value it is composited with.
  1.1070 +            The meaning of addition is dependent on the type of animation.
  1.1071 +          </dd>
  1.1072 +          <dt>merge</dt>
  1.1073 +          <dd>
  1.1074 +            The animation should merge with the value it is composited with.
  1.1075 +            The meaning of merge is dependent on the type of animation.
  1.1076 +            The duration of the merge is the calculated animation duration
  1.1077 +            of the <code>AnimationTemplate</code> containing this
  1.1078 +            <code>AnimationEffect</code>.
  1.1079 +          </dd>
  1.1080 +        </dl>
  1.1081 +      </section>
  1.1082 +      <section>
  1.1083 +        <h3>The <code>KeyframeAnimationEffect</code> interface</h3>
  1.1084 +        <dl title="interface KeyframeAnimationEffect : AnimationEffect"
  1.1085 +          class="idl">
  1.1086 +          <dt>Constructor (DOMString property,
  1.1087 +      (DOMString or sequence&lt;(KeyframeDictionary or DOMString)&gt;) frames,
  1.1088 +      optional CompositeOperation operation = "replace",
  1.1089 +      optional CompositeOperation compositeOperation = "replace")</dt>
  1.1090 +          <dd>
  1.1091 +            <p>
  1.1092 +              Creates a new <a>KeyframeAnimationEffect</a> object for the
  1.1093 +              specified property from the given list of keyframes.
  1.1094 +            </p>
  1.1095 +            <p>
  1.1096 +              The list of keyframes may be a sequence of
  1.1097 +              <a>KeyframeDictionary</a> dictionaries, a sequence of
  1.1098 +              <code>DOMString</code>s, a combination of both, or
  1.1099 +              a single <code>DOMString</code>.
  1.1100 +            </p>
  1.1101 +            <p>
  1.1102 +              <code>DOMString</code>s are used to create keyframes with an
  1.1103 +              offset of 1.
  1.1104 +              When the list of keyframes is a sequence consisting entirely of
  1.1105 +              <code>DOMString</code>s the offsets of the newly created
  1.1106 +              <a>Keyframe</a>s are distributed evenly from 0 to 1.
  1.1107 +            </p>
  1.1108 +            <p>
  1.1109 +              The <var>property</var>, <var>operation</var> and
  1.1110 +              <var>compositeOperation</var> arguments are assigned to the
  1.1111 +              attributes of the same names.
  1.1112 +            </p>
  1.1113 +            <p>
  1.1114 +              The <var>frames</var> argument is processed as follows:
  1.1115 +            </p>
  1.1116 +            <ol>
  1.1117 +              <li>Let <var>effect</var> be the
  1.1118 +                  <a>KeyframeAnimationEffect</a> currently under construction.
  1.1119 +              </li>
  1.1120 +              <li>
  1.1121 +                <p>
  1.1122 +                  The processing of <var>frames</var> depends on its type as
  1.1123 +                  follows:
  1.1124 +                </p>
  1.1125 +                <dl class="switch">
  1.1126 +                  <dt>If <var>frames</var> is a <code>DOMString</code>,</dt>
  1.1127 +                  <dd>
  1.1128 +                    <ol>
  1.1129 +                      <li>
  1.1130 +                        Let <var>frame</var> be a new <a>Keyframe</a>
  1.1131 +                        constructed from a <a>KeyframeDictionary</a> whose
  1.1132 +                        <code>value</code> member is set to
  1.1133 +                        <var>frames</var> and whose other members are set
  1.1134 +                        to their default values.
  1.1135 +                      </li>
  1.1136 +                      <li>
  1.1137 +                        Call
  1.1138 +                <code><var>effect</var>.frames.add(<var>frame</var>)</code>.
  1.1139 +                      </li>
  1.1140 +                    </ol>
  1.1141 +                  </dd>
  1.1142 +                  <dt>If <var>frames</var> is a sequence of <code>(DOMString
  1.1143 +                      or <a>KeyframeDictionary</a>)</code>,</dt>
  1.1144 +                  <dd>
  1.1145 +                    <ol>
  1.1146 +                      <li>Set a flag <var>all strings</var> to
  1.1147 +                          <code>true</code>.</li>
  1.1148 +                      <li>
  1.1149 +                        For each <var>item</var> in <var>frames</var>:
  1.1150 +                        <ol>
  1.1151 +                          <li>
  1.1152 +                            <dl class="switch">
  1.1153 +                              <dt>If <var>item</var> is
  1.1154 +                                  a <code>DOMString</code>,</dt>
  1.1155 +                              <dd>
  1.1156 +                                Let <var>frame</var> be a new <a>Keyframe</a>
  1.1157 +                                constructed from a <a>KeyframeDictionary</a>
  1.1158 +                                whose <code>value</code> member is set to
  1.1159 +                                <var>item</var> and whose other members are
  1.1160 +                                set to their default values.
  1.1161 +                              </dd>
  1.1162 +                              <dt>Otherwise (<var>item</var> is
  1.1163 +                                  a <a>KeyframeDictionary</a>),</dt>
  1.1164 +                              <dd>
  1.1165 +                                <ol>
  1.1166 +                                  <li>
  1.1167 +                                    Let <var>frame</var> be a new
  1.1168 +                                    <a>Keyframe</a> constructed by calling
  1.1169 +                                    <code>Keyframe(<var>item</var>)</code>.
  1.1170 +                                  </li>
  1.1171 +                                  <li>
  1.1172 +                                    Set <var>all strings</var> to
  1.1173 +                                    <code>false</code>.
  1.1174 +                                  </li>
  1.1175 +                                </ol>
  1.1176 +                              </dd>
  1.1177 +                            </dl>
  1.1178 +                          </li>
  1.1179 +                          <li>
  1.1180 +                            Call
  1.1181 +                <code><var>effect</var>.frames.add(<var>frame</var>)</code>.
  1.1182 +                          </li>
  1.1183 +                        </ol>
  1.1184 +                      </li>
  1.1185 +                      <li>If flag <var>all strings</var> is
  1.1186 +                          <code>true</code> call
  1.1187 +                        <code><var>effect</var>.frames.distribute()</code>.
  1.1188 +                      </li>
  1.1189 +                    </ol>
  1.1190 +                  </dd>
  1.1191 +                </dl>
  1.1192 +              </li>
  1.1193 +            </ol>
  1.1194 +          </dd>
  1.1195 +          <dt>attribute DOMString property</dt>
  1.1196 +          <dd>
  1.1197 +            The name of the target property or attribute.
  1.1198 +          </dd>
  1.1199 +          <dt>readonly attribute KeyframeList frames</dt>
  1.1200 +          <dd>
  1.1201 +            The series of values that make up this effect sorted by their
  1.1202 +            offset within the iteration duration of the animation.
  1.1203 +          </dd>
  1.1204 +        </dl>
  1.1205 +      </section>
  1.1206 +      <section>
  1.1207 +        <h3>The <code>KeyframeList</code> interface</h3>
  1.1208 +        <p>
  1.1209 +          The <a>KeyframeList</a> object is a collection of <a>Keyframe</a>
  1.1210 +          objects sorted by the offset of each <a>Keyframe</a>.
  1.1211 +        </p>
  1.1212 +        <dl title="interface KeyframeList" class="idl">
  1.1213 +          <dt>readonly attribute unsigned long length</dt>
  1.1214 +          <dd>
  1.1215 +            The number of frames in the list.
  1.1216 +          </dd>
  1.1217 +          <dt>void clear ()</dt>
  1.1218 +          <dd>
  1.1219 +            Removes all frames from this list.
  1.1220 +          </dd>
  1.1221 +          <dt>getter Keyframe? (unsigned long index)</dt>
  1.1222 +          <dd>
  1.1223 +            Returns the frame at <code>index</code> if it exists or
  1.1224 +            <code>null</code> otherwise.
  1.1225 +          </dd>
  1.1226 +          <dt>Keyframe add((Keyframe or KeyframeDictionary) frame)</dt>
  1.1227 +          <dd>
  1.1228 +            <p>
  1.1229 +              Adds <var>frame</var> to the list such that the list remains
  1.1230 +              sorted by the offset of the frames.
  1.1231 +            </p>
  1.1232 +            <p>
  1.1233 +              If <var>frame</var> is of type <a>KeyframeDictionary</a> then
  1.1234 +              a <a>Keyframe</a> object is first constructed by calling
  1.1235 +              <code>Keyframe(<var>frame</var>)</code> before adding the
  1.1236 +              newly constructed <a>Keyframe</a> to the list.
  1.1237 +            </p>
  1.1238 +            <p>
  1.1239 +              If there already exists a frame in this list with offset
  1.1240 +              <code><var>frame</var>.offset</code>, the newly added
  1.1241 +              <var>frame</var> will appear in the list <em>after</em> the
  1.1242 +              already existing frames in the list with the same offset.
  1.1243 +            </p>
  1.1244 +            <p>
  1.1245 +              If <var>frame</var> is already part of another <a>KeyframeList</a>
  1.1246 +              it is first removed from that list before being added to this
  1.1247 +              list.
  1.1248 +            </p>
  1.1249 +            <p>
  1.1250 +              Exceptions:
  1.1251 +            </p>
  1.1252 +            <dl class="exceptions">
  1.1253 +              <dt>DOMException of type <code>IndexSizeError</code></dt>
  1.1254 +              <dd>
  1.1255 +                Raised if <var>frame</var> is a <a>KeyframeDictionary</a> whose
  1.1256 +                offset is outside the range [0,1] or missing.
  1.1257 +              </dd>
  1.1258 +            </dl>
  1.1259 +          </dd>
  1.1260 +          <dt>Keyframe? remove(unsigned long index)</dt>
  1.1261 +          <dd>
  1.1262 +            Removes the frame at position <var>index</var> and returns it.
  1.1263 +            If index is outside the range [0, length), then <code>null</code> is
  1.1264 +            returned.
  1.1265 +          </dd>
  1.1266 +          <dt>long indexOf(Keyframe frame)</dt>
  1.1267 +          <dd>
  1.1268 +            Returns the index of <var>frame</var> within the list. If
  1.1269 +            <var>frame</var> is not a member of the list, returns
  1.1270 +            <code>-1</code>.
  1.1271 +          </dd>
  1.1272 +          <dt>KeyframeList distribute()</dt>
  1.1273 +          <dd>
  1.1274 +            <p>
  1.1275 +              Adjusts the offsets of the frames in the list such that the
  1.1276 +              offsets are spaced equidistantly whilst maintaining their current
  1.1277 +              order and such that the first frame (when there are multiple
  1.1278 +              frames) has offset 0 and the last frame (if any) has offset 1.
  1.1279 +            </p>
  1.1280 +            <p>
  1.1281 +              For <var>frame</var> at position <var>i</var> in the list where
  1.1282 +              0 &le; <var>i</var> &lt; <code>length</code>, an offset will be
  1.1283 +                assigned equal to <code>i / (length - 1)</code> unless
  1.1284 +                <code>length</code> is 1 in which case it will be given offset
  1.1285 +                1.
  1.1286 +            </p>
  1.1287 +            <p>
  1.1288 +              After applying the changes, this list is returned.
  1.1289 +            </p>
  1.1290 +          </dd>
  1.1291 +        </dl>
  1.1292 +        <div class="annotation">
  1.1293 +          <p>
  1.1294 +            The following changes for making keyframes easier to work with in
  1.1295 +            future have been proposed:
  1.1296 +          </p>
  1.1297 +          <pre class="example sh_javascript">
  1.1298 +// Currently you have to do this
  1.1299 +effect.frames.add({ property: 'left', offset: 0.3, value: '100px' }); 
  1.1300 +
  1.1301 +// It would be nice if you could also do this
  1.1302 +effect.frames.add(0.3, 'left', '100px');
  1.1303 +
  1.1304 +// Also, fetching by offset would be good
  1.1305 +
  1.1306 +// Returns the last frame with offset 0.3 if there is one.
  1.1307 +// If there is none, does the interpolation and returns a new frame? 
  1.1308 +var frame = effect.frames['0.3']; 
  1.1309 +          </pre>
  1.1310 +        </div>
  1.1311 +      </section>
  1.1312 +      <section>
  1.1313 +        <h3>The <code>Keyframe</code> interface</h3>
  1.1314 +        <p>
  1.1315 +          A <a>Keyframe</a> represents a moment within an animation that has
  1.1316 +          a specified value to be applied to the target property or attribute.
  1.1317 +          In between such moments values may be interpolated or filled based on
  1.1318 +          the <a>TimingFunction</a> specified on the <a>TimedItem</a> where the
  1.1319 +          <a>Keyframe</a> is used, or on the previous <a>Keyframe</a>.
  1.1320 +        </p>
  1.1321 +        <div class="issue">
  1.1322 +          <p>
  1.1323 +            Currently a <a>Keyframe</a> can only target a single property which
  1.1324 +            is defined on the <a>KeyframeAnimationEffect</a>.
  1.1325 +            This is different to CSS.
  1.1326 +            Is this something we want to change?
  1.1327 +            It would complicate the API, of course, but is it worth it?
  1.1328 +          </p>
  1.1329 +        </div>
  1.1330 +        <p>
  1.1331 +          <dl title="interface Keyframe" class="idl">
  1.1332 +            <dt>Constructor (KeyframeDictionary dictionary)</dt>
  1.1333 +            <dd>
  1.1334 +              <p>
  1.1335 +                Creates a new <a>Keyframe</a> object using the parameters
  1.1336 +                specified in <var>dictionary</var>.
  1.1337 +              </p>
  1.1338 +              <p>
  1.1339 +                <code><var>dictionary</var>.offset</code> is clamped to the
  1.1340 +                range [0, 1] before setting.
  1.1341 +              </p>
  1.1342 +            </dd>
  1.1343 +            <dt>attribute DOMString value</dt>
  1.1344 +            <dd>
  1.1345 +              The value to assign to the target attribute or property at the
  1.1346 +              given offset.
  1.1347 +            </dd>
  1.1348 +            <dt>attribute double offset</dt>
  1.1349 +            <dd>
  1.1350 +              <p>
  1.1351 +                A value between 0 and 1 inclusive representing the offset
  1.1352 +                within the iteration duration of the animation where this value
  1.1353 +                should appear.
  1.1354 +              </p>
  1.1355 +              <p>
  1.1356 +                If this keyframe belongs to a <a>KeyframeList</a>, changes to
  1.1357 +                this value cause the <a>KeyframeList</a> to be immediately
  1.1358 +                re-sorted using a stable sort such that all children are ordered
  1.1359 +                by their offset but children with identical offsets retain their
  1.1360 +                relative position in the list.
  1.1361 +              </p>
  1.1362 +              <p>
  1.1363 +                Exceptions:
  1.1364 +              </p>
  1.1365 +              <dl class="exceptions">
  1.1366 +                <dt>DOMException of type <code>IndexSizeError</code></dt>
  1.1367 +                <dd>
  1.1368 +                  Raised on setting a value outside the range [0,1].
  1.1369 +                </dd>
  1.1370 +              </dl>
  1.1371 +            </dd>
  1.1372 +            <dt>attribute TimingFunction? timingFunction</dt>
  1.1373 +            <dd>
  1.1374 +              <p>
  1.1375 +                The timing function to apply between this keyframe and the
  1.1376 +                next keyframe in any <a>KeyframeList</a> in which this object
  1.1377 +                appears.
  1.1378 +              </p>
  1.1379 +              <p>
  1.1380 +                May be <code>null</code> in which case linear interpolation will
  1.1381 +                be used.
  1.1382 +              </p>
  1.1383 +            </dd>
  1.1384 +          </dl>
  1.1385 +        </p>
  1.1386 +      </section>
  1.1387 +      <section>
  1.1388 +        <h3>The <code>KeyframeDictionary</code> dictionary</h3>
  1.1389 +        <p>
  1.1390 +          To simplify creation of <a>Keyframe</a> objects
  1.1391 +          a <code>KeyframeDictionary</code> can be used.
  1.1392 +        </p>
  1.1393 +        <p>
  1.1394 +          The members of the dictionary correspond to attributes in the
  1.1395 +          <a>Keyframe</a> interface which provides a more complete description
  1.1396 +          of their meaning and usage.
  1.1397 +        </p>
  1.1398 +        <dl title="dictionary KeyframeDictionary" class="idl">
  1.1399 +          <dt>DOMString value = ""</dt>
  1.1400 +          <dd>
  1.1401 +            The value to assign to the target attribute or property at the given
  1.1402 +            offset.
  1.1403 +          </dd>
  1.1404 +          <dt>double offset = 1</dt>
  1.1405 +          <dd>
  1.1406 +            A value between 0 and 1 (inclusive) representing the offset within
  1.1407 +            the iteration duration of the animation where this value should
  1.1408 +            appear.
  1.1409 +          </dd>
  1.1410 +          <dt>TimingFunction? timingFunction = null</dt>
  1.1411 +          <dd>
  1.1412 +            The timing function to apply between this keyframe and the
  1.1413 +            next keyframe in any <a>KeyframeList</a> in which this object
  1.1414 +            appears.
  1.1415 +          </dd>
  1.1416 +        </dl>
  1.1417 +      </section>
  1.1418 +      <section>
  1.1419 +        <h3>The <code>PathAnimationEffect</code> interface</h3>
  1.1420 +        <dl title="[Constructor] interface PathAnimationEffect
  1.1421 +          : AnimationEffect" class="idl">
  1.1422 +          <dt>attribute SVGPathSegList segments</dt>
  1.1423 +          <dd>
  1.1424 +            The list of segments that make up this path.
  1.1425 +          </dd>
  1.1426 +          <dt>attribute boolean rotate</dt>
  1.1427 +          <dd>
  1.1428 +            True if objects animating along this path should be rotated
  1.1429 +            such that their positive x axis is aligned with the direction of
  1.1430 +            movement along the path.
  1.1431 +          </dd>
  1.1432 +        </dl>
  1.1433 +      </section>
  1.1434 +      <section>
  1.1435 +        <h3>The <code>GroupedAnimationEffect</code> interface</h3>
  1.1436 +        <p>
  1.1437 +          The <code>GroupedAnimationEffect</code> interface represents a
  1.1438 +          set of animation effects that share the same
  1.1439 +          <code>AnimationTemplate</code> parent.
  1.1440 +        </p>
  1.1441 +        <p class="todo">
  1.1442 +          If the group contains multiple effects that target the same property
  1.1443 +          does order in the group matter? If so, we need to add a means for
  1.1444 +          re-ordering the group other than popping and pushing. For example,
  1.1445 +          <code>insertBefore</code>.
  1.1446 +        </p>
  1.1447 +        <dl title="interface GroupedAnimationEffect : AnimationEffect"
  1.1448 +          class="idl">
  1.1449 +          <dt>Constructor (object properties)</dt>
  1.1450 +          <dd>
  1.1451 +            <p class="todo">
  1.1452 +              TBD whilst we decide whether we need this interface or whether we
  1.1453 +              can merge it with <a>KeyframeAnimationEffect</a> somehow.
  1.1454 +            </p>
  1.1455 +          </dd>
  1.1456 +          <dt>readonly attribute unsigned long length</dt>
  1.1457 +          <dd>
  1.1458 +            The number of animation effects in the group.
  1.1459 +          </dd>
  1.1460 +          <dt>void clear()</dt>
  1.1461 +          <dd>
  1.1462 +            Removes all effects from this group.
  1.1463 +          </dd>
  1.1464 +          <dt>getter AnimationEffect? (unsigned long index)</dt>
  1.1465 +          <dd>
  1.1466 +            Returns the effect at <var>index</var> if it exists, or
  1.1467 +            <code>null</code> otherwise.
  1.1468 +          </dd>
  1.1469 +          <dt>AnimationEffect add(AnimationEffect effect)</dt>
  1.1470 +          <dd>
  1.1471 +            <p>
  1.1472 +              Appends <code>effect</code> to the end of the group such that
  1.1473 +              <code>group.indexOf(<var>effect</var>)</code> equals
  1.1474 +              <code>group.length - 1</code>.
  1.1475 +            </p>
  1.1476 +            <p class="todo">
  1.1477 +              I'm assuming that <a>AnimationEffect</a>s can be shared amongst
  1.1478 +              animations and groups.
  1.1479 +              Or does <var>effect</var> need to be removed from any previous
  1.1480 +              <a>AnimationEffect</a>s or <a>Animation</a>s first?
  1.1481 +            </p>
  1.1482 +          </dd>
  1.1483 +          <dt>AnimationEffect? remove(unsigned long index)</dt>
  1.1484 +          <dd>
  1.1485 +            Removes the effect at <code>index</code> and returns it. If
  1.1486 +            <var>index</var> is outside the range [0, <code>length</code>), then
  1.1487 +            <code>null</code> is returned.
  1.1488 +          </dd>
  1.1489 +          <dt>long indexOf(AnimationEffect effect)</dt>
  1.1490 +          <dd>
  1.1491 +            Returns the index of <var>effect</var> within the group.
  1.1492 +            If <var>effect</var> is not a member of the group, returns
  1.1493 +            <code>-1</code>.
  1.1494 +          </dd>
  1.1495 +        </dl>
  1.1496 +      </section>
  1.1497 +      <section>
  1.1498          <h3>Extensions to the <code>Document</code> interface</h3>
  1.1499          <p>
  1.1500            The following extensions are made to the <a
  1.1501 @@ -5592,6 +5654,12 @@
  1.1502            start reporting events to content expecting only CSS animations).
  1.1503          </p>
  1.1504        </div>
  1.1505 +      <div class="todo">
  1.1506 +        Clarify somewhere that timing events are a property of the <em>timing
  1.1507 +        model</em> hence they continue to fire even if there is no animation
  1.1508 +        effect and even if the target property is in a <code>display:
  1.1509 +        none</code> block.
  1.1510 +      </div>
  1.1511        <section>
  1.1512          <h3>The <code>TimingEvent</code> interface</h3>
  1.1513          <dl title="interface TimingEvent : Event" class="idl">

mercurial