Giter Site home page Giter Site logo

flipping's Introduction

Flipping

A library (and collection of adapters) for implementing FLIP transitions.

For more information about the FLIP technique, view the flipping slides:

Examples

Installation

npm install flipping@latest --save

Or grab the files directly:

Quick Start

In your HTML, add the data-flip-key="..." attribute to shared elements (see HTML example below).

import Flipping from 'flipping';

const flipping = new Flipping();

// Before a layout change happens
flipping.read();

// Any effect that changes the layout
doSomething(); 

// After a layout change happens
// With an adapter, this will start the FLIP animation
flipping.flip();
<!-- first view -->
<section class="gallery">
  <div class="photo-1" data-flip-key="photo-1">
    <img src="/photo-1"/>
  </div>
  <div class="photo-2" data-flip-key="photo-2">
    <img src="/photo-2"/>
  </div>
  <div class="photo-3" data-flip-key="photo-3">
    <img src="/photo-3"/>
  </div>
</section>

<!-- second view -->
<section class="details">
  <div class="photo" data-flip-key="photo-1">
    <img src="/photo-1"/>
  </div>
  <p class="description">
    Lorem ipsum dolor sit amet...
  </p>
</section>

API

new Flipping(options?)

Creates a new Flipping instance. This is the thing that keeps track of all the changes made, and determines if any elements changed positions or size.

Parameters for options

For greater control and custom animations, you can pass in the following parameters (all optional):

  • selector?: (parent: Element) => Element[]; - Selects all "flippable" elements. Defaults to all elements that have a [data-flip-key] attribute.
  • activeSelector: (element) => Element[]; - Selects the currently active "flippable" elements. Defaults to selecting the visible flippable elements.
  • onFlip?: (state: IFlipStateMap) => void; - Event listener. Called with the entire state map of tracked flippable elements whenever .flip() is called.
  • onRead?: (state: IFlipStateMap) => void; - Event listener. Called with the entire state map of tracked flippable elements whenever .read() is called.
  • onEnter?: (state: IFlipStateMap) => void; - Event listener. Called with the state map of elements that enter (that is, not previously tracked).
  • onLeave?: (state: IFlipStateMap) => void; - Event listener. Called with the state map of elements that leave (that is, previously tracked but no longer active).
  • parent?: Element; - The root element to query all flippable elements. Defaults to the <body>.
  • plugins?: FlipPlugin[]; - An array of plugins that transform the state map before being emitted.
  • duration?: number - Animation duration in ms. Defaults to 300.
  • easing?: string - Easing function name e.g. ease-in-out. Defaults to cubic-bezier(.5, 0, .5, 1).

flipping.read(): void

Queries all the flippable selectors and reads their bounds (position and size). This must be called before layout changes are made.

Will call any onRead() event listeners with the entire state map.

flipping.flip(): void

Queries all the flippable selectors and reads their bounds (position and size), and then determines the deltas (changes in position and/or size)

Will call any onFlip() event listeners with the entire state map.

flipping.wrap(fn): void

  1. Calls flipping.read()
  2. Calls the wrapped fn()
  3. Returns the result of the wrapped fn()
  4. Calls flipping.flip()

It's a nice shorthand. Use it.

data-flip-key="..."

HTML data-attribute that tracks the same/shared elements and identifies them as the "same" element.

data-flip-no-scale

HTML data-attribute that prevents the Flipping adapters from trying to apply scale() to a transformed element.

flipping's People

Contributors

davidkpiano avatar mattahj avatar phelma avatar tsiq-swyx avatar vinayakbagaria 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

flipping's Issues

Cannot set duration and easing when using CSS Adapter

Description

import Flipping from 'flipping/lib/adapters/css';

const flipping = new Flipping({ duration: 300, easing: 'ease' });

Expected Behavior

Duration and easing are set to value passed in Flipping constructor.

Actual Behavior

Duration is hard coded to 0.6s and easing is not set.

Details

  • version 1.1.0

@davidkpiano

Maybe missing scss folder in examples?

Specifically, the "examples" npm script won't find any scss.
npm start & node-sass -w examples/scss -o examples/css

(I liked your articles, I found your technique very smart, I'm here to discover more about it)

onEnter no longer triggered

Unless I'm missing something, it seems like onEnter is no longer valid (and my guess is there are other invalid documented options in the README as well). Is there a new way to customize entry / exit animations?

Clarification about .js vs .web.js vs .css.js

(Posting this for anyone who gets stuck in the future like I did.)

Hello, the docs mention these 3 files:

https://unpkg.com/flipping@latest/dist/flipping.js (core)
https://unpkg.com/flipping@latest/dist/flipping.web.js (WAAPI adapter)
๐Ÿ”œ https://unpkg.com/flipping@latest/dist/flipping.css.js (CSS adapter - WIP!)

I was stuck for a while when my animation wasn't working. Eventually I realized it's because I was using flipping.js when I should have been using flipping.css.js. I assumed that flipping.js was the main one I needed. Of course I am aware that they are CSS based animations but I still veered away from flipping.css.js because it sounded like something experimental/beta. But for people making browser-based animations I guess .css.js is the one that's needed? (Not sure what the other 2 are used for? Maybe would be good to clarify for people who might encounter this issue in the future?)

Broken expand example

For example, the expand.html example just flips states without animation.

In the console I got.

Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.
    at clone (file:///path/to/examples/expand.html:102:22)
    at flipping.onFlip.stateMap (file:///path/to/examples/expand.html:145:31)
    at file:///path/to/node_modules/flipping/dist/flipping.js:1:9988
    at Array.map (native)
    at Object.emit (file:///path/to/node_modules/flipping/dist/flipping.js:1:9972)
    at t.dispatch (file:///path/to/node_modules/flipping/dist/flipping.js:1:4374)
    at t.flip (file:///path/to/node_modules/flipping/dist/flipping.js:1:5696)
    at HTMLBodyElement.<anonymous> (file:///path/to/node_modules/flipping/dist/flipping.js:1:5962)
clone @ expand.html:102
flipping.onFlip.stateMap @ expand.html:145
(anonymous) @ flipping.js:1
emit @ flipping.js:1
t.dispatch @ flipping.js:1
t.flip @ flipping.js:1
(anonymous) @ flipping.js:1

I have adjusted the path to go to the current library's version installed node_modules/, if that might be part of the issue.

Project Dead?

This project seems very dead, are there any viable alternatives?

FLIP with `appendChild` method

Why is flip animation not working in this example with simple dom-manipulation via appendChild
https://codepen.io/monochromer/pen/rRMLda?editors=0011

<img src="image.jpg" data-flip-key="image" />
var f = window.f = new Flipping();

var image = document.querySelector('.image');
var grid = document.querySelector('.grid');

grid.onclick = (e) => {
  var gridCell = e.target.closest('.grid__cell');
  if (!gridCell) return;
  
  f.read();  
  gridCell.appendChild(image);    
  f.flip();  
}

How to customize transitions?

Thanks for the wonderful library! How does one tweak the animation in play, such as easing/spring parameters, duration, etc.?

How do i import this into a typescript code-base?

I'm working on a react app written in typescript, based on create-react-app with react-scripts-ts.
Trying to import this library, i failed miserably.

  • import Flipping from 'flipping'
    โ†’ module has no default export
  • import * as Flipping from 'flipping'
    โ†’ module resolves to a non-module entity and cannot be imported using this construct
  • import Flippin = require('flipping')
    โ†’ import assignment cannot be used when targeting ECMAScript modules

I would really like to test this library, but i'm rather new to typescript and really struggling with this. What can i do - preferrably without changing my typescript settings?

My tsconfig.json settings are

{
  "module": "esnext",
  "target": "es5"
}

Mithril FLIP

Hello David, thank you for all the great explanations and examples on the FLIP animations.

Thought you'd be interested in knowing that we've been iterating on a Mithril component that helps with the FLIP approach and your material has been really helpful.

Here's a couple examples:

Vulnerabilities

Hi @davidkpiano ! First off, really like your work.

Just wanted to bring to your attention the vulnerabilities warning I'm getting when cloning and npm iing the repo:

found 91 vulnerabilities (2 low, 2 moderate, 86 high, 1 critical)
  run `npm audit fix` to fix them, or `npm audit` for details

Cannot import adapters correctly

Hi,
I'm working in a TypeScript project with webpack.

I stumbled across this post [https://css-tricks.com/animating-layouts-with-the-flip-technique/] and decided to try your library. In your example, you use this import syntax:

import Flipping from 'flipping/adapters/web';

Unfortunately, this doesn't work (I'm using the latest version, 1.1.0). The only way I found for importing the Web Adapter is this, which feels unnatural:

import Flipping from 'flipping/lib/adapters/web';

This works, but the editor complains about that file not having a default export.

I think that with some minor changes to your project structure/configuration we should be able to use the syntax you used in that article, let me know if I'm doing something wrong :) Cheers!

Expected behavior in the presence of nested flipping elements?

I might be trying to do something slightly out of scope; I'm not sure if I'm exposing a gap in the implementation logic or if what I'm trying to do doesn't make sense (or I just have a bug somewhere else of course). In this example, I am using a Flipping with all-default options. I'm using solidjs, and sandwiching my signal setter with read() and update().

I'm trying to do shared element transitions with changing parent-child relations. The discrepancy in expectation arises when in the specific case when I have a parent and child element, which both flip, but in the new state, the child has a different parent. In such cases, the child either skips the transition entirely, or has an unexpected starting position.

To illustrate what I expect, here I have disabled the flip keys on the parents, so only children are flipping. Here, all children (emojis) proceed to their correct positions:
https://imgur.com/a/chlXRmv

On the other hand, when I enable the parent flip keys as well, something more complicated happens. The parent + node, and the tooth, which has the same parent in both the inital and final states, both behave as-expected. However, the mushroom transitions with unexpected initial position, and the space invader does not transition at all:
https://imgur.com/a/n7LQ1C6

Any idea as to what's happening?

Uncaught TypeError: Cannot read property 'parentElement' of undefined

Uncaught TypeError: Cannot read property 'parentElement' of undefined
    at t.flip (flipping.web.js:1)

I get this every time I use the library and call flip() - no matter which js file I pick.
I looked at the source code, and it compiles to lines including these:

            t.prototype.flip = function(t) {
                var e = this;
                void 0 === t && (t = {});
                var n = t.parent || this.parentElement
                  , r = this.selectActive(n)
                  , i = {};
                return r.forEach(function(t, r) {
                    var o = t.getAttribute(e.attribute);

That this.parentElement call is the problem. In every browser I've tried, this was undefined there, and you cant get the .parentElement of undefined.

The error message varies, but it's always about this...

Can't import; problems with export declaration?

I'm trying to replace isotope on my site for a grid of employees, and since replacing category filtering and instant search is pretty easy (I'm using vanilla js without libraries, only StimulusJS for structure), I just need something for the animation that happens when repositioning on filtering. In researching this, I found your css-tricks article and then a codepen demo that uses this library for filtering with categories. I forked that demo, and got to an implementation I can use in my application.

So far, so good. Now to get it into my app. But when doing proper importing, I can't get it to work. The pens were using the internal codepen "Add External Scripts" method with both the regular dist file and the web adapter with unpkg, which isn't an alternative for me in my app.

Here's what I've tried:

  • yarn add flipping (defaults to 1.1.0)
    • import Flipping from 'flipping' (fails silently; no console error but no animation either)
    • import { Flipping } from 'flipping' (Uncaught SyntaxError: import not found: Flipping)
    • import Flipping from 'flipping/dist/flipping.web' (almost works; see below EDIT: It works, I had a syntax error in my HTML)
    • various methods using require (none work)
  • yarn add flipping@next (version 2.0.0-3)
    • import Flipping from 'flipping' (SyntaxError: import not found: default)
    • import { Flipping } from 'flipping' (fails silently; no console error but no animation either)
    • import Flipping from 'flipping/dist/flipping.web' (adapter doesn't exist in version 2)
    • import Flipping from 'flipping/dist/flipping' (really long TypeError message)

I've also tried various tricks for using import when the library doesn't really support it, like this method: FredKSchott/snowpack#2338. Didn't work.

Importing the web adapter almost works, but only one element is animated when repositioning. This is not like the codepen, where all elements slide nicely into their new positions. I assume something from the main lib is missing since only the adapter is imported? EDIT: It works, I had a syntax error in my HTML

Any ideas to fix this? I'm very happy with this library the way it works in the codepen demo, so I'd love to use this instead of rolling my own. Thanks! :)

PS: I'm using snowpack now, if it matters, but I couldn't get it to work with webpack either.

Explanations of examples

I've already been leveraging flipping.js for basic transitions, but the examples are neat! Any elaboration to help understand how they work / how they use flipping.js would be amazing.

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.