|
@@ -7,63 +7,63 @@ type Direction = "up" | "down" | "left" | "right"
|
|
|
type Effect = "fade" | "slide" | "scale" | "rotate" | "flip"
|
|
type Effect = "fade" | "slide" | "scale" | "rotate" | "flip"
|
|
|
|
|
|
|
|
interface AnimatedSectionProps {
|
|
interface AnimatedSectionProps {
|
|
|
- children: ReactNode
|
|
|
|
|
- effect?: Effect
|
|
|
|
|
- direction?: Direction // 仅在 slide 时有用
|
|
|
|
|
- duration?: number
|
|
|
|
|
- delay?: number
|
|
|
|
|
|
|
+ children: ReactNode
|
|
|
|
|
+ effect?: Effect
|
|
|
|
|
+ direction?: Direction // 仅在 slide 时有用
|
|
|
|
|
+ duration?: number
|
|
|
|
|
+ delay?: number
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export default function AnimatedSection({
|
|
export default function AnimatedSection({
|
|
|
- children,
|
|
|
|
|
- effect = "slide",
|
|
|
|
|
- direction = "up",
|
|
|
|
|
- duration = 0.8,
|
|
|
|
|
- delay = 0,
|
|
|
|
|
|
|
+ children,
|
|
|
|
|
+ effect = "slide",
|
|
|
|
|
+ direction = "up",
|
|
|
|
|
+ duration = 0.8,
|
|
|
|
|
+ delay = 0,
|
|
|
}: AnimatedSectionProps) {
|
|
}: AnimatedSectionProps) {
|
|
|
- let initial: any = { opacity: 0 }
|
|
|
|
|
- let animate: any = { opacity: 1 }
|
|
|
|
|
|
|
+ let initial: any = {opacity: 0}
|
|
|
|
|
+ let animate: any = {opacity: 1}
|
|
|
|
|
|
|
|
- switch (effect) {
|
|
|
|
|
- case "fade":
|
|
|
|
|
- // 纯渐隐渐显
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ switch (effect) {
|
|
|
|
|
+ case "fade":
|
|
|
|
|
+ // 纯渐隐渐显
|
|
|
|
|
+ break
|
|
|
|
|
|
|
|
- case "slide":
|
|
|
|
|
- const offset: Record<Direction, { x: number; y: number }> = {
|
|
|
|
|
- up: { x: 0, y: 40 },
|
|
|
|
|
- down: { x: 0, y: -40 },
|
|
|
|
|
- left: { x: 40, y: 0 },
|
|
|
|
|
- right: { x: -40, y: 0 },
|
|
|
|
|
- }
|
|
|
|
|
- initial = { opacity: 0, ...offset[direction] }
|
|
|
|
|
- animate = { opacity: 1, x: 0, y: 0 }
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ case "slide":
|
|
|
|
|
+ const offset: Record<Direction, { x: number; y: number }> = {
|
|
|
|
|
+ up: {x: 0, y: 40},
|
|
|
|
|
+ down: {x: 0, y: -40},
|
|
|
|
|
+ left: {x: 40, y: 0},
|
|
|
|
|
+ right: {x: -40, y: 0},
|
|
|
|
|
+ }
|
|
|
|
|
+ initial = {opacity: 0, ...offset[direction]}
|
|
|
|
|
+ animate = {opacity: 1, x: 0, y: 0}
|
|
|
|
|
+ break
|
|
|
|
|
|
|
|
- case "scale":
|
|
|
|
|
- initial = { opacity: 0, scale: 0.8 }
|
|
|
|
|
- animate = { opacity: 1, scale: 1 }
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ case "scale":
|
|
|
|
|
+ initial = {opacity: 0, scale: 0.8}
|
|
|
|
|
+ animate = {opacity: 1, scale: 1}
|
|
|
|
|
+ break
|
|
|
|
|
|
|
|
- case "rotate":
|
|
|
|
|
- initial = { opacity: 0, rotate: -15 }
|
|
|
|
|
- animate = { opacity: 1, rotate: 0 }
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ case "rotate":
|
|
|
|
|
+ initial = {opacity: 0, rotate: -15}
|
|
|
|
|
+ animate = {opacity: 1, rotate: 0}
|
|
|
|
|
+ break
|
|
|
|
|
|
|
|
- case "flip":
|
|
|
|
|
- initial = { opacity: 0, rotateY: 90 }
|
|
|
|
|
- animate = { opacity: 1, rotateY: 0 }
|
|
|
|
|
- break
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ case "flip":
|
|
|
|
|
+ initial = {opacity: 0, rotateY: 90}
|
|
|
|
|
+ animate = {opacity: 1, rotateY: 0}
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- return (
|
|
|
|
|
- <motion.div
|
|
|
|
|
- initial={initial}
|
|
|
|
|
- whileInView={animate}
|
|
|
|
|
- transition={{ duration, delay, ease: "easeOut" }}
|
|
|
|
|
- viewport={{ once: true }}
|
|
|
|
|
- >
|
|
|
|
|
- {children}
|
|
|
|
|
- </motion.div>
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ return (
|
|
|
|
|
+ <motion.div
|
|
|
|
|
+ initial={initial}
|
|
|
|
|
+ whileInView={animate}
|
|
|
|
|
+ transition={{duration, delay, ease: "easeOut"}}
|
|
|
|
|
+ viewport={{once: true}}
|
|
|
|
|
+ >
|
|
|
|
|
+ {children}
|
|
|
|
|
+ </motion.div>
|
|
|
|
|
+ )
|
|
|
}
|
|
}
|