|
@@ -0,0 +1,69 @@
|
|
|
|
|
+"use client"
|
|
|
|
|
+
|
|
|
|
|
+import {motion} from "framer-motion"
|
|
|
|
|
+import {ReactNode} from "react"
|
|
|
|
|
+
|
|
|
|
|
+type Direction = "up" | "down" | "left" | "right"
|
|
|
|
|
+type Effect = "fade" | "slide" | "scale" | "rotate" | "flip"
|
|
|
|
|
+
|
|
|
|
|
+interface AnimatedSectionProps {
|
|
|
|
|
+ children: ReactNode
|
|
|
|
|
+ effect?: Effect
|
|
|
|
|
+ direction?: Direction // 仅在 slide 时有用
|
|
|
|
|
+ duration?: number
|
|
|
|
|
+ delay?: number
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export default function AnimatedSection({
|
|
|
|
|
+ children,
|
|
|
|
|
+ effect = "slide",
|
|
|
|
|
+ direction = "up",
|
|
|
|
|
+ duration = 0.8,
|
|
|
|
|
+ delay = 0,
|
|
|
|
|
+ }: AnimatedSectionProps) {
|
|
|
|
|
+ let initial: any = { opacity: 0 }
|
|
|
|
|
+ let animate: any = { opacity: 1 }
|
|
|
|
|
+
|
|
|
|
|
+ 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 "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 "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>
|
|
|
|
|
+ )
|
|
|
|
|
+}
|