diff --git a/confetti.js b/confetti.js index c6b4c80..806be04 100644 --- a/confetti.js +++ b/confetti.js @@ -1,109 +1,115 @@ -import React, {Component} from 'react'; -import { - AppRegistry, - StyleSheet, - Text, - View, - Animated, - Dimensions -} from 'react-native'; - -let windowHeight = Dimensions.get('window').height; -let windowWidth = Dimensions.get('window').width; +import React, { Component } from "react"; +import { Animated, Dimensions, StyleSheet } from "react-native"; + +const windowHeight = Dimensions.get("window").height; +const windowWidth = Dimensions.get("window").width; class Confetti extends Component { constructor(props) { - super(props); - this._yAnimation = new Animated.Value(0); - this.color = this.randomColor(this.props.colors); - this.left = this.randomValue(0, windowWidth); - let rotationOutput = this.randomValue(-220, 220) + 'deg'; - this._rotateAnimation = this._yAnimation.interpolate({ - inputRange: [0, windowHeight / 2, windowHeight], - outputRange: ['0deg', rotationOutput, rotationOutput] - }); - - let xDistance = this.randomIntValue((windowWidth / 3 * -1), windowWidth / 3); - this._xAnimation = this._yAnimation.interpolate({ - inputRange: [0, windowHeight], - outputRange: [0, xDistance] - }); + super(props); + + this._yAnimation = new Animated.Value(0); + this.color = this._randomColor(this.props.colors); + this.left = this._randomValue(0, windowWidth); + + const rotationOutput = `${this._randomValue(-220, 220)}deg`; + + this._rotateAnimation = this._yAnimation.interpolate({ + inputRange: [0, windowHeight / 2, windowHeight], + outputRange: ["0deg", rotationOutput, rotationOutput] + }); + + const xDistance = this._randomIntValue( + (windowWidth / 3) * -1, + windowWidth / 3 + ); + + this._xAnimation = this._yAnimation.interpolate({ + inputRange: [0, windowHeight], + outputRange: [0, xDistance] + }); } componentDidMount() { - let {duration, index} = this.props; - Animated.timing(this._yAnimation, { - duration: duration + this.randomIntValue(duration * .2, duration * -.2), - toValue: windowHeight + 1.25, - useNativeDriver: true - }).start(this.props.onAnimationComplete); - } + const { duration } = this.props; - getTransformStyle() { - return { - transform: [ - {translateY: this._yAnimation}, - {translateX: this._xAnimation}, - {rotate: this._rotateAnimation} - ] - } + Animated.timing(this._yAnimation, { + duration: + duration + this._randomIntValue(duration * 0.2, duration * -0.2), + toValue: windowHeight + 1.25, + useNativeDriver: true + }).start(this.props.onAnimationComplete); } - getConfettiStyle() { - let {index, size, bsize} = this.props; - let bigConfetti = { - height: 5.5*size, - width: 11*size, - borderBottomLeftRadius: 5*bsize, - borderBottomRightRadius: 5*bsize, - borderTopLeftRadius: 2.6*bsize, - borderTopRightRadius: 2.6*bsize - }; - let smallConfetti = { - height: 4.5*size, - width: 8*size, - borderBottomLeftRadius: 2.5*bsize, - borderBottomRightRadius: 2.5*bsize, - borderTopLeftRadius: 1.3*bsize, - borderTopRightRadius: 1.3*bsize - } - return index % 5 === 0 ? smallConfetti : bigConfetti; - } + _getTransformStyle = () => ({ + transform: [ + { translateY: this._yAnimation }, + { translateX: this._xAnimation }, + { rotate: this._rotateAnimation } + ] + }); - randomValue(min, max) { - return Math.random() * (max - min) + min; - } + _getConfettiStyle = () => { + const { index, size, bsize } = this.props; - randomIntValue(min, max) { - return Math.floor(Math.random() * (max - min) + min); - } + const bigConfetti = { + height: 5.5 * size, + width: 11 * size, + borderBottomLeftRadius: 5 * bsize, + borderBottomRightRadius: 5 * bsize, + borderTopLeftRadius: 2.6 * bsize, + borderTopRightRadius: 2.6 * bsize + }; - randomColor(colors) { - return colors[this.randomIntValue(0,colors.length)]; - } + const smallConfetti = { + height: 4.5 * size, + width: 8 * size, + borderBottomLeftRadius: 2.5 * bsize, + borderBottomRightRadius: 2.5 * bsize, + borderTopLeftRadius: 1.3 * bsize, + borderTopRightRadius: 1.3 * bsize + }; + + return index % 5 === 0 ? smallConfetti : bigConfetti; + }; + + _randomValue = (min, max) => Math.random() * (max - min) + min; + + _randomIntValue = (min, max) => Math.floor(Math.random() * (max - min) + min); + + _randomColor = colors => colors[this._randomIntValue(0, colors.length)]; render() { - let {left, ...otherProps} = this.props; - return + return ( + + ); } } Confetti.defaultProps = { - duration: 6000, - colors: [ - "rgb(242.2, 102, 68.8)", - "rgb(255, 198.9, 91.8)", - "rgb(122.4, 198.9, 163.2)", - "rgb(76.5, 193.8, 216.7)", - "rgb(147.9, 99.4, 140.2)" - ], - size: 1, - bsize: 1 -} + duration: 6000, + colors: [ + "rgb(242.2, 102, 68.8)", + "rgb(255, 198.9, 91.8)", + "rgb(122.4, 198.9, 163.2)", + "rgb(76.5, 193.8, 216.7)", + "rgb(147.9, 99.4, 140.2)" + ], + size: 1, + bsize: 1 +}; const styles = StyleSheet.create({ confetti: { - position: 'absolute', + position: "absolute", marginTop: 0 } }); diff --git a/confettiView.js b/confettiView.js index 45ea06e..a91dda1 100644 --- a/confettiView.js +++ b/confettiView.js @@ -1,20 +1,13 @@ -import React, {Component} from 'react'; -import { - AppRegistry, - StyleSheet, - View, - Animated -} from 'react-native'; - +import React, { Component } from "react"; +import { StyleSheet, View } from "react-native"; import Confetti from "./confetti.js"; class ConfettiView extends Component { - constructor(props) { - super(props); - this.state = {confettis: []}; - this.confettiIndex = 0; - this.shouldStop = false; - } + state = { confettis: [] }; + + _timeout = null; + confettiIndex = 0; + shouldStop = false; componentDidMount() { if (this.props.startOnLoad) { @@ -24,71 +17,103 @@ class ConfettiView extends Component { componentWillUnmount() { this.stopConfetti(); - } - startConfetti(onComplete) { - let {confettis} = this.state; - let {confettiCount, timeout, untilStopped} = this.props; - this.shouldStop = false; - if(untilStopped || this.confettiIndex < confettiCount) { - setTimeout(() => { - if (this.shouldStop) { - return; - } else { - confettis.push({key: this.confettiIndex}); - this.confettiIndex++; - onComplete && this.setState({onComplete}); - this.setState({confettis}); - this.startConfetti(); - } - }, timeout); - } + if (this._timeout) { + clearTimeout(this._timeout); + } } - removeConfetti(key) { - let {confettis, onComplete} = this.state; - let {confettiCount} = this.props; - let index = confettis.findIndex(confetti => {return confetti.key === key}); - confettis.splice(index, 1); - this.setState({confettis}); - if(key === confettiCount - 1) { - this.confettiIndex = 0; - } - if(confettis.length === 0 && onComplete && typeof onComplete === 'function') { - onComplete(); - } - } + startConfetti = onComplete => { + const { confettis } = this.state; + const { confettiCount, timeout, untilStopped } = this.props; + + this.shouldStop = false; + + if (untilStopped || this.confettiIndex < confettiCount) { + this._timeout = setTimeout(() => { + if (this.shouldStop) { + return; + } + + confettis.push({ key: this.confettiIndex }); + this.confettiIndex++; + + if (onComplete) { + this.setState({ onComplete }); + } + + this.setState({ confettis }); + this.startConfetti(); + }, timeout); + } + }; + + stopConfetti = () => { + const { onComplete } = this.state; - stopConfetti() { this.shouldStop = true; this.confettiIndex = 0; - const { onComplete } = this.state; - if(onComplete && typeof onComplete === 'function') { - onComplete(); + + if (onComplete && typeof onComplete === "function") { + onComplete(); } + this.setState({ confettis: [], onComplete: null }); - } + }; + + _removeConfetti = key => { + const { confettis, onComplete } = this.state; + const { confettiCount } = this.props; + + const index = confettis.findIndex(confetti => confetti.key === key); + + confettis.splice(index, 1); + this.setState({ confettis }); + + if (key === confettiCount - 1) { + this.confettiIndex = 0; + } + + if ( + confettis.length === 0 && + onComplete && + typeof onComplete === "function" + ) { + onComplete(); + } + }; render() { - let {confettis} = this.state; - let {...otherProps} = this.props - return - {confettis.map(confetti => { - return - })} - + const { confettis } = this.state; + const { colors } = this.props; + + return ( + + {confettis.map(confetti => { + return ( + this._removeConfetti(confetti.key)} + colors={colors} + {...this.props} + /> + ); + })} + + ); } } ConfettiView.defaultProps = { - confettiCount: 100, - timeout: 30, - untilStopped: false -} + confettiCount: 100, + timeout: 30, + untilStopped: false +}; const styles = StyleSheet.create({ container: { - position: 'absolute', + position: "absolute", top: 0, left: 0, right: 0