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