View Source Easing
Easing function calculations
Credits
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.
Description
Calculates the easing value of a given function and progress of an animation 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
Installation
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
Usage
Calculating a single point
You can calculate a single point for a function along the progress of an animation:
iex> Easing.sine_in(0.4)
0.19098300562505255
Calculating a list of animation frame values
However you likely want to calculate the list of values for a given animation. 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]
Calculating animation frames from a Stream
In many cases you will generate many animation 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
Custom easing functions
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
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}
Authors
We are very thankful for the many contributors
Versioning
This library follows Semantic Versioning
Looking for help with your Elixir project?
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
Legal
DockYard, Inc. © 2022