Kinetic Lissajous Matrix
🔵 InteractiveA mathematically precise, symmetrical geometric mandala that seamlessly morphs and folds into itself in response to your cursor coordinates.
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 Interactive & Cursor-Driven
Loading Canvas Shader...
Magnetic Fluid Grid
A highly responsive minimalist geometric grid that warps, bends, and reacts under the user's cursor using custom spring-mass physics and high-performance distance calculation.
Loading Canvas Shader...
Semantic Warp Lens
A gorgeous, high-fidelity monospaced text grid that warps, rotates, and inverts colors like an optical lens centered directly on the user's cursor.
Loading Canvas Shader...
Ethereal Smoke Trails
An ultra-responsive interactive canvas trail that renders smooth, glowing fluid-like ribbons accompanied by drifting and slowly dissolving micro-smoke particles.
Kinetic Lissajous Matrix - HTML5 Canvas & JavaScript Interactive & Cursor-Driven background for React & Tailwind
Integrate the Kinetic Lissajous Matrix 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: INTERACTIVE (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 Lissajous Matrix</title>
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: #09090b;
}
.kinetic-lissajous-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #050505;
overflow: hidden;
}
#canvas-kinetic-lissajous {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
display: block;
}
</style>
</head>
<body>
<div class="kinetic-lissajous-container">
<canvas id="canvas-kinetic-lissajous"></canvas>
</div>
<script>
(function() {
const canvas = document.getElementById('canvas-kinetic-lissajous');
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
let active = true;
let dpr = 1;
let width = 0;
let height = 0;
let targetMouseX = 0.5;
let targetMouseY = 0.5;
let mouseX = 0.5;
let mouseY = 0.5;
let phase = 0;
const pointsCount = 450;
function resize() {
const rect = canvas.parentNode ? canvas.parentNode.getBoundingClientRect() : null;
width = rect ? rect.width : window.innerWidth;
height = rect ? rect.height : window.innerHeight;
dpr = window.devicePixelRatio || 1;
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);
}
function handleMouseMove(e) {
const rect = canvas.getBoundingClientRect();
const currentWidth = rect.width || window.innerWidth;
const currentHeight = rect.height || window.innerHeight;
targetMouseX = Math.max(0, Math.min(1, (e.clientX - rect.left) / currentWidth));
targetMouseY = Math.max(0, Math.min(1, (e.clientY - rect.top) / currentHeight));
}
function handleTouchMove(e) {
if (e.touches.length === 0) return;
const rect = canvas.getBoundingClientRect();
const currentWidth = rect.width || window.innerWidth;
const currentHeight = rect.height || window.innerHeight;
targetMouseX = Math.max(0, Math.min(1, (e.touches[0].clientX - rect.left) / currentWidth));
targetMouseY = Math.max(0, Math.min(1, (e.touches[0].clientY - rect.top) / currentHeight));
}
function handleMouseLeave() {
targetMouseX = 0.5;
targetMouseY = 0.5;
}
function handleMessage(e) {
if (e.data) {
if (e.data.type === 'mousemove') {
targetMouseX = Math.max(0, Math.min(1, e.data.x / width));
targetMouseY = Math.max(0, Math.min(1, e.data.y / height));
} else if (e.data.type === 'mouseleave') {
targetMouseX = 0.5;
targetMouseY = 0.5;
}
}
}
window.addEventListener('resize', resize);
window.addEventListener('mousemove', handleMouseMove, { passive: true });
window.addEventListener('mouseleave', handleMouseLeave, { passive: true });
window.addEventListener('touchmove', handleTouchMove, { passive: true });
window.addEventListener('touchcancel', handleMouseLeave, { passive: true });
window.addEventListener('message', handleMessage);
resize();
ctx.fillStyle = '#050505';
ctx.fillRect(0, 0, width, height);
function animate() {
if (!active) return;
if (!canvas.isConnected) {
cleanup();
return;
}
mouseX += (targetMouseX - mouseX) * 0.08;
mouseY += (targetMouseY - mouseY) * 0.08;
ctx.fillStyle = 'rgba(5, 5, 5, 0.06)';
ctx.fillRect(0, 0, width, height);
phase += 0.006;
const centerX = width / 2;
const centerY = height / 2;
const maxRadius = Math.min(width, height) * 0.38;
ctx.shadowBlur = 12;
ctx.shadowColor = 'rgba(14, 165, 233, 0.35)';
ctx.lineWidth = 1.25;
const freqX = 1 + mouseX * 8.0;
const freqY = 1 + mouseY * 8.0;
ctx.beginPath();
for (let i = 0; i <= pointsCount; i++) {
const t = (i / pointsCount) * Math.PI * 2;
const x = centerX + Math.sin(t * freqX + phase) * Math.cos(t * 1.5) * maxRadius;
const y = centerY + Math.cos(t * freqY + phase) * Math.sin(t * 1.5) * maxRadius;
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
const gradient = ctx.createRadialGradient(centerX, centerY, 10, centerX, centerY, maxRadius);
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.85)');
gradient.addColorStop(0.5, 'rgba(56, 189, 248, 0.65)');
gradient.addColorStop(1, 'rgba(99, 102, 241, 0.1)');
ctx.strokeStyle = gradient;
ctx.stroke();
ctx.shadowBlur = 0;
requestAnimationFrame(animate);
}
function cleanup() {
active = false;
window.removeEventListener('resize', resize);
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseleave', handleMouseLeave);
window.removeEventListener('touchmove', handleTouchMove);
window.removeEventListener('touchcancel', handleMouseLeave);
window.removeEventListener('message', handleMessage);
}
requestAnimationFrame(animate);
})();
</script>
<script>
// Throttled interactive cursor coordinates mapping
(function() {
document.documentElement.style.setProperty('--mouse-x', '0');
document.documentElement.style.setProperty('--mouse-y', '0');
let targetX = 0, targetY = 0;
let currentX = 0, currentY = 0;
window.addEventListener('mousemove', (e) => {
targetX = (e.clientX / window.innerWidth) - 0.5;
targetY = (e.clientY / window.innerHeight) - 0.5;
});
window.addEventListener('mouseleave', () => {
targetX = 0;
targetY = 0;
});
function update() {
currentX += (targetX - currentX) * 0.08;
currentY += (targetY - currentY) * 0.08;
document.documentElement.style.setProperty('--mouse-x', currentX.toFixed(4));
document.documentElement.style.setProperty('--mouse-y', currentY.toFixed(4));
requestAnimationFrame(update);
}
requestAnimationFrame(update);
})();
</script>
</body>
</html>React Component Wrapper (TSX)
import React, { useEffect, useRef } from 'react';
export default function KineticLissajousMatrixBackground() {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
let targetX = 0, targetY = 0;
let currentX = 0, currentY = 0;
let frameId: number;
const handleMouseMove = (e: MouseEvent) => {
targetX = (e.clientX / window.innerWidth) - 0.5;
targetY = (e.clientY / window.innerHeight) - 0.5;
};
const handleMouseLeave = () => {
targetX = 0;
targetY = 0;
};
window.addEventListener('mousemove', handleMouseMove);
window.addEventListener('mouseleave', handleMouseLeave);
const updateCoordinates = () => {
currentX += (targetX - currentX) * 0.08;
currentY += (targetY - currentY) * 0.08;
if (containerRef.current) {
containerRef.current.style.setProperty('--mouse-x', currentX.toFixed(4));
containerRef.current.style.setProperty('--mouse-y', currentY.toFixed(4));
}
frameId = requestAnimationFrame(updateCoordinates);
};
frameId = requestAnimationFrame(updateCoordinates);
return () => {
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseleave', handleMouseLeave);
cancelAnimationFrame(frameId);
};
}, []);
return (
<div
ref={containerRef}
style={{ width: '100%', height: '100%', position: 'relative', overflow: 'hidden' }}
>
<style dangerouslySetInnerHTML={{ __html: `
.kinetic-lissajous-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #050505;
overflow: hidden;
}
#canvas-kinetic-lissajous {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
display: block;
}
` }} />
{/* HTML Structure */}
<div
style={{ width: '100%', height: '100%' }}
dangerouslySetInnerHTML={{ __html: `
<div class="kinetic-lissajous-container">
<canvas id="canvas-kinetic-lissajous"></canvas>
</div>
<script>
(function() {
const canvas = document.getElementById('canvas-kinetic-lissajous');
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
let active = true;
let dpr = 1;
let width = 0;
let height = 0;
let targetMouseX = 0.5;
let targetMouseY = 0.5;
let mouseX = 0.5;
let mouseY = 0.5;
let phase = 0;
const pointsCount = 450;
function resize() {
const rect = canvas.parentNode ? canvas.parentNode.getBoundingClientRect() : null;
width = rect ? rect.width : window.innerWidth;
height = rect ? rect.height : window.innerHeight;
dpr = window.devicePixelRatio || 1;
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);
}
function handleMouseMove(e) {
const rect = canvas.getBoundingClientRect();
const currentWidth = rect.width || window.innerWidth;
const currentHeight = rect.height || window.innerHeight;
targetMouseX = Math.max(0, Math.min(1, (e.clientX - rect.left) / currentWidth));
targetMouseY = Math.max(0, Math.min(1, (e.clientY - rect.top) / currentHeight));
}
function handleTouchMove(e) {
if (e.touches.length === 0) return;
const rect = canvas.getBoundingClientRect();
const currentWidth = rect.width || window.innerWidth;
const currentHeight = rect.height || window.innerHeight;
targetMouseX = Math.max(0, Math.min(1, (e.touches[0].clientX - rect.left) / currentWidth));
targetMouseY = Math.max(0, Math.min(1, (e.touches[0].clientY - rect.top) / currentHeight));
}
function handleMouseLeave() {
targetMouseX = 0.5;
targetMouseY = 0.5;
}
function handleMessage(e) {
if (e.data) {
if (e.data.type === 'mousemove') {
targetMouseX = Math.max(0, Math.min(1, e.data.x / width));
targetMouseY = Math.max(0, Math.min(1, e.data.y / height));
} else if (e.data.type === 'mouseleave') {
targetMouseX = 0.5;
targetMouseY = 0.5;
}
}
}
window.addEventListener('resize', resize);
window.addEventListener('mousemove', handleMouseMove, { passive: true });
window.addEventListener('mouseleave', handleMouseLeave, { passive: true });
window.addEventListener('touchmove', handleTouchMove, { passive: true });
window.addEventListener('touchcancel', handleMouseLeave, { passive: true });
window.addEventListener('message', handleMessage);
resize();
ctx.fillStyle = '#050505';
ctx.fillRect(0, 0, width, height);
function animate() {
if (!active) return;
if (!canvas.isConnected) {
cleanup();
return;
}
mouseX += (targetMouseX - mouseX) * 0.08;
mouseY += (targetMouseY - mouseY) * 0.08;
ctx.fillStyle = 'rgba(5, 5, 5, 0.06)';
ctx.fillRect(0, 0, width, height);
phase += 0.006;
const centerX = width / 2;
const centerY = height / 2;
const maxRadius = Math.min(width, height) * 0.38;
ctx.shadowBlur = 12;
ctx.shadowColor = 'rgba(14, 165, 233, 0.35)';
ctx.lineWidth = 1.25;
const freqX = 1 + mouseX * 8.0;
const freqY = 1 + mouseY * 8.0;
ctx.beginPath();
for (let i = 0; i <= pointsCount; i++) {
const t = (i / pointsCount) * Math.PI * 2;
const x = centerX + Math.sin(t * freqX + phase) * Math.cos(t * 1.5) * maxRadius;
const y = centerY + Math.cos(t * freqY + phase) * Math.sin(t * 1.5) * maxRadius;
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
const gradient = ctx.createRadialGradient(centerX, centerY, 10, centerX, centerY, maxRadius);
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.85)');
gradient.addColorStop(0.5, 'rgba(56, 189, 248, 0.65)');
gradient.addColorStop(1, 'rgba(99, 102, 241, 0.1)');
ctx.strokeStyle = gradient;
ctx.stroke();
ctx.shadowBlur = 0;
requestAnimationFrame(animate);
}
function cleanup() {
active = false;
window.removeEventListener('resize', resize);
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseleave', handleMouseLeave);
window.removeEventListener('touchmove', handleTouchMove);
window.removeEventListener('touchcancel', handleMouseLeave);
window.removeEventListener('message', handleMessage);
}
requestAnimationFrame(animate);
})();
</script>
` }}
/>
</div>
);
}Next.js App Router Component (use client)
'use client';
import React, { useEffect, useRef } from 'react';
export default function KineticLissajousMatrixBackground() {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
let targetX = 0, targetY = 0;
let currentX = 0, currentY = 0;
let frameId: number;
const handleMouseMove = (e: MouseEvent) => {
targetX = (e.clientX / window.innerWidth) - 0.5;
targetY = (e.clientY / window.innerHeight) - 0.5;
};
const handleMouseLeave = () => {
targetX = 0;
targetY = 0;
};
window.addEventListener('mousemove', handleMouseMove);
window.addEventListener('mouseleave', handleMouseLeave);
const updateCoordinates = () => {
currentX += (targetX - currentX) * 0.08;
currentY += (targetY - currentY) * 0.08;
if (containerRef.current) {
containerRef.current.style.setProperty('--mouse-x', currentX.toFixed(4));
containerRef.current.style.setProperty('--mouse-y', currentY.toFixed(4));
}
frameId = requestAnimationFrame(updateCoordinates);
};
frameId = requestAnimationFrame(updateCoordinates);
return () => {
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseleave', handleMouseLeave);
cancelAnimationFrame(frameId);
};
}, []);
return (
<div
ref={containerRef}
className="w-full h-full relative overflow-hidden"
>
<style dangerouslySetInnerHTML={{ __html: `
.kinetic-lissajous-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #050505;
overflow: hidden;
}
#canvas-kinetic-lissajous {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
display: block;
}
` }} />
{/* HTML Structure */}
<div
className="w-full h-full"
dangerouslySetInnerHTML={{ __html: `
<div class="kinetic-lissajous-container">
<canvas id="canvas-kinetic-lissajous"></canvas>
</div>
<script>
(function() {
const canvas = document.getElementById('canvas-kinetic-lissajous');
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
let active = true;
let dpr = 1;
let width = 0;
let height = 0;
let targetMouseX = 0.5;
let targetMouseY = 0.5;
let mouseX = 0.5;
let mouseY = 0.5;
let phase = 0;
const pointsCount = 450;
function resize() {
const rect = canvas.parentNode ? canvas.parentNode.getBoundingClientRect() : null;
width = rect ? rect.width : window.innerWidth;
height = rect ? rect.height : window.innerHeight;
dpr = window.devicePixelRatio || 1;
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);
}
function handleMouseMove(e) {
const rect = canvas.getBoundingClientRect();
const currentWidth = rect.width || window.innerWidth;
const currentHeight = rect.height || window.innerHeight;
targetMouseX = Math.max(0, Math.min(1, (e.clientX - rect.left) / currentWidth));
targetMouseY = Math.max(0, Math.min(1, (e.clientY - rect.top) / currentHeight));
}
function handleTouchMove(e) {
if (e.touches.length === 0) return;
const rect = canvas.getBoundingClientRect();
const currentWidth = rect.width || window.innerWidth;
const currentHeight = rect.height || window.innerHeight;
targetMouseX = Math.max(0, Math.min(1, (e.touches[0].clientX - rect.left) / currentWidth));
targetMouseY = Math.max(0, Math.min(1, (e.touches[0].clientY - rect.top) / currentHeight));
}
function handleMouseLeave() {
targetMouseX = 0.5;
targetMouseY = 0.5;
}
function handleMessage(e) {
if (e.data) {
if (e.data.type === 'mousemove') {
targetMouseX = Math.max(0, Math.min(1, e.data.x / width));
targetMouseY = Math.max(0, Math.min(1, e.data.y / height));
} else if (e.data.type === 'mouseleave') {
targetMouseX = 0.5;
targetMouseY = 0.5;
}
}
}
window.addEventListener('resize', resize);
window.addEventListener('mousemove', handleMouseMove, { passive: true });
window.addEventListener('mouseleave', handleMouseLeave, { passive: true });
window.addEventListener('touchmove', handleTouchMove, { passive: true });
window.addEventListener('touchcancel', handleMouseLeave, { passive: true });
window.addEventListener('message', handleMessage);
resize();
ctx.fillStyle = '#050505';
ctx.fillRect(0, 0, width, height);
function animate() {
if (!active) return;
if (!canvas.isConnected) {
cleanup();
return;
}
mouseX += (targetMouseX - mouseX) * 0.08;
mouseY += (targetMouseY - mouseY) * 0.08;
ctx.fillStyle = 'rgba(5, 5, 5, 0.06)';
ctx.fillRect(0, 0, width, height);
phase += 0.006;
const centerX = width / 2;
const centerY = height / 2;
const maxRadius = Math.min(width, height) * 0.38;
ctx.shadowBlur = 12;
ctx.shadowColor = 'rgba(14, 165, 233, 0.35)';
ctx.lineWidth = 1.25;
const freqX = 1 + mouseX * 8.0;
const freqY = 1 + mouseY * 8.0;
ctx.beginPath();
for (let i = 0; i <= pointsCount; i++) {
const t = (i / pointsCount) * Math.PI * 2;
const x = centerX + Math.sin(t * freqX + phase) * Math.cos(t * 1.5) * maxRadius;
const y = centerY + Math.cos(t * freqY + phase) * Math.sin(t * 1.5) * maxRadius;
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
const gradient = ctx.createRadialGradient(centerX, centerY, 10, centerX, centerY, maxRadius);
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.85)');
gradient.addColorStop(0.5, 'rgba(56, 189, 248, 0.65)');
gradient.addColorStop(1, 'rgba(99, 102, 241, 0.1)');
ctx.strokeStyle = gradient;
ctx.stroke();
ctx.shadowBlur = 0;
requestAnimationFrame(animate);
}
function cleanup() {
active = false;
window.removeEventListener('resize', resize);
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseleave', handleMouseLeave);
window.removeEventListener('touchmove', handleTouchMove);
window.removeEventListener('touchcancel', handleMouseLeave);
window.removeEventListener('message', handleMessage);
}
requestAnimationFrame(animate);
})();
</script>
` }}
/>
</div>
);
}Raw CSS Stylesheet Snippet
.kinetic-lissajous-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #050505;
overflow: hidden;
}
#canvas-kinetic-lissajous {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
display: block;
}