Tips
Animated Boat Loading Component
Custom loading animation with sailing boat and wave effects
Overview
A theme-aware loading component featuring an animated sailing boat with wave effects. Built with SVG and CSS animations for smooth, performant loading states.
Implementation
From Logo to Animation
1. SVG Structure
- Started with static boat logo SVG
- Separated elements: sails, hull, mast
- Created light/dark mode variants
2. Sail Animation
- Main sail:
skewYtransform (0° → 3° → -3°) - Secondary sail: Opposite phase for depth
- Transform origin:
left centerfor realistic pivot
3. Boat Float
- Rotation: 8° to -8° swing
- Duration: 1.5s ease-in-out
- Combined with
translateX(-50%)for centering
4. Wave Effects
- 8 wave lines with staggered delays (0.2s intervals)
- Flow animation: left to right (bow to stern)
- Smooth fade in/out with opacity transitions
- Duration: 1s per wave cycle
Code Structure
// Component: src/components/ui/loading.tsx
export function Loading() {
return (
<div className="flex min-h-screen items-center justify-center">
{/* Boat with float animation */}
<div className="animate-boat-float">
<svg>{/* Boat SVG with sail animations */}</svg>
</div>
{/* Wave lines */}
<div className="animate-wave-slide">
{Array.from({ length: 8 }).map((_, i) => (
<path style={{ animationDelay: `${i * 0.2}s` }} />
))}
</div>
</div>
);
}Key Animations
Sail Wave
@keyframes sail-wave-main {
0%, 100% { transform: skewY(0deg); }
25% { transform: skewY(3deg); }
75% { transform: skewY(-3deg); }
}Boat Float
@keyframes boat-float {
0%, 100% { transform: translateX(-50%) rotate(8deg); }
50% { transform: translateX(-50%) rotate(-8deg); }
}Wave Slide
@keyframes wave-slide {
0% { transform: translateX(-50px); opacity: 0; }
10%, 90% { opacity: 0.6; }
100% { transform: translateX(180px); opacity: 0; }
}Theme Support
- Light mode: White sails, dark hull, blue waves
- Dark mode: Dark sails, light hull, light waves
- Automatic switching with
dark:variants
Usage
import { Loading } from "@/components/ui/loading";
export default function Page() {
return <Loading />;
}Performance
- Pure CSS animations (GPU accelerated)
- No JavaScript runtime overhead
- Smooth 60fps on all devices
- Minimal DOM elements (< 20 nodes)