Restore scrolling/spinning logo animation by separating canvas and React modal card

This commit is contained in:
2026-07-10 13:40:00 +05:30
parent ecfc9d3b43
commit cdf50ed99c
3 changed files with 33 additions and 37 deletions

File diff suppressed because one or more lines are too long

View File

@@ -20,6 +20,10 @@ def port_html():
display: none !important; display: none !important;
} }
#stage, .hint { #stage, .hint {
background: transparent !important;
box-shadow: none !important;
}
.count, .panel, .hint {
display: none !important; display: none !important;
} }
""" """
@@ -39,6 +43,13 @@ def port_html():
""" """
html = re.sub(r"const parseTarget=\(\)=>\{.*?\};", parse_target_replacement, html, flags=re.DOTALL) html = re.sub(r"const parseTarget=\(\)=>\{.*?\};", parse_target_replacement, html, flags=re.DOTALL)
# 3. Replace the huge base64 logo image in .badge class with the local PragatiVeer SVG logo
new_badge_css = """ .badge{
position:absolute; inset:0; border-radius:50%;
background: url('/PragatiVeer_Logo/SVG_Logos/Square_dark_background.svg') center/cover no-repeat !important;
}"""
html = re.sub(r"\.badge\s*\{[^}]*\}", new_badge_css, html, flags=re.DOTALL)
with open(dest_path, 'w', encoding='utf-8') as f: with open(dest_path, 'w', encoding='utf-8') as f:
f.write(html) f.write(html)
print("Ported successfully to public/streak-animation.html") print("Ported successfully to public/streak-animation.html")

View File

@@ -2,7 +2,7 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Flame, Trophy, Sparkles } from "lucide-react"; import { Flame, Sparkles } from "lucide-react";
import { useActiveUser } from "@/hooks/useActiveUser"; import { useActiveUser } from "@/hooks/useActiveUser";
export function StreakOnboardingModal() { export function StreakOnboardingModal() {
@@ -27,24 +27,16 @@ export function StreakOnboardingModal() {
// Streak-based wishes and titles // Streak-based wishes and titles
let wishTitle = "Welcome to PragatiVeer! 🌟"; let wishTitle = "Welcome to PragatiVeer! 🌟";
let wishMessage = `Prepare yourself to conquer ${targetExam}. Your daily practice starts here!`; let wishMessage = `Prepare yourself to conquer ${targetExam}. Your daily practice starts here!`;
let badgeBorderColor = "border-[#00F0FF]/30";
let badgeShadow = "shadow-[0_0_25px_rgba(0,240,255,0.25)]";
if (streak === 0) { if (streak === 0) {
wishTitle = "Start Your Streak Today! 🚀"; wishTitle = "Start Your Streak Today! 🚀";
wishMessage = "Today is Day 1 of your journey. Establish your streak now and build the consistency needed for IIT/AIIMS!"; wishMessage = "Today is Day 1 of your journey. Establish your streak now and build the consistency needed for IIT/AIIMS!";
badgeBorderColor = "border-blue-500/30";
badgeShadow = "shadow-[0_0_20px_rgba(59,130,246,0.2)]";
} else if (streak < 4) { } else if (streak < 4) {
wishTitle = "Keep the Fire Burning! 🔥"; wishTitle = "Keep the Fire Burning! 🔥";
wishMessage = `Great job! You have maintained a ${streak}-day study streak. Keep practicing daily to build solid muscle memory!`; wishMessage = `Great job! You have maintained a ${streak}-day study streak. Keep practicing daily to build solid muscle memory!`;
badgeBorderColor = "border-orange-500/30";
badgeShadow = "shadow-[0_0_20px_rgba(249,115,22,0.25)]";
} else { } else {
wishTitle = "Unstoppable Dedication! ⚡"; wishTitle = "Unstoppable Dedication! ⚡";
wishMessage = `Incredible! A ${streak}-day streak shows true championship discipline. You are outperforming the competition. Let's make today count!`; wishMessage = `Incredible! A ${streak}-day streak shows true championship discipline. You are outperforming the competition. Let's make today count!`;
badgeBorderColor = "border-[#D1FF4D]/30";
badgeShadow = "shadow-[0_0_25px_rgba(209,255,77,0.25)]";
} }
const handleEnter = () => { const handleEnter = () => {
@@ -53,9 +45,9 @@ export function StreakOnboardingModal() {
}; };
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/90 backdrop-blur-lg animate-in fade-in duration-300"> <div className="fixed inset-0 z-50 flex flex-col items-center justify-end pb-12 bg-black/90 backdrop-blur-lg animate-in fade-in duration-300">
{/* Celebration Animation Canvas Overlay */} {/* Celebration Animation Canvas & Logo Iframe */}
<iframe <iframe
src={`/streak-animation.html?streak=${streak}`} src={`/streak-animation.html?streak=${streak}`}
className="absolute inset-0 w-full h-full border-none pointer-events-none z-10" className="absolute inset-0 w-full h-full border-none pointer-events-none z-10"
@@ -63,50 +55,38 @@ export function StreakOnboardingModal() {
allowtransparency="true" allowtransparency="true"
/> />
{/* Adaptive Modal Content Card */} {/* Adaptive Modal Content Card (positioned at the bottom to let the animated logo shine in the center) */}
<div className="bg-background/95 border border-border/80 shadow-[0_0_60px_-10px_rgba(0,240,255,0.15)] rounded-3xl w-full max-w-lg p-8 text-center space-y-6 relative overflow-hidden animate-in zoom-in-95 slide-in-from-bottom-4 duration-300 z-20 pointer-events-auto mx-4"> <div className="bg-background/85 backdrop-blur-md border border-border/60 shadow-[0_0_50px_-15px_rgba(0,240,255,0.1)] rounded-3xl w-full max-w-lg p-6 text-center space-y-4 relative overflow-hidden animate-in zoom-in-95 slide-in-from-bottom-4 duration-300 z-20 pointer-events-auto mx-4">
{/* Subtle background glow */} {/* Subtle background glow */}
<div className="absolute -right-20 -top-20 size-48 bg-[#00F0FF]/5 rounded-full blur-3xl pointer-events-none" /> <div className="absolute -right-20 -top-20 size-48 bg-[#00F0FF]/5 rounded-full blur-3xl pointer-events-none" />
<div className="absolute -left-20 -bottom-20 size-48 bg-primary/5 rounded-full blur-3xl pointer-events-none" /> <div className="absolute -left-20 -bottom-20 size-48 bg-primary/5 rounded-full blur-3xl pointer-events-none" />
{/* Pulsing Badge with PragatiVeer Logo */}
<div className="relative size-28 mx-auto flex items-center justify-center">
{/* Glowing pulse rings */}
<div className="absolute inset-2 rounded-full bg-[#00F0FF]/10 animate-ping" style={{ animationDuration: '3s' }} />
<img
src="/PragatiVeer_Logo/SVG_Logos/Square_dark_background.svg"
alt="PragatiVeer"
className={`size-24 rounded-full border-2 ${badgeBorderColor} ${badgeShadow} animate-pulse relative z-10 object-cover`}
/>
</div>
{/* Text Greetings */} {/* Text Greetings */}
<div className="space-y-3"> <div className="space-y-2">
{streak > 0 ? ( {streak > 0 ? (
<div className="inline-flex items-center gap-1.5 px-3 py-1 bg-orange-500/10 border border-orange-500/20 text-orange-500 text-xs font-extrabold rounded-full tracking-wider uppercase"> <div className="inline-flex items-center gap-1.5 px-3 py-0.5 bg-orange-500/10 border border-orange-500/20 text-orange-500 text-xs font-extrabold rounded-full tracking-wider uppercase">
<Flame size={12} className="fill-current animate-bounce" /> {streak} Day Streak Active <Flame size={12} className="fill-current animate-bounce" /> {streak} Day Streak Active
</div> </div>
) : ( ) : (
<div className="inline-flex items-center gap-1.5 px-3 py-1 bg-blue-500/10 border border-blue-500/20 text-blue-400 text-xs font-extrabold rounded-full tracking-wider uppercase"> <div className="inline-flex items-center gap-1.5 px-3 py-0.5 bg-blue-500/10 border border-blue-500/20 text-blue-400 text-xs font-extrabold rounded-full tracking-wider uppercase">
<Sparkles size={12} className="animate-spin" style={{ animationDuration: '4s' }} /> Day 1 Awaits <Sparkles size={12} className="animate-spin" style={{ animationDuration: '4s' }} /> Day 1 Awaits
</div> </div>
)} )}
<h3 className="text-2xl md:text-3xl font-black tracking-tight bg-gradient-to-r from-white via-white to-gray-400 bg-clip-text text-transparent"> <h3 className="text-xl md:text-2xl font-black tracking-tight bg-gradient-to-r from-white via-white to-gray-400 bg-clip-text text-transparent">
{wishTitle} {wishTitle}
</h3> </h3>
<p className="text-gray-400 text-sm md:text-base leading-relaxed max-w-sm mx-auto pt-1"> <p className="text-gray-400 text-xs md:text-sm leading-relaxed max-w-sm mx-auto">
{wishMessage} {wishMessage}
</p> </p>
</div> </div>
{/* Action Button */} {/* Action Button */}
<div className="pt-2"> <div className="pt-1">
<Button <Button
onClick={handleEnter} onClick={handleEnter}
className="w-full h-14 rounded-xl text-lg font-black bg-[#00F0FF] text-black hover:bg-[#00F0FF]/90 shadow-[0_0_20px_-3px_#00F0FF] hover:shadow-[0_0_30px_#00F0FF] hover:-translate-y-1 transition-all duration-300" className="w-full h-12 rounded-xl text-base font-black bg-[#00F0FF] text-black hover:bg-[#00F0FF]/90 shadow-[0_0_15px_-3px_#00F0FF] hover:shadow-[0_0_25px_#00F0FF] hover:-translate-y-0.5 transition-all duration-300"
> >
Enter Workspace Enter Workspace
</Button> </Button>