원클릭으로
nextjs-motion-animations
Motion-based animation system for Next.js with performance-optimized patterns
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Motion-based animation system for Next.js with performance-optimized patterns
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Comprehensive Nushell scripting best practices, idioms, security, and code review. Use when writing, reviewing, auditing, or refactoring Nushell (.nu) scripts to ensure they follow idiomatic patterns, naming conventions, proper type annotations, functional style, security best practices, and Nushell's unique design principles. Triggers on tasks involving Nushell scripts, modules, custom commands, pipelines, or any .nu file editing. Also helps convert Bash/POSIX scripts to idiomatic Nushell. Covers the type system, data manipulation, performance optimization, security hardening, script review, and common gotchas.
Typst document creation and package development. Use when: (1) Working with .typ files, (2) User mentions typst, typst.toml, or typst-cli, (3) Creating or using Typst packages, (4) Developing document templates, (5) Converting Markdown/LaTeX to Typst
This skill should be used when the user asks to "create a justfile", "write just recipes", "configure just settings", "add just modules", "use just attributes", "set up task automation", mentions justfile, just command runner, or task automation with just.
| name | nextjs-motion-animations |
| description | Motion-based animation system for Next.js with performance-optimized patterns |
| license | MIT |
| compatibility | nextjs |
| metadata | {"library":"motion","version":"12.23.26","framework":"nextjs","css":"tailwindcss"} |
A comprehensive animation system using Motion (formerly Framer Motion) v12.23.26 with performance-optimized patterns for Next.js applications.
Use this skill when you need to:
npm install motion@12.23.26
# Optional for CSS animations
npm install tw-animate-css@1.4.0
Create src/lib/animations.ts with reusable variants:
// Basic fade animations with directional movement
export const fadeInUp = {
hidden: { opacity: 0, y: 30 },
visible: { opacity: 1, y: 0, transition: { duration: 0.6 } }
};
export const fadeInDown = {
hidden: { opacity: 0, y: -30 },
visible: { opacity: 1, y: 0, transition: { duration: 0.6 } }
};
export const fadeInLeft = {
hidden: { opacity: 0, x: -30 },
visible: { opacity: 1, x: 0, transition: { duration: 0.6 } }
};
export const fadeInRight = {
hidden: { opacity: 0, x: 30 },
visible: { opacity: 1, x: 0, transition: { duration: 0.6 } }
};
export const fadeInScale = {
hidden: { opacity: 0, scale: 0.8 },
visible: { opacity: 1, scale: 1, transition: { duration: 0.6 } }
};
// Container for staggered child animations
export const staggerContainer = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: { staggerChildren: 0.1, delayChildren: 0.2 }
}
};
// Individual items within staggered containers
export const staggerItem = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0, transition: { duration: 0.5 } }
};
Standard pattern for content reveals:
import { motion } from 'motion';
import { fadeInUp } from '@/lib/animations';
<motion.div
variants={fadeInUp}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
Content here
</motion.div>
For sequential reveals of multiple elements:
import { motion } from 'motion';
import { staggerContainer, staggerItem } from '@/lib/animations';
<motion.div
variants={staggerContainer}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
<motion.h1 variants={staggerItem}>Title</motion.h1>
<motion.p variants={staggerItem}>Subtitle</motion.p>
<motion.div variants={staggerItem}>CTA Buttons</motion.div>
</motion.div>
For buttons and interactive elements:
import { motion } from 'motion';
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
animate={{ y: [0, -8, 0] }}
transition={{
y: { duration: 2, repeat: Infinity, ease: "easeInOut" }
}}
>
Call to Action
</motion.button>
For connecting lines and decorative elements:
import { motion } from 'motion';
<motion.svg>
<motion.path
d="M 200 100 Q 400 50 600 100 T 1000 100"
stroke="rgb(var(--primary) / 0.3)"
strokeDasharray="8 8"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 2, delay: 0.5 }}
/>
</motion.svg>
import { motion } from 'motion';
<motion.span
whileHover={{
scale: 1.2,
backgroundColor: "rgb(var(--primary) / 0.2)"
}}
transition={{ duration: 0.2 }}
>
Icon
</motion.span>
Complement Motion animations with CSS for always-running effects:
/* Add to globals.css */
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-5px); }
}
@keyframes slide-up {
0% { opacity: 0; transform: translateY(10px); }
100% { opacity: 1; transform: translateY(0); }
}
.animate-float {
animation: float 4s ease-in-out infinite;
}
.animate-slide-up {
animation: slide-up 0.4s ease-out forwards;
opacity: 0;
}
viewport={{ once: true }} to prevent re-triggersTwo-column layout with opposing slide animations:
<motion.section className="grid md:grid-cols-2 gap-8">
<motion.div
variants={fadeInLeft}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
<h1>Hero Title</h1>
<p>Hero Description</p>
</motion.div>
<motion.div
variants={fadeInRight}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
<img src="/hero-image.jpg" alt="Hero" />
</motion.div>
</motion.section>
Staggered item reveals with hover interactions:
<motion.div
variants={staggerContainer}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className="grid md:grid-cols-3 gap-6"
>
{features.map((feature, index) => (
<motion.div
key={index}
variants={staggerItem}
whileHover={{ y: -5 }}
className="p-6 bg-white rounded-lg shadow"
>
<h3>{feature.title}</h3>
<p>{feature.description}</p>
</motion.div>
))}
</motion.div>
Sequential reveals with connecting line animations:
<motion.div className="relative">
{/* Connecting line */}
<motion.div
className="absolute left-4 top-8 h-full w-0.5 bg-primary/20"
initial={{ scaleY: 0 }}
whileInView={{ scaleY: 1 }}
viewport={{ once: true }}
transition={{ duration: 1, delay: 0.5 }}
/>
{/* Steps */}
<motion.div
variants={staggerContainer}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
{steps.map((step, index) => (
<motion.div
key={index}
variants={staggerItem}
className="relative pl-12 pb-8"
>
<div className="absolute left-0 w-8 h-8 bg-primary rounded-full" />
<h3>{step.title}</h3>
<p>{step.description}</p>
</motion.div>
))}
</motion.div>
</motion.div>
Pulsing buttons with bounce effects:
<motion.section
variants={fadeInScale}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className="text-center py-16"
>
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
animate={{
boxShadow: [
"0 0 0 0 rgba(59, 130, 246, 0.7)",
"0 0 0 10px rgba(59, 130, 246, 0)",
]
}}
transition={{
boxShadow: { duration: 1.5, repeat: Infinity }
}}
className="px-8 py-4 bg-blue-500 text-white rounded-lg"
>
Get Started Now
</motion.button>
</motion.section>
viewport={{ once: true }} for scroll animationstransform and opacity changes over layout propertieswill-change: transform sparingly and remove after animationprefers-reduced-motion media queryimport { motion } from 'motion';
const AnimatedComponent = ({ children }) => {
const prefersReducedMotion = typeof window !== 'undefined' &&
window.matchMedia('(prefers-reduced-motion: reduce)').matches;
return (
<motion.div
variants={prefersReducedMotion ? {} : fadeInUp}
initial={prefersReducedMotion ? false : "hidden"}
whileInView={prefersReducedMotion ? false : "visible"}
viewport={{ once: true }}
>
{children}
</motion.div>
);
};
{
"dependencies": {
"motion": "^12.23.26"
},
"devDependencies": {
"tw-animate-css": "^1.4.0"
}
}
This animation system provides:
The system scales from simple fade-ins to complex orchestrated sequences while maintaining optimal performance in Next.js applications.