@fluritheme/spider
Version:
A tiny, expressive spider for your website. Delicate webs that follow DOM layers, blinking eyes, and playful pointer reactions.
54 lines • 2.01 kB
JavaScript
export const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
export function intersect(a, b) {
const x = Math.max(a.x, b.x), y = Math.max(a.y, b.y);
return {
x,
y,
width: Math.max(0, Math.min(a.x + a.width, b.x + b.width) - x),
height: Math.max(0, Math.min(a.y + a.height, b.y + b.height) - y),
};
}
export function cornerPoint(box, corner, x, y) {
return {
x: box.x + (corner.endsWith('right') ? box.width - x : x),
y: box.y + (corner.startsWith('bottom') ? box.height - y : y),
};
}
/** Fan geometry with tensioned, gently scalloped cross threads. */
export function webLines(span) {
const count = 7;
const rays = Array.from({ length: count }, (_, i) => ({
x: span * Math.cos(((i / (count - 1)) * Math.PI) / 2),
y: span * Math.sin(((i / (count - 1)) * Math.PI) / 2),
}));
const lines = rays.map((p) => [{ x: 0, y: 0 }, p]);
for (let ring = 1; ring <= 7; ring++) {
const radius = ring / 7;
for (let i = 0; i < count - 1; i++) {
const a = rays[i], b = rays[i + 1];
const points = [];
for (let j = 0; j <= 8; j++) {
const t = j / 8, sag = 1 - Math.sin(t * Math.PI) * 0.045;
points.push({
x: (a.x * (1 - t) + b.x * t) * radius * sag,
y: (a.y * (1 - t) + b.y * t) * radius * sag,
});
}
lines.push(points);
}
}
return lines;
}
export function escapeOffset(home, pointer, radius) {
const dx = home.x - pointer.x, dy = home.y - pointer.y;
const distance = Math.hypot(dx, dy);
const force = radius > 0 ? clamp(1 - distance / radius, 0, 1) : 0;
if (force === 0)
return { x: 0, y: 0, scared: false };
return {
x: (dx / (distance || 1)) * force * 78,
y: (distance ? dy / distance : -1) * force * 78,
scared: force > 0,
};
}
//# sourceMappingURL=geometry.js.map