UNPKG

leumas-private-shared

Version:

Private React JSX Package For Leumas Shared Components, Headers, Footers, Asides, Login Pages, API Key Manager and much more. Styles and everything reusable to avoid DRY code across all of our subdomains

192 lines (160 loc) 4.72 kB
import React, { useEffect, useRef } from 'react'; import { TweenLite, TweenMax, Power0 } from 'gsap/all'; import { styled } from '@mui/system'; import './Dots2.scss'; // Import the SCSS file here const DotsWrapper = styled('div')` position: relative; width: 100%; height: 100%; overflow: hidden; `; const Credits = styled('div')` position: fixed; bottom: 1rem; right: 1rem; font-size: 0.75rem; display: flex; align-items: center; justify-content: flex-end; color: var(--color); `; const Dots2Background = ({ children }) => { const canvasRef = useRef(null); useEffect(() => { const { log } = console; log('🎨'); const internals = { config: { totalGroups: 50, }, colors: [ ['#00ffff', '#ff0000'], ['#00ff00', '#ff00ff'], ['#0000ff', '#ffff00'], ], random: (min, max) => min + Math.random() * (max - min), }; const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); const w = window.innerWidth; const h = window.innerHeight; canvas.width = w; canvas.height = h; class Shapes { constructor(index) { this.index = index; this.offset = 50; this.colorsIndex = 0; this.draw(0); this.reset().animate(); } draw(colorsIndex) { if (colorsIndex === undefined) { this.colorsIndex = (this.colorsIndex + 1) % internals.colors.length; } const colors = internals.colors[this.colorsIndex]; ctx.clearRect(0, 0, w, h); if (this.index % 2) { ctx.fillStyle = colors[0]; ctx.fillRect( internals.random(0, this.offset), internals.random(0, this.offset), 60, 60 ); ctx.fillStyle = colors[1]; ctx.fillRect( internals.random(0, this.offset), internals.random(0, this.offset), 60, 60 ); } else { ctx.fillStyle = colors[0]; ctx.beginPath(); ctx.arc( internals.random(0, this.offset), internals.random(0, this.offset), 30, 0, Math.PI * 2 ); ctx.fill(); ctx.fillStyle = colors[1]; ctx.beginPath(); ctx.arc( internals.random(0, this.offset), internals.random(0, this.offset), 30, 0, Math.PI * 2 ); ctx.fill(); } return this; } animate() { let positionX, positionY; const rotation = internals.random(-360, 360); const scale = internals.random(0.5, 1.25); const delay = this.index * 0.1; if (Math.random() > 0.5) { positionX = internals.random(0 - w, w * 2); positionY = Math.random() > 0.5 ? h * 2 : -h; } else { positionX = Math.random() > 0.5 ? w * 2 : -w; positionY = internals.random(0 - h, h * 2); } TweenMax.to(this, internals.random(2, 6), { x: positionX, y: positionY, rotation, scale, delay, onComplete: () => { this.reset().animate(); }, }); return this; } reset() { this.x = w / 2; this.y = h / 2; this.rotation = 0; this.scale = 0; return this; } } TweenLite.defaultEase = Power0.easeNone; const shapes = []; for (let i = 0; i < internals.config.totalGroups; i++) { shapes.push(new Shapes(i)); } function changeColors() { shapes.forEach((shape) => shape.draw()); } function resize() { setTimeout(() => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }, 200); } window.addEventListener('click', changeColors); window.addEventListener('touchstart', changeColors); window.addEventListener('resize', resize); window.addEventListener('orientationchange', resize); return () => { window.removeEventListener('click', changeColors); window.removeEventListener('touchstart', changeColors); window.removeEventListener('resize', resize); window.removeEventListener('orientationchange', resize); }; }, []); return ( <DotsWrapper> <canvas ref={canvasRef}></canvas> {children} </DotsWrapper> ); }; export default Dots2Background;