feat: Add Magic UI components including DotPattern, RainbowButton, ShineBorder, WordRotate, and BlurIn, along with corresponding Tailwind configuration updates.
This commit is contained in:
120
components/hero-shader.tsx
Normal file
120
components/hero-shader.tsx
Normal file
@@ -0,0 +1,120 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
export function HeroShader() {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = canvasRef.current;
|
||||
if (!canvas) return;
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (!ctx) return;
|
||||
|
||||
let t = 0;
|
||||
let animationFrameId: number;
|
||||
|
||||
const resize = () => {
|
||||
canvas.width = canvas.offsetWidth;
|
||||
canvas.height = canvas.offsetHeight;
|
||||
};
|
||||
resize();
|
||||
window.addEventListener("resize", resize);
|
||||
|
||||
const draw = () => {
|
||||
// Clear canvas with some transparency for trails?
|
||||
// Or just clear completely given the math looks like it redraws?
|
||||
// Tweet says background(9), which is very dark.
|
||||
// Tweetcarts usually redraw fully or rely on trails.
|
||||
// Given complexity, let's clear fully first.
|
||||
ctx.fillStyle = "#090909"; // background(9) approximation
|
||||
// ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Actually, let's make it transparent so it blends with our site
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
ctx.fillStyle = "rgba(255, 255, 255, 0.5)"; // stroke(w, 116) approx white with alpha
|
||||
|
||||
// Center of drawing - offset to the right
|
||||
const cx = canvas.width * 0.75;
|
||||
const cy = canvas.height / 2;
|
||||
|
||||
// Loop for points
|
||||
// for(t+=PI/90,i=1e4;i--;)a()
|
||||
t += Math.PI / 90;
|
||||
|
||||
for (let i = 10000; i > 0; i--) {
|
||||
// y = i / 790
|
||||
let y = i / 790;
|
||||
|
||||
// k = (y<8 ? 9+sin(y^9)*6 : 4+cos(y)) * cos(i+t/4)
|
||||
// Note: processing sin(y^9) is bitwise XOR in JS, but usually in math it's power?
|
||||
// "y^9" in many tweetcarts (JS) is XOR if it's straight JS evaluation,
|
||||
// but if it's GLSL it might mean pow.
|
||||
// Given "tweetcart", it's likely JS/Processing, where ^ is XOR in standard JS but often used as Pow in math context?
|
||||
// Processing language: ^ is bitwise XOR. pow(n, e) is power.
|
||||
// Let's assume XOR as it's common in condensed code.
|
||||
// Wait, standard JS `^` is XOR.
|
||||
let k_term1 = (y < 8)
|
||||
? (9 + Math.sin(y ** 9) * 6) // Trying Power first as it produces curves
|
||||
: (4 + Math.cos(y));
|
||||
|
||||
// Wait, dweet/tweetcart usually use JS syntax.
|
||||
// Let's try to replicate exact syntax logic.
|
||||
// Logic: k = (condition) * cos(i + t/4)
|
||||
|
||||
// Re-evaluating y^9. If y is float, XOR converts to int.
|
||||
// y = i / 790, which is float.
|
||||
// Let's stick to Math.pow for smoother graphs if intended.
|
||||
// But let's try standard JS behavior for ^ (XOR) might be intended for glitchy look?
|
||||
// Let's try power first.
|
||||
|
||||
const k = ((y < 8) ? (9 + Math.sin(Math.pow(y, 9)) * 6) : (4 + Math.cos(y))) * Math.cos(i + t / 4);
|
||||
|
||||
// e = y/3 - 13 + cos(e ?? no, that was likely comma operator)
|
||||
// Original: d=mag(k=(...), e=y/3-13) + cos(e+t*2+i%2*4)
|
||||
// mag(a, b) = sqrt(a*a + b*b)
|
||||
// So args to mag are k and e.
|
||||
const e = y / 3 - 13;
|
||||
|
||||
const mag_ke = Math.sqrt(k * k + e * e);
|
||||
|
||||
// d = mag(...) + cos(e + t*2 + i%2*4)
|
||||
const d = mag_ke + Math.cos(e + t * 2 + (i % 2) * 4);
|
||||
|
||||
// c = d/4 - t/2 + i%2*3
|
||||
const c = d / 4 - t / 2 + (i % 2) * 3;
|
||||
|
||||
// q = y * k / 5 * (2 + sin(d*2 + y - t*4)) + 80
|
||||
const q = y * k / 5 * (2 + Math.sin(d * 2 + y - t * 4)) + 80;
|
||||
|
||||
// x = q * cos(c) + 200
|
||||
// y_out = q * sin(c) + d * 9 + 60
|
||||
// 200 and 60 are likely offsets for 400x400 canvas.
|
||||
// We should center it.
|
||||
|
||||
const x = (q * Math.cos(c)) + cx;
|
||||
const y_out = (q * Math.sin(c) + d * 9) + cy;
|
||||
|
||||
ctx.fillRect(x, y_out, 1.5, 1.5);
|
||||
}
|
||||
|
||||
animationFrameId = requestAnimationFrame(draw);
|
||||
};
|
||||
|
||||
draw();
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", resize);
|
||||
cancelAnimationFrame(animationFrameId);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
className="absolute inset-0 h-full w-full opacity-60 mix-blend-screen pointer-events-none"
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user