Skip to content

Instantly share code, notes, and snippets.

@tol-is
Created October 4, 2019 09:47
Show Gist options
  • Select an option

  • Save tol-is/d442f7de5e25d22d213b2a003654da7d to your computer and use it in GitHub Desktop.

Select an option

Save tol-is/d442f7de5e25d22d213b2a003654da7d to your computer and use it in GitHub Desktop.

Revisions

  1. tol-is created this gist Oct 4, 2019.
    53 changes: 53 additions & 0 deletions Parallax
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,53 @@
    import React, { useState, useRef, useEffect, useLayoutEffect } from 'react';
    import { useViewportScroll, useTransform, motion } from 'framer-motion';

    const Parallax = ({ rangeX, rangeY, children, ...rest }) => {
    const ref = useRef();

    const [rangeStart, setRangeStart] = useState(0);
    const [rangeEnd, setRangeEnd] = useState(0);

    const { scrollY } = useViewportScroll();
    useLayoutEffect(() => {
    const onResize = () => {
    const scrollPos = window.pageYOffset;
    const html = document.documentElement;
    const viewportHeight = window.innerHeight || html.clientHeight;
    const rect = ref.current.getBoundingClientRect();

    let start = rect.top + scrollPos - viewportHeight;
    let end = rect.top + scrollPos + rect.height;

    setRangeStart(start);
    setRangeEnd(end);
    };

    setTimeout(onResize, 350);
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
    }, [ref, rangeX, rangeX]);

    const y = useTransform(
    scrollY,
    [rangeStart, rangeEnd],
    [`${rangeY[0] * 100}%`, `${rangeY[1] * 100}%`]
    );
    const x = useTransform(
    scrollY,
    [rangeStart, rangeEnd],
    [`${rangeX[0] * 100}%`, `${rangeX[1] * 100}%`]
    );

    return (
    <motion.div ref={ref} style={{ x, y }} {...rest}>
    {children}
    </motion.div>
    );
    };

    Parallax.defaultProps = {
    rangeX: [0, 0],
    rangeY: [0, 0],
    };

    export default Parallax;