返回动效库
滚动进阶

视差浮动

元素随滚动以不同速率移动,产生深度视差效果,增强页面层次感。

滚动时continuous

交互预览

动效定义与代码

{
  "slug": "parallax-float",
  "name": "视差浮动",
  "nameEn": "Parallax Float",
  "description": "元素随滚动以不同速率移动,产生深度视差效果,增强页面层次感。",
  "descriptionEn": "Elements move at different speeds during scroll, creating a depth parallax effect that enhances visual layers.",
  "category": "scroll",
  "tags": [
    "scroll",
    "parallax",
    "depth",
    "float"
  ],
  "trigger": "on-scroll",
  "difficulty": "intermediate",
  "duration": "continuous",
  "easing": "linear",
  "cssProperties": [
    "transform"
  ],
  "isGPUAccelerated": true,
  "previewBg": "gradient",
  "keywords": [
    "parallax",
    "float",
    "depth",
    "scroll speed",
    "layers",
    "3D"
  ],
  "useCases": [
    "Hero section background layers",
    "Landing page depth effect",
    "Decorative floating elements",
    "Image gallery parallax"
  ],
  "relatedAnimations": [
    "scroll-reveal"
  ],
  "recommendedStyles": [
    "hero-fullscreen",
    "magazine-grid",
    "glassmorphism"
  ],
  "codeSnippets": [
    {
      "label": "CSS Keyframes",
      "language": "css",
      "code": ".parallax-container {\n  will-change: transform;\n  perspective: 1px;\n  height: 100vh;\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n\n.parallax-layer-back {\n  transform: translateZ(-2px) scale(3);\n}\n\n.parallax-layer-mid {\n  transform: translateZ(-1px) scale(2);\n}\n\n.parallax-layer-front {\n  transform: translateZ(0);\n}\n\n/* Each layer shares these base styles */\n.parallax-layer-back,\n.parallax-layer-mid,\n.parallax-layer-front {\n  position: absolute;\n  inset: 0;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .parallax-container {\n    animation: none;\n  }\n}"
    },
    {
      "label": "Tailwind CSS",
      "language": "tsx",
      "code": "// JS-driven parallax with scroll listener\nimport { useEffect, useRef } from \"react\";\n\nfunction useParallax(speed = 0.5) {\n  const ref = useRef<HTMLDivElement>(null);\n\n  useEffect(() => {\n    const el = ref.current;\n    if (!el) return;\n\n    function onScroll() {\n      const rect = el!.getBoundingClientRect();\n      const offset = rect.top * speed;\n      el!.style.transform = `translateY(${offset}px)`;\n    }\n\n    window.addEventListener(\"scroll\", onScroll, { passive: true });\n    return () => window.removeEventListener(\"scroll\", onScroll);\n  }, [speed]);\n\n  return ref;\n}\n\n// Usage:\n// const ref = useParallax(0.3);\n// <div ref={ref} className=\"will-change-transform\">\n//   Floating content\n// </div>"
    },
    {
      "label": "Framer Motion",
      "language": "tsx",
      "code": "import { motion, useScroll, useTransform } from \"framer-motion\";\nimport { useRef } from \"react\";\n\n// Tip: disable parallax for reduced motion users\n// import { useReducedMotion } from \"framer-motion\";\n// const reduced = useReducedMotion();\n// const y = reduced ? 0 : useTransform(...);\n\nfunction ParallaxSection() {\n  const ref = useRef(null);\n  const { scrollYProgress } = useScroll({\n    target: ref,\n    offset: [\"start end\", \"end start\"],\n  });\n  const y = useTransform(scrollYProgress, [0, 1], [-50, 50]);\n\n  return (\n    <div ref={ref}>\n      <motion.div style={{ y }}>\n        Parallax content\n      </motion.div>\n    </div>\n  );\n}"
    }
  ]
}