fix(ui): ensure instant video playback with auto-muted state and high-contrast white text for hero section
This commit is contained in:
@@ -11,6 +11,11 @@ export default function LazyVideoHero({ children }: LazyVideoHeroProps) {
|
|||||||
const [isVideoPlaying, setIsVideoPlaying] = useState(false);
|
const [isVideoPlaying, setIsVideoPlaying] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (videoRef.current) {
|
||||||
|
videoRef.current.muted = true;
|
||||||
|
videoRef.current.play().catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
const container = containerRef.current;
|
const container = containerRef.current;
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
@@ -19,6 +24,7 @@ export default function LazyVideoHero({ children }: LazyVideoHeroProps) {
|
|||||||
setIsIntersecting(entry.isIntersecting);
|
setIsIntersecting(entry.isIntersecting);
|
||||||
if (videoRef.current) {
|
if (videoRef.current) {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
|
videoRef.current.muted = true;
|
||||||
videoRef.current.play().catch(() => {});
|
videoRef.current.play().catch(() => {});
|
||||||
} else {
|
} else {
|
||||||
videoRef.current.pause();
|
videoRef.current.pause();
|
||||||
@@ -37,25 +43,10 @@ export default function LazyVideoHero({ children }: LazyVideoHeroProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={containerRef} className="relative w-full overflow-hidden">
|
<div ref={containerRef} className="relative w-full overflow-hidden">
|
||||||
{/* Ambient Mesh Backdrop (Used when video is loading or absent) */}
|
|
||||||
<div className="absolute top-0 left-0 right-0 h-[650px] overflow-hidden pointer-events-none z-0">
|
|
||||||
<div
|
|
||||||
className="absolute -top-[20%] -left-[10%] w-[60%] h-[80%] rounded-full opacity-20 blur-[120px]"
|
|
||||||
style={{ background: 'radial-gradient(circle, #F97316 0%, #FB923C 100%)' }}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className="absolute top-[10%] -right-[10%] w-[50%] h-[70%] rounded-full opacity-15 blur-[120px]"
|
|
||||||
style={{ background: 'radial-gradient(circle, #EA580C 0%, #F97316 100%)' }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* ─── Optimized Video Background ────────────────────────────────────────── */}
|
{/* ─── Optimized Video Background ────────────────────────────────────────── */}
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 w-full h-full z-0 pointer-events-none"
|
className="absolute inset-0 w-full h-full z-0 pointer-events-none"
|
||||||
style={{
|
style={{ contain: 'strict', willChange: 'transform' }}
|
||||||
contain: 'strict',
|
|
||||||
willChange: 'transform',
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<video
|
<video
|
||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
@@ -63,31 +54,25 @@ export default function LazyVideoHero({ children }: LazyVideoHeroProps) {
|
|||||||
muted
|
muted
|
||||||
loop
|
loop
|
||||||
playsInline
|
playsInline
|
||||||
preload="metadata"
|
preload="auto"
|
||||||
onPlaying={() => setIsVideoPlaying(true)}
|
className="w-full h-full object-cover transition-opacity duration-500"
|
||||||
onError={() => setIsVideoPlaying(false)}
|
|
||||||
className="w-full h-full object-cover transition-opacity duration-700"
|
|
||||||
style={{
|
style={{
|
||||||
filter: 'contrast(1.08) brightness(0.85) saturate(1.05)',
|
filter: 'contrast(1.1) brightness(0.85) saturate(1.1)',
|
||||||
opacity: (isIntersecting && isVideoPlaying) ? 1 : 0,
|
opacity: isIntersecting ? 1 : 0,
|
||||||
contain: 'strict',
|
contain: 'strict',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<source src="/video/whatsapp-video.mp4" type="video/mp4" />
|
<source src="/video/whatsapp-video.mp4" type="video/mp4" />
|
||||||
<source src="/video/whatsapp-video.webm" type="video/webm" />
|
<source src="/video/whatsapp-video.webm" type="video/webm" />
|
||||||
<source src="/video/RIT Video.mp4" type="video/mp4" />
|
|
||||||
<source src="/video/RIT Video.webm" type="video/webm" />
|
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
{/* High-Contrast Glassmorphic Overlay Gradient (Only active when video plays) */}
|
{/* High-Contrast Glassmorphic Overlay Gradient */}
|
||||||
{isVideoPlaying && (
|
<div
|
||||||
<div
|
className="absolute inset-0"
|
||||||
className="absolute inset-0 transition-opacity duration-700"
|
style={{
|
||||||
style={{
|
background: 'linear-gradient(to bottom, rgba(15, 23, 42, 0.5) 0%, rgba(15, 23, 42, 0.8) 100%)',
|
||||||
background: 'linear-gradient(to bottom, rgba(15, 23, 42, 0.45) 0%, rgba(15, 23, 42, 0.75) 100%)',
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ─── Hero Content ──────────────────────────────────────────────────────── */}
|
{/* ─── Hero Content ──────────────────────────────────────────────────────── */}
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ export default function Home() {
|
|||||||
initial={{ opacity: 0, y: 15 }}
|
initial={{ opacity: 0, y: 15 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{ duration: 0.6, delay: 0.1 }}
|
transition={{ duration: 0.6, delay: 0.1 }}
|
||||||
className="text-[#1E293B] text-3xl md:text-4xl font-light mb-1"
|
className="text-white text-3xl md:text-4xl font-light mb-1"
|
||||||
style={{ fontFamily: 'Playfair Display, serif' }}
|
style={{ fontFamily: 'Playfair Display, serif', textShadow: '0 2px 10px rgba(0,0,0,0.5)' }}
|
||||||
>
|
>
|
||||||
Welcome to
|
Welcome to
|
||||||
</motion.h1>
|
</motion.h1>
|
||||||
@@ -54,8 +54,8 @@ export default function Home() {
|
|||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{ duration: 0.7, delay: 0.2 }}
|
transition={{ duration: 0.7, delay: 0.2 }}
|
||||||
className="text-5xl md:text-7xl font-black leading-tight mb-6 bg-gradient-to-r from-[#F97316] via-[#EA580C] to-[#F97316] bg-clip-text text-transparent"
|
className="text-5xl md:text-7xl font-black leading-tight mb-6 bg-gradient-to-r from-[#F97316] via-[#FB923C] to-[#F97316] bg-clip-text text-transparent"
|
||||||
style={{ fontFamily: 'Playfair Display, serif', filter: 'drop-shadow(0 2px 8px rgba(249, 115, 22, 0.2))' }}
|
style={{ fontFamily: 'Playfair Display, serif', filter: 'drop-shadow(0 4px 12px rgba(249, 115, 22, 0.45))' }}
|
||||||
>
|
>
|
||||||
RIT Freshers Hub
|
RIT Freshers Hub
|
||||||
</motion.h2>
|
</motion.h2>
|
||||||
@@ -64,7 +64,7 @@ export default function Home() {
|
|||||||
initial={{ opacity: 0, y: 15 }}
|
initial={{ opacity: 0, y: 15 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{ duration: 0.7, delay: 0.3 }}
|
transition={{ duration: 0.7, delay: 0.3 }}
|
||||||
className="max-w-2xl text-[#475569] text-base md:text-lg leading-relaxed mb-8"
|
className="max-w-2xl text-slate-200 text-base md:text-lg leading-relaxed mb-8"
|
||||||
style={{ fontFamily: 'Inter, sans-serif' }}
|
style={{ fontFamily: 'Inter, sans-serif' }}
|
||||||
>
|
>
|
||||||
Your centralized gateway to campus life at Rajalakshmi Institute of Technology — academic notes, AI assistant, bus routes, faculty directory, and campus navigation.
|
Your centralized gateway to campus life at Rajalakshmi Institute of Technology — academic notes, AI assistant, bus routes, faculty directory, and campus navigation.
|
||||||
@@ -95,9 +95,9 @@ export default function Home() {
|
|||||||
|
|
||||||
<Link to="/ai-assistant">
|
<Link to="/ai-assistant">
|
||||||
<motion.button
|
<motion.button
|
||||||
whileHover={{ scale: 1.04, borderColor: '#F97316', backgroundColor: '#FFF7ED' }}
|
whileHover={{ scale: 1.04, borderColor: '#F97316', backgroundColor: 'rgba(255,255,255,0.2)' }}
|
||||||
whileTap={{ scale: 0.96 }}
|
whileTap={{ scale: 0.96 }}
|
||||||
className="flex items-center gap-2 px-8 py-3.5 rounded-xl font-semibold text-sm border-2 border-[#E5E7EB] text-[#1E293B] bg-white transition-all cursor-pointer shadow-2xs hover:text-[#F97316]"
|
className="flex items-center gap-2 px-8 py-3.5 rounded-xl font-semibold text-sm border-2 border-white/30 text-white bg-white/10 backdrop-blur-md transition-all cursor-pointer shadow-2xs"
|
||||||
style={{ fontFamily: 'Poppins, sans-serif' }}
|
style={{ fontFamily: 'Poppins, sans-serif' }}
|
||||||
>
|
>
|
||||||
<Bot className="w-4 h-4 text-[#F97316]" />
|
<Bot className="w-4 h-4 text-[#F97316]" />
|
||||||
@@ -111,7 +111,7 @@ export default function Home() {
|
|||||||
initial={{ opacity: 0 }}
|
initial={{ opacity: 0 }}
|
||||||
animate={{ opacity: 1 }}
|
animate={{ opacity: 1 }}
|
||||||
transition={{ duration: 0.8, delay: 0.5 }}
|
transition={{ duration: 0.8, delay: 0.5 }}
|
||||||
className="flex flex-wrap justify-center gap-6 text-[#64748B] border-t border-[#E5E7EB] pt-6 max-w-lg w-full"
|
className="flex flex-wrap justify-center gap-6 text-slate-300 border-t border-white/20 pt-6 max-w-lg w-full"
|
||||||
>
|
>
|
||||||
{[
|
{[
|
||||||
{ icon: CheckCircle, text: 'Official Portal' },
|
{ icon: CheckCircle, text: 'Official Portal' },
|
||||||
@@ -124,9 +124,9 @@ export default function Home() {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</section>
|
</section>
|
||||||
</LazyVideoHero>
|
</LazyVideoHero>
|
||||||
|
|
||||||
{/* Sleek Stats Card Section */}
|
{/* Sleek Stats Card Section */}
|
||||||
<section className="relative z-30 -mt-6 px-4">
|
<section className="relative z-30 -mt-6 px-4">
|
||||||
|
|||||||
Reference in New Issue
Block a user