Skip to content

Instantly share code, notes, and snippets.

@Echooff3
Last active November 21, 2020 23:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Echooff3/a233d7e459f9327d390536c6650c9b79 to your computer and use it in GitHub Desktop.
Save Echooff3/a233d7e459f9327d390536c6650c9b79 to your computer and use it in GitHub Desktop.
Moving Gradient in React
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