diff --git a/package.json b/package.json index 23cd6913..5d9969fe 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "academicons": "https://github.com/jpswalsh/academicons#v1.9.3", "babel-jest": "29.5.0", "bootstrap": "5.2.3", + "canvas-confetti": "^1.9.3", "classnames": "2.3.2", "dotenv": "16.0.3", "fs-extra": "11.1.1", @@ -93,6 +94,7 @@ "@types/react-dom": "18.2.1", "@types/react-helmet": "6.1.6", "@types/react-slick": "0.23.10", + "@types/canvas-confetti": "^1.6.4", "@typescript-eslint/eslint-plugin": "5.59.2", "@typescript-eslint/parser": "5.59.2", "babel-preset-gatsby": "3.9.0", diff --git a/src/components/ftsrg30page-components/BannerSection.tsx b/src/components/ftsrg30page-components/BannerSection.tsx new file mode 100644 index 00000000..5f592f65 --- /dev/null +++ b/src/components/ftsrg30page-components/BannerSection.tsx @@ -0,0 +1,126 @@ +import { StaticImage } from 'gatsby-plugin-image' +import { useI18next } from 'gatsby-plugin-react-i18next' +import React, { useEffect, useRef } from 'react' +import { Col, Container, Row } from 'react-bootstrap' +import { useDeviceSelectors } from 'react-device-detect' +import useIsClient from '~hooks/useIsClient' +import confetti from 'canvas-confetti' + +const BannerSection: React.FC = () => { + const { t, language } = useI18next() + const { isClient, key } = useIsClient() + const confettiCanvas = useRef() as React.MutableRefObject + + const isMobile = isClient ? (useDeviceSelectors(window.navigator.userAgent)[0].isMobile as boolean) : false + + function confettiFrame(myConfetti: confetti.CreateTypes) { + window.requestAnimationFrame(() => { + // launch a few confetti from the left edge + myConfetti({ + particleCount: 40, + angle: 30, + spread: 55, + decay: 0.94, + origin: { x: 0, y: 0.7 } + }) + // and launch a few from the right edge + myConfetti({ + particleCount: 40, + angle: 150, + spread: 55, + decay: 0.94, + origin: { x: 1, y: 0.7 } + }) + }) + } + + useEffect(() => { + const myConfetti = confetti.create(confettiCanvas.current, { + resize: true + }) + const confettiIdx = setInterval(() => confettiFrame(myConfetti), 2500) + return () => { + clearInterval(confettiIdx) + } + }) + + return ( +