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:
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?
Source: FormidableLabs/radium