Framer: Проверьте, находится ли элемент в окне просмотра - PullRequest
0 голосов
/ 28 января 2020

При использовании Framer Motion API для создания взаимодействия и анимации на моем сайте я не могу найти, как использовать его для запуска анимации, когда что-то появляется на экране.

Например, это SVG dr aws правильно, но Framer не ждет, пока элемент появится в окне просмотра, и запускает его сразу после загрузки сайта:

import React, { Component } from 'react'
import { motion } from "framer-motion";

class IsometricScreen extends Component {

    constructor() {
        super()
        this.icon = {
            hidden: { pathLength: 0 },
            visible: { pathLength: 1 }
        }
    }

    render() {
        return (
            <motion.svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 1000" className="svg-mobile">
                <motion.path
                    d="M418,988.93H82c-39.76,0-72-32.24-72-72V83.07c0-39.76,32.24-72,72-72h336c39.76,0,72,32.24,72,72v833.86
                    C490,956.69,457.76,988.93,418,988.93z"
                    variants={this.icon}
                    initial="hidden"
                    animate="visible"
                    transition={{
                        default: { duration: 2, ease: "easeInOut" }
                    }}
                />
            </motion.svg>
        )
    }
}

export default IsometricScreen

Имеет ли Framer триггер для определения области просмотра здесь реализовано?

Ответы [ 2 ]

3 голосов
/ 26 апреля 2020

Кроме того, вы можете использовать Intersection Observer, прекрасно сочетающийся с движением React и framer.

import { useInView } from "react-intersection-observer"; // 1.9K gzipped
import { motion, useAnimation } from "framer-motion";

const Component = () => {
    const animation = useAnimation();    
    const [ref, inView, entry] = useInView({ threshold: 0.1 });

    useEffect(() => {
      if (inView) {
        animation.start("visible");
      } else {
        animation.start("hidden");
      }
    }, [animation, inView]);

    const variants = {
        visible: {
          y: 0,
          opacity: 1,
          transition: { duration: 0.5, delayChilden: 0.2, staggerChildren: 0.1 },
        },
        hidden: {
          y: enter,
          opacity: 0,
        },
    }

    return (
        <motion.div
          ref={ref}
          animate={animation}
          initial="hidden"
          variants={{variants}}
        />
      );
}

Вы также можете уточнить анимацию, посмотрев на входной объект (вход сверху или снизу и т. Д. * 1005) *)

0 голосов
/ 28 января 2020

Я наконец решил это с помощью крошечного функционального компонента:

function inViewport() {

    const isInViewport = el => {
        const rect = el.getBoundingClientRect()
        const vertInView = (rect.top <= window.innerHeight) && ((rect.top + rect.height) >= 0)
        const horInView = (rect.left <= window.innerWidth) && ((rect.left + rect.width) >= 0)
        return (vertInView && horInView)
    }

    this.elms = document.querySelectorAll('.showOnScreen')

    window.addEventListener("scroll", () => {
        this.elms.forEach(elm => isInViewport(elm) ? elm.classList.add('visible') : elm.classList.remove('visible'))
    })
}

export default inViewport
...