lightswind
Version:
A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.
141 lines • 5.94 kB
JavaScript
;
"use client";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SparkleCursor = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const gsap_1 = __importDefault(require("gsap"));
const SparkleCursor = ({ distance = 50, glow = true }) => {
const canvasRef = (0, react_1.useRef)(null);
(0, react_1.useEffect)(() => {
const canvas = canvasRef.current;
if (!canvas)
return;
const ctx = canvas.getContext("2d");
if (!ctx)
return;
// Handle resize
const resize = () => {
canvas.width = window.innerWidth * window.devicePixelRatio;
canvas.height = window.innerHeight * window.devicePixelRatio;
};
resize();
window.addEventListener("resize", resize);
// SVG Star
const svgData = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="hsl(40 90% 80%)">
<path fill-rule="evenodd" d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z" clip-rule="evenodd" />
</svg>
`;
const img = new Image();
const svgBlob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });
const url = URL.createObjectURL(svgBlob);
img.onload = () => {
URL.revokeObjectURL(url);
};
img.src = url;
let parts = [];
let glows = [];
const render = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (const g of glows) {
ctx.beginPath();
ctx.arc(g.x, g.y, g.size * g.scale, 0, Math.PI * 2);
ctx.fillStyle = "hsl(265 90% 80% / 0.2)";
ctx.fill();
}
for (const part of parts) {
ctx.save();
ctx.globalAlpha = part.alpha;
ctx.filter = `brightness(${part.sy < 0 ? part.b + 0.5 : part.b})`;
// Scale coordinates for devicePixelRatio
const x = part.x * window.devicePixelRatio;
const y = part.y * window.devicePixelRatio;
ctx.translate(x, y);
ctx.rotate(part.r * (Math.PI / 180));
ctx.scale(1, part.sy);
const size = part.size * part.scale * window.devicePixelRatio;
ctx.drawImage(img, size * -0.5, size * -0.5, size, size);
ctx.restore();
}
};
let distCounter = 0;
let lastPoint = null;
const paint = (e) => {
const x = e.clientX;
const y = e.clientY;
if (lastPoint) {
const dist = Math.hypot(x - lastPoint[0], y - lastPoint[1]);
if (!Number.isNaN(dist))
distCounter += dist;
}
lastPoint = [x, y];
if (glow) {
const g = {
id: `glow--${Date.now()}-${Math.random()}`,
size: 30,
scale: 1,
x: x * window.devicePixelRatio,
y: y * window.devicePixelRatio,
};
gsap_1.default.to(g, {
duration: 0.2,
scale: 0,
onComplete: () => {
glows = glows.filter((glow) => glow.id !== g.id);
},
});
glows.push(g);
}
if (distCounter >= distance) {
distCounter = 0;
const newPart = {
id: Date.now() + Math.random(),
x,
y,
sy: Math.random() > 0.5 ? 1 : -1,
b: gsap_1.default.utils.random(0.5, 1.5),
r: gsap_1.default.utils.random(0, 359, 1),
hue: gsap_1.default.utils.random(0, 359, 1),
size: gsap_1.default.utils.random(10, 40, 1),
scale: 1,
alpha: 1,
};
const spin = gsap_1.default.to(newPart, {
sy: newPart.sy < 0 ? 1 : -1,
duration: gsap_1.default.utils.random(0.1, 0.5),
repeat: gsap_1.default.utils.random(0, 10, 1),
});
gsap_1.default.to(newPart, {
duration: gsap_1.default.utils.random(0.5, 2.5),
r: newPart.r + gsap_1.default.utils.random(-45, 45, 1),
y: y + gsap_1.default.utils.random(50, 350, 1),
alpha: 0,
scale: 0,
onComplete: () => {
spin.kill();
parts = parts.filter((p) => p.id !== newPart.id);
},
});
parts.push(newPart);
}
};
window.addEventListener("pointermove", paint);
gsap_1.default.ticker.add(render);
return () => {
window.removeEventListener("resize", resize);
window.removeEventListener("pointermove", paint);
gsap_1.default.ticker.remove(render);
};
}, [distance, glow]);
return ((0, jsx_runtime_1.jsx)("canvas", { ref: canvasRef, className: "fixed inset-0 pointer-events-none z-[9999]", style: {
width: "100vw",
height: "100vh",
} }));
};
exports.SparkleCursor = SparkleCursor;
exports.default = exports.SparkleCursor;
//# sourceMappingURL=SparkleCursor.js.map