Packages

Easing functions for animation in pure Gleam

Current section

Files

Jump to
easings_gleam src ease.erl
Raw

src/ease.erl

-module(ease).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/ease.gleam").
-export([linear/1, quadratic/1, cubic/1, quartic/1, quintic/1, sine/1, exponential/1, circular/1, back/1, elastic/1, bounce/1, spring/1, reverse/1, join_at/3, join/2, symmetry/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Easing functions for more natural animation transitions, derived from\n"
" [Easings.net](https://easings.net).\n"
"\n"
" <style>\n"
" @font-face {\n"
" font-family: \"Iosevka\";\n"
" font-style: normal;\n"
" font-display: swap;\n"
" font-weight: 400;\n"
" src: url(https://cdn.jsdelivr.net/fontsource/fonts/iosevka@latest/latin-400-normal.woff2) format('woff2'), url(https://cdn.jsdelivr.net/fontsource/fonts/iosevka@latest/latin-400-normal.woff) format('woff');\n"
" }\n"
"\n"
" .language-ansi {\n"
" font-family: \"Iosevka\", \"monospace\";\n"
" line-height: 1.0;\n"
" }\n"
" </style>\n"
).
-file("src/ease.gleam", 45).
?DOC(
" Linear easing is an identity transformation, time is not skewed.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ _________________________________________________⢀⡀\n"
" _ ⣀⣀⠤⠔⠒⠉⠁\n"
" 0.75 _ ⣀⡠⠤⠒⠊⠉\n"
" _ ⢀⣀⡠⠤⠒⠊⠉\n"
" 0.5 _ ⢀⣀⠤⠔⠒⠉⠁\n"
" _ ⣀⣀⠤⠔⠒⠉⠁\n"
" 0.25 _ ⣀⡠⠤⠒⠊⠉\n"
" _ ⢀⣀⡠⠤⠒⠊⠉\n"
" 0 _ ⣀⠤⠔⠒⠉⠁_____________________________________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
).
-spec linear(float()) -> float().
linear(T) ->
T.
-file("src/ease.gleam", 69).
?DOC(
" Eases in quadratically.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________________________________⡀\n"
" _ ⢀⡠⠔⠉\n"
" 0.75 _ ⣀⠤⠒⠁\n"
" _ ⢀⡠⠒⠉\n"
" 0.5 _ ⣀⠤⠒⠊⠁\n"
" _ ⣀⡠⠔⠒⠉\n"
" 0.25 _ ⢀⣀⠤⠔⠒⠉\n"
" _ ⣀⣀⠤⠤⠒⠒⠉⠁\n"
" 0 _ ⣀⣀⣀⣀⣀⣀⡠⠤⠤⠤⠤⠒⠒⠒⠉⠉⠉__________________________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
"\n"
" See more info on [Easings.net](https://easings.net/#easeInQuad).\n"
).
-spec quadratic(float()) -> float().
quadratic(T) ->
T * T.
-file("src/ease.gleam", 93).
?DOC(
" Eases in cubically.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________________________________⡀\n"
" _ ⡠⠊\n"
" 0.75 _ ⢀⠔⠉\n"
" _ ⢀⡠⠊⠁\n"
" 0.5 _ ⢀⡠⠒⠁\n"
" _ ⣀⠔⠊⠁\n"
" 0.25 _ ⣀⡠⠔⠊⠉\n"
" _ ⣀⣀⡠⠤⠒⠊⠉\n"
" 0 _ ⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⡠⠤⠤⠤⠤⠤⠔⠒⠒⠊⠉⠉___________________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
"\n"
" See more info on [Easings.net](https://easings.net/#easeInCubic).\n"
).
-spec cubic(float()) -> float().
cubic(T) ->
(T * T) * T.
-file("src/ease.gleam", 117).
?DOC(
" Eases in quartically.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________________________________⡀\n"
" _ ⢀⠊\n"
" 0.75 _ ⢀⠔⠁\n"
" _ ⢀⠔⠁\n"
" 0.5 _ ⡠⠒⠁\n"
" _ ⣀⠔⠊\n"
" 0.25 _ ⣀⠤⠒⠉\n"
" _ ⣀⣀⠤⠔⠒⠉\n"
" 0 _ ⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⠤⠤⠤⠤⠤⠔⠒⠒⠊⠉⠉______________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
"\n"
" See more info on [Easings.net](https://easings.net/#easeInQuart).\n"
).
-spec quartic(float()) -> float().
quartic(T) ->
((T * T) * T) * T.
-file("src/ease.gleam", 141).
?DOC(
" Eases in quintically.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________________________________⡀\n"
" _ ⠔\n"
" 0.75 _ ⠠⠊\n"
" _ ⢀⠔⠁\n"
" 0.5 _ ⢀⠔⠁\n"
" _ ⡠⠔⠁\n"
" 0.25 _ ⢀⡠⠔⠊\n"
" _ ⢀⣀⠤⠔⠊⠁\n"
" 0 _ ⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⠤⠤⠤⠤⠤⠔⠒⠒⠊⠉⠁__________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
"\n"
" See more info on [Easings.net](https://easings.net/#easeInQuint).\n"
).
-spec quintic(float()) -> float().
quintic(T) ->
(((T * T) * T) * T) * T.
-file("src/ease.gleam", 165).
?DOC(
" Eases in with a sine function.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________________________________⡀\n"
" _ ⣀⠤⠒⠉\n"
" 0.75 _ ⢀⡠⠔⠒⠉\n"
" _ ⢀⡠⠔⠊⠁\n"
" 0.5 _ ⣀⠤⠔⠊⠁\n"
" _ ⣀⡠⠔⠒⠉\n"
" 0.25 _ ⢀⣀⠤⠔⠒⠉\n"
" _ ⢀⣀⡠⠤⠒⠒⠉⠁\n"
" 0 _ ⣀⣀⣀⣀⣀⣀⠤⠤⠤⠤⠒⠒⠒⠉⠉⠁___________________________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
"\n"
" See more info on [Easings.net](https://easings.net/#easeInSine).\n"
).
-spec sine(float()) -> float().
sine(T) ->
Half_pi = 1.5707963267948966,
1.0 - gleam_community@maths:cos(T * Half_pi).
-file("src/ease.gleam", 191).
?DOC(
" Eases in exponentially.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________________________________⡀\n"
" _ ⡐\n"
" 0.75 _ ⡐\n"
" _ ⢀⠌\n"
" 0.5 _ ⡠⠂\n"
" _ ⡠⠊\n"
" 0.25 _ ⡠⠔⠉\n"
" _ ⢀⣀⠤⠔⠒⠉\n"
" 0 _ ⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⠤⠤⠤⠤⠤⠤⠤⠤⠒⠒⠒⠒⠉⠉⠁________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
"\n"
" See more info on [Easings.net](https://easings.net/#easeInExpo).\n"
).
-spec exponential(float()) -> float().
exponential(T) ->
case T of
+0.0 ->
+0.0;
_ ->
X@1 = case gleam@float:power(2.0, (10.0 * T) - 10.0) of
{ok, X} -> X;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"ease"/utf8>>,
function => <<"exponential"/utf8>>,
line => 195,
value => _assert_fail,
start => 7331,
'end' => 7385,
pattern_start => 7342,
pattern_end => 7347})
end,
X@1
end.
-file("src/ease.gleam", 221).
?DOC(
" Eases in on an elliptic arc.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________________________________⡀\n"
" _\n"
" 0.75 _ ⢀⠊\n"
" _ ⢀⠔⠁\n"
" 0.5 _ ⣀⠤⠊⠁\n"
" _ ⢀⣀⠤⠒⠉\n"
" 0.25 _ ⢀⣀⠤⠤⠒⠊⠁\n"
" _ ⣀⣀⣀⠤⠤⠔⠒⠊⠉⠁\n"
" 0 _ ⣀⣀⣀⣀⣀⣀⣀⣀⣀⠤⠤⠤⠤⠤⠤⠔⠒⠒⠒⠊⠉⠉⠉____________________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
"\n"
" See more info on [Easings.net](https://easings.net/#easeInCirc).\n"
).
-spec circular(float()) -> float().
circular(T) ->
X@1 = case gleam@float:square_root(1.0 - (T * T)) of
{ok, X} -> X;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"ease"/utf8>>,
function => <<"circular"/utf8>>,
line => 222,
value => _assert_fail,
start => 8305,
'end' => 8356,
pattern_start => 8316,
pattern_end => 8321})
end,
1.0 - X@1.
-file("src/ease.gleam", 230).
?DOC(
" Eases away from the goal before accelerating toward it.\n"
"\n"
" See more info on [Easings.net](https://easings.net/#easeInBack).\n"
).
-spec back(float()) -> float().
back(T) ->
C1 = 1.70158,
C3 = C1 + 1.0,
(((C3 * T) * T) * T) - ((C1 * T) * T).
-file("src/ease.gleam", 257).
?DOC(
" Eases by oscillating with increasing amplitude around the start.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________________________________⡀\n"
" _ ⠠\n"
" 0.75 _ ⠄\n"
" _ ⠠\n"
" 0.5 _ ⡀\n"
" _\n"
" 0.25 _ ⠈\n"
" _ ⢀⣀⣀⡀ ⠁\n"
" 0 _ ⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⠤⢄⣀⣀⣀______⣀⠤⠊⠁__⠈⠢_______⠐____\n"
" ⠉⠉⠉⠉⠉⠉ ⠑⡀ ⠂\n"
" |''''|''''|''''|''''|''''|''''|''''|''''⠐⠄'''⡈''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8⠢⣀0.9 1\n"
" ```\n"
"\n"
" See more info on [Easings.net](https://easings.net/#easeInElastic).\n"
).
-spec elastic(float()) -> float().
elastic(T) ->
C4 = 2.0943951,
case T of
+0.0 ->
+0.0;
1.0 ->
1.0;
_ ->
P@1 = case gleam@float:power(2.0, (10.0 * T) - 10.0) of
{ok, P} -> P;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"ease"/utf8>>,
function => <<"elastic"/utf8>>,
line => 264,
value => _assert_fail,
start => 9728,
'end' => 9782,
pattern_start => 9739,
pattern_end => 9744})
end,
(+0.0 - P@1) * gleam_community@maths:sin(((T * 10.0) - 10.75) * C4)
end.
-file("src/ease.gleam", 290).
?DOC(
" Eases in by \"bouncing\" around the start.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ ________________________________________________⣀⣀⡀\n"
" _ ⢀⠤⠒⠊⠉\n"
" 0.75 _ ⡠⠊⠁\n"
" _ ⡠⠊\n"
" 0.5 _ ⡠⠊\n"
" _ ⢀⠔\n"
" 0.25 _ ⢀⣀⣀⣀⣀⡀ ⠠⠂\n"
" _ ⣀⠤⠒⠉⠁ ⠈⠉⠒⠤⣀ ⡐⠁\n"
" 0 _ ⣀⣀⣀⣀⣀⡠⠤⠒⠒⠒⠒⠢⠤⢄⠤⠊______________⠑⢄⠔__________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
"\n"
" See more info on [Easings.net](https://easings.net/#easeInBounce).\n"
).
-spec bounce(float()) -> float().
bounce(T) ->
N1 = 7.5625,
D1 = 2.75,
A = case D1 of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator -> 1.0 / Gleam@denominator
end,
B = 2.0 * A,
C = 2.5 * A,
X = case 1.0 - T of
T@1 when T@1 < A ->
(N1 * T@1) * T@1;
T@2 when T@2 < B ->
T@3 = T@2 - (case D1 of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator@1 -> 1.5 / Gleam@denominator@1
end),
((N1 * T@3) * T@3) + 0.75;
T@4 when T@4 < C ->
T@5 = T@4 - (case D1 of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator@2 -> 2.25 / Gleam@denominator@2
end),
((N1 * T@5) * T@5) + 0.9375;
T@6 ->
T@7 = T@6 - (case D1 of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator@3 -> 2.625 / Gleam@denominator@3
end),
((N1 * T@7) * T@7) + 0.984375
end,
1.0 - X.
-file("src/ease.gleam", 335).
?DOC(
" Eases in like a spring around the start.\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________________________________⡀\n"
" _ ⡠⠊\n"
" 0.75 _ ⡠⠊\n"
" _ ⡠⠊\n"
" 0.5 _ ⣀⠔⠉\n"
" _ ⢀⠤⠊\n"
" 0.25 _ ⣀⠤⠊⠁\n"
" _ ⢀⡠⠔⠊\n"
" 0 _ ⣀⣀⣀⣀⣀⣀⣀⣀⠤⠤⠤⠤⢄⣀⣀____________⣀⡠⠔⠊⠁___________________\n"
" ⠉⠉⠒⠒⠢⠤⠤⠤⠒⠒⠊⠉\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
).
-spec spring(float()) -> float().
spring(T) ->
Pi = 3.1415926535897932,
{T@1, S1} = {1.0 - T, T},
S2@1 = case gleam@float:power(S1, 2.2) of
{ok, S2} -> S2;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"ease"/utf8>>,
function => <<"spring"/utf8>>,
line => 339,
value => _assert_fail,
start => 12204,
'end' => 12244,
pattern_start => 12215,
pattern_end => 12221})
end,
1.0 - (((gleam_community@maths:sin(
(T@1 * Pi) * (0.2 + (((2.5 * T@1) * T@1) * T@1))
)
* S2@1)
+ T@1)
* (1.0 + (1.2 * S1))).
-file("src/ease.gleam", 373).
?DOC(
" Inverts an easing function, so ease-in becomes ease-out and ease-out\n"
" becomes ease-in.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" quartic |> reverse\n"
" ```\n"
"\n"
" Output functions graph:\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ ________________________________⢀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⡀\n"
" _ ⢀⣀⡠⠤⠤⠒⠒⠒⠉⠉⠉⠉⠉⠁\n"
" 0.75 _ ⢀⡠⠔⠒⠉⠁\n"
" _ ⢀⡠⠔⠊⠁\n"
" 0.5 _ ⡠⠒⠁\n"
" _ ⢀⠔⠊\n"
" 0.25 _ ⢀⠔⠁\n"
" _ ⢀⠔⠁\n"
" 0 _ ⡠⠂_________________________________________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
).
-spec reverse(fun((float()) -> float())) -> fun((float()) -> float()).
reverse(Ease) ->
fun(T) -> 1.0 - Ease(1.0 - T) end.
-file("src/ease.gleam", 487).
?DOC(
" Join two easing functions at a given point.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" join(linear, bounce |> reverse, 0.25)\n"
" ```\n"
"\n"
" Output functions graph:\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________⡀____________⢀⡀_____⣀⣀⣀⣀⡀\n"
" _ ⡐⠈⠑⠤⣀ ⢀⡠⠔⠁⠈⠉⠉⠉⠉⠉\n"
" 0.75 _ ⢀⠌ ⠉⠒⠒⠒⠒⠉⠁\n"
" _ ⡠⠂\n"
" 0.5 _ ⢀⠔\n"
" _ ⡠⠔⠁\n"
" 0.25 _ ⣀⣀⡠⠤⠒⠉\n"
" _ ⢀⣀⡠⠤⠒⠊⠉\n"
" 0 _ ⣀⠤⠔⠒⠉⠁_____________________________________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
).
-spec join_at(fun((float()) -> float()), fun((float()) -> float()), float()) -> fun((float()) -> float()).
join_at(Ease_start, Ease_end, At) ->
fun(T) -> case T < At of
true ->
Ease_start(case At of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator -> T / Gleam@denominator
end) * At;
false ->
(Ease_end(case (1.0 - At) of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator@1 -> (T - At) / Gleam@denominator@1
end) * (1.0 - At)) + At
end end.
-file("src/ease.gleam", 457).
?DOC(
" Join two easing functions.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" join(back, elastic |> reverse)\n"
" ```\n"
"\n"
" Output functions graph:\n"
"\n"
" ```ansi\n"
"\n"
" ⢀⠒⢄\n"
" 1 _ ___________________________⠄__⢂___⣀⠤⠤⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⡀\n"
" _ ⠠ ⠑⠒⠊\n"
" 0.75 _ ⡀\n"
" _\n"
" 0.5 _ ⡈\n"
" _ ⢀⠌\n"
" 0.25 _ ⡠⠁\n"
" _ ⢀⠔⠊\n"
" 0 _ ⣀⣀⣀⣀___________⣀⡠⠤⠊⠁_______________________________\n"
" ⠉⠉⠉⠉⠉⠒⠒⠒⠉⠉⠉\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
).
-spec join(fun((float()) -> float()), fun((float()) -> float())) -> fun((float()) -> float()).
join(Ease_start, Ease_end) ->
join_at(Ease_start, Ease_end, 0.5).
-file("src/ease.gleam", 426).
?DOC(
" Making an easing function symmetry by joining it to its reversed self, so\n"
" ease-in becomes ease-in-out and ease-out becomes ease-out-in.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" quartic |> symmetry\n"
" ```\n"
"\n"
" Output functions graph:\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ _______________________________________⢀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⡀\n"
" _ ⣀⠤⠔⠒⠊⠉⠉⠁\n"
" 0.75 _ ⡠⠔⠉\n"
" _ ⢀⠔⠊\n"
" 0.5 _ ⡠⠂\n"
" _ ⢀⠊\n"
" 0.25 _ ⡠⠒⠁\n"
" _ ⢀⡠⠔⠉\n"
" 0 _ ⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⠤⠤⠤⠒⠒⠉⠁_________________________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
"\n"
" ```gleam\n"
" quartic |> reverse |> symmetry\n"
" ```\n"
"\n"
" Output functions graph:\n"
"\n"
" ```ansi\n"
"\n"
" 1 _ __________________________________________________⡀\n"
" _ ⢀⠊\n"
" 0.75 _ ⡠⠒⠁\n"
" _ ⢀⡠⠔⠉\n"
" 0.5 _ ⢀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⠤⠤⠤⠒⠒⠉⠁\n"
" _ ⣀⠤⠔⠒⠊⠉⠉⠁\n"
" 0.25 _ ⡠⠔⠉\n"
" _ ⢀⠔⠊\n"
" 0 _ ⡠⠂_________________________________________________\n"
"\n"
" |''''|''''|''''|''''|''''|''''|''''|''''|''''|''''|\n"
" 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1\n"
" ```\n"
).
-spec symmetry(fun((float()) -> float())) -> fun((float()) -> float()).
symmetry(Ease) ->
join(
Ease,
begin
_pipe = Ease,
reverse(_pipe)
end
).