使用react-visibility-sensor

时间:2019-10-17 15:35:47

标签: reactjs scroll react-hooks

使用react-visibility-sensor,我创建了一个更高的组件来对滚动项目的各个部分进行动画处理。

我在尝试使其仅在第一个滚动条上工作时遇到问题。 此刻这些部分出现和消失。

任何帮助将不胜感激。干杯!

import VisibilitySensor from 'react-visibility-sensor';

export const SlideUp = ({ children }) => {
  const [isVisible, setVisibility] = useState(false);

  const onChange = visiblity => {
    setVisibility(visiblity);
  };

  return (
    <VisibilitySensor
      partialVisibility
      offset={{ top: 200 }}
      onChange={onChange}
    >
      <div
        style={{
          transition: `opacity ${0.5}s ease, transform ${0.5}s ease`,
          opacity: isVisible ? 1 : 0,
          transform: isVisible ? `translateY(${0}px)` : `translateY(${20}px)`,
        }}
      >
        {children}
      </div>
    </VisibilitySensor>
  );
};```

- use example:

<SlideUp>
  <Section />
</SlideUp>

4 个答案:

答案 0 :(得分:0)

backgroundColor

CSS

import VisibilitySensor from 'react-visibility-sensor';

export const SlideUp = ({ children }) => {
  const [isVisible, setVisibility] = useState(false);

  const onChange = visiblity => {
    setVisibility(visiblity);
  };

  return (
    <VisibilitySensor
      partialVisibility
      offset={{ top: 200 }}
      onChange={onChange}
    >
      <div
        className={`example ${isVisible ? 'visible' : ''}`}
      >
        {children}
      </div>
    </VisibilitySensor>
  );
};

尝试使用.example{ ... opacity: 0; transform: translateY(20px); transition: opacity 0.5s ease, transform 0.5s ease; } .example.visible{ opacity: 1; transform: translateY(0px); }

答案 1 :(得分:0)

我的解决方案是将React Pose与React Visibility混合使用。

可见性触发了React Pose中的动画,动画仅发生一次。动画取决于姿势,而不取决于可见性。

import VisibilitySensor from 'react-visibility-sensor';
import posed from 'react-pose';

const PoseDiv = posed.div({
  enter: {
    y: 0,
    opacity: 1,
    transition: {
      duration: 300,
      ease: 'easeIn',
    },
  },
  exit: { y: 20, opacity: 0 },
});

export const SlideUp = ({ children }) => {
  const [isVisible, setVisibility] = useState(false);
  const [entered, setEntered] = useState(false);

  const onChange = visiblity => {
    setVisibility(visiblity);
  };

  useEffect(() => {
    if (isVisible) {
      setEntered(true);
    }
  }, [isVisible]);

  return (
    <>
      <VisibilitySensor
        partialVisibility
        offset={{ top: 100 }}
        onChange={onChange}
      >
        <PoseDiv pose={entered ? 'enter' : 'exit'}>{children}</PoseDiv>
      </VisibilitySensor>
    </>
  );
}; 

我希望它可以帮助其他人。干杯!

PS:由于现已弃用React Pose,因此需要更新此解决方案。

https://www.framer.com/api/motion/migrate-from-pose/

答案 2 :(得分:0)

我认为您正在切换可见性状态,以使ui在显示后保持可见状态,请勿将状态更改为不可见

只是改变

const onChange = visiblity => {
   setVisibility(visiblity);
  };

const onChange = visiblity => {
if(visiblity){
 setVisibility(visiblity);
}
};

答案 3 :(得分:0)

这是我一直在使用的解决方案。只需使用hasBeenVisible渲染道具而不是isVisible

import React, { useState } from "react";
import VisibilitySensor from "react-visibility-sensor";

/**
 * VisibilitySensor does not implement some kind of funcionality to track first time
 * visibility. This component extends VisibilitySensor compoment to provide this
 * feature. Just use `hasBeenVisible` render prop instead of `isVisible`.
 * 
 * https://github.com/joshwnj/react-visibility-sensor/issues/117#issuecomment-686365798
 */
const AppearSensor = ({
  onChange,
  children,
  ...rest
}) => {
  const [hasBeenVisible, setHasBeenVisible] = useState(false);

  return (
    <VisibilitySensor {...rest} onChange={(isVisible) => {
      if (isVisible) setHasBeenVisible(true)
      if (onChange) onChange(isVisible)
    }}>
      {
        ({
          isVisible,
          ...restRenderProps
        }) => {
          return children({ isVisible, ...restRenderProps, hasBeenVisible })
        }
      }
    </VisibilitySensor>
  );
};

AppearSensor.propTypes = VisibilitySensor.propTypes
AppearSensor.defaultProps = VisibilitySensor.defaultProps

export default AppearSensor;