diff --git a/components/Header/Confetti.js b/components/Header/Confetti.js index f1808ea..3b5165e 100644 --- a/components/Header/Confetti.js +++ b/components/Header/Confetti.js @@ -1,19 +1,8 @@ // @flow -import React, { useState, useRef, useEffect } from 'react'; +import React, { useState, useRef, useEffect, Fragment } from 'react'; import ReactDOM from 'react-dom'; -import styled from 'styled-components'; +import { ParticleZone } from './style'; -const ConfettiZone = styled.div` - .particles { - position: fixed; - top: 0; - - .particle { - position: absolute; - transition: all 5s ease-out; - } - } -` const COLORS = ['#2ecc71','#3498db','#e67e22','#e67e22','#e74c3c']; const TOP_OFFSET = typeof window !== 'undefined' && window.innerHeight; @@ -31,7 +20,7 @@ export function CircularParticle(props: Props) { const ROTATION_RANGE = [0, 45]; const size = generateWholeNumber(...SIZE_RANGE); - style = { + const style = { backgroundColor: generateRandomColor(), width: size, height: size, @@ -41,63 +30,66 @@ export function CircularParticle(props: Props) { top: generateWholeNumber(-TOP_OFFSET, 0) }; - const {left} = style; - - setTimeout(() => { - const node = ReactDOM.findDOMNode(currentConfetti); - node.style.top = TOP_OFFSET + generateWholeNumber(0, TOP_OFFSET) + 'px'; - node.style.left = left + generateWholeNumber(-LEFT_OFFSET, LEFT_OFFSET) + 'px'; - },0); - + useEffect(() => { + const {left} = style; + setTimeout(() => { + const node = currentConfetti.current; + if (node) { + node.style.top = TOP_OFFSET + generateWholeNumber(0, TOP_OFFSET) + 'px'; + node.style.left = left + generateWholeNumber(-LEFT_OFFSET, LEFT_OFFSET) + 'px'; + } + },10); + }); return ( -
+
); } -// function SquiggleParticle(props: Props) { - -// static SIZE_RANGE = [15, 45]; -// static ROTATION_RANGE = [-15, 15]; +function SquiggleParticle(props: Props) { + const currentConfetti = useRef(null); + const SIZE_RANGE = [15, 45]; + const ROTATION_RANGE = [-15, 15]; -// const size = generateWholeNumber(...SquiggleParticle.SIZE_RANGE); -// this.style = { -// fill: generateRandomColor(), -// width: size, -// height: size, -// transform: `rotateZ(${generateWholeNumber(...SquiggleParticle.ROTATION_RANGE)}deg)`, -// left: generateWholeNumber(0, window.innerWidth), -// top: generateWholeNumber(-TOP_OFFSET, 0) -// }; + const size = generateWholeNumber(...SIZE_RANGE); + const style = { + fill: generateRandomColor(), + width: size, + height: size, + transform: `rotateZ(${generateWholeNumber(...ROTATION_RANGE)}deg)`, + left: generateWholeNumber(0, INNER_WIDTH), + top: generateWholeNumber(-TOP_OFFSET, 0) + }; -// useEffect(() => { -// const {left} = this.style; -// const {ROTATION_RANGE} = SquiggleParticle; -// setTimeout(() => { -// const node = ReactDOM.findDOMNode(this.ref); -// node.style.top = window.innerHeight + generateWholeNumber(0, TOP_OFFSET) + 'px'; -// node.style.left = left + generateWholeNumber(-LEFT_OFFSET, LEFT_OFFSET) + 'px'; -// node.style.transform = `rotateZ(${generateWholeNumber(...ROTATION_RANGE)}deg)`; -// },0); -// } -// return ( -// this.ref = ref} -// className='particle' -// style={this.style} -// xmlns="http://www.w3.org/2000/svg" -// viewBox="0 0 512 512"> -// -// -// ); -// } + useEffect(() => { + const {left} = style; + setTimeout(() => { + const node = currentConfetti.current; + if (node){ + node.style.top = window.innerHeight + generateWholeNumber(0, TOP_OFFSET) + 'px'; + node.style.left = left + generateWholeNumber(-LEFT_OFFSET, LEFT_OFFSET) + 'px'; + node.style.transform = `rotateZ(${generateWholeNumber(...ROTATION_RANGE)}deg)`; + } + },10); + }); + + return ( + + + + ); +} export function Particles(props: Props) { let {count: n} = props; const particles = []; - // const types = [SquiggleParticle, CircularParticle, CircularParticle]; - const types = [CircularParticle]; + const types = [SquiggleParticle, CircularParticle, CircularParticle]; while(n--) { const Particle = types[generateWholeNumber(0,3)]; @@ -107,9 +99,9 @@ export function Particles(props: Props) { } return ( -
+ {particles} -
+ ); } @@ -124,21 +116,25 @@ export default function Confetti(props: Props) { } useEffect(() => { - id = id; - id++; + if (props.fireConfetti) { + id = id; + id++; + + setParticles([...particles, id]) - setParticles([...particles, id]) - - setTimeout(() => { - clean(id); - }, 5000); - }); + setTimeout(() => { + clean(id); + }, 5000); + } + }, + [props.fireConfetti] + ); return ( - - {particles.map(id => ( + + {props.fireConfetti && particles.map(id => ( ))} - + ); } diff --git a/components/Header/index.js b/components/Header/index.js index f9de96d..d791655 100644 --- a/components/Header/index.js +++ b/components/Header/index.js @@ -22,12 +22,6 @@ type Props = { export default function Header(props: Props) { const { showHeaderShadow, totalItemsCount, currentCount, displayProgress } = props; - const getConfetti = () => { - if (currentCount === totalItemsCount) { - return (); - } - }; - return (
@@ -43,7 +37,7 @@ export default function Header(props: Props) { { currentCount === totalItemsCount && `🎉 `} {currentCount} of {totalItemsCount} completed { currentCount === totalItemsCount && ` 🎉`} - { getConfetti() } + diff --git a/components/Header/style.js b/components/Header/style.js index 4e9ea36..58a03b5 100644 --- a/components/Header/style.js +++ b/components/Header/style.js @@ -93,3 +93,17 @@ export const Label = styled.h1` left: -9999px; visibility: none; `; + +export const ParticleZone = styled.div` + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + + & > div, & > svg { + position: absolute; + transition: all 5s ease-out; + } +` +