Javascript library to create physics-based animations

Overview

Dynamics.js

Dynamics.js is a JavaScript library to create physics-based animations

To see some demos, check out dynamicsjs.com.

Usage

Download:

Include dynamics.js into your page:

<script src="dynamics.js"></script>

You can animate CSS properties of any DOM element.

var el = document.getElementById("logo")
dynamics.animate(el, {
  translateX: 350,
  scale: 2,
  opacity: 0.5
}, {
  type: dynamics.spring,
  frequency: 200,
  friction: 200,
  duration: 1500
})

You also can animate SVG properties.

var path = document.querySelector("path")
dynamics.animate(path, {
  d: "M0,0 L0,100 L100,50 L0,0 Z",
  fill: "#FF0000",
  rotateZ: 45,
  // rotateCX and rotateCY are the center of the rotation
  rotateCX: 100,
  rotateCY: 100
}, {
  friction: 800
})

And any JavaScript object.

var o = {
  number: 10,
  color: "#FFFFFF",
  string: "10deg",
  array: [ 1, 10 ]
}
dynamics.animate(o, {
  number: 20,
  color: "#000000",
  string: "90deg",
  array: [-9, 99 ]
})

Reference

dynamics.animate(el, properties, options)

Animates an element to the properties with the animation options.

  • el is a DOM element, a JavaScript object or an Array of elements
  • properties is an object of the properties/values you want to animate
  • options is an object representing the animation
    • type is the animation type: dynamics.spring, dynamics.easeInOut,... (default: dynamics.easeInOut)
    • frequency, friction, bounciness,... are specific to the animation type you are using
    • duration is in milliseconds (default: 1000)
    • delay is in milliseconds (default: 0)
    • complete (optional) is the completion callback
    • change (optional) is called at every change. Two arguments are passed to the function. function(el, progress)
      • el is the element it's animating
      • progress is the progress of the animation between 0 and 1

dynamics.stop(el)

Stops the animation applied on the element

dynamics.css(el, properties)

This is applying the CSS properties to your element with the correct browser prefixes.

  • el is a DOM element
  • properties is an object of the CSS properties

dynamics.setTimeout(fn, delay)

Dynamics.js has its own setTimeout. The reason is that requestAnimationFrame and setTimeout have different behaviors. In most browsers, requestAnimationFrame will not run in a background tab while setTimeout will. This can cause a lot of problems while using setTimeout along your animations. I suggest you use Dynamics's setTimeout and clearTimeout to handle these scenarios.

  • fn is the callback
  • delay is in milliseconds

Returns a unique id

dynamics.clearTimeout(id)

Clears a timeout that was defined earlier

  • id is the timeout id

dynamics.toggleSlow()

Toggle a debug mode to slow down every animations and timeouts. This is useful for development mode to tweak your animation. This can be activated using Shift-Control-D in the browser.

Dynamics and properties

dynamics.spring

  • frequency default is 300
  • friction default is 200
  • anticipationSize (optional)
  • anticipationStrength (optional)

dynamics.bounce

  • frequency default is 300
  • friction default is 200

dynamics.forceWithGravity and dynamics.gravity

  • bounciness default is 400
  • elasticity default is 200

dynamics.easeInOut, dynamics.easeIn and dynamics.easeOut

  • friction default is 500

dynamics.linear

No properties

dynamics.bezier

  • points array of points and control points

The easiest way to output this kind of array is to use the curve creator. Here is an example:

[{"x":0,"y":0,"cp":[{"x":0.2,"y":0}]},
 {"x":0.5,"y":-0.4,"cp":[{"x":0.4,"y":-0.4},{"x":0.8,"y":-0.4}]},
 {"x":1,"y":1,"cp":[{"x":0.8,"y":1}]}]

Contributing

Compile: npm run build or npm run build:watch

Run tests: npm test

Browser Support

Working on

  • Safari 7+
  • Firefox 35+
  • Chrome 34+
  • IE10+

Sylvester

Some code from Sylvester.js has been used (part of Vector and Matrix).

License

The MIT License (MIT)

Copyright (c) 2015 Michael Villar

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Comments
  • change callback doesn't expose the animation progress

    change callback doesn't expose the animation progress

    dynamics.animate(picture, {
      opacity: 0
    }, {
      type: dynamics.spring,
      duration: 1500,
      frequency: 94,
      friction: 480,
      change: (progress) => {
        dynamics.css(picture, { filter: `blur(${progress * 20}px)` })
      }
    })
    
    opened by kilianc 6
  • Some strange error occured

    Some strange error occured

    I've been writing some tests and got some error occured in karma test Chrome environment.

    var $elem = document.querySelector('.message');
    dynamics.animate($elem, {
        scale: 1.5
      }, {
        type: dynamics.bounce,
        frequency: 450,
        friction: 200,
        duration: 1000
    })
    

    Will raise following error in karma Chrome:

    Uncaught TypeError: Cannot read property '0' of undefined
        DecomposedMatrix.interpolate @ index.js:17591
        __bind @ index.js:16817
        interpolate @ index.js:18198
        animationTick @ index.js:18181
        runLoopTick @ index.js:18149
    

    It fails on the following line src/dynamics.coffee#L495

    decomposed[k][i] = (decomposedB[k][i] - decomposedA[k][i]) * t + decomposedA[k][i];
    

    I've dived into code and find that it's because decomposedB.transform is false, so decomposedB['transform'][0] cannot be evaulated.

    The decomposedB is set to false in startAnimation with following line:

    endProperties['transform'] = matrix.decompose(); 
    

    matrix is created with

    matrix = Matrix.fromTransform(Matrix.matrixForTransform(v));
    

    v is "scaleX(1.5) scaleY(1.5) scaleZ(1.5)"

    And later matrix.decompose() returns false because of this statement:

    if (els[3][3] === 0) {
      return false;
    }
    

    So if this is normal, then problem with some if statement in for cycle:

    if !only? or only.indexOf(k) > -1 or only.indexOf("#{k}#{['x','y','z'][i]}") > -1
    

    In original non karma environment everything works fine, but few conditions is not the same.

    opened by fobdy 6
  • Weird Issue Animating Object Propery

    Weird Issue Animating Object Propery

    I have the following code: dynamicsweirdness1 which, should, in theory, animate the zoom property on the Camera object to the specified value. However, the behavior I'm seeing is very strange where only the first few frames animate and then it spends the rest of the duration setting the value to the end value: dynamicsweirdness2 This seems like a bug, but if perhaps I'm doing this incorrectly, please let me know.

    opened by JohnLouderback 5
  • [NEED HELP] Need your help, @michaelvillar!

    [NEED HELP] Need your help, @michaelvillar!

    Hi @michaelvillar I used matrix compose/decompose from you dynamics.js, and my tweening engine is another type. All works fine, including IE9, also gets all current style back to IE9! But in all browser rotateZ doesn't work properly, i seen in your demo site all works fine, please help.

    • I will keep dynamics.js link in tweening engine my source used list

    Sorry for my english

    opened by dalisoft 5
  • some advices

    some advices

    some advices: 1: add samples to repo not just on website page 2: add some tests to codepen 3: integrate with angularjs/reactjs or any popular FE projects.

    opened by xiasenhai 5
  • Support animating DOM properties like scrollTop

    Support animating DOM properties like scrollTop

    Before, only properties inside style were animated by dynamics.js. This PR first checks for properties belonging to the element, and then opts to animate style properties. I think this falls in line with how dynamics.js animates arbitrary javascript objects too.

    opened by perrin4869 3
  • Uncaught TypeError: Cannot read property 'format' of null

    Uncaught TypeError: Cannot read property 'format' of null

    I tried using this code. It seems to be working well on safari but triggers an error on chrome and the other browers. Is there an extra set up needed?

    var dots = document.querySelectorAll('.dot') var colors = ['#007EFF', '#FF3700', '#92FF00']

    // Start the 3 dot animations with different delays function animateDots() { for(var i=0; i<dots.length; i++) { dynamics.animate(dots[i], { translateY: -70, backgroundColor: colors[i] }, { type: dynamics.forceWithGravity, bounciness: 800, elasticity: 200, duration: 2000, delay: i * 450 }) }

    dynamics.setTimeout(animateDots, 2500) }

    animateDots()

    opened by ollipop 3
  • Fix start and end values of element properties animation

    Fix start and end values of element properties animation

    Couple of things I noticed I missed in my last PR, since the animation of scrollTop wasn't working as expected ><;; Basically, I fixed the calculation of start and end values, and now everything works as it should :)

    opened by perrin4869 2
  • Fixed a bug with Chrome 52

    Fixed a bug with Chrome 52

    I animate with d and apparently since chrome52 path have now a computedStyle for d (something like path(M023 003...) that prevent dynamics.js from loading d from getAttribute.

    opened by Grafikart 2
  • Dynamics.js Uncaught TypeError for arguments.callee in strict mode.

    Dynamics.js Uncaught TypeError for arguments.callee in strict mode.

    Hello Michael,

    I've run into an issue using Dynamics.js in React component's with strict mode and ES6 classes. Using methods such as spring which use arguments.callee.defaults throw TypeErrors's. To solve this, I change the arguments.callee to the following format(dynamics.methodName.defaults) in order to avoid errors in my project. Is this something you would be interested in changing or having a pull request for?

    Error Message: Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

    Example Solution for 'spring' method: applyDefaults(options, arguments.callee.defaults); now applyDefaults(options, dynamics.spring.defaults);

    Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee

    opened by djfrsn 2
  • Uncaught TypeError: Cannot read property 'length' of undefined

    Uncaught TypeError: Cannot read property 'length' of undefined

    Can't seem to get this to work properly, seem to be doing everything right from what I can see in the docs.

    Uncaught TypeError: Cannot read property 'length' of undefined
        at t.interpolate (dynamics.min.js:1)
        at t.interpolate (dynamics.min.js:1)
        at q (dynamics.min.js:1)
        at m (dynamics.min.js:1)
        at P (dynamics.min.js:1)
    
    var block = $('.feature-block');
    var path = $('#feature-path');
    block.data('dragging', false);
    block.data('c', { x: 100, y: 10 });
    block.data('start', { x: 0, y: 0 });
    
    function update() {
        var dy = block.data('c').y - 10;
        var dampen = dy > 0 ? 2 : 4;
    
        block.css('transform', 'translate3d(0,' + dy / dampen + 'px,0)');
        path.attr('d', 'M0,100 L100,100 L100,10 ' + 'Q' + block.data('c').x + ',' + block.data('c').y + ' 0,10');
    }
    update();
    
    block.on('mousedown', function(e) {
        e = e.changedTouches ? e.changedTouches[0] : e;
        var $this = $(this);
        $this.data('dragging', true);
        $this.data('start').x = e.pageX;
        $this.data('start').y = e.pageY;
    });
    
    $(document).on('mousemove', function(e) {
        e = e.changedTouches ? e.changedTouches[0] : e
        if (block.data('dragging') && ((e.pageY - block.position().top > -200 && e.pageY - block.position().top <= 0) || (e.pageY - block.position().top < 250 && e.pageY - block.position().top >= 0))) {
          block.data('c').x = (50 + (e.pageX - block.data('start').x)/block.width())
          // dampen vertical drag by a factor
          var dy = e.pageY - block.data('start').y
          var dampen = dy > 0 ? 20 : 20
          block.data('c').y = 10 + dy / dampen
          update();
        }
    });
    
    $(document).on('mouseup', function(e) {
        if (block.data('dragging')) {
          block.data('dragging', false);
          dynamics.animate(path, {
            x: 100,
            y: 100
          }, {
            type: dynamics.spring,
            duration: 700,
            friction: 280,
            change: update
          })
        }
    });
    
    opened by fourbytes 1
  • animate background on chrome not working.

    animate background on chrome not working.

    Hello there,

    First of all i would like to express my gratitude for this amazing library, also I'm a big fan of your work.

    I was playing around with dynamics.js for the first time and noticed that my code does not work on chrome, but does on firefox, the code that throws the error is the following:

    dynamics.animate(el, {
          background: "red"
    });
    

    the error is the following:

    Uncaught TypeError: Cannot read property 'rgb' of undefined
        at e.interpolate (dynamics.min.js:1)
        at e.interpolate (dynamics.min.js:1)
        at t.interpolate (dynamics.min.js:1)
        at t.interpolate (dynamics.min.js:1)
        at q (dynamics.min.js:1)
        at m (dynamics.min.js:1)
        at P (dynamics.min.js:1)
    

    I'm Not sure if it's something that I'm doing wrong, if yes then i can't figure it out.

    opened by konshensx16 1
  • Fix crash for interleaving animations + modernise dependencies

    Fix crash for interleaving animations + modernise dependencies

    This PR:

    • Modernises all dependencies (couldn't get it to build on my machine with the existing ones)
    • Fixes a bug where calling dynamics.stop in complete for example with another interleaved animation in place caused a crash. Also added a test. This happens frequently when combined with react animations since the react lifecycle componentWillLeave(callback) will call componentWillUnmount once callback is called (synchronously) which usually should call dynamics.stop.
    opened by alexander-stripe 0
  • Complete callback not correct?

    Complete callback not correct?

    I'm trying to use dynamics.js and in my example i'm using it with hammer.js.

    Everything works so far, but the complete-callback fires when animate starts, not when it ends.

    I have the example on codepen Codpenexample

    Do i do something wrong or is it a bug?

    opened by ingomc 0
  • Why % css doesn't work

    Why % css doesn't work

    I try to use css percent value and the result is bad. The animate func try to animate to the value, if you put 50% on a width for example, it will translate to 50px and in the end of animation set 50%. Strange result

    opened by antoninlanglade 2
  • Older browsers `document.visibilityState`

    Older browsers `document.visibilityState`

    For example Android 4.4 doesn't supports document.visibilityState without the webkit prefix, creating an animation with a delay will never be triggered on these devices because isDocumentVisible will not return false. Is it an idea to check for 'visibilityState' in document and then return the document visibility or true for older browsers?

    opened by Saartje87 1
Releases(1.1.5)
Owner
Michael Villar
Michael Villar
Matteo Bruni 4.7k Jan 4, 2023
Nebula is a lightweight (1kb compressed) JavaScript library that creates beautiful universe animations.

Nebula is a lightweight JavaScript library for creating beautiful universe animations. Including configurable Stars, Nebulas, Comets, Planets and Suns. Compatible with SSR

Florian DE LA COMBLE 34 Nov 25, 2022
🍿 A cross-browser library of CSS animations. As easy to use as an easy thing.

Animate.css If you need the old docs - v3.x.x and under - you can find it here. Just-add-water CSS animation Installation Install with npm: npm instal

Animate.css 76.7k Dec 30, 2022
🍿 A cross-browser library of CSS animations. As easy to use as an easy thing.

Animate.css If you need the old docs - v3.x.x and under - you can find it here. Just-add-water CSS animation Installation Install with npm: npm instal

Animate.css 76.7k Jan 4, 2023
A jquery plugin for CSS3 text animations.

Textillate.js v0.4.1 See a live demo here. Textillate.js combines some awesome libraries to provide an easy-to-use plugin for applying CSS3 animations

Jordan Schroter 3.6k Jan 2, 2023
Animation Academy teaches you CSS animations using the transition and animation properties.

Animation Academy Open Animation Academy > Contents Background Built With Functionality Feature Highlights Wireframes Features In Development Backgrou

Jacob Benowitz 6 Jun 23, 2022
Create scroll-based animation without JavaScript

Trigger JS Create scroll-based animation without JavaScript. Sometimes we want to update the CSS style of an HTML element based on the scroll position

Trigger JS 1.1k Jan 4, 2023
Slide-element - A ~700 byte Promise-based library for animating elements with dynamic heights open & closed. Basically, a modern variant of jQuery's slideUp(), slideDown(), and slideToggle().

slide-element A tiny, accessible, Promise-based, jQuery-reminiscent library for sliding elements with dynamic heights open & closed. To see it in acti

Alex MacArthur 165 Dec 12, 2022
fakeLoader.js is a lightweight jQuery plugin that helps you create an animated spinner with a fullscreen loading mask to simulate the page preloading effect.

What is fakeLoader.js fakeLoader.js is a lightweight jQuery plugin that helps you create an animated spinner with a fullscreen loading mask to simulat

João Pereira 721 Dec 6, 2022
fullPage plugin by Alvaro Trigo. Create full screen pages fast and simple

fullPage.js English | Español | Français | Pусский | 中文 | 한국어 Available for Vue, React and Angular. | 7Kb gziped | Created by @imac2 Demo online | Cod

Álvaro 34.3k Dec 30, 2022
Animator Core is the runtime and rendering engine for Haiku Animator and the components you create with Animator

Animator Core is the runtime and rendering engine for Haiku Animator and the components you create with Animator. This engine is a dependency for any Haiku Animator components that are run on the web.

Haiku 757 Nov 27, 2022
A lightweight JavaScript library for creating particles

particles.js A lightweight JavaScript library for creating particles. Demo / Generator Configure, export, and share your particles.js configuration on

Vincent Garreau 26.7k Jan 8, 2023
GreenSock's GSAP JavaScript animation library (including Draggable).

GSAP (GreenSock Animation Platform) Professional-grade animation for the modern web GSAP is a robust JavaScript toolset that turns developers into ani

GreenSock 15.5k Jan 8, 2023
Javascript and SVG odometer effect library with motion blur

SVG library for transitioning numbers with motion blur JavaScript odometer or slot machine effect library for smoothly transitioning numbers with moti

Mike Skowronek 793 Dec 27, 2022
🐿 Super easy and lightweight(<3kb) JavaScript animation library

Overview AniX - A super easy and lightweight javascript animation library. AniX is a lightweight and easy-to-use animation library with excellent perf

anonymous namespace 256 Sep 19, 2022
Responsive, interactive and more accessible HTML5 canvas elements. Scrawl-canvas is a JavaScript library designed to make using the HTML5 canvas element a bit easier, and a bit more fun!

Scrawl-canvas Library Version: 8.5.2 - 11 Mar 2021 Scrawl-canvas website: scrawl-v8.rikweb.org.uk. Do you want to contribute? I've been developing thi

Rik Roots 227 Dec 31, 2022
GreenSock's GSAP JavaScript animation library (including Draggable).

GSAP (GreenSock Animation Platform) Professional-grade animation for the modern web GSAP is a robust JavaScript toolset that turns developers into ani

GreenSock 15.4k Jan 5, 2023
simple JavaScript library to animate texts

Animated Texts Hi, this library is a simple javascript text animator Properties force type: number default: 300 start_delay_time type: number default:

Cristóvão 4 Jan 11, 2022
Slickscroll - A Lightweight JavaScript library for quick and painless momentum & parallax scrolling effects.

Slickscroll is a JavaScript library that makes momentum & parallax scrolling quick and painless View Demo: slickscroll.musabhassan.com Momentum Scroll

Musab Hassan 33 Dec 28, 2022