Skip to content
This repository has been archived by the owner on Aug 19, 2022. It is now read-only.

I have a problem about radium.keyframes #912

Open
HsuTing opened this issue Jul 19, 2017 · 6 comments
Open

I have a problem about radium.keyframes #912

HsuTing opened this issue Jul 19, 2017 · 6 comments

Comments

@HsuTing
Copy link

HsuTing commented Jul 19, 2017

I try to change the animation when I click a button and do something when the animation is complete.
Here is a simple example:

import React from 'react';
import radium, {StyleRoot} from 'radium';

const isClickedStyle = {
  opacity: '0'
};

const normalStyle = {
  opacity: '1'
};

const normalAnimation = radium.keyframes({
  '0%': isClickedStyle,
  '100%': normalStyle
});

const isClickAnimation = radium.keyframes({
  '0%': normalStyle,
  '100%': isClickedStyle
});

const style = isClicked => ({
  width: '100px',
  height: '100px',
  background: 'blue',
  animation: 'x 0.5s ease-in-out',
  animationName: isClicked ? isClickAnimation : normalAnimation,
  ...(isClicked ? isClickedStyle : normalStyle)
});

@radium
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isClicked: false
    };

    this.animationEnd = true;
    this.onClick = this.onClick.bind(this);
  }

  render() {
    return (
      <div>
        <StyleRoot style={testStyle(this.state.isClicked)}
          onClick={this.onClick}
          onAnimationEnd={() => (this.animationEnd = true)}
        />
      </div>
    );
  }

  onClick() {
    if(this.animationEnd) {
      this.animationEnd = false;
      this.setState({isClicked: !this.state.isClicked});
    }
  }
}

This code can work in chrome, but can not work in safari, iphone`s chrome.
The problem is that keyframe is added to style tag after the browser add style to component.
As a result, onAnimationEnd will not be called because the animation does not work.
Here is my solution:

  render() {
    return (
      <div>
        <StyleRoot style={{animationName: isClickAnimation}} />
        <StyleRoot style={{animationName: normalAnimation}} />

        <StyleRoot style={testStyle(this.state.isClicked)}
          onClick={this.onClick}
          onAnimationEnd={() => (this.animationEnd = true)}
        />
      </div>
    );
  }

This can add keyframe to style tag at the begin. animation will work because keyframe does exist.
However, I don`t think this is a good solution. Is any another way to solve it?

@solancer
Copy link

I'm facing the same problem is there a possible fix to this? or keyframes animation inline is just not possible at all?

@PatrickNausha
Copy link

Here's a minimal repro. Works in Chrome 60 but not Safari 10.1.1: https://codepen.io/patricknausha/pen/GvQxKR

@PatrickNausha
Copy link

PatrickNausha commented Aug 18, 2017

It seems my codepen sometimes works (the box rotates) the first time in Safari. After a refresh, it won't.

@solancer
Copy link

I ended up using GASP tweenmax to achieve this, worked like a charm!

@apiv
Copy link

apiv commented Jul 6, 2018

My suspicion is that this is a race condition, in which the @keyframes are added to the stylesheet on the page after the animationName style property is added to the element. Safari doesn't find the animation, and doesn't refresh those elements when the animation is added to the stylesheet.

This can also be verified by doing the following:

  1. Find the element which is not animating in the web inspector.
  2. Remove the animation style rule and then re-add it
  3. Safari will now find the animation in the existing stylesheet and the element will animate.

Looking at the code, the update of the global stylesheet (src/components/style-sheet.js:43) is deferred by 0 milliseconds, while the addition of the style rule to the element is synchronous. This would cause the race condition described above.

Does anyone know why the _onChange method of StyleSheet in src/components/style-sheet.js is deferred?

@tonyhallett
Copy link

You could also try this AnimationAwareStyle component

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

No branches or pull requests

6 participants