From ced5968affb04e4ab310d02b2d268b2ced011093 Mon Sep 17 00:00:00 2001 From: Joachim Robert Date: Sat, 9 Feb 2019 11:50:37 +0100 Subject: [PATCH] First try (doesn't work) --- components/Header/Confetti.js | 144 ++++++++++++++++++++++++++++++++++ components/Header/index.js | 10 +++ 2 files changed, 154 insertions(+) create mode 100644 components/Header/Confetti.js diff --git a/components/Header/Confetti.js b/components/Header/Confetti.js new file mode 100644 index 0000000..f1808ea --- /dev/null +++ b/components/Header/Confetti.js @@ -0,0 +1,144 @@ +// @flow +import React, { useState, useRef, useEffect } from 'react'; +import ReactDOM from 'react-dom'; +import styled from 'styled-components'; + +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; +const INNER_WIDTH = typeof window !== 'undefined' && window.innerWidth; +const LEFT_OFFSET = 250; + +const generateWholeNumber = (min, max) => min + Math.floor(Math.random()*(max - min)); + +const generateRandomColor = () => COLORS[generateWholeNumber(0,COLORS.length)]; + +export function CircularParticle(props: Props) { + const currentConfetti = useRef(null); + + const SIZE_RANGE = [5, 10]; + const ROTATION_RANGE = [0, 45]; + + const size = generateWholeNumber(...SIZE_RANGE); + style = { + backgroundColor: generateRandomColor(), + width: size, + height: size, + borderRadius: size, + transform: `rotateZ(${generateWholeNumber(...ROTATION_RANGE)}deg)`, + left: generateWholeNumber(0, INNER_WIDTH), + 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); + + + return ( +
+ ); +} + +// function SquiggleParticle(props: Props) { + +// static SIZE_RANGE = [15, 45]; +// static 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) +// }; + +// 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"> +// +// +// ); +// } + +export function Particles(props: Props) { + let {count: n} = props; + const particles = []; + // const types = [SquiggleParticle, CircularParticle, CircularParticle]; + const types = [CircularParticle]; + + while(n--) { + const Particle = types[generateWholeNumber(0,3)]; + particles.push( + + ); + } + + return ( +
+ {particles} +
+ ); +} + + +export default function Confetti(props: Props) { + const [particles, setParticles] = useState([]); + + var id = 1; + + function clean(id) { + setParticles(particles.filter(_id => _id !== id)) + } + + useEffect(() => { + id = id; + id++; + + setParticles([...particles, id]) + + setTimeout(() => { + clean(id); + }, 5000); + }); + + return ( + + {particles.map(id => ( + + ))} + + ); +} diff --git a/components/Header/index.js b/components/Header/index.js index f07c922..f9de96d 100644 --- a/components/Header/index.js +++ b/components/Header/index.js @@ -10,6 +10,7 @@ import { ProgressBar } from './style'; import { PrimaryButton, GhostButton } from '../Button'; import Logo from './Logo'; +import Confetti from './Confetti'; type Props = { showHeaderShadow: boolean, @@ -21,6 +22,12 @@ type Props = { export default function Header(props: Props) { const { showHeaderShadow, totalItemsCount, currentCount, displayProgress } = props; + const getConfetti = () => { + if (currentCount === totalItemsCount) { + return (); + } + }; + return (
@@ -33,7 +40,10 @@ export default function Header(props: Props) {
+ { currentCount === totalItemsCount && `🎉 `} {currentCount} of {totalItemsCount} completed + { currentCount === totalItemsCount && ` 🎉`} + { getConfetti() }