#912·radium

I have a problem about radium.keyframes

Author: HsuTingCreated Jul 19, 2017Updated Jan 29, 2020
Labelshigh priorityunverified

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

javascript
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?