Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b4bad72
Calculating progress & serialising linear-spline
jakearchibald Jun 24, 2022
1c326ef
Define function creation
jakearchibald Jun 24, 2022
1e5b11d
Update largest number when inferring 0 for the first item
jakearchibald Jun 24, 2022
a4c01be
Simplify serialisation
jakearchibald Jun 27, 2022
8276f40
Spec tidy up
jakearchibald Jun 27, 2022
0e5043f
Connecting parsing and serialising
jakearchibald Jun 27, 2022
f621932
Fix indenting
jakearchibald Jun 27, 2022
ef29eae
Dark mode figures
jakearchibald Jul 6, 2022
2739467
Merge remote-tracking branch 'origin/main' into css-easing-2-linear-s…
jakearchibald Jul 6, 2022
05473a9
Markdown headings
jakearchibald Jul 6, 2022
f3c7508
Switch back to linear()
jakearchibald Jul 6, 2022
973a84a
Missed a few old spline references
jakearchibald Jul 7, 2022
c6fe005
Examples
jakearchibald Jul 8, 2022
c51794a
Existing examples are good enough IMO
jakearchibald Jul 8, 2022
8e38422
Forgot to specify 'index'
jakearchibald Jul 8, 2022
8fbc910
Missing comma
jakearchibald Jul 8, 2022
5221e11
Adding serialization examples
jakearchibald Jul 10, 2022
589a383
Be more specific about the linear keyword
jakearchibald Jul 10, 2022
ce4c5d1
A little more specific about the serialization of linear()
jakearchibald Jul 11, 2022
932ce07
Apply suggestions from code review
jakearchibald Jul 12, 2022
a509029
Fixes following review
jakearchibald Jul 12, 2022
d75bd5c
Clarify note
jakearchibald Jul 12, 2022
bdbb745
Make all graphs transparent
jakearchibald Jul 17, 2022
17e0ad3
One more
jakearchibald Jul 17, 2022
8ee8bf2
Move examples after normative text
jakearchibald Jul 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Switch back to linear()
  • Loading branch information
jakearchibald committed Jul 6, 2022
commit f3c75080589a506046b80d5d6ed5939b4ec704ef
142 changes: 69 additions & 73 deletions css-easing-2/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -128,42 +128,32 @@ The syntax for specifying an [=easing function=] is as follows:

<div class="prod"><dfn type>&lt;easing-function&gt;</dfn> =
''linear'' |
''linear-spline()'' |
''linear()'' |
<<cubic-bezier-easing-function>> |
<<step-easing-function>></div>

<h3 id=the-linear-easing-function oldids=linear-timing-function-section>The linear easing function: ''linear''</h3>

The <dfn export lt="linear easing function|linear timing function">linear easing
function</dfn> is 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
<dfn dfn-type=value for=easing-function>linear</dfn> keyword.

## The linear spline easing function: ''linear-spline()'' ## {#the-linear-spline-easing-function}
## The linear easing function: ''linear()'' ## {#the-linear-easing-function}

<div class=note>
''linear-spline()'' allows developers to define their own easing using a series of points that are interpolated linearly.
''linear()'' allows developers to define their own easing using a series of points that are interpolated linearly.

By default, points are
TODO: expand note
</div>

A <dfn export>linear spline easing function</dfn>
A <dfn export>linear easing function</dfn>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind moving this normative text to the top of the section, and having all the examples below?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How much of it do you want above the examples? Everything from here until ### Syntax ###?

is an [=easing function=]
that interpolates linearly
between its [=linear spline easing function/points=].
between its [=linear easing function/points=].

A [=linear spline easing function=] has <dfn for="linear spline easing function">points</dfn>,
a [=/list=] of [=linear spline easing points=].
A [=linear easing function=] has <dfn for="linear easing function">points</dfn>,
a [=/list=] of [=linear easing points=].
Initially a new empty [=/list=].

A <dfn>linear spline easing point</dfn>
A <dfn>linear easing point</dfn>
is a [=/struct=]
that has:

<dl dfn-for="linear spline easing point">
<dl dfn-for="linear easing point">

: <dfn>input</dfn>
:: A number or null
Expand All @@ -175,105 +165,105 @@ that has:

</dl>

### Syntax ### {#linear-spline-easing-function-syntax}
### Syntax ### {#linear-easing-function-syntax}

A [=linear spline easing function=] has the following syntax:
A [=linear easing function=] has the following syntax:

<dfn function lt="linear-spline()">linear-spline(<<linear-spline-stop-list>>)</dfn>
<dfn function lt="linear()">linear(<<linear-stop-list>>)</dfn>

<pre class="prod">
<dfn>&lt;linear-spline-stop-list></dfn> = [ <<linear-spline-stop>> ]#
<dfn>&lt;linear-spline-stop></dfn> = <<number>> && <<linear-spline-stop-length>>?
<dfn>&lt;linear-spline-stop-length></dfn> = <<percentage>>{1,2}
<dfn>&lt;linear-stop-list></dfn> = [ <<linear-stop>> ]#
<dfn>&lt;linear-stop></dfn> = <<number>> && <<linear-stop-length>>?
<dfn>&lt;linear-stop-length></dfn> = <<percentage>>{1,2}
</pre>

''linear-spline()'' is parsed into a [=linear spline easing function=]
''linear()'' is parsed into a [=linear easing function=]
by calling [=create a linear easing function=],
passing in its <<linear-spline-stop-list>> as a [=/list=] of <<linear-spline-stop>>s.
passing in its <<linear-stop-list>> as a [=/list=] of <<linear-stop>>s.

### Parsing ### {#linear-spline-easing-function-parsing}
### Parsing ### {#linear-easing-function-parsing}

<section algorithm="to create a linear easing function">

To <dfn>create a linear easing function</dfn>
given a [=/list=] of <<linear-spline-stop>>s |stopList|,
given a [=/list=] of <<linear-stop>>s |stopList|,
perform the following.
It returns a [=linear spline easing function=].
It returns a [=linear easing function=] or <i>failure</i>.

1. Let |function| be a new [=linear spline easing function=].
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. If there are less than two [=list/items=] in |stopList|, then return <i>failure</i>.

1. [=list/For each=] |stop| in |stopList|:

1. Let |point| be a new [=linear spline easing point=]
with its [=linear spline easing point/output=] set to |stop|'s <<number>> as a number.
1. Let |point| be a new [=linear easing point=]
with its [=linear easing point/output=] set to |stop|'s <<number>> as a number.

1. [=list/Append=] |point| to |function|'s [=linear spline easing function/points=].
1. [=list/Append=] |point| to |function|'s [=linear easing function/points=].

1. If |stop| has a <<linear-spline-stop-length>>, then:
1. If |stop| has a <<linear-stop-length>>, then:

1. Set |point|'s [=linear spline easing point/input=] to whichever is greater:
|stop|'s <<linear-spline-stop-length>>'s first <<percentage>> as a number,
1. Set |point|'s [=linear easing point/input=] to whichever is greater:
|stop|'s <<linear-stop-length>>'s first <<percentage>> as a number,
or |largestInput|.

1. Set |largestInput| to |point|'s [=linear spline easing point/input=].
1. Set |largestInput| to |point|'s [=linear easing point/input=].

1. If |stop|'s <<linear-spline-stop-length>> has a second <<percentage>>, then:
1. If |stop|'s <<linear-stop-length>> has a second <<percentage>>, then:

1. Let |extraPoint| be a new [=linear spline easing point=]
with its [=linear spline easing point/output=] set to |stop|'s <<number>> as a number.
1. Let |extraPoint| be a new [=linear easing point=]
with its [=linear easing point/output=] set to |stop|'s <<number>> as a number.

1. [=list/Append=] |extraPoint| to |function|'s [=linear spline easing function/points=].
1. [=list/Append=] |extraPoint| to |function|'s [=linear easing function/points=].

1. Set |extraPoint|'s [=linear spline easing point/input=] to whichever is greater:
|stop|'s <<linear-spline-stop-length>>'s second <<percentage>> as a number,
1. Set |extraPoint|'s [=linear easing point/input=] to whichever is greater:
|stop|'s <<linear-stop-length>>'s second <<percentage>> as a number,
or |largestInput|.

1. Set |largestInput| to |extraPoint|'s [=linear spline easing point/input=].
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 spline easing point/input=] to 0.
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 spline easing point/input=] to whichever is greater:
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 spline easing function/points=] that have a null [=linear spline easing point/input=],
assign a number to the [=linear spline easing point/input=] by linearly interpolating between the closest previous and next [=linear spline easing function/points=]
that have a non-null [=linear spline easing point/input=].
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|.

</section>

### Serializing ### {#linear-spline-easing-function-serializing}
### Serializing ### {#linear-easing-function-serializing}

<section algorithm="linear spline easing function">
<section algorithm="linear easing function">

To get a [=linear spline easing function=]'s (|linearSplineEasingFunction|) <dfn for="linear spline easing function" export>serialized computed value</dfn>,
To get a [=linear easing function=]'s (|linearSplineEasingFunction|) <dfn for="linear easing function" export>serialized computed value</dfn>,
perform the following.
It returns a [=string=].

1. Let |output| be "`linear-spline(`".
1. Let |output| be "`linear(`".

1. [=list/For each=] |point| in |linearSplineEasingFunction|'s [=linear spline easing function/points=]:
1. [=list/For each=] |point| in |linearSplineEasingFunction|'s [=linear easing function/points=]:

1. If |point| is not the first [=list/item=] of |linearSplineEasingFunction|'s [=linear spline easing function/points=],
1. If |point| is not the first [=list/item=] of |linearSplineEasingFunction|'s [=linear easing function/points=],
append "<code>, </code>" to |output|.

1. Append the computed value of |point|'s [=linear spline easing point/output=],
1. Append the computed value of |point|'s [=linear easing point/output=],
as a <<number>>,
to |output|.

1. Append "<code> </code>" to |output|.

1. Append the computed value of |point|'s [=linear spline easing point/input=],
1. Append the computed value of |point|'s [=linear easing point/input=],
as a <<percentage>>
to |output|.

Expand All @@ -283,49 +273,53 @@ It returns a [=string=].

</section>

### Output of a linear spline easing function ### {#linear-spline-easing-function-output}
### Output of a linear easing function ### {#linear-easing-function-output}

<section algorithm="to calculate linear spline output progress">

To <dfn export>calculate linear spline output progress</dfn>
for a given [=linear spline easing function=] |linearSplineEasingFunction|,
for a given [=linear easing function=] |linearSplineEasingFunction|,
and an [=input progress value=] |inputProgress|,
perform the following.
It returns an [=output progress value=].

Note: TODO explain this with diagrams

1. Let |points| be |linearSplineEasingFunction|'s [=linear spline easing function/points=].
1. Let |points| be |linearSplineEasingFunction|'s [=linear easing function/points=].

1. Let |pointAIndex| be the last [=list/item=] in |points| with an [=linear spline easing point/input=] less than or equal to |inputProgress|,
1. Let |pointAIndex| be 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 spline easing point|point=] to compare to.
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 spline easing point/input=] is equal to |pointB|'s [=linear spline easing point/input=],
return |pointB|'s [=linear spline easing point/output=].
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 spline easing point/input=].
1. Let |progressFromPointA| be |inputProgress| minus |pointA|'s [=linear easing point/input=].

1. Let |pointInputRange| be |pointB|'s [=linear spline easing point/input=] minus |pointA|'s [=linear spline 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 spline easing point/output=] minus |pointA|'s [=linear spline easing point/output=].
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 spline easing point/output=] plus |outputFromLastPoint|.
1. Return |pointA|'s [=linear easing point/output=] plus |outputFromLastPoint|.

</section>

<h3 id=the-linear-easing-keyword oldids=linear-timing-function-section>The linear easing keyword: ''linear''</h3>

The <dfn dfn-type=value for=easing-function>linear</dfn> keyword is shorthand for <a lt="linear()" function>linear(0, 1)</a>.

<h3 id=cubic-bezier-easing-functions oldids=cubic-bezier-timing-functions>Cubic
B&eacute;zier easing functions:
''ease'', ''ease-in'', ''ease-out'', ''ease-in-out'', ''cubic-bezier()''</h3>
Expand Down Expand Up @@ -614,6 +608,8 @@ and [=before flag=] as follows:

<h3 id=serialization oldids=serializing-a-timing-function>Serialization</h3>

Note: TODO - briefly explain the impact of this.

Easing functions are serialized using the common serialization patterns
defined in [[CSSOM]] with the following additional requirements:

Expand All @@ -632,8 +628,8 @@ defined in [[CSSOM]] with the following additional requirements:
2. Otherwise, serialize as <a lt="steps()"
function>steps(&lt;integer&gt;, &lt;step-position&gt;)</a>.

* A [=Linear spline easing function=] is serialized by getting its
[=linear spline easing function/serialized computed value=].
* A [=linear easing function=] is serialized by getting its
[=linear easing function/serialized computed value=].

Privacy and Security Considerations {#priv-sec}
===================================
Expand Down