abersbail's picture
Deploy React 10 high level animations
76e35d6 verified
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>React 10 High Level Animations</title>
<style>
:root {
--bg: #070912;
--panel: rgba(15, 19, 34, 0.82);
--panel-solid: #111624;
--ink: #f8fafc;
--muted: #a6b0c3;
--line: rgba(255, 255, 255, 0.14);
--accent: #7dd3fc;
--accent-2: #fb7185;
--gold: #facc15;
}
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
min-height: 100%;
background: var(--bg);
color: var(--ink);
font-family: Inter, Arial, Helvetica, sans-serif;
overflow-x: hidden;
}
button,
input {
font: inherit;
}
#root {
min-height: 100vh;
}
.shell {
min-height: 100vh;
display: grid;
grid-template-columns: 318px 1fr;
background:
radial-gradient(circle at 20% 10%, rgba(125, 211, 252, 0.16), transparent 34%),
radial-gradient(circle at 80% 80%, rgba(251, 113, 133, 0.14), transparent 32%),
#070912;
}
.sidebar {
position: sticky;
top: 0;
height: 100vh;
border-right: 1px solid var(--line);
background: rgba(8, 11, 20, 0.94);
backdrop-filter: blur(14px);
overflow: auto;
z-index: 4;
}
.brand {
padding: 22px 18px 16px;
border-bottom: 1px solid var(--line);
}
h1 {
margin: 0 0 8px;
font-size: 30px;
line-height: 1;
}
p {
margin: 0;
color: var(--muted);
line-height: 1.5;
font-size: 14px;
}
.nav {
padding: 12px;
}
.nav button {
display: grid;
grid-template-columns: 36px 1fr;
gap: 10px;
width: 100%;
min-height: 68px;
margin-bottom: 8px;
border: 1px solid var(--line);
border-radius: 8px;
padding: 10px;
color: var(--ink);
background: rgba(255, 255, 255, 0.04);
cursor: pointer;
text-align: left;
}
.nav button:hover,
.nav button.active {
border-color: var(--accent);
background: rgba(125, 211, 252, 0.12);
}
.badge {
display: grid;
place-items: center;
width: 36px;
height: 36px;
border-radius: 8px;
background: linear-gradient(135deg, var(--accent), var(--accent-2));
color: #06111c;
font-weight: 900;
}
.nav strong,
.nav span {
display: block;
}
.nav strong {
margin-bottom: 5px;
font-size: 14px;
line-height: 1.2;
}
.nav span {
color: var(--muted);
font-size: 12px;
line-height: 1.35;
}
.stage-wrap {
min-width: 0;
padding: 22px;
}
.topbar {
display: grid;
grid-template-columns: 1fr auto;
gap: 16px;
align-items: end;
margin-bottom: 16px;
}
h2 {
margin: 0 0 7px;
font-size: clamp(30px, 5vw, 54px);
line-height: 0.95;
}
.controls {
display: flex;
gap: 10px;
align-items: center;
border: 1px solid var(--line);
border-radius: 8px;
padding: 10px 12px;
background: var(--panel);
}
.controls label {
color: var(--muted);
font-size: 12px;
text-transform: uppercase;
}
input[type="range"] {
accent-color: var(--accent);
}
.stage {
position: relative;
min-height: 620px;
border: 1px solid var(--line);
border-radius: 8px;
background:
linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px),
linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
rgba(10, 14, 25, 0.82);
background-size: 36px 36px;
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.34);
overflow: hidden;
}
.demo {
position: absolute;
inset: 0;
display: grid;
place-items: center;
padding: 24px;
}
.caption {
position: absolute;
left: 16px;
bottom: 16px;
max-width: min(620px, calc(100% - 32px));
border: 1px solid var(--line);
border-radius: 8px;
padding: 12px 14px;
background: rgba(7, 9, 18, 0.76);
color: var(--muted);
backdrop-filter: blur(10px);
}
.mobile-select {
display: none;
width: 100%;
height: 44px;
margin-bottom: 12px;
border: 1px solid var(--line);
border-radius: 8px;
padding: 0 12px;
color: var(--ink);
background: var(--panel-solid);
}
.particle-canvas {
width: min(760px, 92vw);
height: min(470px, 62vh);
border: 1px solid var(--line);
border-radius: 8px;
background: radial-gradient(circle at center, rgba(56, 189, 248, 0.13), rgba(3, 7, 18, 0.82));
}
.blob-scene {
position: relative;
width: min(760px, 86vw);
height: 440px;
filter: contrast(1.16) saturate(1.2);
}
.liquid-blob {
position: absolute;
border-radius: 48% 52% 42% 58% / 58% 41% 59% 42%;
background: radial-gradient(circle at 28% 24%, #fff, var(--color), transparent 72%);
mix-blend-mode: screen;
filter: blur(2px);
animation: liquid var(--speed) ease-in-out infinite alternate;
}
.liquid-blob:nth-child(1) { width: 240px; height: 240px; left: 12%; top: 18%; --color: #22d3ee; --speed: 5s; }
.liquid-blob:nth-child(2) { width: 300px; height: 300px; left: 36%; top: 8%; --color: #fb7185; --speed: 6.2s; animation-delay: -1.2s; }
.liquid-blob:nth-child(3) { width: 210px; height: 210px; left: 56%; top: 40%; --color: #a78bfa; --speed: 4.4s; animation-delay: -2s; }
@keyframes liquid {
to {
transform: translate(42px, -24px) rotate(55deg) scale(1.16);
border-radius: 57% 43% 63% 37% / 34% 57% 43% 66%;
}
}
.carousel {
position: relative;
width: 420px;
height: 420px;
transform-style: preserve-3d;
animation: carousel-spin calc(14s / var(--speed-factor)) linear infinite;
}
.card3d {
position: absolute;
left: 120px;
top: 108px;
width: 180px;
height: 220px;
border: 1px solid var(--line);
border-radius: 8px;
background: linear-gradient(145deg, rgba(125, 211, 252, 0.88), rgba(251, 113, 133, 0.82));
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.38);
transform: rotateY(calc(var(--i) * 45deg)) translateZ(280px);
display: grid;
place-items: center;
font-size: 44px;
font-weight: 900;
color: #07111c;
}
@keyframes carousel-spin {
to { transform: rotateY(360deg) rotateX(8deg); }
}
.tunnel {
position: relative;
width: 520px;
height: 520px;
transform-style: preserve-3d;
perspective: 700px;
}
.tunnel-ring {
position: absolute;
inset: 50%;
width: 280px;
height: 280px;
margin: -140px;
border: 2px solid hsl(calc(var(--i) * 28), 90%, 66%);
border-radius: 18px;
transform: translateZ(calc(var(--i) * -70px)) rotateZ(calc(var(--i) * 13deg));
animation: tunnel calc(2.4s / var(--speed-factor)) linear infinite;
animation-delay: calc(var(--i) * -0.13s);
}
@keyframes tunnel {
from { opacity: 0; transform: translateZ(-900px) rotateZ(0deg) scale(0.2); }
35% { opacity: 1; }
to { opacity: 0; transform: translateZ(220px) rotateZ(120deg) scale(1.8); }
}
.hologram {
position: relative;
width: 430px;
height: 430px;
display: grid;
place-items: center;
}
.holo-core {
width: 190px;
height: 190px;
border-radius: 50%;
background:
radial-gradient(circle at 35% 25%, #fff, rgba(125, 211, 252, 0.85) 25%, rgba(59, 130, 246, 0.18) 58%, transparent 70%);
box-shadow: 0 0 60px rgba(125, 211, 252, 0.55);
animation: pulse calc(2.4s / var(--speed-factor)) ease-in-out infinite;
}
.holo-ring {
position: absolute;
width: calc(150px + var(--i) * 62px);
height: calc(150px + var(--i) * 62px);
border: 2px dashed rgba(125, 211, 252, 0.72);
border-radius: 50%;
transform: rotateX(64deg) rotateZ(calc(var(--i) * 24deg));
animation: orbit calc((4s + var(--i) * .7s) / var(--speed-factor)) linear infinite;
}
@keyframes pulse {
50% { transform: scale(1.08); filter: brightness(1.35); }
}
@keyframes orbit {
to { transform: rotateX(64deg) rotateZ(360deg); }
}
.type-stack {
display: grid;
gap: 8px;
text-align: center;
font-size: clamp(42px, 9vw, 112px);
font-weight: 900;
line-height: 0.86;
text-transform: uppercase;
}
.type-stack span {
display: block;
background: linear-gradient(90deg, #7dd3fc, #fb7185, #facc15, #7dd3fc);
background-size: 280% 100%;
color: transparent;
-webkit-background-clip: text;
background-clip: text;
animation: text-wave calc(2.2s / var(--speed-factor)) ease-in-out infinite;
animation-delay: calc(var(--i) * .18s);
}
@keyframes text-wave {
0%, 100% { transform: translateX(-20px) skewX(-8deg); background-position: 0% 50%; }
50% { transform: translateX(20px) skewX(8deg); background-position: 100% 50%; }
}
.magnet-field {
position: relative;
width: min(760px, 90vw);
height: 430px;
}
.magnet-dot {
position: absolute;
left: calc(var(--x) * 1%);
top: calc(var(--y) * 1%);
width: 38px;
height: 38px;
border-radius: 50%;
background: radial-gradient(circle at 30% 25%, #fff, var(--accent));
transform: translate(calc(var(--mx) * 1px), calc(var(--my) * 1px)) scale(var(--scale));
box-shadow: 0 0 26px rgba(125, 211, 252, 0.45);
transition: transform 120ms linear;
}
.aurora {
position: relative;
width: min(820px, 92vw);
height: 440px;
overflow: hidden;
border-radius: 8px;
background: #020617;
}
.aurora-band {
position: absolute;
left: -12%;
width: 125%;
height: 170px;
border-radius: 50%;
filter: blur(22px);
opacity: .78;
mix-blend-mode: screen;
animation: aurora calc(var(--duration) / var(--speed-factor)) ease-in-out infinite alternate;
}
.aurora-band:nth-child(1) { top: 60px; background: #22d3ee; --duration: 4.5s; }
.aurora-band:nth-child(2) { top: 150px; background: #a78bfa; --duration: 6s; animation-delay: -1s; }
.aurora-band:nth-child(3) { top: 230px; background: #fb7185; --duration: 5.2s; animation-delay: -2s; }
@keyframes aurora {
to { transform: translateY(-48px) skewY(-8deg) scaleX(1.08); }
}
.scanner {
position: relative;
width: min(760px, 90vw);
height: 430px;
border: 1px solid rgba(34, 211, 238, 0.4);
background:
linear-gradient(90deg, rgba(34, 211, 238, 0.13) 1px, transparent 1px),
linear-gradient(rgba(34, 211, 238, 0.13) 1px, transparent 1px),
radial-gradient(circle at center, rgba(34, 211, 238, 0.12), #020617 70%);
background-size: 32px 32px, 32px 32px, auto;
overflow: hidden;
}
.scan-line {
position: absolute;
inset: 0 auto 0 0;
width: 90px;
background: linear-gradient(90deg, transparent, rgba(34, 211, 238, 0.7), transparent);
animation: scan calc(2.3s / var(--speed-factor)) linear infinite;
}
.scan-target {
position: absolute;
left: calc(var(--x) * 1%);
top: calc(var(--y) * 1%);
width: 46px;
height: 46px;
border: 2px solid #22d3ee;
border-radius: 8px;
transform: rotate(45deg);
animation: blink calc((1.1s + var(--i) * .2s) / var(--speed-factor)) infinite alternate;
}
@keyframes scan {
to { transform: translateX(820px); }
}
@keyframes blink {
to { opacity: .25; transform: rotate(45deg) scale(.72); }
}
.timeline {
display: flex;
align-items: center;
gap: clamp(8px, 2vw, 22px);
width: min(860px, 92vw);
justify-content: center;
}
.time-node {
position: relative;
width: clamp(54px, 9vw, 86px);
height: clamp(54px, 9vw, 86px);
border: 1px solid var(--line);
border-radius: 50%;
background: rgba(255, 255, 255, 0.06);
display: grid;
place-items: center;
color: var(--muted);
font-weight: 900;
transition: 360ms ease;
}
.time-node.active {
color: #07111c;
background: var(--gold);
box-shadow: 0 0 42px rgba(250, 204, 21, 0.5);
transform: translateY(-22px) scale(1.13);
}
.time-node:after {
content: "";
position: absolute;
left: 100%;
width: clamp(8px, 2vw, 22px);
height: 2px;
background: var(--line);
}
.time-node:last-child:after {
display: none;
}
.energy-mesh {
position: relative;
width: min(720px, 90vw);
height: 430px;
display: grid;
place-items: center;
}
.mesh-cell {
position: absolute;
width: 110px;
height: 110px;
border: 1px solid rgba(125, 211, 252, 0.45);
border-radius: 28px;
transform: rotate(calc(var(--i) * 18deg)) translateY(calc(var(--i) * 9px));
animation: mesh calc((2.4s + var(--i) * .15s) / var(--speed-factor)) ease-in-out infinite alternate;
box-shadow: inset 0 0 30px rgba(125, 211, 252, 0.12), 0 0 28px rgba(251, 113, 133, 0.12);
}
@keyframes mesh {
to {
width: 360px;
height: 360px;
border-radius: 50%;
transform: rotate(calc(var(--i) * 38deg)) translateY(calc(var(--i) * -4px));
}
}
@media (max-width: 860px) {
.shell {
display: block;
}
.sidebar {
display: none;
}
.stage-wrap {
padding: 14px;
}
.topbar {
grid-template-columns: 1fr;
}
.mobile-select {
display: block;
}
.stage {
min-height: 570px;
}
.controls {
width: fit-content;
}
}
</style>
</head>
<body>
<div id="root"></div>
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<script>
const h = React.createElement;
const { useEffect, useMemo, useRef, useState } = React;
const demos = [
{ name: "Quantum Particle Field", label: "Canvas particle network with depth drift.", key: "particles" },
{ name: "Liquid Morph System", label: "Metaball-style blobs with fluid morphing.", key: "liquid" },
{ name: "3D Card Orbit", label: "Perspective carousel with layered glass cards.", key: "cards" },
{ name: "Neon Warp Tunnel", label: "Fast depth tunnel made from animated geometry.", key: "tunnel" },
{ name: "Hologram Core", label: "Orbital rings around a pulsing digital planet.", key: "holo" },
{ name: "Kinetic Typography", label: "Large animated headline with gradient motion.", key: "type" },
{ name: "Magnetic Particle Board", label: "Pointer-reactive dots pulled by cursor gravity.", key: "magnet" },
{ name: "Aurora Wave Layers", label: "Soft color fields moving at layered speeds.", key: "aurora" },
{ name: "Cyber Scanner Grid", label: "Scanning beam with tracked targets.", key: "scanner" },
{ name: "Reactive Timeline Orbs", label: "Autoplay sequence with animated state changes.", key: "timeline" }
];
function ParticleField({ speed }) {
const ref = useRef(null);
useEffect(() => {
const canvas = ref.current;
const context = canvas.getContext("2d");
let raf = 0;
let width = 0;
let height = 0;
const particles = Array.from({ length: 95 }, () => ({
x: Math.random(),
y: Math.random(),
vx: (Math.random() - 0.5) * 0.0014,
vy: (Math.random() - 0.5) * 0.0014,
r: 1.4 + Math.random() * 2.7
}));
function resize() {
const rect = canvas.getBoundingClientRect();
width = Math.max(1, Math.floor(rect.width * devicePixelRatio));
height = Math.max(1, Math.floor(rect.height * devicePixelRatio));
canvas.width = width;
canvas.height = height;
}
function draw() {
context.clearRect(0, 0, width, height);
context.fillStyle = "rgba(3, 7, 18, 0.24)";
context.fillRect(0, 0, width, height);
for (const particle of particles) {
particle.x += particle.vx * speed;
particle.y += particle.vy * speed;
if (particle.x < 0 || particle.x > 1) particle.vx *= -1;
if (particle.y < 0 || particle.y > 1) particle.vy *= -1;
}
for (let i = 0; i < particles.length; i += 1) {
for (let j = i + 1; j < particles.length; j += 1) {
const a = particles[i];
const b = particles[j];
const dx = (a.x - b.x) * width;
const dy = (a.y - b.y) * height;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 116) {
context.strokeStyle = `rgba(125, 211, 252, ${1 - dist / 116})`;
context.lineWidth = devicePixelRatio;
context.beginPath();
context.moveTo(a.x * width, a.y * height);
context.lineTo(b.x * width, b.y * height);
context.stroke();
}
}
}
for (const particle of particles) {
const gradient = context.createRadialGradient(
particle.x * width, particle.y * height, 0,
particle.x * width, particle.y * height, particle.r * 6 * devicePixelRatio
);
gradient.addColorStop(0, "rgba(255,255,255,.95)");
gradient.addColorStop(0.36, "rgba(125,211,252,.8)");
gradient.addColorStop(1, "rgba(125,211,252,0)");
context.fillStyle = gradient;
context.beginPath();
context.arc(particle.x * width, particle.y * height, particle.r * devicePixelRatio, 0, Math.PI * 2);
context.fill();
}
raf = requestAnimationFrame(draw);
}
resize();
draw();
window.addEventListener("resize", resize);
return () => {
cancelAnimationFrame(raf);
window.removeEventListener("resize", resize);
};
}, [speed]);
return h("canvas", { className: "particle-canvas", ref });
}
function LiquidMorph() {
return h("div", { className: "blob-scene" },
h("div", { className: "liquid-blob" }),
h("div", { className: "liquid-blob" }),
h("div", { className: "liquid-blob" })
);
}
function CardOrbit() {
return h("div", { className: "carousel" },
Array.from({ length: 8 }, (_, index) =>
h("div", { className: "card3d", style: { "--i": index }, key: index }, String(index + 1).padStart(2, "0"))
)
);
}
function NeonTunnel() {
return h("div", { className: "tunnel" },
Array.from({ length: 15 }, (_, index) =>
h("div", { className: "tunnel-ring", style: { "--i": index }, key: index })
)
);
}
function HologramCore() {
return h("div", { className: "hologram" },
h("div", { className: "holo-core" }),
Array.from({ length: 5 }, (_, index) =>
h("div", { className: "holo-ring", style: { "--i": index + 1 }, key: index })
)
);
}
function KineticType() {
return h("div", { className: "type-stack" },
["REACT", "MOTION", "SYSTEM"].map((word, index) =>
h("span", { style: { "--i": index }, key: word }, word)
)
);
}
function MagneticBoard() {
const [pos, setPos] = useState({ x: 50, y: 50 });
const dots = useMemo(() => Array.from({ length: 42 }, () => ({
x: 8 + Math.random() * 84,
y: 8 + Math.random() * 84
})), []);
return h("div", {
className: "magnet-field",
onPointerMove: (event) => {
const rect = event.currentTarget.getBoundingClientRect();
setPos({ x: ((event.clientX - rect.left) / rect.width) * 100, y: ((event.clientY - rect.top) / rect.height) * 100 });
}
},
dots.map((dot, index) => {
const dx = pos.x - dot.x;
const dy = pos.y - dot.y;
const dist = Math.max(12, Math.sqrt(dx * dx + dy * dy));
const pull = Math.max(0, 1 - dist / 45);
return h("span", {
className: "magnet-dot",
key: index,
style: {
"--x": dot.x,
"--y": dot.y,
"--mx": dx * pull * 0.46,
"--my": dy * pull * 0.46,
"--scale": 0.76 + pull * 1.05
}
});
})
);
}
function AuroraWaves() {
return h("div", { className: "aurora" },
h("div", { className: "aurora-band" }),
h("div", { className: "aurora-band" }),
h("div", { className: "aurora-band" })
);
}
function CyberScanner() {
const targets = [
[18, 24], [34, 58], [54, 34], [73, 68], [82, 22], [14, 75]
];
return h("div", { className: "scanner" },
h("div", { className: "scan-line" }),
targets.map(([x, y], index) =>
h("span", { className: "scan-target", style: { "--x": x, "--y": y, "--i": index }, key: index })
)
);
}
function TimelineOrbs({ speed }) {
const [active, setActive] = useState(0);
useEffect(() => {
const interval = setInterval(() => setActive((value) => (value + 1) % 8), 900 / speed);
return () => clearInterval(interval);
}, [speed]);
return h("div", { className: "timeline" },
Array.from({ length: 8 }, (_, index) =>
h("div", { className: `time-node${active === index ? " active" : ""}`, key: index }, index + 1)
)
);
}
function EnergyMesh() {
return h("div", { className: "energy-mesh" },
Array.from({ length: 14 }, (_, index) =>
h("span", { className: "mesh-cell", style: { "--i": index }, key: index })
)
);
}
const demoMap = {
particles: ParticleField,
liquid: LiquidMorph,
cards: CardOrbit,
tunnel: NeonTunnel,
holo: HologramCore,
type: KineticType,
magnet: MagneticBoard,
aurora: AuroraWaves,
scanner: CyberScanner,
timeline: TimelineOrbs,
mesh: EnergyMesh
};
function App() {
const [active, setActive] = useState(0);
const [speed, setSpeed] = useState(1.15);
const current = demos[active];
const Demo = demoMap[current.key];
return h("div", { className: "shell", style: { "--speed-factor": speed } },
h("aside", { className: "sidebar" },
h("div", { className: "brand" },
h("h1", null, "React 10 High Level Animations"),
h("p", null, "Interactive motion demos built with React state, CSS animation, canvas, and pointer input.")
),
h("nav", { className: "nav" },
demos.map((demo, index) =>
h("button", {
className: active === index ? "active" : "",
type: "button",
onClick: () => setActive(index),
key: demo.name
},
h("span", { className: "badge" }, String(index + 1).padStart(2, "0")),
h("span", null, h("strong", null, demo.name), h("span", null, demo.label))
)
)
)
),
h("main", { className: "stage-wrap" },
h("select", {
className: "mobile-select",
value: active,
onChange: (event) => setActive(Number(event.target.value))
},
demos.map((demo, index) => h("option", { value: index, key: demo.name }, `${index + 1}. ${demo.name}`))
),
h("section", { className: "topbar" },
h("div", null, h("h2", null, current.name), h("p", null, current.label)),
h("div", { className: "controls" },
h("label", { htmlFor: "speed" }, "Speed"),
h("input", {
id: "speed",
type: "range",
min: "0.5",
max: "2",
step: "0.05",
value: speed,
onChange: (event) => setSpeed(Number(event.target.value))
})
)
),
h("section", { className: "stage" },
h("div", { className: "demo" }, h(Demo, { speed })),
h("div", { className: "caption" }, "React controls the selected demo, animation speed, pointer state, and canvas lifecycle. CSS and canvas handle the high-frequency motion.")
)
)
);
}
ReactDOM.createRoot(document.getElementById("root")).render(h(App));
</script>
</body>
</html>