使用反应可见性传感器,我创建了一个更高的组件来滚动时对项目的各个部分进行动画处理。
我在尝试使其仅在第一个滚动上工作时遇到问题。 目前,这些部分出现并消失。
任何帮助将不胜感激。干杯!
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>
我的解决方案是将 React Pose 与 React 可见性混合使用。
可见性会触发 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:由于 反应姿势 现已弃用。
https://www.framer.com/api/motion/migrate-from-pose/
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>
);
};
.CSS
.example{
...
opacity: 0;
transform: translateY(20px);
transition: opacity 0.5s ease, transform 0.5s ease;
}
.example.visible{
opacity: 1;
transform: translateY(0px);
}
尝试使用className
我认为您正在切换可见性状态,以保持 UI 在显示后可见,不要将状态更改为不可见
只是改变
const onChange = visiblity => {
setVisibility(visiblity);
};
自
const onChange = visiblity => {
if(visiblity){
setVisibility(visiblity);
}
};
这是我一直在使用的解决方案。只需使用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;
如果您希望div淡入一次,请保留在屏幕上。
更改此内容
const onChange = visiblity => {
setVisibility(visiblity);
};
对此
const onChange = visiblity => {
if(visiblity)
setVisibility(true);
};