Skip to content
This repository has been archived by the owner on Apr 27, 2021. It is now read-only.

Fails if flipped element has css transforms. #4

Open
ju1ius opened this issue Jan 22, 2016 · 2 comments
Open

Fails if flipped element has css transforms. #4

ju1ius opened this issue Jan 22, 2016 · 2 comments

Comments

@ju1ius
Copy link

ju1ius commented Jan 22, 2016

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 !

@paullewis
Copy link
Contributor

Firstly, thank you for such an awesome write-up! I definitely agree that a) it needs fixing and b) that we should keep that small :D I'm out of play a little this coming week, and I didn't want you to think this was being ignored. I have a feeling you're right that the FLIP default should just be CSS and that everything else is an add-on that you make a custom build for, but I shall noodle on it a little more first.

Thanks again!

@wprater
Copy link

wprater commented Jun 22, 2016

Great work here @ju1ius . Any progress or help needed to work on this?

PS: I vote keep it small !
👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants