讨论

带动画3D英雄区域,支持滚动驱动视频

来自 Wikiprompt,自由的提示词百科全书

Kashberg

2026年6月19日

带动画3D英雄区域,支持滚动驱动视频 一个全面的提示,用于使用React、Tailwind和Framer Motion构建一个电影级、视频背景的落地页,包含滚动擦除、模糊效果和流畅动画。

提示词内容收藏

🌐
import { useEffect, useRef } from 'react'; import { motion, useScroll, useTransform } from 'motion/react'; import Lenis from 'lenis'; // LiquidVideoCanvas component function LiquidVideoCanvas({ onReady }) { const videoRef = useRef(null); const containerRef = useRef(null); const isSeeking = useRef(false); const nextSeekTime = useRef(null); const currentScroll = useRef(0); const targetTime = useRef(0); const isAnimatingIn = useRef(false); // Entrance animation useEffect(() => { const video = videoRef.current; if (!video) return; const handleReady = () => { if (video.readyState >= 3 && !isAnimatingIn.current) { isAnimatingIn.current = true; video.style.transition = 'transform 1.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 1.4s cubic-bezier(0.16, 1, 0.3, 1)'; video.style.transform = 'scale(1)'; video.style.opacity = '1'; onReady?.(); } }; // Safety timeout const timeout = setTimeout(handleReady, 3500); video.addEventListener('loadeddata', handleReady); video.addEventListener('canplaythrough', handleReady); return () => { clearTimeout(timeout); video.removeEventListener('loadeddata', handleReady); video.removeEventListener('canplaythrough', handleReady); }; }, [onReady]); // Scroll-driven seeking useEffect(() => { const video = videoRef.current; if (!video) return; const handleScroll = () => { const scrollY = window.scrollY; const maxScroll = document.documentElement.scrollHeight - window.innerHeight; const progress = maxScroll > 0 ? scrollY / maxScroll : 0; targetTime.current = progress * video.duration; }; const handleSeeked = () => { isSeeking.current = false; if (nextSeekTime.current !== null) { const time = nextSeekTime.current; nextSeekTime.current = null; if (!video.seeking) { isSeeking.current = true; video.currentTime = time; } } }; const handleSeeking = () => { isSeeking.current = true; }; const animate = () => { if (!video.seeking && !isSeeking.current) { const lerped = currentScroll.current + (targetTime.current - currentScroll.current) * 0.12; currentScroll.current = lerped; if (Math.abs(lerped - targetTime.current) > 0.01) { isSeeking.current = true; video.currentTime = lerped; } } requestAnimationFrame(animate); }; window.addEventListener('scroll', handleScroll, { passive: true }); video.addEventListener('seeked', handleSeeked); video.addEventListener('seeking', handleSeeking); const raf = requestAnimationFrame(animate); return () => { window.removeEventListener('scroll', handleScroll); video.removeEventListener('seeked', handleSeeked); video.removeEventListener('seeking', handleSeeking); cancelAnimationFrame(raf); }; }, []); return ( <div ref={containerRef} className="fixed inset-0 z-[1] bg-black"> <video ref={videoRef} className="w-full h-full object-cover" style={{ transform: 'scale(1.12)', opacity: 0 }} loop muted playsInline preload="auto" src="https://t.co/cvkGVS5C0E" /> </div> ); } // Progressive blur component function ProgressiveBlur() { const blurRef = useRef(null); const { scrollYProgress } = useScroll(); useEffect(() => { const unsubscribe = scrollYProgress.on('change', (value) => { if (!blurRef.current) return; let blur = 0; if (value < 0.5) { blur = (value / 0.5) * 5; } else { blur = 5 + ((value - 0.5) / 0.5) * 50; } blurRef.current.style.backdropFilter = `blur(${blur}px)`; blurRef.current.style.webkitBackdropFilter = `blur(${blur}px)`; }); return () => unsubscribe(); }, [scrollYProgress]); return <div ref={blurRef} className="fixed bottom-0 left-0 right-0 h-32 z-30 pointer-events-none" />; } // Text scramble effect component function ScrambleText({ text, className }) { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()'; const intervalRef = useRef(null); useEffect(() => { let iteration = 0; clearInterval(intervalRef.current); intervalRef.current = setInterval(() => { const target = text; const el = document.querySelector(`[data-scramble="${text}"]`); if (!el) return; el.innerText = target .split('') .map((char, index) => { if (char === ' ') return ' '; if (index < iteration) return target[index]; return chars[Math.floor(Math.random() * chars.length)]; }) .join(''); if (iteration >= target.length) { clearInterval(intervalRef.current); } iteration += 1 / 3; }, 30); return () => clearInterval(intervalRef.current); }, [text]); return ( <span data-scramble={text} className={className}> {text} </span> ); } // Main App component export default function App() { const mainRef = useRef(null); const { scrollYProgress } = useScroll(); const opacity = useTransform(scrollYProgress, [0, 0.1], [1, 0]); const y = useTransform(scrollYProgress, [0, 0.1], [0, -50]); // Lenis smooth scroll useEffect(() => { const lenis = new Lenis({ duration: 1.2, easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), smoothWheel: true, }); function raf(time) { lenis.raf(time); requestAnimationFrame(raf); } const rafId = requestAnimationFrame(raf); return () => { cancelAnimationFrame(rafId); lenis.destroy(); }; }, []); return ( <div className="relative overflow-x-hidden bg-black"> <LiquidVideoCanvas /> {/* Header */} <header className="fixed top-0 left-0 right-0 z-50 flex items-center justify-between px-8 py-6"> <div className="text-xl font-bold tracking-widest">SYNAPSE<span className="text-blue-500">X</span></div> <nav className="hidden md:flex items-center gap-8 text-sm"> <a href="#" className="hover:text-blue-400 transition-colors">Technology</a> <a href="#" className="hover:text-blue-400 transition-colors">Solutions</a> <a href="#" className="hover:text-blue-400 transition-colors">Research</a> <a href="#" className="hover:text-blue-400 transition-colors">Contact</a> </nav> <button className="px-4 py-2 border border-white/20 rounded-full text-sm hover:bg-white/10 transition-colors"> Get Access </button> </header> {/* Main content */} <main ref={mainRef} className="relative z-10 min-h-screen"> <motion.section style={{ opacity, y }} className="flex flex-col items-center justify-center min-h-screen text-center px-4" > <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.8, delay: 0.5 }} className="mb-8" > <i className="bi bi-apple text-4xl text-white/80" /> </motion.div> <motion.h1 initial={{ opacity: 0, y: 30 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.8, delay: 0.7 }} className="text-5xl md:text-7xl font-bold mb-6 tracking-tight" > <ScrambleText text="SYNAPSE" /> <span className="text-blue-500">X</span> </motion.h1> <motion.p initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.8, delay: 0.9 }} className="text-lg md:text-xl text-white/70 max-w-2xl mb-12" > <ScrambleText text="Next-generation neural interfaces" /> <br /> <ScrambleText text="for human-machine symbiosis" /> </motion.p> <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.8, delay: 1.1 }} className="flex flex-col md:flex-row gap-4" > <button className="px-8 py-4 bg-blue-600 hover:bg-blue-500 rounded-full font-bold transition-colors"> Explore Technology </button> <button className="px-8 py-4 border border-white/20 hover:bg-white/10 rounded-full font-bold transition-colors"> Watch Demo </button> </motion.div> </motion.section> {/* Scroll indicator */} <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 1.5 }} className="absolute bottom-8 left-1/2 transform -translate-x-1/2" > <div className="w-6 h-10 border-2 border-white/30 rounded-full flex justify-center pt-2"> <motion.div animate={{ y: [0, 12, 0] }} transition={{ repeat: Infinity, duration: 1.5 }} className="w-1 h-2 bg-white/50 rounded-full" /> </div> </motion.div> </main> <ProgressiveBlur /> {/* Additional content sections */} <section className="relative z-10 min-h-screen flex items-center justify-center"> <div className="max-w-4xl mx-auto px-8 text-center"> <h2 className="text-4xl md:text-5xl font-bold mb-8"> <ScrambleText text="Beyond Human Limits" /> </h2> <p className="text-white/70 text-lg leading-relaxed"> <ScrambleText text="Our neural interface technology enables unprecedented" /> <br /> <ScrambleText text="cognitive enhancement and seamless digital integration" /> </p> </div> </section> <section className="relative z-10 min-h-screen flex items-center justify-center"> <div className="max-w-4xl mx-auto px-8 text-center"> <h2 className="text-4xl md:text-5xl font-bold mb-8"> <ScrambleText text="The Future is Here" /> </h2> <div className="grid grid-cols-1 md:grid-cols-3 gap-8 mt-12"> {['Neural Link', 'Quantum Core', 'Bio Sync'].map((item) => ( <div key={item} className="p-6 border border-white/10 rounded-2xl hover:border-blue-500/50 transition-colors"> <h3 className="text-xl font-bold mb-4">{item}</h3> <p className="text-white/60 text-sm"> Advanced technology for the next generation of human-computer interaction </p> </div> ))} </div> </div> </section> </div> ); } ``` ```css /* index.css */ @import url('https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400&display=swap'); @import url('https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css'); @import "tailwindcss"; @theme { --font-sans: "Space Mono", monospace; --font-serif: "Space Mono", monospace; --font-inter: "Space Mono", monospace; --font-mono: "Space Mono", monospace; } html, body { font-family: var(--font-sans); background: black; color: white; margin: 0; padding: 0; overflow-x: hidden; overflow-y: auto; } /* Lenis compatibility */ html.lenis, html.lenis body { height: auto; } .lenis.lenis-smooth { scroll-behavior: auto !important; } .lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; } .lenis.lenis-stopped { overflow: hidden; } .lenis.lenis-smooth iframe { pointer-events: none; }

登录以查看完整提示词

继续使用:

登录即表示你同意我们的 使用条款 和 隐私政策

用法

此提示词专为 coding 设计。复制上方内容并粘贴到你常用的 AI 工具中。

为获得最佳效果,可将占位符(方括号或大写字母标示)替换为你的具体需求。

参考资料

分类:coding| twitter| react| vite

讨论