Reputation: 151
I'm trying to create a save button (basically to bookmark a screen) that toggles animation whether a user taps the button to "save" an item or remove the "save". Tapping the button should call one of the animations whether it's the "on" animation or the "off" animation.
Unfortunately besides iOS I can't find any documentation on toggling an animation on a button in React Native. Any ideas would be appreciated.
Here's the component:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
StyleSheet,
TouchableOpacity
} from 'react-native';
import _ from 'lodash';
import { connect } from 'react-redux';
import { toggleSaved } from '../../actions';
import Animation from 'lottie-react-native';
import onAnimation from '../animations/heart_On.json';
import offAnimation from '../animations/heart_Off.json';
class SaveButton extends Component {
isSaved = () => {
let item = this.props.item;
if (_.find(this.props.saved, function(i) { return i.type == item.type && i.id == item.id; })) {
return true;
} else {
return false;
}
}
toggleSaved = (saved, item) => {
const { dispatch } = this.props;
dispatch(toggleSaved(saved, item));
this.animation.play();
}
render() {
return (
<TouchableOpacity
onPress={ () => this.toggleSaved(this.props.saved, this.props.item) }
>
<Animation
ref={ animation => {
this.animation = animation;
} }
style={ styles.icon }
loop={ false }
source={ this.isSaved() ? onAnimation: offAnimation }
/>
</TouchableOpacity>
);
}
}
SaveButton.propTypes = {
dispatch: PropTypes.func.isRequired,
saved: PropTypes.array.isRequired,
item: PropTypes.object.isRequired
};
const styles = StyleSheet.create({
icon: {
width: 30,
height: 30,
marginTop: 5,
marginRight: 10
}
});
function mapStateToProps(state) {
const { saved } = state.saved;
return {
saved
};
}
export default connect(mapStateToProps)(SaveButton);
Upvotes: 0
Views: 1661
Reputation: 19049
I'd suggest you to have two separate animation elements and then, depending on the state, show or hide (and of course .play()) them accordingly.
So (code in half-pseudo to get the idea):
isSaved
, which defines which animation is currently on stage,this.refToCorrectAnimation.play()
.constructor(props) {
super(props);
this.state = {
isSaved: false,
};
}
isSavedVisible() {
return (this.state.isSaved) ? { display: 'flex' } : { display: 'none' };
}
isRemovedVisible() {
return (!this.state.isSaved) ? { display: 'flex' } : { display: 'none' };
}
toggleSaved(...) {
if (this.state.isSaved) {
this.isSavedAnimation.play();
} else {
this.isRemovedAnimation.play();
}
render() {
return (
<TouchableOpacity onPress={() => this.toggleSaved()} ...>
<Animation style={this.isSavedVisible()} ref={(animation) = this.isSavedAnimation = animation} ... />
<Animation style={this.isRemovedVisible()} ref={(animation) = this.isRemovedAnimation = animation} ... />
</TouchableOpacity>
)
}
Upvotes: 2