diff --git a/css-easing-2/Overview.bs b/css-easing-2/Overview.bs
index d89a762e631..de246ff9c30 100644
--- a/css-easing-2/Overview.bs
+++ b/css-easing-2/Overview.bs
@@ -7,10 +7,13 @@ Level: 2
Group: csswg
ED: https://drafts.csswg.org/css-easing/
TR: https://www.w3.org/TR/css-easing-2/
+Editor: Jake Archibald, Google, jakearchibald@google.com, w3cid 76394
Editor: Brian Birtles, Mozilla https://www.mozilla.org/, bbirtles@mozilla.com, w3cid 43194
Editor: Dean Jackson, Apple Inc https://www.apple.com/, dino@apple.com, w3cid 42080
Editor: Matt Rakow, Microsoft, w3cid 62267
Former Editor: Shane Stephens, Google, shans@google.com, w3cid 47691
+Markup Shorthands: markdown yes
+Indent: 2
Abstract: This CSS module describes a way for authors to define a transformation
that controls the rate of change of some value.
@@ -38,6 +41,14 @@ Repository: w3c/csswg-drafts
}
+
+
Introduction {#introduction}
============================
@@ -61,7 +72,7 @@ input progress value and producing a corresponding transformed output progress
value.
-
Example of an easing function that produces an ease-in effect.
@@ -118,20 +129,323 @@ The syntax for specifying an [=easing function=] is as follows:
+## The linear easing function: ''linear()'' ## {#the-linear-easing-function}
+
+A linear easing function
+is an [=easing function=]
+that interpolates linearly
+between its [=linear easing function/points=].
+
+A [=linear easing function=] has points,
+a [=/list=] of [=linear easing points=].
+Initially a new empty [=/list=].
+
+A linear easing point
+is a [=/struct=]
+that has:
+
+
+
+: input
+:: A number or null
+
+ Note: This is only null during [=create a linear easing function=].
+
+: output
+:: A number
+
+
+
+### Syntax ### {#linear-easing-function-syntax}
+
+A [=linear easing function=] has the following syntax:
+
+linear(<>)
+
+
+
+''linear()'' is parsed into a [=linear easing function=]
+by calling [=create a linear easing function=],
+passing in its <> as a [=/list=] of <>s.
+
+### Parsing ### {#linear-easing-function-parsing}
+
+
+
+To create a linear easing function
+given a [=/list=] of <>s |stopList|,
+perform the following.
+It returns a [=linear easing function=] or failure.
+
+1. Let |function| be a new [=linear easing function=].
+
+1. Let |largestInput| be negative infinity.
+
+1. If there are less than two [=list/items=] in |stopList|, then return failure.
+
+1. [=list/For each=] |stop| in |stopList|:
+
+ 1. Let |point| be a new [=linear easing point=]
+ with its [=linear easing point/output=] set to |stop|'s <> as a number.
+
+ 1. [=list/Append=] |point| to |function|'s [=linear easing function/points=].
+
+ 1. If |stop| has a <>, then:
+
+ 1. Set |point|'s [=linear easing point/input=] to whichever is greater:
+ |stop|'s <>'s first <> as a number,
+ or |largestInput|.
+
+ 1. Set |largestInput| to |point|'s [=linear easing point/input=].
+
+ 1. If |stop|'s <> has a second <>, then:
+
+ 1. Let |extraPoint| be a new [=linear easing point=]
+ with its [=linear easing point/output=] set to |stop|'s <> as a number.
+
+ 1. [=list/Append=] |extraPoint| to |function|'s [=linear easing function/points=].
+
+ 1. Set |extraPoint|'s [=linear easing point/input=] to whichever is greater:
+ |stop|'s <>'s second <> as a number,
+ or |largestInput|.
+
+ 1. Set |largestInput| to |extraPoint|'s [=linear easing point/input=].
+
+ 1. Otherwise, if |stop| is the first [=list/item=] in |stopList|, then:
+
+ 1. Set |point|'s [=linear easing point/input=] to 0.
+
+ 1. Set |largestInput| to 0.
+
+ 1. Otherwise, if |stop| is the last [=list/item=] in |stopList|,
+ then set |point|'s [=linear easing point/input=] to whichever is greater:
+ 1 or |largestInput|.
+
+1. For runs of [=list/items=] in |function|'s [=linear easing function/points=] that have a null [=linear easing point/input=],
+ assign a number to the [=linear easing point/input=] by linearly interpolating between the closest previous and next [=linear easing function/points=]
+ that have a non-null [=linear easing point/input=].
+
+1. Return |function|.
+
+
+
+### Serializing ### {#linear-easing-function-serializing}
+
+
+ The serialization of ''linear()'' includes input values for each point,
+ and input values are never less than the input of the previous point.
+
+ For example:
+
+ - ''linear(0, 0.25, 1)'' serializes as ''linear(0 0%, 0.25 50%, 1 100%)''
+ - ''linear(0 20%, 0.5 10%, 1)'' serializes as ''linear(0 20%, 0.5 20%, 1 100%)''
+ - ''linear(0, 0.25 25% 75%, 1)'' serializes as ''linear(0 0%, 0.25 25%, 0.25 75%, 1 100%)''
+
+
+
+
+To get a [=linear easing function=]'s (|linearEasingFunction|) serialized computed value,
+perform the following.
+It returns a [=string=].
+
+1. Let |output| be "`linear(`".
-
The linear easing function: ''linear''
+1. [=list/For each=] |point| in |linearEasingFunction|'s [=linear easing function/points=]:
-The linear easing
-function is an identity function
+ 1. If |point| is not the first [=list/item=] of |linearEasingFunction|'s [=linear easing function/points=],
+ append ", " to |output|.
+
+ 1. Append the computed value of |point|'s [=linear easing point/output=],
+ as a <>,
+ to |output|.
+
+ 1. Append "" to |output|.
+
+ 1. Append the computed value of |point|'s [=linear easing point/input=],
+ as a <>,
+ to |output|.
+
+1. Append "`)`" to |output|.
+
+1. Return |output|.
+
+
+
+### Output of a linear easing function ### {#linear-easing-function-output}
+
+
+
+To calculate linear easing output progress
+for a given [=linear easing function=] |linearEasingFunction|,
+and an [=input progress value=] |inputProgress|,
+perform the following.
+It returns an [=output progress value=].
+
+1. Let |points| be |linearEasingFunction|'s [=linear easing function/points=].
+
+1. Let |pointAIndex| be index of the last [=list/item=] in |points|
+ with an [=linear easing point/input=] less than or equal to |inputProgress|,
+ or 0 if there is no match.
+
+1. If |pointAIndex| is equal to |points| [=list/size=] minus 1,
+ decrement |pointAIndex| by 1.
+
+ Note: This ensures we have a "next" [=linear easing point|point=] to compare to.
+
+1. Let |pointA| be |points|[pointAIndex].
+
+1. Let |pointB| be |points|[pointAIndex + 1].
+
+1. If |pointA|'s [=linear easing point/input=] is equal to |pointB|'s [=linear easing point/input=],
+ return |pointB|'s [=linear easing point/output=].
+
+1. Let |progressFromPointA| be |inputProgress| minus |pointA|'s [=linear easing point/input=].
+
+1. Let |pointInputRange| be |pointB|'s [=linear easing point/input=] minus |pointA|'s [=linear easing point/input=].
+
+1. Let |progressBetweenPoints| be |progressFromPointA| divided by |pointInputRange|.
+
+1. Let |pointOutputRange| be |pointB|'s [=linear easing point/output=] minus |pointA|'s [=linear easing point/output=].
+
+1. Let |outputFromLastPoint| be |progressBetweenPoints| multiplied by |pointOutputRange|.
+
+1. Return |pointA|'s [=linear easing point/output=] plus |outputFromLastPoint|.
+
+
+
+### Examples ### {#linear-easing-function-examples}
+
+
+ ''linear()'' allows the definition of easing functions that interpolate linearly between a set of points.
+
+ For example, ''linear(0, 0.25, 1)'' produces an easing function
+ that moves linearly from 0, to 0.25, then to 1:
+
+
+
+
+
+
+ By default, values are spread evenly between entries that don't have an explicit "input".
+ Input values can be provided using a <>.
+
+ For example, ''linear(0, 0.25 75%, 1)'' produces the following easing function,
+ which spends 75% of the time transitioning from ''0'' to ''.25'',
+ then the last 25% transitioning from ''.25'' to ''1'':
+
+
+
+
+
+
+ If two input values are provided for a single output,
+ it results in two points with the same output.
+
+ For example, ''linear(0, 0.25 25% 75%, 1)''
+ is equivalent to ''linear(0, 0.25 25%, 0.25 75%, 1)'',
+ producing the following easing function:
+
+
+
+
+
+
+ If the input is outside the range provided,
+ the trajectory of the nearest two points is continued.
+
+ For example, here are the implicit values from the previous function:
+
+
+
+
+
+
+ A typical use of ''linear()'' is to provide many points to create the illusion of a curve.
+
+ For example, here's how ''linear()'' could be used to create a reusable "bounce" easing function:
+
+ ```css
+ :root {
+ --bounce: linear(
+ /* Start to 1st bounce */
+ 0, 0.063, 0.25, 0.563, 1 36.4%,
+ /* 1st to 2nd bounce */
+ 0.812, 0.75, 0.813, 1 72.7%,
+ /* 2nd to 3rd bounce */
+ 0.953, 0.938, 0.953, 1 90.9%,
+ /* 3rd bounce to end */
+ 0.984, 1 100% 100%
+ );
+ }
+
+ .example {
+ animation-timing-function: var(--bounce);
+ }
+ ```
+
+ The definition ends `1 100% 100%` to create two final points,
+ so inputs greater than 1 always output 1.
+
+
+
+
+
+ More points could be used to create a smoother result,
+ which may be needed for slower animations.
+
+
+
The linear easing keyword: ''linear''
+
+The linear keyword
+produces a [=linear easing function=]
+with two [=linear easing function/points=]:
+
+1. : [=linear easing point/input=]
+ :: 0
+ : [=linear easing point/output=]
+ :: 0
+
+1. : [=linear easing point/input=]
+ :: 1
+ : [=linear easing point/output=]
+ :: 1
+
+Note: This results in an identity function,
meaning that its [=output progress value=] is equal to the
[=input progress value=] for all inputs.
-The syntax for the [=linear easing function=] is simply the
-linear keyword.
-
+Note: Although this produces a [=linear easing function=],
+uses of the keyword ''linear'' always serialize as-is, to ''linear''.
+Whereas the function equivalent ''linear(0, 1)'' will serialize to ''linear(0 0%, 1 100%)''.
+These rules are in [Serialization](#serialization).