Skip to content

Commit 658127e

Browse files
committed
easing
1 parent f80c703 commit 658127e

File tree

9 files changed

+180
-5
lines changed

9 files changed

+180
-5
lines changed

Writerside/Geometry.tree

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
<toc-element topic="number-line.md">
1111
<toc-element topic="number-line-abs.md"/>
1212
<toc-element topic="number-line-distance.md"/>
13-
<toc-element topic="number-line-lerp.md"/>
13+
<toc-element topic="number-line-lerp.md">
14+
<toc-element topic="number-line-lerp-easing.md"/>
15+
</toc-element>
1416
<toc-element topic="number-line-segment.md">
1517
<toc-element topic="number-line-segment-intersect.md"/>
1618
</toc-element>

Writerside/cfg/buildprofiles.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
<include-in-head>js/core/segment.js</include-in-head>
4040
<include-in-head>js/core/rect.js</include-in-head>
4141
<include-in-head>js/core/polygon.js</include-in-head>
42+
<include-in-head>js/core/cubic.js</include-in-head>
4243

4344
<include-in-head>js/core/text-span.js</include-in-head>
4445
<include-in-head>js/core/text-line.js</include-in-head>
@@ -49,6 +50,7 @@
4950
<include-in-head>js/example/number-line-abs.js</include-in-head>
5051
<include-in-head>js/example/number-line-distance.js</include-in-head>
5152
<include-in-head>js/example/number-line-lerp.js</include-in-head>
53+
<include-in-head>js/example/number-line-lerp-easing.js</include-in-head>
5254
<include-in-head>js/example/number-line-segment.js</include-in-head>
5355
<include-in-head>js/example/number-line-segment-intersect.js</include-in-head>
5456

Writerside/cfg/js/core/cubic.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// https://codepen.io/onedayitwillmake/pen/nJjYRp
2+
3+
class Cubic {
4+
constructor(p1x, p1y, p2x, p2y) {
5+
this.cx = 3.0 * p1x
6+
this.bx = 3.0 * (p2x - p1x) - this.cx
7+
this.ax = 1.0 - this.cx - this.bx
8+
9+
this.cy = 3.0 * p1y
10+
this.by = 3.0 * (p2y - p1y) - this.cy
11+
this.ay = 1.0 - this.cy - this.by
12+
}
13+
14+
#sampleCurveX(t) {
15+
return ((this.ax * t + this.bx) * t + this.cx) * t
16+
}
17+
18+
#sampleCurveY(t) {
19+
return ((this.ay * t + this.by) * t + this.cy) * t
20+
}
21+
22+
#sampleCurveDerivativeX(t) {
23+
return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx
24+
}
25+
26+
#solveCurveX(x, epsilon) {
27+
let t0
28+
let t1
29+
let t2
30+
let x2
31+
let d2
32+
let i
33+
34+
for (t2 = x, i = 0; i < 32; i++) {
35+
x2 = this.#sampleCurveX(t2) - x
36+
if (Math.abs(x2) < epsilon)
37+
return t2
38+
d2 = this.#sampleCurveDerivativeX(t2)
39+
if (Math.abs(d2) < epsilon)
40+
break
41+
t2 = t2 - x2 / d2
42+
}
43+
44+
t0 = 0.0
45+
t1 = 1.0
46+
t2 = x
47+
48+
if (t2 < t0) return t0
49+
if (t2 > t1) return t1
50+
51+
while (t0 < t1) {
52+
x2 = this.#sampleCurveX(t2)
53+
if (Math.abs(x2 - x) < epsilon)
54+
return t2
55+
if (x > x2) t0 = t2
56+
else t1 = t2
57+
58+
t2 = (t1 - t0) * .5 + t0
59+
}
60+
61+
return t2
62+
}
63+
64+
solve(x, epsilon = 1e-5) {
65+
return this.#sampleCurveY(this.#solveCurveX(x, epsilon))
66+
}
67+
}

Writerside/cfg/js/core/easing.js

Whitespace-only changes.
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
class CanvasNumberLineLerpEasing extends CanvasDraw {
2+
static name = 'canvas-number-line-lerp-easing'
3+
4+
constructor() {
5+
super()
6+
7+
const c = this.cartesian = new Cartesian(this.lerp(.5), 26, {round: false})
8+
9+
c.points.push(
10+
new Point(-5, 0, {color: Color.pointA, dragY: false}),
11+
new Point(5, 0, {color: Color.pointB, dragY: false}),
12+
)
13+
}
14+
15+
draw() {
16+
const c = this.cartesian.axis({y: false, yalign: -1})
17+
18+
const [A, B] = c.points
19+
20+
const lerp = (A, B, name, points) => {
21+
A.draw(c)
22+
B.draw(c)
23+
let k = this.lerpK
24+
if (points) k = (new Cubic(...points)).solve(k)
25+
26+
const x = A.x * (1 - k) + B.x * k
27+
const C = new Point(x, A.y - 0.0000001, {
28+
name: name,
29+
color: Color.pointC,
30+
dash: [2, 2]
31+
}).draw(c)
32+
33+
new Segment(A, C, {dash: [2, 2]}).draw(c)
34+
new Segment(B, C, {dash: [2, 2]}).draw(c)
35+
}
36+
37+
lerp(A, B, 'linear')
38+
39+
const list = [
40+
['easeInSine', 0.12, 0, 0.39, 0],
41+
['easeOutSine', 0.61, 1, 0.88, 1],
42+
['easeInOutSine', 0.37, 0, 0.63, 1],
43+
['easeInCirc', 0.55, 0, 1, 0.45],
44+
['easeOutCirc', 0, 0.55, 0.45, 1],
45+
['easeInOutCirc', 0.85, 0, 0.15, 1],
46+
['easeInCubic', 0.32, 0, 0.67, 0],
47+
['easeOutCubic', 0.33, 1, 0.68, 1],
48+
['easeInOutCubic', 0.65, 0, 0.35, 1],
49+
['easeInQuad', 0.11, 0, 0.5, 0],
50+
['easeOutQuad', 0.5, 1, 0.89, 1],
51+
['easeInOutQuad', 0.45, 0, 0.55, 1],
52+
['easeInQuart', 0.5, 0, 0.75, 0],
53+
['easeOutQuart', 0.25, 1, 0.5, 1],
54+
['easeInOutQuart', 0.76, 0, 0.24, 1],
55+
['easeInQuint', 0.64, 0, 0.78, 0],
56+
['easeOutQuint', 0.22, 1, 0.36, 1],
57+
['easeInOutQuint', 0.83, 0, 0.17, 1],
58+
['easeInExpo', 0.7, 0, 0.84, 0],
59+
['easeOutExpo', 0.16, 1, 0.3, 1],
60+
['easeInOutExpo', 0.87, 0, 0.13, 1],
61+
['easeInBack', 0.36, 0, 0.66, -0.56],
62+
['easeOutBack', 0.34, 1.56, 0.64, 1],
63+
['easeInOutBack', 0.68, -0.6, 0.32, 1.6],
64+
]
65+
66+
for (let i = 0; i < list.length; i++) {
67+
const name = list[i].shift()
68+
const y = (i + 1) * 2
69+
lerp(
70+
new Point(A.x, y, {color: Color.pointA, dash: [2, 2]}),
71+
new Point(B.x, y, {color: Color.pointB, dash: [2, 2]}),
72+
name,
73+
list[i]
74+
)
75+
}
76+
c.draw()
77+
}
78+
}
79+
80+
CanvasDraw.define(CanvasNumberLineLerpEasing)

Writerside/cfg/js/example/number-line-lerp.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class CanvasNumberLineLerp extends CanvasDraw {
44
constructor() {
55
super()
66

7-
const c = this.cartesian = new Cartesian(this.lerp(.5), 2, {round: true})
7+
const c = this.cartesian = new Cartesian(this.lerp(.5), 2, {round: false})
88

99
c.points.push(
1010
new Point(-5, 0, {name: 'A', color: Color.pointA, dragY: false}),
@@ -20,7 +20,11 @@ class CanvasNumberLineLerp extends CanvasDraw {
2020
A.draw(c)
2121
B.draw(c)
2222

23-
const C = new Point(A.x + (B.x - A.x) * this.lerpK, -0.0000001, {name: 'C', color: Color.pointC, dash: [2, 2]}).draw(c)
23+
const C = new Point(A.x + (B.x - A.x) * this.lerpK, -0.0000001, {
24+
name: 'C',
25+
color: Color.pointC,
26+
dash: [2, 2]
27+
}).draw(c)
2428

2529
new Segment(A, C, {dash: [2, 2]}).draw(c)
2630
new Segment(B, C, {dash: [2, 2]}).draw(c)

Writerside/cfg/js/example/test.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<script type="text/javascript" src="../core/segment.js"></script>
5656
<script type="text/javascript" src="../core/rect.js"></script>
5757
<script type="text/javascript" src="../core/polygon.js"></script>
58+
<script type="text/javascript" src="../core/cubic.js"></script>
5859

5960
<script type="text/javascript" src="../core/text-span.js"></script>
6061
<script type="text/javascript" src="../core/text-line.js"></script>
@@ -65,6 +66,7 @@
6566
<script type="text/javascript" src="number-line-abs.js"></script>
6667
<script type="text/javascript" src="number-line-distance.js"></script>
6768
<script type="text/javascript" src="number-line-lerp.js"></script>
69+
<script type="text/javascript" src="number-line-lerp-easing.js"></script>
6870
<script type="text/javascript" src="number-line-segment.js"></script>
6971
<script type="text/javascript" src="number-line-segment-intersect.js"></script>
7072

@@ -105,8 +107,9 @@
105107
<div id="canvas-number-line-segment-intersect"></div>
106108
<div id="canvas-number-line-segment"></div>
107109
<div id="canvas-number-line-distance"></div>
108-
-->
109110
<div id="canvas-number-line-lerp"></div>
111+
-->
112+
<div id="canvas-number-line-lerp-easing"></div>
110113
<!--
111114
<div id="canvas-number-line-abs"></div>
112115
<div id="canvas-number-line"></div>

Writerside/topics/cartesian-line-slope.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ $$ k = \frac{B_y - A_y}{B_x - A_x}, \quad \text{если } B_x \neq A_x $$
2929
> Значение улового коэффициента так же является тангенсом угла между прямой $ A'B' $ и положительным направлением
3030
> оси $ X $.
3131
32-
## Две прямые {id=two}
32+
## Пересечение прямых {id=intersect}
3333

3434
Для двух прямых $AB$ и $CD$, заданых соответствующими точками верны следующие утверждения:
3535

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Функции плавности
2+
3+
При линейной интерполяции коэфициент $ t $ зачастую изменяется линейно так как в основном является отношением времени
4+
начала анимации ко времени завершения.
5+
6+
В случае, когда необходима некая нелинейность применяют функцию, которая изменяет $ t $ в зависимости от его значения. К
7+
примеру, функция [easeInSine](https://easings.net/#easeInSine) выглядит таким образом:
8+
9+
$$ f(x) = 1 - \cos\left(\frac{\pi}{2}x\right) $$
10+
11+
Минусом таких функций является невозможность тонкой настройки. Поэтому зачастую
12+
используется [кривые Безье](https://w.wiki/7eEb) для четырёх точек. Поиграться с коэфициентами вы можете на
13+
этом [сайте](https://cubic-bezier.com).
14+
15+
Ниже приведены часто используемые коэцициенты взятые на этом [сайте](https://easings.net):
16+
17+
```.``` {id=canvas-number-line-lerp-easing}

0 commit comments

Comments
 (0)