function Doodle({ src, style }) { return ; } function ContactSplit() { const canvasRef = React.useRef(null); const doodleRefs = React.useRef([]); const [form, setForm] = React.useState({ name: "", company: "", website: "", email: "", phone: "", details: "" }); const [sent, setSent] = React.useState(false); const [sending, setSending] = React.useState(false); const [error, setError] = React.useState(""); const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value })); React.useEffect(() => { const canvas = canvasRef.current, section = canvas.parentElement; const ctx = canvas.getContext("2d"); let w, h, particles, mouse = { x: -9999, y: -9999 }, mx = 0, my = 0; const colors = ["217,119,6", "245,158,11", "251,191,36", "255,255,255"]; const spriteSize = 64, spriteR = spriteSize / 2; const sprites = {}; colors.forEach((c) => { const s = document.createElement("canvas"); s.width = spriteSize; s.height = spriteSize; const sctx = s.getContext("2d"); const grad = sctx.createRadialGradient(spriteR, spriteR, 0, spriteR, spriteR, spriteR); grad.addColorStop(0, `rgba(${c},1)`); grad.addColorStop(1, `rgba(${c},0)`); sctx.fillStyle = grad; sctx.beginPath(); sctx.arc(spriteR, spriteR, spriteR, 0, Math.PI * 2); sctx.fill(); sprites[c] = s; }); function resize() { w = canvas.width = section.offsetWidth; h = canvas.height = section.offsetHeight; } function makeParticles() { const count = Math.round((w * h) / 16000); particles = Array.from({ length: count }, () => { const ox = Math.random() * w, oy = Math.random() * h; return { x: ox, y: oy, ox, oy, vx: (Math.random() - 0.5) * 0.1, vy: (Math.random() - 0.5) * 0.1, r: Math.random() * 1.8 + 0.8, color: colors[Math.floor(Math.random() * colors.length)], a: Math.random() * 0.4 + 0.25, phase: Math.random() * Math.PI * 2, }; }); } resize(); makeParticles(); window.addEventListener("resize", () => { resize(); makeParticles(); }); function onMove(e) { const r = section.getBoundingClientRect(); mouse.x = e.clientX - r.left; mouse.y = e.clientY - r.top; mx = ((e.clientX - r.left) / r.width - 0.5); my = ((e.clientY - r.top) / r.height - 0.5); } section.addEventListener("mousemove", onMove); section.addEventListener("mouseleave", () => { mouse.x = -9999; mouse.y = -9999; }); let raf = null, t = 0; function tick() { t += 0.02; ctx.clearRect(0, 0, w, h); particles.forEach((p) => { const dx = mouse.x - p.x, dy = mouse.y - p.y, dist = Math.sqrt(dx * dx + dy * dy); if (dist < 160) { const f = (160 - dist) / 160; p.x += (dx / dist) * f * 0.6; p.y += (dy / dist) * f * 0.6; } else { p.x += (p.ox - p.x) * 0.01; p.y += (p.oy - p.y) * 0.01; } p.x += p.vx; p.y += p.vy; if (p.x < 0) p.x = w; if (p.x > w) p.x = 0; if (p.y < 0) p.y = h; if (p.y > h) p.y = 0; const shimmer = 0.6 + 0.4 * Math.sin(t + p.phase); const d = p.r * 5 * 2; ctx.globalAlpha = p.a * shimmer; ctx.drawImage(sprites[p.color], p.x - d / 2, p.y - d / 2, d, d); }); ctx.globalAlpha = 1; doodleRefs.current.forEach((el, i) => { if (!el) return; const depth = 4 + (i % 3) * 2; el.style.setProperty("--dx", `${mx * depth}px`); el.style.setProperty("--dy", `${my * depth}px`); }); raf = requestAnimationFrame(tick); } const io = new IntersectionObserver((entries) => { const visible = entries[0].isIntersecting; if (visible && raf === null) { raf = requestAnimationFrame(tick); } else if (!visible && raf !== null) { cancelAnimationFrame(raf); raf = null; } }, { threshold: 0 }); io.observe(section); return () => { cancelAnimationFrame(raf); io.disconnect(); section.removeEventListener("mousemove", onMove); }; }, []); async function handleSubmit(e) { e.preventDefault(); if (sending) return; setSending(true); setError(""); try { const res = await fetch("https://api.web3forms.com/submit", { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json" }, body: JSON.stringify({ access_key: "0e2ad7c7-5603-4b14-9cf0-80ae7dcd4eb9", subject: "New Project Inquiry — The Visuals Brothers", from_name: form.name || "Website Inquiry", to: "info@thevisualsbrothers.com", "Full Name": form.name, "Company / Brand": form.company, "Website": form.website, "Email Address": form.email, "Phone Number": form.phone, "Project Details": form.details, }), }); const data = await res.json(); if (data.success) { setSent(true); } else { setError("Something went wrong. Please try again."); } } catch (err) { setError("Network error. Please try again."); } finally { setSending(false); } } const fieldStyle = { background: "var(--slate-800)", border: "1px solid var(--border-subtle)", borderRadius: "8px", color: "var(--text-primary)", fontFamily: "var(--font-body)", fontSize: "14px", padding: "12px 14px", width: "100%", boxSizing: "border-box", transition: "border-color 0.3s ease, box-shadow 0.3s ease", }; const focusHandlers = { onFocus: (e) => { e.currentTarget.style.borderColor = "var(--accent-primary)"; e.currentTarget.style.boxShadow = "0 0 12px rgba(217,119,6,0.2)"; }, onBlur: (e) => { e.currentTarget.style.borderColor = "var(--border-subtle)"; e.currentTarget.style.boxShadow = "none"; }, }; const label = { fontSize: "12px", color: "var(--text-muted)", textTransform: "uppercase", letterSpacing: "1px", marginBottom: "8px" }; return (
doodleRefs.current[0] = el} src="site/doodle-contact-camera-a.png" alt="" aria-hidden="true" className="vb-doodle vb-doodle-parallax" style={{ position: "absolute", pointerEvents: "none", zIndex: 0, width: "84px", opacity: 0.14, top: "7%", left: "5%", "--r": "-6deg" }} /> doodleRefs.current[1] = el} src="site/doodle-contact-filmreel-a.png" alt="" aria-hidden="true" className="vb-doodle vb-doodle-parallax" style={{ position: "absolute", pointerEvents: "none", zIndex: 0, width: "64px", opacity: 0.12, bottom: "8%", right: "6%", "--r": "6deg" }} /> doodleRefs.current[2] = el} src="site/doodle-contact-moviecam-a.png" alt="" aria-hidden="true" className="vb-doodle vb-doodle-parallax" style={{ position: "absolute", pointerEvents: "none", zIndex: 0, width: "58px", opacity: 0.13, top: "8%", right: "6%", "--r": "5deg" }} /> doodleRefs.current[3] = el} src="site/doodle-contact-filmstrip-a.png" alt="" aria-hidden="true" className="vb-doodle vb-doodle-parallax" style={{ position: "absolute", pointerEvents: "none", zIndex: 0, width: "72px", opacity: 0.12, bottom: "7%", left: "6%", "--r": "-5deg" }} />
The Visuals Brothers
Start a Project
{sent ? (
Thank you — your inquiry has been received. The team will be in touch shortly.
) : (
Full Name
Company / Brand
Website (Optional)
Email Address
Phone Number
Project Details