Easing function calculations
This library implements all of the easing functions as provided on https://easings.net written by Andrey Sitnik and Ivan Solovev with slight modifications to the mathematical implementations to account for Elixir's immutability.
Calculates the easing value of a given function and progress of an timing represented by a range between 0..1
. The following easings are availalbe with in, out, and in_out varients:
Note: If you'd like to see visualizations of the easing calculations visit https://easings.net
If available in Hex, the package can be installed
by adding ease
to your list of dependencies in mix.exs
:
def deps do
[
{:easing, "~> 0.3.1"}
]
end
You can calculate a single point for a function along the progress of a timing:
iex> Easing.sine_in(0.4)
0.19098300562505255
However you likely want to calculate the list of values for a given timing. Easing.to_list/2
will take a Easing.Range
struct and the easing as either a function reference or a tuple.
iex> Easing.to_list(%Easing.Range{first: 0, last: 0.5, step: 0.1}, &Easing.bounce_in_out(&1))
[0.0, 0.030000000000000027, 0.11375000000000002, 0.04499999999999993, 0.3487500000000001, 0.5]
iex> Easing.to_list(%Easing.Range{first: 0, last: 0.5, step: 0.1}, {:bounce, :in_out})
[0.0, 0.030000000000000027, 0.11375000000000002, 0.04499999999999993, 0.3487500000000001, 0.5]
In many cases you will generate many timing frame values and it may be most performant to calculate those values lazily. We can easily do this with Elixir Streams
iex> Easing.stream(%Easing.Range{first: 0, last: 1, step: 0.0001}, &Easing.sine_in/1) |> Enum.take(3)
[0.0, 1.2337005528273437e-8, 4.9348021557982236e-8]
Easing.stream/2
also take a tuple
similar to Easing.to_list/2
There is no need for you to limit to the included easing functions. A custom easing function takes a single value and returns the approximation.
iex> custom_easing = fn(progress) ->
if progress < 0.5 do
Easing.sine_in(progress) / 2
else
1 - Easing.sine_in(progress) / 2
end
end
iex> Easing.to_list(Easing.Range.new(0, 1, 0.1), custom_easing)
[0.0, 0.006155829702431115, 0.024471741852423234, 0.054496737905816106,
0.09549150281252627, 0.8535533905932737, 0.7938926261462367,
0.7269952498697734, 0.6545084971874737, 0.5782172325201156, 0.5]
Easing.Range
is a reimplementation of Elixir's Range
struct but will allow for ranges to be built across and between fractional values
rather than limited to Integer
values. You can create a new Easing.Range
struct with either form:
# struct form
iex> %Easing.Range{first: 0.5, last: 1, step: 0.1}
%Easing.Range{first: 0.5, last: 1, step: 0.1}
# function form
iex> Easing.Range(0, 0.5, 0.1)
%Easing.Range{first: 0, last: 0.5, step: 0.1}
There is also a convenience function:
iex> Easing.Range.new(0, 1, 0.1)
%Easing.Range{first: 0, last: 1, step: 0.1}
You can also calculate the steps from a target frame rate
iex> duration_in_ms = 1000
iex> fps = 60
iex> Easing.Range.calculate(duaration_in_ms, fps)
%Easing.Range{first: 0, last: 1, step: 1.6666666666666667e-5}
We are very thankful for the many contributors
This library follows Semantic Versioning
At DockYard we are ready to help you build your next Elixir project. We have a unique expertise in Elixir and Phoenix development that is unmatched. Get in touch!
At DockYard we love Elixir! You can read our Elixir blog posts
DockYard, Inc. © 2022