GithubHelp home page GithubHelp logo

googlearchive / flipjs Goto Github PK

View Code? Open in Web Editor NEW
1.4K 43.0 91.0 445 KB

A helper library for doing FLIP animations.

Home Page: https://aerotwist.com/blog/flip-your-animations

License: Apache License 2.0

JavaScript 100.00%

flipjs's Introduction

FLIP.js

A helper library for FLIP animations.

FLIP Demos

FLIP is an approach to animations that remaps animating expensive properties, like width, height, left and top to significantly cheaper changes using transforms. It does this by taking two snapshots, one of the element's First position (F), another of its Last position (L). It then uses a transform to Invert (I) the element's changes, such that the element appears to still be in the First position. Lastly it Plays (P) the animation forward by removing the transformations applied in the Invert step.

Usage

You can use the FLIP helper on its own, like this:

let flip = new FLIP({
  element: target,
  duration: 2000
});

// First position & opacity.
flip.first();

// Apply the 'end' class and snapshot the last position & opacity.
flip.last('end');

// Move and fade the element back to the original position.
flip.invert();

// Play it forwards.
flip.play();

Using GSAP.

If you've already got GSAP in place, you may wish for it to handle playback. In which case, you can declare that in the config object:

let flip = new FLIP({
  element: target,
  duration: 2000,
  play: 'GSAP'
});

Specifying timing functions

You can either specify your own function, or, if you're using GSAP, you can use its easing functions:

// Declare an easing function directly.
let flip = new FLIP({
  element: target,
  easing: function (t) {
    return t * t;
  }
});

// ... or declare an easing function from GSAP.
let flip = new FLIP({
  element: target,
  easing: Bounce.easeOut
});

Documentation & Demos

New to FLIP?

For more background info take a look at the FLIP intro post.

License: Apache 2.0 - See /LICENSE.

Author: paullewis.

Please note: this is not an official Google product.

flipjs's People

Contributors

paullewis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flipjs's Issues

Fails if flipped element has css transforms.

Hi,
The main issue with this lib atm is that it breaks if you specify css transforms on your element.

TL;DR

See this fiddle for an example of the failure.
See this fiddle for a fix working with the new CSS player.
See this requirebin for a fix working with the rAF player.

Why does it break ?

For two reasons:

  1. The FLIP.invert() method overwrites the transforms of the element by setting this.element_.style.transform
  2. The diff calculations use element.getBoundingClientRect(), which returns the transformed bounding box of the element.

How do we fix this ?

To fix this, we have to:

  • Store the transforms of the element in FLIP.first() and FLIP.last()
// in Flip.first()
this.first_.transform = getComputedStyle(this.element_).transform;
// in Flip.last()
this.last_.transform = getComputedStyle(this.element_).transform;
  • Apply the original element's transform after our inversion transforms:
// in FLIP.invert() method
const transform = this.first_.transform === 'none' ? '' : this.first_.transform;
this.element_.style.transform = `
  translate(${this.invert_.x}px, ${this.invert_.y}
  scale(${this.invert_.sx}, ${this.invert_.sy})
  ${transform}
`;
  • Use element.offset{Top,Left,Width,Height} to compute our diffs, since we have to use the element's untransformed bounding box for this to work. (And of course we can keep using the gBCR fast path if we detect no transforms on the element).

See this fiddle for a working example.

What does it imply ?

It implies that the players be able to interpolate the raw transform matrix returned by getComputedStyle(this.element_).transform.
For the CSS player, no prob, that's what CSS transitions do !
For the rAF player, some math are needed. Fortunately, there's an npm module for that !
See this requirebin for a fix working with the rAF player.

So a redesign might be needed regarding the different players, like maybe keep only CSS in core, and move rAF, GSAP (and others ?) to external modules, to keep the lib small by default.
Or maybe something like a FLIP.interpolate_(alpha) method that would be able to return the interpolated matrix for the players to consume...

What do you think ?

PS: I vote keep it small !

Support for Shared Element Transitions

Currently, flipjs supports implementing the FLIP technique for a single element that changes position due to a class change. However, a common use-case (similar to Android's Shared Element Activity Transitions) is that:

  • The final node is nearly equivalent to the initial node, save for differences in position/size.
  • The final node is not the same node as the initial node.

One strategy I've been using is [data-flip="foo"] on both the initial and final nodes, so that I can:

  • getBoundingClientRect() on the initial (currently visible) node
  • execute the code that removes the initial node and displays the final node
  • getBoundingClientRect() on the final (now visible) node
  • execute FLIP.

Perhaps we can supply an argument to last(...) that allows us to specify the new shared node?

GSAP Support

The GSAP play option is nice, but a little lacking.

It would be helpful if flip.play() would return the TweenLite/TweenMax instance it creates when using the play: 'GSAP' option. Alternatively, the tween could be created & returned through another method ( flip.tween(), flip.gsap() ? ). Either of these would allow you to queue up multiple FLIP animations on a GSAP timeline, or control them manually with GSAP's methods.

Another helpful feature would be to pass along options to the TweenLite/TweenMax setup. Perhaps as an argument in the play method.

var flip = new FLIP({
  element: target,
  duration: 2000,
  play: 'GSAP'
});
flip.first();
flip.last('end');
flip.invert();
flip.play(null, {
  easing: "Power4.easeInOut",
  onComplete: function(){ console.log('animation complete!'); }
});

Support for NPM

Hi, is there any plan to make this package available to be downloaded via NPM?

Chaining multiple FLIPs on element

I'm really enjoying working with FLIP! Thanks for the write-ups and demos.

Wondering what the most effective way of chaining animations to fire on an element sequentially would be. Request for complete callback would get us part of the way there, but wondering if there's something else at an API level that could be explored? Would love to hear your thoughts.

Cheers

Callback functions

The ability to have a complete callback when the animation is done would be quite handy. start could also be useful.

var flip = new FLIP({
  element: target,
  easing: function (t) {
    return t * t;
  },
  start: function(){ console.log('animating is starting'); },
  complete: function(){ console.log('animation is done!'); }
});

Non-Minified /dist/ file

I've submitted a simple pull request that helps FLIP be used in module loaders, but Webpack presents this error due to the file being minified.

screen shot 2016-08-19 at 12 27 07 pm

It looks like if you custom build it with isProd set to false, it won't be minified, but that's not a great option for those who'd like to drop it into a project and use it right away.

A flip.js and flip.min.js in the /dist/ dir would be fantastic!

Submit to NPM

Took me a while to figure out you can install FLIP via npm install GoogleChrome/flipjs (the GitHub username & repo name), and I spent way too long searching NPM for the "correct" FLIP.

Would you please submit FLIP to NPM to make it easier to load into projects, or at least list the proper install step?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.