Last active
November 21, 2020 23:30
-
-
Save Echooff3/a233d7e459f9327d390536c6650c9b79 to your computer and use it in GitHub Desktop.
Moving Gradient in React
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useRef, useEffect } from 'react' | |
const Gradient = ({ className }) => { | |
const refContainer = useRef() | |
const refCanvas = useRef() | |
const refAnimationFrame = useRef() | |
useEffect(() => { | |
const colors = [ | |
0x00aeef, | |
0x1b5cff, | |
0x7d2e61, | |
// 0xed3d24, | |
0xffd600, | |
0xed0f69, | |
] | |
const NUM_CIRCLES = 15 | |
const canvas = refCanvas.current | |
const ctx = canvas.getContext('2d'); | |
let w = canvas.offsetWidth | |
let h = canvas.offsetHeight | |
let velocity = 0 | |
const circles = Array.from(new Array(NUM_CIRCLES), (_, i) => { | |
const MIN_RADIUS = h * 0.25 | |
const MAX_RADIUS = h * 0.5 | |
const rad = (Math.random() * MIN_RADIUS) + MAX_RADIUS | |
const x = (Math.random() * w) | |
const y = (Math.random() * h) | |
const vx = (Math.random() * -1) + 1 | |
const vy = (Math.random() * -1) + 1 | |
const c = colors[i % colors.length] | |
const color = `${(c >> 16) & 0xFF}, ${(c >> 8) & 0xFF},${c & 0xFF}` | |
return { rad, x, y, vx, vy, color } | |
}) | |
const render = _ => { | |
ctx.clearRect(0, 0, w, h); | |
ctx.fillStyle = '#ffffff'; | |
ctx.fillRect(0, 0, w, h); | |
circles.forEach((c, i) => { | |
if (c.x > w) c.vx = -c.vx | |
if (c.x < 0) c.vx = -c.vx | |
if (c.y > h) c.vy = -c.vy | |
if (c.y < 0) c.vy = -c.vy | |
c.x += c.vx * velocity | |
c.y += c.vy * velocity | |
ctx.beginPath() | |
const g = ctx.createRadialGradient( | |
c.x, c.y, c.rad * 0.01, c.x, c.y, c.rad | |
) | |
g.addColorStop(0, `rgb( ${c.color} , .5)`) | |
g.addColorStop(1, `rgb( ${c.color} , 0)`) | |
ctx.fillStyle = g | |
ctx.arc(c.x, c.y, c.rad, 0, Math.PI * 2, false) | |
ctx.fill() | |
}) | |
velocity -= velocity < 0.1 ? 0 : (velocity * 0.1) | |
refAnimationFrame.current = window.requestAnimationFrame(render) | |
} | |
const resize = _ => { | |
//Resize canvas | |
refCanvas.current.width = refContainer.current.offsetWidth | |
refCanvas.current.height = refContainer.current.offsetHeight | |
w = refContainer.current.offsetWidth | |
h = refContainer.current.offsetHeight | |
} | |
window.addEventListener('resize', resize) | |
const mouseMove = _ => { | |
velocity += 1 | |
console.log(velocity) | |
} | |
refCanvas.current.addEventListener('mousemove', mouseMove, false) | |
refCanvas.current.addEventListener('touchmove', mouseMove, false) | |
// Start it | |
resize() | |
render() | |
return () => { | |
window.removeEventListener('resize', resize) | |
refCanvas.current.removeEventListener('mousemove', mouseMove) | |
refCanvas.current.removeEventListener('touchmove', mouseMove) | |
cancelAnimationFrame(refAnimationFrame.current) | |
} | |
}, [refContainer, refCanvas]) | |
return ( | |
<div ref={refContainer} className={className}> | |
<canvas ref={refCanvas}> | |
</canvas> | |
</div> | |
) | |
} | |
export default Gradient |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment