# Animation

See also [Physics](https://github.com/mems/calepin/blob/main/Animation/Physics/README.md)

* [FN1403001 | バネのような動きを加速度から定める ー オイラー法 | HTML5 : テクニカルノート](http://www.fumiononaka.com/Business/html5/FN1403001.html)
* <https://github.com/MengTo/Spring/blob/master/Spring/Spring.swift>

### Resources

* [The ultimate guide to proper use of animation in UX](https://uxdesign.cc/the-ultimate-guide-to-proper-use-of-animation-in-ux-10bd98614fa9)
* [12 basic principles of animation — Wikipedia](https://en.wikipedia.org/wiki/12_basic_principles_of_animation)
* [Creating Usability with Motion: The UX in Motion Manifesto](https://medium.com/@ux_in_motion/creating-usability-with-motion-the-ux-in-motion-manifesto-a87a4584ddc)
* [CAPPTIVATE.co | iOS UI Animations](http://capptivate.co/)
* [Hover States / The home of alternative digital design](http://hoverstat.es/)
* [Motion blur — Wikipedia](https://en.wikipedia.org/wiki/Motion_blur)

### The illusion of life

!\[The illusion of life\_hd.mp4]\(The illusion of life\_hd.mp4) !\[10 principles of motion design.mp4]\(10 principles of motion design.mp4)

### Precision

Eular method is frame based More precise is time based

The Eular method simplifies equation:

```
position += velocity * dt;
velocity += acceleration * dt;
```

The semi-implicit euler (better):

```
velocity += acceleration * dt;
position += velocity * dt;
```

frame skip = based on time non frame skip = based on number frames. It's not precise especially if the frame rate is irregular or not at the original speed

[Recusive functions](https://en.wikipedia.org/wiki/Recursive_function) are frame based

Eular method:

```
let threshold = 0.07;// resting velocity
let friction = 0.15;
let x = 0;
let velocity = 30;

// loop is an equivalent to call a render frame function
while ( velocity > threshold ) {
	velocity *= 1 - friction;
	x += velocity;
}
return x;
```

See also:

```
static double lastUpdate=0;
if (lastUpdate!=0) {
	deltaT = time() - lastUpdate;
	velocity += acceleration * deltaT;
	position += velocity * deltaT;
}
lastUpdate = time();
```

Time based (use integration and calculus):

```
var restingVelo = 0.07;
var startVelo = 30;
var friction = 0.15;
var startX = 0;

function getBaseLog( a, b ) {
  return Math.log( b ) / Math.log( a );
}

let damping = 1 - friction;
let ticks = getBaseLog( damping, restingVelo / Math.abs( startVelo ) );
// http://mikestoolbox.com/powersum.html
let sum = ( Math.pow( damping, ticks + 1 ) - 1 ) / ( damping - 1 );
x += startVelo * damping * sum;
```

* [Integration Basics | Gaffer On Games](https://gafferongames.com/post/integration_basics/)
* [Fix Your Timestep! | Gaffer On Games](https://gafferongames.com/post/fix_your_timestep/)
* [Physics for Flash Games](http://www.richardlord.net/presentations/physics-for-flash-games.html) - difference between integrator
* [physics - Pros and cons of different integrators - Game Development Stack Exchange](https://gamedev.stackexchange.com/questions/33694/pros-and-cons-of-different-integrators)
* [PhysicsJS/src/integrators at master · wellcaffeinated/PhysicsJS](https://github.com/wellcaffeinated/PhysicsJS/tree/master/src/integrators) - Implementation of different integrators in PhysicsJS
* [Matter.js Simple Ball Pool](http://www.cake23.de/matterjs-simple-ball-pool.html)
* [Loop vs log · jsPerf](https://jsperf.com/loop-vs-log/)

### Eular method

* [Euler method — Wikipedia](https://en.wikipedia.org/wiki/Euler_method)

#### Inching

Aka Ease out animation

> position += (destination - position) \* friction

```
ease = 0.25;
position = 0;
destination = 100;

frame{
	velocity = (destination - position) * ease;
	position += velocity;
}
```

#### Elastic

[Simple harmonic motion — Wikipedia](https://en.wikipedia.org/wiki/Simple_harmonic_motion)

```
ease = 0.25;
velocity = 0;
friction = 0.75;
position = 0;
destination = 100;

frame{
	velocity += (destination - position) * ease;
	velocity *= friction;
	position += velocity;
}
```

#### Flexible Partial Shifts

```
var dx:Number = displayObject.x - fixedX;
var dy:Number = displayObject.y - fixedY;
var angle:Number = Math.atan2(dy, dx);
var targetX:Number = fixedX + Math.cos(angle) * springLength;
var targetY:Number = fixedX + Math.sin(angle) * springLength;
```

#### Waveform

```
displayObject.y = centerScale + Math.sin(angle) * range;
angle += speed;
```

#### Heartthrob

```
displayObject.scaleX = displayObject.scaleY = centerScale + Math.sin(angle) * range;
angle += speed;
```

### Easing

See also [Catmull–Rom spline](https://github.com/mems/calepin/blob/main/Animation/Spline/README.md) and [Gradient](https://github.com/mems/calepin/blob/main/Animation/Gradient/README.md)

* [Easing Functions Cheat Sheet](http://easings.net/en)
* [Equations for Organic Motion](http://codepen.io/soulwire/pen/kqHxB)
* <https://github.com/greensock/GreenSock-JS/blob/master/src/uncompressed/easing/EasePack.js>
* [A Performant Transitions and Animations Library](https://github.com/h5bp/Effeckt.css)
* [Inbetweening — Wikipedia](https://en.wikipedia.org/wiki/Inbetweening)
* [Tweener, 4 years later – A post mortem – Zeh Fernando](http://zehfernando.com/2009/tweener-4-years-later-a-post-mortem/)
* [Animation Principles in UI Design: Understanding Easing – Motion In Interaction – Medium](https://medium.com/motion-in-interaction/animation-principles-in-ui-design-understanding-easing-bea05243fe3)
* [Understanding Easing (Explaining Penner’s equations) – JavaScript and ActionScript | upshots](http://upshots.org/actionscript/jsas-understanding-easing)
* [Inigo Quilez :: fractals, computer graphics, mathematics, demoscene and more](http://www.iquilezles.org/www/articles/functions/functions.htm) - useful little functions
* [Better Cubic Bezier Approximations for Robert Penner Easing Equations | kepo-ing Zz85](http://www.lab4games.net/zz85/blog/2014/12/26/better-cubic-bezier-approximations-for-robert-penner-easing-equations/) - see <https://github.com/zz85/cubic-bezier-approximations>
* [Ease Visualizer for GSAP | HTML5 Animation | GreenSock](https://greensock.com/ease-visualizer)
* [phaser/v3/src/math/easing at master · photonstorm/phaser](https://github.com/photonstorm/phaser/tree/master/v3/src/math/easing)
* [curves | kynd.info | Flickr](https://www.flickr.com/photos/kynd/9546075099/) - Easing functions/equations <https://farm8.staticflickr.com/7346/9546075099\\_18ccc66a2d\\_o\\_d.png>
* [scripty2 API documentation | S2.FX.Transitions namespace](http://scripty2.com/doc/scripty2%20fx/s2/fx/transitions.html)
* `sin(t)`
* `cos(t)`
* `cos(t)*sin(t)`
* `sin(t)*sin(t*1.5)`
* `sin(tan(cos(t)*1.2))`
* `sin(tan(t)*0.05)`
* `cos(sin(t*3))*sin(t*0.2)`
* `sin(pow(8,sin(t)))`
* `sin(exp(cos(t*0.8))*2)`
* `sin(t-PI*tan(t)*0.01)`
* `pow(sin(t*PI),12)`
* `cos(sin(t)*tan(t*PI)*PI/8)`
* `sin(tan(t)*pow(sin(t),10))`
* `cos(sin(t*3)+t*3)`
* `pow(abs(sin(t*2))*0.6,sin(t*2))*0.6`
* ... (see links above)
* `cos(pi*x) / (-LN2*x)`
* `sqrt(1-x^2)` Semi arc (\* -1 to get negative)
* `1-pow(x*2-1, 6)` smooth in-out, use power of 2, 4, 6, etc. to make the transition sharper
* Linear (Power0)
* Quad (Power1)
* Cubic (Power2)
* Quart (Power3)
* Quint (Power4)
* Strong (Power4)

#### Time progression

```
progress = max(min((nowTimestamp - timestamp) / duration, 1), 0);// 0 to 1
```

### Animation duration

* [How fast should your UI animations be? | Val Head - Designer & UI Animation Consultant](http://valhead.com/2016/05/05/how-fast-should-your-ui-animations-be/)

### Physics based

Animation based on physics

Use friction, attraction force (gravity, magnetism), push force Mass, velocity (speed + direction), momentum

See [Physics](https://github.com/mems/calepin/blob/main/Animation/Physics/README.md)

* [The Nature of Code](http://natureofcode.com/book/)
* Lib for lot of domains (math, graphics) <https://github.com/hapticdata/toxiclibsjs> from <http://toxiclibs.org/about/>
* <https://en.wikipedia.org/wiki/Physics\\_engine>
* A posteriori (discrete) versus a priori (continuous) computation: <https://en.wikipedia.org/wiki/Collision\\_detection#A\\_posteriori\\_.28discrete.29\\_versus\\_a\\_priori\\_.28continuous.29>
* <https://openclassrooms.com/courses/theorie-des-collisions>
* Parametric easing (easing function with parameters like frequency, friction) <http://dynamicsjs.com>
* game libs <http://phaser.io> <https://libgdx.badlogicgames.com/index.html>
* native JS canvas only lib <https://github.com/phoboslab/Ejecta>

<https://en.wikipedia.org/wiki/Force> <https://en.wikipedia.org/wiki/Classical\\_mechanics>

### Cat walking

> Cats have a very precise method of walking, called “direct registering”, wherein their hind paws fall almost exactly into the place their fore paws did a moment before—this method of walking minimizes noise and visible tracks while ensuring more stable footing as the place has already been felt out by the fore paws

* [How a cat makes footprints : interestingasfuck](https://www.reddit.com/r/interestingasfuck/comments/6b3u4n/how_a_cat_makes_footprints/)
* [Animal Gaits for Animators on Vimeo](https://vimeo.com/215637283)

### Draggable with inertia

Scrollable, deceleration, rubber band, paging (aka Soft close drawer)

> Linear Motion Equations:
>
> vf = vi + at d = ½(vf + vi)t d = vi∙t + ½at vf² = vi² + 2ad
>
> where:
>
> * d is displacement (∆x)
> * t is time of travel (∆t)
> * a is rate of constant acceleration
> * vi is initial velocity
> * vf is final velocity
>
> <https://s2.studylib.net/store/data/005704450.pdf?key=7f28457ce04d3cb302b11a2f52dba5b3\\&r=1\\&fn=5704450.pdf\\&t=1536095317883\\&p=600>

Rubber-banding: x = (1.0 - (1.0 / ((x \* c / d) + 1.0))) \* d or x = x \* 0.5

> f(x, d, c) = (x \* d \* c) / (d + c \* x)
>
> where:
>
> * x is distance from the edge
> * c is constant (UIScrollView uses 0.55)
> * d is dimension, either width or height

UIScrollView to find out the formulae its using for paging, inertia, and bouncing: rubber banding: offset = (0.55 \* offset \* height) / (height + 0.55 \* offset); inertia: exponential decay with .decelerationRate

* [Implementing Inertial Scrolling in iOS - The Joy Of Hack](http://aijazansari.com/2011/04/25/implementing-inertial-scrolling-in-ios/index.html)
* [ios - UIScrollView with "inertia" but paged. - Stack Overflow](https://stackoverflow.com/questions/20667613/uiscrollview-with-inertia-but-paged/20669439#20669439)
* [CircularScrollInertia/RDDRotationControlSurface.m at master · rdsquared09/CircularScrollInertia](https://github.com/rdsquared09/CircularScrollInertia/blob/master/CircularScrollInertiaDemo/RDDRotationControlSurface.m) - Circular slider [SpinnyDisk on Vimeo](https://vimeo.com/51800558)
* [grp/CustomScrollView: A fork of Ole Begemann's custom scroll view project, that adds decelerated scrolling, just like `UIScrollView`](https://github.com/grp/CustomScrollView/tree/custom-scroll-with-pop) with [facebook/pop: An extensible iOS and OS X animation library, useful for physics-based interactions.](https://github.com/facebook/pop)
* [Grant Paul on Twitter: "I mentioned a while back iOS 6 uses a new formula for rubber-banding. Here's the formula: x = (1.0 - (1.0 / ((x \* c / d) + 1.0))) \* d"](https://twitter.com/chpwn/status/285540192096497664)
* [UIScrollView's Inertia, Bouncing and Rubber-Banding with UIKit Dynamics](http://holko.pl/2014/07/06/inertia-bouncing-rubber-banding-uikit-dynamics/)
* [Implementing scrolling behaviour without UIScrollView – Successful coder](http://successfulcoder.com/2016/09/04/implementing-scrolling-behaviour-without-uiscrollview/) - (end of article) about need to evaluate multiple touchmove events at the end of gesture to get the velocity desizered
* [Scrolling — Wikipedia](https://en.wikipedia.org/wiki/Scrolling) - "Touch-screens often use inertial scrolling"
* [Inertial Scrolling for Unity 3D](https://gist.github.com/russianryebread/46dc971afe20861e9158)
* [kinetic scrolling: the state machine · ariya.io](https://ariya.io/2009/10/kinetic-scrolling-the-state-machine) - State machine for a slider
* [Creating Animations and Interactions with Physical Models](http://iamralpht.github.io/physics/) <https://github.com/iamralpht/iamralpht.github.io/tree/master/physics>
* [openseadragon/openseadragon: An open-source, web-based viewer for zoomable images, implemented in pure JavaScript.](https://github.com/openseadragon/openseadragon) - image explorer, zoom use springs [openseadragon/spring.js at master · openseadragon/openseadragon](https://github.com/openseadragon/openseadragon/blob/master/src/spring.js)
* [Framer/LayerDraggable.coffee at master · koenbok/Framer](https://github.com/koenbok/Framer/blob/master/framer/LayerDraggable.coffee)
* [iamralpht/gravitas: A super fast, super small Physics Engine for super awesome User Interface](https://github.com/iamralpht/gravitas)
* [Impetus.js - Add Momentum to Anything](http://chrisbateman.github.io/impetus/)
* [Draggable | GSAP from GreenSock | JavaScript HTML5 Animation](https://greensock.com/draggable) <https://github.com/kevinglb/Cartier-Wechat/blob/master/greensock-js/src/uncompressed/utils/Draggable.js> <https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/ThrowPropsPlugin.min.js> <https://github.com/iWoz/AirScroll/blob/master/src/com/greensock/plugins/ThrowPropsPlugin.as>
* [Add experimental support for spring based CSS animations](https://trac.webkit.org/changeset/201759/trunk/Source) - see `WebCore/platform/graphics/SpringSolver.h`
* [ScrollMagic/iscroll-probe.js at master · janpaepke/ScrollMagic](https://github.com/janpaepke/ScrollMagic/blob/master/js/lib/iscroll-probe.js#L56-L81)

Like scroll with touch or mouse wheel. See also <http://dev.w3.org/csswg/css-snappoints/>, [`-ms-scroll-limit`](http://msdn.microsoft.com/en-us/library/windows/apps/hh996918.aspx) (offlimit bounce) and <https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/IpBdJEppjzE/V1Biy1D4v-kJ>

* [Prototyping with Facebook Origami on Vimeo](https://vimeo.com/85578380)

Scroll time based on distance:

```
var baseMinScrollTime = 200;
var baseMaxScrollTime = 500;

var docHeight = $(document).height();
var triggerTop = $(this).offset().top;
var targetTop = $target.offset().top;

var scrollProportion = (targetTop - triggerTop) / docHeight,
var relativeTime = ((baseMaxScrollTime - baseMinScrollTime) * scrollProportion) + baseMinScrollTime,
// Create inverse relationship (quicker the further we scroll)
var scrollTime = -1 * (1 - relativeTime);

$('html, body').animate({
  scrollTop: targetTop - 10
}, scrollTime);
```

Friction:

> vector velocity = speed + direction
>
> google maps Speed decrease like POWER2
>
> f(x) = 99.9%^x
>
> drop (a=0→1)
>
> v = d / t where v = speed or velocity d = distance t = time or duration
>
> stopping distance: start velocity to 0 d = k \* v \* v, where d = distance k = friction coef v = start speed or velocity
>
> stopping duration?ranl(fr) t = d / v t = time or duration v = average speed or velocity (= start speed / 2) d = distance

* [Math time: Resting position · Metafizzy blog](https://metafizzy.co/blog/math-time-resting-position/)

In source of the map engine Leaflet <https://github.com/Leaflet/Leaflet/blob/63fd4edc76893ab2a2f83d54e703e0a4da73de7b/src/map/handler/Map.Drag.js>

### Particles

* [gifloopcoder-scripts/roy-dust.js at master · roytanck/gifloopcoder-scripts](https://github.com/roytanck/gifloopcoder-scripts/blob/master/code/roy-dust.js) - Particle emitter [Roy Tanck on Twitter: "Quick & easy TGIF #gifloopcoder GIF. Code (very little of it, actually): https://t.co/Gr4wDVeKLU https://t.co/yUIXacFrBR"](https://twitter.com/roytanck/status/840279090296967168)

### Character control

* [Phase-Functioned Neural Networks for Character Control](http://theorangeduck.com/page/phase-functioned-neural-networks-character-control)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mmems.gitbook.io/calepin/animation/animation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
