Skip to main content
Glama
animation-patterns.ts11.8 kB
export const EASING_FUNCTIONS = { spring: { name: "Spring", css: "cubic-bezier(0.175, 0.885, 0.32, 1.275)", description: "Overshoots slightly then settles - feels organic and bouncy", useCase: "Button presses, modal appearances, playful interfaces" }, smoothOut: { name: "Smooth Out", css: "cubic-bezier(0.22, 1, 0.36, 1)", description: "Fast start, slow end - feels responsive and controlled", useCase: "Menu openings, dropdowns, expanding elements" }, smoothIn: { name: "Smooth In", css: "cubic-bezier(0.64, 0, 0.78, 0)", description: "Slow start, fast end - builds anticipation", useCase: "Exit animations, elements leaving viewport" }, smooth: { name: "Smooth", css: "cubic-bezier(0.45, 0, 0.55, 1)", description: "Symmetrical ease - natural and balanced", useCase: "Hover states, toggle switches, general transitions" }, snappy: { name: "Snappy", css: "cubic-bezier(0.68, -0.55, 0.265, 1.55)", description: "Quick with overshoot - energetic and dynamic", useCase: "Notifications, alerts, attention-grabbing elements" }, elastic: { name: "Elastic", css: "cubic-bezier(0.68, -0.6, 0.32, 1.6)", description: "Strong bounce effect - playful and fun", useCase: "Game-like interfaces, children's apps, celebrations" } }; export const ENTRY_ANIMATIONS = { fadeUp: { name: "Fade Up", initial: "opacity: 0; transform: translateY(20px)", final: "opacity: 1; transform: translateY(0)", duration: "0.6s", easing: "smoothOut", description: "Content rises into view - classic and reliable", stagger: "0.1s" }, fadeIn: { name: "Fade In", initial: "opacity: 0", final: "opacity: 1", duration: "0.4s", easing: "smooth", description: "Simple opacity transition - subtle and elegant", stagger: "0.05s" }, slideFromLeft: { name: "Slide From Left", initial: "opacity: 0; transform: translateX(-40px)", final: "opacity: 1; transform: translateX(0)", duration: "0.5s", easing: "smoothOut", description: "Content slides from left - dynamic horizontal motion", stagger: "0.08s" }, slideFromRight: { name: "Slide From Right", initial: "opacity: 0; transform: translateX(40px)", final: "opacity: 1; transform: translateX(0)", duration: "0.5s", easing: "smoothOut", description: "Content slides from right - complementary to left slide", stagger: "0.08s" }, scaleUp: { name: "Scale Up", initial: "opacity: 0; transform: scale(0.9)", final: "opacity: 1; transform: scale(1)", duration: "0.4s", easing: "spring", description: "Content grows into view - impactful and attention-grabbing", stagger: "0.1s" }, blurIn: { name: "Blur In", initial: "opacity: 0; filter: blur(10px)", final: "opacity: 1; filter: blur(0)", duration: "0.6s", easing: "smooth", description: "Content comes into focus - cinematic and premium", stagger: "0.15s" }, flipIn: { name: "Flip In", initial: "opacity: 0; transform: perspective(600px) rotateX(-20deg)", final: "opacity: 1; transform: perspective(600px) rotateX(0)", duration: "0.7s", easing: "smoothOut", description: "3D flip effect - dramatic and engaging", stagger: "0.12s" }, bounceIn: { name: "Bounce In", initial: "opacity: 0; transform: scale(0.3)", final: "opacity: 1; transform: scale(1)", duration: "0.6s", easing: "elastic", description: "Elastic bounce entrance - fun and energetic", stagger: "0.1s" } }; export const SCROLL_ANIMATIONS = { parallax: { name: "Parallax", description: "Background moves slower than foreground creating depth", speeds: ["0.2x (far)", "0.5x (mid)", "0.8x (near)", "1x (content)"], useCase: "Hero sections, landing pages, storytelling" }, revealOnScroll: { name: "Reveal on Scroll", description: "Elements animate in as they enter viewport", trigger: "element enters viewport (with offset)", useCase: "Content sections, feature lists, testimonials" }, progressiveBlur: { name: "Progressive Blur", description: "Background blurs as user scrolls, focusing on content", implementation: "backdrop-filter tied to scroll position", useCase: "Long-form content, reading experiences" }, horizontalScroll: { name: "Horizontal Scroll", description: "Vertical scroll translates to horizontal movement", implementation: "transform: translateX tied to scroll", useCase: "Portfolios, galleries, timelines" }, stickyReveal: { name: "Sticky Reveal", description: "Content sticks while new content scrolls over/under", implementation: "position: sticky with z-index choreography", useCase: "Feature comparisons, step-by-step guides" }, scaleOnScroll: { name: "Scale on Scroll", description: "Element scales based on scroll position", implementation: "transform: scale tied to scroll progress", useCase: "Hero images, focal points, transitions" } }; export const HOVER_ANIMATIONS = { lift: { name: "Lift", effect: "transform: translateY(-4px); box-shadow: larger", duration: "0.3s", description: "Card lifts up with enhanced shadow", useCase: "Cards, buttons, clickable items" }, glow: { name: "Glow", effect: "box-shadow: 0 0 20px rgba(accent, 0.4)", duration: "0.3s", description: "Soft glow emanates from element", useCase: "CTAs, featured items, interactive elements" }, borderDraw: { name: "Border Draw", effect: "border animates around element perimeter", duration: "0.4s", description: "Border draws itself around element", useCase: "Buttons, links, navigation items" }, backgroundFill: { name: "Background Fill", effect: "background color fills from one direction", duration: "0.3s", description: "Color sweeps across background", useCase: "Buttons, menu items, tabs" }, textReveal: { name: "Text Reveal", effect: "text slides/fades to reveal alternate text", duration: "0.3s", description: "Text transforms to show hover state", useCase: "Links, navigation, buttons with icons" }, magneticPull: { name: "Magnetic Pull", effect: "element slightly follows cursor position", duration: "0.2s", description: "Element is attracted to cursor", useCase: "CTAs, important buttons, interactive demos" }, tilt3D: { name: "3D Tilt", effect: "element tilts based on cursor position", duration: "0.1s", description: "Perspective tilt following mouse", useCase: "Cards, images, product showcases" } }; export const LOADING_ANIMATIONS = { skeleton: { name: "Skeleton Loader", effect: "Gray placeholder shapes with shimmer animation", implementation: "linear-gradient animation moving across element", description: "Shows content structure while loading", useCase: "Content-heavy pages, lists, cards" }, pulse: { name: "Pulse", effect: "Opacity pulses between 0.4 and 1", implementation: "animation: pulse 1.5s ease-in-out infinite", description: "Subtle pulsing indicates activity", useCase: "Buttons, status indicators, awaiting response" }, spinner: { name: "Spinner", effect: "Rotating circular indicator", implementation: "Rotating element with partial border", description: "Classic loading indicator", useCase: "Form submissions, page transitions" }, progressBar: { name: "Progress Bar", effect: "Horizontal bar showing completion percentage", implementation: "Width animation with background gradient", description: "Shows determinate progress", useCase: "File uploads, multi-step forms, installations" }, dots: { name: "Bouncing Dots", effect: "Three dots bouncing in sequence", implementation: "Staggered translateY animations", description: "Friendly, conversational loading state", useCase: "Chat interfaces, AI responses, messaging" }, morphing: { name: "Morphing Shape", effect: "Shape smoothly transforms through different forms", implementation: "SVG path morphing or clip-path animation", description: "Premium, engaging loading experience", useCase: "Brand moments, app launches, special transitions" } }; export const TRANSITION_CHOREOGRAPHY = { staggeredFade: { name: "Staggered Fade", description: "Elements fade in sequence with consistent delay", timing: "Each element delayed by 50-100ms from previous", direction: "Top-to-bottom or left-to-right", useCase: "Lists, grids, navigation items" }, cascadeReveal: { name: "Cascade Reveal", description: "Elements reveal in a wave pattern", timing: "Delay based on element position (x + y coordinates)", direction: "Top-left to bottom-right diagonal", useCase: "Grids, dashboards, gallery layouts" }, orchestrated: { name: "Orchestrated Entrance", description: "Different elements have unique, timed animations", timing: "Custom timeline: background → image → headline → text → CTA", direction: "Based on visual hierarchy", useCase: "Hero sections, feature highlights" }, exitThenEnter: { name: "Exit Then Enter", description: "Old content exits before new content enters", timing: "Exit: 200ms, Gap: 50ms, Enter: 300ms", direction: "Exit opposite to enter direction", useCase: "Page transitions, tab content, modals" } }; export function getAnimationPrompt(intensity: 'subtle' | 'moderate' | 'dramatic' | 'cinematic'): string { const intensityConfig = { subtle: { entry: ["fadeIn", "fadeUp"], hover: ["lift"], scroll: ["revealOnScroll"], duration: "shorter (0.2-0.4s)", stagger: "minimal (0.05s)" }, moderate: { entry: ["fadeUp", "slideFromLeft", "scaleUp"], hover: ["lift", "glow", "backgroundFill"], scroll: ["revealOnScroll", "parallax"], duration: "standard (0.3-0.6s)", stagger: "noticeable (0.1s)" }, dramatic: { entry: ["scaleUp", "blurIn", "flipIn"], hover: ["lift", "glow", "magneticPull", "tilt3D"], scroll: ["parallax", "horizontalScroll", "scaleOnScroll"], duration: "extended (0.5-0.8s)", stagger: "pronounced (0.15s)" }, cinematic: { entry: ["blurIn", "flipIn", "bounceIn"], hover: ["magneticPull", "tilt3D", "borderDraw"], scroll: ["parallax", "horizontalScroll", "stickyReveal", "scaleOnScroll"], duration: "cinematic (0.6-1.2s)", stagger: "dramatic (0.2s)" } }; const config = intensityConfig[intensity]; return ` ## Animation Specifications (${intensity.toUpperCase()} Intensity) ### Entry Animations Use: ${config.entry.join(", ")} - Duration: ${config.duration} - Stagger: ${config.stagger} - Easing: Use spring or smoothOut for organic feel ### Hover States Implement: ${config.hover.join(", ")} - Response time: Immediate (under 100ms perceived) - Use GPU-accelerated properties (transform, opacity) ### Scroll-Triggered Effects Apply: ${config.scroll.join(", ")} - Trigger when element is 20% in viewport - Use Intersection Observer for performance ### Loading States - Use skeleton loaders for content placeholders - Pulse animation for action buttons - Progress indicators for longer operations ### Transition Choreography - Stagger related elements by ${config.stagger} - Exit animations should be faster than entrances (70% of enter time) - Follow visual hierarchy: background → container → content → CTAs ### Reduced Motion Support - Provide @media (prefers-reduced-motion: reduce) alternatives - Replace motion with opacity fades - Remove parallax and complex scroll effects `; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Nwabukin/mcp-ui-prompt-refiner'

If you have feedback or need assistance with the MCP directory API, please join our Discord server