|
| 1 | +<h1>CSS Timing Functions Level 1</h1> |
| 2 | + |
| 3 | +<pre class='metadata'> |
| 4 | +Status: ED |
| 5 | +Work Status: Refining |
| 6 | +Shortname: css-timing-functions |
| 7 | +Level: 1 |
| 8 | +Group: csswg |
| 9 | +ED: https://drafts.csswg.org/css-timing-functions/ |
| 10 | +Editor: Brian Birtles 43194, Mozilla https://www.mozilla.org, bbirtles@mozilla.com |
| 11 | +Editor: Dean Jackson, Apple Inc https://www.apple.com/, dino@apple.com |
| 12 | +Editor: Matt Rakow, Microsoft |
| 13 | +Editor: Shane Stephens 47691, Google Inc, shans@google.com |
| 14 | +Repository: w3c/csswg-drafts |
| 15 | +!Issue Tracking: <a href="https://github.com/w3c/csswg-drafts/labels/css-timing-functions">GitHub</a> |
| 16 | +
|
| 17 | +Abstract: This CSS module describes a way for authors to define a transformation |
| 18 | + to be applied to the time of an animation. This can be used to produce |
| 19 | + animations that mimic physical phenomena such as momentum or to |
| 20 | + cause the animation to move in discrete steps producing robot-like |
| 21 | + movement. |
| 22 | +</pre> |
| 23 | + |
| 24 | +Introduction {#introduction} |
| 25 | +============================ |
| 26 | + |
| 27 | +<em>This section is not normative.</em> |
| 28 | + |
| 29 | +It is often desirable to control the rate at which an animation progresses. |
| 30 | +For example, gradually increasing the speed at which an element moves can |
| 31 | +give the element a sense weight as it appears to gather momentum. |
| 32 | +This can be used to produce user intuitive interface elements or convincing |
| 33 | +cartoon props that behave like their physical counterparts. |
| 34 | +Alternatively, it is sometimes desirable for animation to move forwards in |
| 35 | +distinct steps such as a segmented wheel that rotates such that the segments |
| 36 | +always appear in the same position. |
| 37 | + |
| 38 | +[=Timing functions=] provide a means to transform animation time by taking an |
| 39 | +input progress value and producing a corresponding transformed output progress |
| 40 | +value. |
| 41 | + |
| 42 | +<figure> |
| 43 | + <img src="timing-function-example.svg" width="350" |
| 44 | + alt="Example of a timing function that produces an ease-in effect."> |
| 45 | + <figcaption> |
| 46 | + Example of a timing function that produces an ease-in effect. |
| 47 | + Given an input progress of 0.7, the timing function scales the |
| 48 | + value to produce an output progress of 0.52. |
| 49 | + By applying this timing function, the animation will progress more |
| 50 | + slowly at first but then gradually progress more quickly. |
| 51 | + </figcaption> |
| 52 | +</figure> |
| 53 | + |
| 54 | +Timing functions {#timing-functions} |
| 55 | +==================================== |
| 56 | + |
| 57 | +A <dfn export>timing function</dfn> takes an [=input progress value=] and |
| 58 | +produces an [=output progress value=]. |
| 59 | + |
| 60 | +A [=timing function=] must be a pure function meaning that for a given set of |
| 61 | +inputs, it always produce the same [=output progress value=]. |
| 62 | + |
| 63 | +The <dfn>input progress value</dfn> is a real number in the range [-∞, |
| 64 | +∞]. |
| 65 | +Typically, the [=input progress value=] is in the range [0, 1] but this may |
| 66 | +not be the case when [=timing functions=] are chained together. |
| 67 | + |
| 68 | +The <dfn>output progress value</dfn> is a real number in the |
| 69 | +range [-∞, ∞]. |
| 70 | + |
| 71 | +Some types of timing function also take an additional boolean [=before flag=] |
| 72 | +input which is defined subsequently. |
| 73 | + |
| 74 | +This specification defines three types of timing functions whose definitions |
| 75 | +follow. |
| 76 | + |
| 77 | + |
| 78 | +The linear timing function {#linear-timing-function-section} |
| 79 | +-------------------------- |
| 80 | + |
| 81 | +The <dfn export>linear timing function</dfn> is an identity function |
| 82 | +meaning that its [=output progress value=] is equal to the |
| 83 | +[=input progress value=] for all inputs. |
| 84 | + |
| 85 | +The syntax for the [=linear timing function=] is simply the |
| 86 | +<dfn for=single-timing-function>''linear''</dfn> keyword. |
| 87 | + |
| 88 | + |
| 89 | +Cubic Bézier timing functions {#cubic-bezier-timing-functions} |
| 90 | +--------------------------------------------------------------------- |
| 91 | + |
| 92 | +A <dfn export>cubic Bézier timing function</dfn> is a type of [=timing |
| 93 | +function=] defined by four real numbers that specify the two control |
| 94 | +points, <var>P1</var> and <var>P2</var>, of a cubic Bézier curve whose |
| 95 | +end points <var ignore>P0</var> and <var ignore>P3</var> are fixed at (0, 0) and |
| 96 | +(1, 1) respectively. |
| 97 | +The <var>x</var> coordinates of <var>P1</var> and <var>P2</var> are |
| 98 | +restricted to the range [0, 1]. |
| 99 | + |
| 100 | +The mapping from input progress to output progress is performed by |
| 101 | +determining the corresponding <var>y</var> value ([=output progress value=]) for |
| 102 | +a given <var>x</var> value ([=input progress value=]). |
| 103 | +The evaluation of this curve is covered in many sources such as |
| 104 | +[[FUND-COMP-GRAPHICS]]. |
| 105 | + |
| 106 | +<figure> |
| 107 | + <img src="cubic-bezier-timing-curve.svg" width="500" |
| 108 | + alt="A cubic Bezier curve used as a timing function."> |
| 109 | + <figcaption> |
| 110 | + A cubic Bézier curve used as a timing function.<br> |
| 111 | + The shape of the curve is determined by the location of the control |
| 112 | + points <var>P1</var> and <var>P2</var>.<br> |
| 113 | + Input progress values serve as <var>x</var> values of the curve, |
| 114 | + whilst the <var>y</var> values are the output progress values. |
| 115 | + </figcaption> |
| 116 | +</figure> |
| 117 | + |
| 118 | +For [=input progress values=] outside the range [0, 1], the curve is extended |
| 119 | +infinitely using tangent of the curve at the closest endpoint as follows: |
| 120 | + |
| 121 | +* For [=input progress values=] less than zero, |
| 122 | + |
| 123 | + 1. If the <var>x</var> value of P1 is greater than zero, use |
| 124 | + a straight line that passes through P1 and P0 as the tangent. |
| 125 | + |
| 126 | + 1. Otherwise, if the <var>x</var> value of P2 is greater than |
| 127 | + zero, use a straight line that passes through P2 and P0 as the tangent. |
| 128 | + |
| 129 | + 1. Otherwise, let the [=output progress value=] be zero for all |
| 130 | + [=input progress values=] in the range [-∞, 0). |
| 131 | + |
| 132 | +* For [=input progress values=] greater than one, |
| 133 | + |
| 134 | + 1. If the <var>x</var> value of P2 is less than one, use |
| 135 | + a straight line that passes through P2 and P3 as the tangent. |
| 136 | + |
| 137 | + 1. Otherwise, if the <var>x</var> value of P1 is less than |
| 138 | + one, use a straight line that passes through P1 and P3 as the tangent. |
| 139 | + |
| 140 | + 1. Otherwise, let the [=output progress value=] be one for all |
| 141 | + [=input progress values=] in the range (1, ∞]. |
| 142 | + |
| 143 | +A <a>cubic Bézier timing function</a> may be specified as a string |
| 144 | +using the following syntax (using notation from [[!CSS3VAL]]): |
| 145 | + |
| 146 | +<div class="prod"><dfn type><cubic-bezier-timing-function></dfn> = |
| 147 | + ''ease'' | ''ease-in'' | ''ease-out'' | ''ease-in-out'' | |
| 148 | + <span class="atom"><a lt="cubic-bezier()" |
| 149 | + function>cubic-bezier</a>(<<number>>, <<number>>, <<number>>, |
| 150 | + <<number>>)</span></div> |
| 151 | + |
| 152 | +The meaning of each value is as follows: |
| 153 | + |
| 154 | +<dl dfn-type="value" dfn-for="cubic-bezier-timing-function, <cubic-bezier-timing-function>"> |
| 155 | + |
| 156 | +: <dfn>ease</dfn> |
| 157 | +:: Equivalent to cubic-bezier(0.25, 0.1, 0.25, 1). |
| 158 | +: <dfn>ease-in</dfn> |
| 159 | +:: Equivalent to cubic-bezier(0.42, 0, 1, 1). |
| 160 | +: <dfn>ease-out</dfn> |
| 161 | +:: Equivalent to cubic-bezier(0, 0, 0.58, 1). |
| 162 | +: <dfn>ease-in-out</dfn> |
| 163 | +:: Equivalent to cubic-bezier(0.42, 0, 0.58, 1). |
| 164 | +: <dt><dfn function lt="cubic-bezier()">cubic-bezier(<<number>>, <<number>>, <<number>>, <<number>>)</dfn></dt> |
| 165 | +:: Specifies a <a>cubic Bézier timing function</a>. |
| 166 | + The four numbers specify points <var>P1</var> and <var>P2</var> of |
| 167 | + the curve as (<var ignore>x1</var>, <var ignore>y1</var>, <var |
| 168 | + ignore>x2</var>, <var ignore>y2</var>). |
| 169 | + Both <var>x</var> values must be in the range [0, 1] or the definition is |
| 170 | + invalid. |
| 171 | + |
| 172 | +</dl> |
| 173 | + |
| 174 | +The keyword values listed above are illustrated below. |
| 175 | + |
| 176 | +<figure> |
| 177 | + <img src="curve-keywords.svg" width="500" |
| 178 | + alt="The timing functions produced by keyword values."> |
| 179 | + <figcaption> |
| 180 | + The timing functions produced by each of cubic Bézier timing |
| 181 | + function keyword values. |
| 182 | + </figcaption> |
| 183 | +</figure> |
| 184 | + |
| 185 | + |
| 186 | +Step timing functions {#step-timing-functions} |
| 187 | +--------------------- |
| 188 | + |
| 189 | +A <dfn>step timing function</dfn> is a type of <a>timing function</a> |
| 190 | +that divides the input time into a specified number of intervals that |
| 191 | +are equal in duration. |
| 192 | + |
| 193 | +Some example step timing functions are illustrated below. |
| 194 | + |
| 195 | +<figure> |
| 196 | + <img src="step-timing-func-examples.svg" width="500" |
| 197 | + alt="Example step timing functions."> |
| 198 | + <figcaption> |
| 199 | + Example step timing functions. |
| 200 | + In each case the domain is the input progress whilst the range |
| 201 | + represents the output progress produced by the step function.<br> |
| 202 | + The first row shows the function for each transition point when only |
| 203 | + one step is specified whilst the second row shows the same for three |
| 204 | + steps. |
| 205 | + </figcaption> |
| 206 | +</figure> |
| 207 | + |
| 208 | +A [=step timing function=] is defined by a non-zero positive number of |
| 209 | +<var>steps</var>, and a <var>step position</var> property that may be either |
| 210 | +<a value for="steps()">start</a> or <a value for="steps()">end</a>. |
| 211 | + |
| 212 | +At the exact point where a step occurs the result of the function is |
| 213 | +conceptually the top of the step. However, an additional <dfn>before flag</dfn> |
| 214 | +passed as input to the [=step timing function=], if true, will cause the |
| 215 | +result of the function to correspond to the bottom of the step at the step |
| 216 | +point. |
| 217 | + |
| 218 | +<div class=note> |
| 219 | +Editorial note: In a future level of this specification the calculation |
| 220 | +of the [=before flag=] from Web Animations should be moved here. |
| 221 | +This level of the specification, however, is intended to be used by |
| 222 | +CSS Transitions Level 1 and CSS Animations Level 1 which do not have a |
| 223 | +dependency on Web Animations so we leave it to each specification that |
| 224 | +references this definition to also define the value of the [=before flag=] |
| 225 | +to use. |
| 226 | +</div> |
| 227 | + |
| 228 | +The [=output progress value=] is calculated from the [=input progress value=] |
| 229 | +and [=before flag=] as follows: |
| 230 | + |
| 231 | +1. Calculate the <var>current step</var> as <code>floor([=input progress |
| 232 | + value=] × <var>steps</var>)</code> clamped to the range [0, |
| 233 | + <var>steps</var>]. |
| 234 | + |
| 235 | +1. If the <var>step position</var> property is <a value |
| 236 | + for="steps()">start</a> and <var>current step</var> < <var>steps</var>, |
| 237 | + increment <var>current step</var> by one. |
| 238 | + |
| 239 | +1. If <em>all</em> of the following conditions are true: |
| 240 | + |
| 241 | + * the [=before flag=] is set, |
| 242 | + * <var>current step</var> > 0, <em>and</em> |
| 243 | + * [=input progress value=] × <var>steps</var> mod 1 equals zero |
| 244 | + (that is, if [=input progress value=] × <var>steps</var> is |
| 245 | + integral), then |
| 246 | + |
| 247 | + decrement <var>current step</var> by one. |
| 248 | + |
| 249 | +1. The [=output progress value=] is <code><var>current step</var> |
| 250 | + / <var>steps</var></code>. |
| 251 | + |
| 252 | +<div class=example> |
| 253 | + |
| 254 | +As an example of how the [=before flag=] affects the behavior of this function, |
| 255 | +consider an animation with a [=step timing function=] whose <var>step |
| 256 | +position</var> is <a value for="steps()">start</a> and which has a positive |
| 257 | +delay and backwards fill. |
| 258 | + |
| 259 | +For example, using CSS animation: |
| 260 | + |
| 261 | +<pre class='lang-css'> |
| 262 | +animation: moveRight 5s 1s steps(5, start); |
| 263 | +</pre> |
| 264 | + |
| 265 | +During the delay phase, the [=input progress value=] will be zero but if the |
| 266 | +[=before flag=] is set to indicate that the animation has yet to reach its |
| 267 | +animation interval, the timing function will produce zero as its [=output |
| 268 | +progress value=], i.e. the bottom of the first step. |
| 269 | + |
| 270 | +At the exact moment when the animation interval begins, the [=input progress |
| 271 | +value=] will still be zero, but the [=before flag=] will not be set and hence |
| 272 | +the result of the timing function will correspond to the top of the first step. |
| 273 | + |
| 274 | +</div> |
| 275 | + |
| 276 | +The syntax for specifying a step timing function is as follows: |
| 277 | + |
| 278 | +<div class="prod"><dfn type><step-timing-function></dfn> = |
| 279 | + ''step-start'' | ''step-end'' | |
| 280 | + <span class="atom"><a lt="steps()" function>steps</a>(<<integer>>[, |
| 281 | + [ ''start'' | ''end'' ] ]?)</span></div> |
| 282 | + |
| 283 | +The meaning of each value is as follows: |
| 284 | + |
| 285 | +<dl dfn-type=value dfn-for="step-timing-function, <step-timing-function>"> |
| 286 | + |
| 287 | +: <dfn>step-start</dfn> |
| 288 | +:: Equivalent to steps(1, start); |
| 289 | +: <dfn>step-end</dfn> |
| 290 | +:: Equivalent to steps(1, end); |
| 291 | +: <dfn function lt="steps()">steps(<integer>[, [ start | end ] ]?)</dfn> |
| 292 | +:: Specifies a <a>step timing function</a>. |
| 293 | + The first parameter specifies the number of intervals in the function. |
| 294 | + It must be a positive integer greater than 0. |
| 295 | + The second parameter, which is optional, is |
| 296 | + either the value <dfn value for="steps()">start</dfn> or <dfn value |
| 297 | + for="steps()">end</dfn>, and specifies the <var>step position</var>. |
| 298 | + If the second parameter is omitted, it is given the value ''end''. |
| 299 | + |
| 300 | +</dfn> |
| 301 | + |
| 302 | +The <single-timing-function> production {#single-timing-function-production} |
| 303 | +============================================= |
| 304 | + |
| 305 | +The syntax for specifying a [=timing function=] is as follows: |
| 306 | + |
| 307 | +<div class="prod"><dfn type><single-timing-function></dfn> = |
| 308 | + ''linear'' | |
| 309 | + <<cubic-bezier-timing-function>> | |
| 310 | + <<step-timing-function>></div> |
0 commit comments