Kinetic Gravity Well
🟣 CanvasAn abstract, massive orbital simulation constructed from thousands of mathematically precise microscopic kinetic dots that violently react to cursor-driven gravity physics.
Responsive Horizontal Leaderboard
Slot ID: ca-pub-detail-below-preview
Interactive Settings
Medium Rectangle Block
Slot ID: ca-pub-detail-after-customization
Quick Copy Actions
Download File Packages
Keyboard Shortcuts
Responsive Horizontal Leaderboard
Slot ID: ca-pub-detail-before-related
More in Abstract
Loading Canvas Shader...
Viscous Chrome Fluid
A premium, edge-to-edge liquid chrome and viscous ink simulation responsive to high-velocity mouse cursor tracking.
Loading Canvas Shader...
Floating 3D Squares
Floating wireframe 3D-rotated square outlines drifting and spinning upwards on cosmic black.
Loading Canvas Shader...
Tactile Claymorphic Spheres
Pristine candy-colored claymorphic spheres casting deep, soft lifelike shadows, morphing and reacting beautifully to mouse coordinates.
Kinetic Gravity Well - HTML5 Canvas & JavaScript Abstract background for React & Tailwind
Integrate the Kinetic Gravity Well directly into your website. This asset is rendered using HTML5 Canvas 2D render loop. It is optimized for zero layout-shifts and runs with high-performance hardware-accelerated processing.
⚡ Performance Specifications
- Render Mode: CANVAS (HTML5 Canvas & JavaScript)
- Fluidity: Locked at 60fps dynamic loop
- Bundle Footprint: Zero external NPM dependencies
- SEO Indexing status: 100% Crawlable static semantic HTML
🛠️ Integration Capabilities
Our templates expose inline design tokens like --color-1 and --color-2 for infinite color palettes. This template is designed to fit inside hero elements, full-screen landing pages, and interactive presentation cards.
Technical Code Reference & Syntaxes for Googlebot & Crawlers
The snippets below display the direct, unminified source code utilized for rendering this background.
HTML & Inline CSS Snippet (Vanilla)
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kinetic Gravity Well</title>
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: #09090b;
}
.kinetic-gravity-container {
width: 100%;
height: 100%;
background: #050505;
position: relative;
overflow: hidden;
}
#gravity-canvas {
width: 100%;
height: 100%;
display: block;
}
</style>
</head>
<body>
<div class="kinetic-gravity-container" style="width: 100%; height: 100%; overflow: hidden; background: #050505;">
<canvas id="gravity-canvas" style="width: 100%; height: 100%; display: block; filter: contrast(1.15) brightness(1.05);"></canvas>
<script>
(function() {
const canvas = document.getElementById('gravity-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
let width = 0;
let height = 0;
const dpr = window.devicePixelRatio || 1;
const mouse = { x: -1000, y: -1000, active: false };
const lerpedMouse = { x: -1000, y: -1000 };
const particles = [];
const numParticles = 2200;
function initSimulation() {
const rect = canvas.parentNode ? canvas.parentNode.getBoundingClientRect() : null;
width = rect ? rect.width : window.innerWidth;
height = rect ? rect.height : window.innerHeight;
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);
particles.length = 0;
const maxDist = Math.max(width, height) * 0.7;
const ringBands = [
{ min: 60, max: 80, density: 0.1 },
{ min: 100, max: 130, density: 0.15 },
{ min: 140, max: 180, density: 0.25 },
{ min: 200, max: 215, density: 0.05 },
{ min: 230, max: 280, density: 0.25 },
{ min: 310, max: 380, density: 0.15 },
{ min: 410, max: maxDist, density: 0.05 },
];
for (let i = 0; i < numParticles; i++) {
let band = ringBands[2];
const rVal = Math.random();
let cumulative = 0;
for (const b of ringBands) {
cumulative += b.density;
if (rVal <= cumulative) {
band = b;
break;
}
}
const baseRadius = band.min + Math.random() * (band.max - band.min);
const angle = Math.random() * Math.PI * 2;
const baseSpeed = 0.001 + (3.5 / baseRadius);
const angularSpeed = baseSpeed * (0.85 + Math.random() * 0.3);
const orbitDirection = Math.random() > 0.04 ? 1 : -1;
const randColor = Math.random();
let color = 'rgba(255, 255, 255, 0.85)';
if (randColor < 0.45) {
color = 'rgba(148, 163, 184, 0.65)';
} else if (randColor < 0.75) {
color = 'rgba(71, 85, 105, 0.4)';
} else if (randColor < 0.92) {
color = 'rgba(255, 255, 255, 0.35)';
} else {
color = 'rgba(255, 255, 255, 0.95)';
}
const size = Math.random() > 0.85 ? (Math.random() > 0.95 ? 2.0 : 1.2) : 0.6 + Math.random() * 0.4;
const cx = width / 2;
const cy = height / 2;
const px = cx + Math.cos(angle) * baseRadius;
const py = cy + Math.sin(angle) * baseRadius;
particles.push({
x: px,
y: py,
vx: 0,
vy: 0,
baseRadius,
angle,
angularSpeed,
orbitDirection,
size,
color,
});
}
}
initSimulation();
const updateMouse = (clientX, clientY) => {
const rect = canvas.getBoundingClientRect();
mouse.x = clientX - rect.left;
mouse.y = clientY - rect.top;
mouse.active = true;
};
window.addEventListener('mousemove', (e) => {
updateMouse(e.clientX, e.clientY);
}, { passive: true });
window.addEventListener('touchmove', (e) => {
if (e.touches && e.touches[0]) {
updateMouse(e.touches[0].clientX, e.touches[0].clientY);
}
}, { passive: true });
const handleMouseLeave = () => {
mouse.active = false;
mouse.x = -1000;
mouse.y = -1000;
};
window.addEventListener('touchend', handleMouseLeave);
canvas.addEventListener('mouseleave', handleMouseLeave);
window.addEventListener('message', (e) => {
if (!e.data) return;
if (e.data.type === 'mousemove') {
mouse.x = e.data.x;
mouse.y = e.data.y;
mouse.active = true;
} else if (e.data.type === 'mouseleave') {
handleMouseLeave();
}
});
window.addEventListener('resize', () => {
initSimulation();
});
function render() {
ctx.fillStyle = '#050505';
ctx.fillRect(0, 0, width, height);
const cx = width / 2;
const cy = height / 2;
const singGrad = ctx.createRadialGradient(cx, cy, 0, cx, cy, 140);
singGrad.addColorStop(0, 'rgba(0, 0, 0, 1)');
singGrad.addColorStop(0.5, 'rgba(3, 3, 4, 0.85)');
singGrad.addColorStop(1, 'rgba(5, 5, 5, 0)');
ctx.fillStyle = singGrad;
ctx.beginPath();
ctx.arc(cx, cy, 140, 0, Math.PI * 2);
ctx.fill();
if (mouse.active) {
if (lerpedMouse.x === -1000) {
lerpedMouse.x = mouse.x;
lerpedMouse.y = mouse.y;
} else {
lerpedMouse.x += (mouse.x - lerpedMouse.x) * 0.12;
lerpedMouse.y += (mouse.y - lerpedMouse.y) * 0.12;
}
} else {
lerpedMouse.x = -1000;
lerpedMouse.y = -1000;
}
const gravityRadius = 300;
const springK = 0.025;
const damping = 0.93;
const maxVelocity = 14;
for (let i = 0; i < particles.length; i++) {
const p = particles[i];
p.angle += p.angularSpeed * p.orbitDirection;
const targetX = cx + Math.cos(p.angle) * p.baseRadius;
const targetY = cy + Math.sin(p.angle) * p.baseRadius;
if (lerpedMouse.x !== -1000) {
const dx = lerpedMouse.x - p.x;
const dy = lerpedMouse.y - p.y;
const dist = Math.hypot(dx, dy);
if (dist < gravityRadius && dist > 1.0) {
const force = (gravityRadius - dist) / gravityRadius;
const gravityPower = force * force * 1.6;
const pullAngle = Math.atan2(dy, dx);
p.vx += Math.cos(pullAngle) * gravityPower;
p.vy += Math.sin(pullAngle) * gravityPower;
}
}
const rx = targetX - p.x;
const ry = targetY - p.y;
p.vx += rx * springK;
p.vy += ry * springK;
p.vx *= damping;
p.vy *= damping;
const currentVelocity = Math.hypot(p.vx, p.vy);
if (currentVelocity > maxVelocity) {
p.vx = (p.vx / currentVelocity) * maxVelocity;
p.vy = (p.vy / currentVelocity) * maxVelocity;
}
p.x += p.vx;
p.y += p.vy;
ctx.fillStyle = p.color;
ctx.fillRect(p.x, p.y, p.size, p.size);
}
if (lerpedMouse.x !== -1000) {
const mouseGlow = ctx.createRadialGradient(
lerpedMouse.x, lerpedMouse.y, 0,
lerpedMouse.x, lerpedMouse.y, 160
);
mouseGlow.addColorStop(0, 'rgba(255, 255, 255, 0.05)');
mouseGlow.addColorStop(0.5, 'rgba(200, 210, 230, 0.01)');
mouseGlow.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.fillStyle = mouseGlow;
ctx.beginPath();
ctx.arc(lerpedMouse.x, lerpedMouse.y, 160, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(render);
}
requestAnimationFrame(render);
})();
</script>
</div>
</body>
</html>React Component Wrapper (TSX)
import React from 'react';
export default function KineticGravityWellBackground() {
return (
<div
style={{ width: '100%', height: '100%', position: 'relative', overflow: 'hidden' }}
>
<style dangerouslySetInnerHTML={{ __html: `
.kinetic-gravity-container {
width: 100%;
height: 100%;
background: #050505;
position: relative;
overflow: hidden;
}
#gravity-canvas {
width: 100%;
height: 100%;
display: block;
}
` }} />
{/* HTML Structure */}
<div
style={{ width: '100%', height: '100%' }}
dangerouslySetInnerHTML={{ __html: `
<div class="kinetic-gravity-container" style="width: 100%; height: 100%; overflow: hidden; background: #050505;">
<canvas id="gravity-canvas" style="width: 100%; height: 100%; display: block; filter: contrast(1.15) brightness(1.05);"></canvas>
<script>
(function() {
const canvas = document.getElementById('gravity-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
let width = 0;
let height = 0;
const dpr = window.devicePixelRatio || 1;
const mouse = { x: -1000, y: -1000, active: false };
const lerpedMouse = { x: -1000, y: -1000 };
const particles = [];
const numParticles = 2200;
function initSimulation() {
const rect = canvas.parentNode ? canvas.parentNode.getBoundingClientRect() : null;
width = rect ? rect.width : window.innerWidth;
height = rect ? rect.height : window.innerHeight;
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);
particles.length = 0;
const maxDist = Math.max(width, height) * 0.7;
const ringBands = [
{ min: 60, max: 80, density: 0.1 },
{ min: 100, max: 130, density: 0.15 },
{ min: 140, max: 180, density: 0.25 },
{ min: 200, max: 215, density: 0.05 },
{ min: 230, max: 280, density: 0.25 },
{ min: 310, max: 380, density: 0.15 },
{ min: 410, max: maxDist, density: 0.05 },
];
for (let i = 0; i < numParticles; i++) {
let band = ringBands[2];
const rVal = Math.random();
let cumulative = 0;
for (const b of ringBands) {
cumulative += b.density;
if (rVal <= cumulative) {
band = b;
break;
}
}
const baseRadius = band.min + Math.random() * (band.max - band.min);
const angle = Math.random() * Math.PI * 2;
const baseSpeed = 0.001 + (3.5 / baseRadius);
const angularSpeed = baseSpeed * (0.85 + Math.random() * 0.3);
const orbitDirection = Math.random() > 0.04 ? 1 : -1;
const randColor = Math.random();
let color = 'rgba(255, 255, 255, 0.85)';
if (randColor < 0.45) {
color = 'rgba(148, 163, 184, 0.65)';
} else if (randColor < 0.75) {
color = 'rgba(71, 85, 105, 0.4)';
} else if (randColor < 0.92) {
color = 'rgba(255, 255, 255, 0.35)';
} else {
color = 'rgba(255, 255, 255, 0.95)';
}
const size = Math.random() > 0.85 ? (Math.random() > 0.95 ? 2.0 : 1.2) : 0.6 + Math.random() * 0.4;
const cx = width / 2;
const cy = height / 2;
const px = cx + Math.cos(angle) * baseRadius;
const py = cy + Math.sin(angle) * baseRadius;
particles.push({
x: px,
y: py,
vx: 0,
vy: 0,
baseRadius,
angle,
angularSpeed,
orbitDirection,
size,
color,
});
}
}
initSimulation();
const updateMouse = (clientX, clientY) => {
const rect = canvas.getBoundingClientRect();
mouse.x = clientX - rect.left;
mouse.y = clientY - rect.top;
mouse.active = true;
};
window.addEventListener('mousemove', (e) => {
updateMouse(e.clientX, e.clientY);
}, { passive: true });
window.addEventListener('touchmove', (e) => {
if (e.touches && e.touches[0]) {
updateMouse(e.touches[0].clientX, e.touches[0].clientY);
}
}, { passive: true });
const handleMouseLeave = () => {
mouse.active = false;
mouse.x = -1000;
mouse.y = -1000;
};
window.addEventListener('touchend', handleMouseLeave);
canvas.addEventListener('mouseleave', handleMouseLeave);
window.addEventListener('message', (e) => {
if (!e.data) return;
if (e.data.type === 'mousemove') {
mouse.x = e.data.x;
mouse.y = e.data.y;
mouse.active = true;
} else if (e.data.type === 'mouseleave') {
handleMouseLeave();
}
});
window.addEventListener('resize', () => {
initSimulation();
});
function render() {
ctx.fillStyle = '#050505';
ctx.fillRect(0, 0, width, height);
const cx = width / 2;
const cy = height / 2;
const singGrad = ctx.createRadialGradient(cx, cy, 0, cx, cy, 140);
singGrad.addColorStop(0, 'rgba(0, 0, 0, 1)');
singGrad.addColorStop(0.5, 'rgba(3, 3, 4, 0.85)');
singGrad.addColorStop(1, 'rgba(5, 5, 5, 0)');
ctx.fillStyle = singGrad;
ctx.beginPath();
ctx.arc(cx, cy, 140, 0, Math.PI * 2);
ctx.fill();
if (mouse.active) {
if (lerpedMouse.x === -1000) {
lerpedMouse.x = mouse.x;
lerpedMouse.y = mouse.y;
} else {
lerpedMouse.x += (mouse.x - lerpedMouse.x) * 0.12;
lerpedMouse.y += (mouse.y - lerpedMouse.y) * 0.12;
}
} else {
lerpedMouse.x = -1000;
lerpedMouse.y = -1000;
}
const gravityRadius = 300;
const springK = 0.025;
const damping = 0.93;
const maxVelocity = 14;
for (let i = 0; i < particles.length; i++) {
const p = particles[i];
p.angle += p.angularSpeed * p.orbitDirection;
const targetX = cx + Math.cos(p.angle) * p.baseRadius;
const targetY = cy + Math.sin(p.angle) * p.baseRadius;
if (lerpedMouse.x !== -1000) {
const dx = lerpedMouse.x - p.x;
const dy = lerpedMouse.y - p.y;
const dist = Math.hypot(dx, dy);
if (dist < gravityRadius && dist > 1.0) {
const force = (gravityRadius - dist) / gravityRadius;
const gravityPower = force * force * 1.6;
const pullAngle = Math.atan2(dy, dx);
p.vx += Math.cos(pullAngle) * gravityPower;
p.vy += Math.sin(pullAngle) * gravityPower;
}
}
const rx = targetX - p.x;
const ry = targetY - p.y;
p.vx += rx * springK;
p.vy += ry * springK;
p.vx *= damping;
p.vy *= damping;
const currentVelocity = Math.hypot(p.vx, p.vy);
if (currentVelocity > maxVelocity) {
p.vx = (p.vx / currentVelocity) * maxVelocity;
p.vy = (p.vy / currentVelocity) * maxVelocity;
}
p.x += p.vx;
p.y += p.vy;
ctx.fillStyle = p.color;
ctx.fillRect(p.x, p.y, p.size, p.size);
}
if (lerpedMouse.x !== -1000) {
const mouseGlow = ctx.createRadialGradient(
lerpedMouse.x, lerpedMouse.y, 0,
lerpedMouse.x, lerpedMouse.y, 160
);
mouseGlow.addColorStop(0, 'rgba(255, 255, 255, 0.05)');
mouseGlow.addColorStop(0.5, 'rgba(200, 210, 230, 0.01)');
mouseGlow.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.fillStyle = mouseGlow;
ctx.beginPath();
ctx.arc(lerpedMouse.x, lerpedMouse.y, 160, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(render);
}
requestAnimationFrame(render);
})();
</script>
</div>
` }}
/>
</div>
);
}Next.js App Router Component (use client)
'use client';
import React from 'react';
export default function KineticGravityWellBackground() {
return (
<div
className="w-full h-full relative overflow-hidden"
>
<style dangerouslySetInnerHTML={{ __html: `
.kinetic-gravity-container {
width: 100%;
height: 100%;
background: #050505;
position: relative;
overflow: hidden;
}
#gravity-canvas {
width: 100%;
height: 100%;
display: block;
}
` }} />
{/* HTML Structure */}
<div
className="w-full h-full"
dangerouslySetInnerHTML={{ __html: `
<div class="kinetic-gravity-container" style="width: 100%; height: 100%; overflow: hidden; background: #050505;">
<canvas id="gravity-canvas" style="width: 100%; height: 100%; display: block; filter: contrast(1.15) brightness(1.05);"></canvas>
<script>
(function() {
const canvas = document.getElementById('gravity-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
let width = 0;
let height = 0;
const dpr = window.devicePixelRatio || 1;
const mouse = { x: -1000, y: -1000, active: false };
const lerpedMouse = { x: -1000, y: -1000 };
const particles = [];
const numParticles = 2200;
function initSimulation() {
const rect = canvas.parentNode ? canvas.parentNode.getBoundingClientRect() : null;
width = rect ? rect.width : window.innerWidth;
height = rect ? rect.height : window.innerHeight;
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);
particles.length = 0;
const maxDist = Math.max(width, height) * 0.7;
const ringBands = [
{ min: 60, max: 80, density: 0.1 },
{ min: 100, max: 130, density: 0.15 },
{ min: 140, max: 180, density: 0.25 },
{ min: 200, max: 215, density: 0.05 },
{ min: 230, max: 280, density: 0.25 },
{ min: 310, max: 380, density: 0.15 },
{ min: 410, max: maxDist, density: 0.05 },
];
for (let i = 0; i < numParticles; i++) {
let band = ringBands[2];
const rVal = Math.random();
let cumulative = 0;
for (const b of ringBands) {
cumulative += b.density;
if (rVal <= cumulative) {
band = b;
break;
}
}
const baseRadius = band.min + Math.random() * (band.max - band.min);
const angle = Math.random() * Math.PI * 2;
const baseSpeed = 0.001 + (3.5 / baseRadius);
const angularSpeed = baseSpeed * (0.85 + Math.random() * 0.3);
const orbitDirection = Math.random() > 0.04 ? 1 : -1;
const randColor = Math.random();
let color = 'rgba(255, 255, 255, 0.85)';
if (randColor < 0.45) {
color = 'rgba(148, 163, 184, 0.65)';
} else if (randColor < 0.75) {
color = 'rgba(71, 85, 105, 0.4)';
} else if (randColor < 0.92) {
color = 'rgba(255, 255, 255, 0.35)';
} else {
color = 'rgba(255, 255, 255, 0.95)';
}
const size = Math.random() > 0.85 ? (Math.random() > 0.95 ? 2.0 : 1.2) : 0.6 + Math.random() * 0.4;
const cx = width / 2;
const cy = height / 2;
const px = cx + Math.cos(angle) * baseRadius;
const py = cy + Math.sin(angle) * baseRadius;
particles.push({
x: px,
y: py,
vx: 0,
vy: 0,
baseRadius,
angle,
angularSpeed,
orbitDirection,
size,
color,
});
}
}
initSimulation();
const updateMouse = (clientX, clientY) => {
const rect = canvas.getBoundingClientRect();
mouse.x = clientX - rect.left;
mouse.y = clientY - rect.top;
mouse.active = true;
};
window.addEventListener('mousemove', (e) => {
updateMouse(e.clientX, e.clientY);
}, { passive: true });
window.addEventListener('touchmove', (e) => {
if (e.touches && e.touches[0]) {
updateMouse(e.touches[0].clientX, e.touches[0].clientY);
}
}, { passive: true });
const handleMouseLeave = () => {
mouse.active = false;
mouse.x = -1000;
mouse.y = -1000;
};
window.addEventListener('touchend', handleMouseLeave);
canvas.addEventListener('mouseleave', handleMouseLeave);
window.addEventListener('message', (e) => {
if (!e.data) return;
if (e.data.type === 'mousemove') {
mouse.x = e.data.x;
mouse.y = e.data.y;
mouse.active = true;
} else if (e.data.type === 'mouseleave') {
handleMouseLeave();
}
});
window.addEventListener('resize', () => {
initSimulation();
});
function render() {
ctx.fillStyle = '#050505';
ctx.fillRect(0, 0, width, height);
const cx = width / 2;
const cy = height / 2;
const singGrad = ctx.createRadialGradient(cx, cy, 0, cx, cy, 140);
singGrad.addColorStop(0, 'rgba(0, 0, 0, 1)');
singGrad.addColorStop(0.5, 'rgba(3, 3, 4, 0.85)');
singGrad.addColorStop(1, 'rgba(5, 5, 5, 0)');
ctx.fillStyle = singGrad;
ctx.beginPath();
ctx.arc(cx, cy, 140, 0, Math.PI * 2);
ctx.fill();
if (mouse.active) {
if (lerpedMouse.x === -1000) {
lerpedMouse.x = mouse.x;
lerpedMouse.y = mouse.y;
} else {
lerpedMouse.x += (mouse.x - lerpedMouse.x) * 0.12;
lerpedMouse.y += (mouse.y - lerpedMouse.y) * 0.12;
}
} else {
lerpedMouse.x = -1000;
lerpedMouse.y = -1000;
}
const gravityRadius = 300;
const springK = 0.025;
const damping = 0.93;
const maxVelocity = 14;
for (let i = 0; i < particles.length; i++) {
const p = particles[i];
p.angle += p.angularSpeed * p.orbitDirection;
const targetX = cx + Math.cos(p.angle) * p.baseRadius;
const targetY = cy + Math.sin(p.angle) * p.baseRadius;
if (lerpedMouse.x !== -1000) {
const dx = lerpedMouse.x - p.x;
const dy = lerpedMouse.y - p.y;
const dist = Math.hypot(dx, dy);
if (dist < gravityRadius && dist > 1.0) {
const force = (gravityRadius - dist) / gravityRadius;
const gravityPower = force * force * 1.6;
const pullAngle = Math.atan2(dy, dx);
p.vx += Math.cos(pullAngle) * gravityPower;
p.vy += Math.sin(pullAngle) * gravityPower;
}
}
const rx = targetX - p.x;
const ry = targetY - p.y;
p.vx += rx * springK;
p.vy += ry * springK;
p.vx *= damping;
p.vy *= damping;
const currentVelocity = Math.hypot(p.vx, p.vy);
if (currentVelocity > maxVelocity) {
p.vx = (p.vx / currentVelocity) * maxVelocity;
p.vy = (p.vy / currentVelocity) * maxVelocity;
}
p.x += p.vx;
p.y += p.vy;
ctx.fillStyle = p.color;
ctx.fillRect(p.x, p.y, p.size, p.size);
}
if (lerpedMouse.x !== -1000) {
const mouseGlow = ctx.createRadialGradient(
lerpedMouse.x, lerpedMouse.y, 0,
lerpedMouse.x, lerpedMouse.y, 160
);
mouseGlow.addColorStop(0, 'rgba(255, 255, 255, 0.05)');
mouseGlow.addColorStop(0.5, 'rgba(200, 210, 230, 0.01)');
mouseGlow.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.fillStyle = mouseGlow;
ctx.beginPath();
ctx.arc(lerpedMouse.x, lerpedMouse.y, 160, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(render);
}
requestAnimationFrame(render);
})();
</script>
</div>
` }}
/>
</div>
);
}Raw CSS Stylesheet Snippet
.kinetic-gravity-container {
width: 100%;
height: 100%;
background: #050505;
position: relative;
overflow: hidden;
}
#gravity-canvas {
width: 100%;
height: 100%;
display: block;
}