来自 react-spring 的动画在 visibility-sensor 和 useEffect 下触发得太快
Animation from react-spring fires off too fast with visibility-sensor and useEffect
我有包装器 React 组件,它使用 react-spring 和 visibility-sensor 使其 children 从右侧淡入并将不透明度从 0 更改为 1。
useEffect 和 useState 都使孩子在第一次滚动后只出现一次。
问题是动画显示速度太快 - 没有从右侧到结束位置的 50px 的转换。 Image/text - 组件 children 在我滚动时弹出。
这是此组件的代码:
import React, { useEffect, useState } from 'react';
import { Spring, config } from 'react-spring/renderprops';
import VisibilitySensor from 'react-visibility-sensor';
export const FadeInContainer = ({
children
}: any) => {
const [isVisible, setVisibility] = useState(false);
const [entered, setEntered] = useState(false);
const onChange = (visiblity: any) => {
setTimeout(() => {
setVisibility(visiblity);
}, 200);
};
useEffect(() => {
if (isVisible) {
setEntered(true);
}
}, [isVisible]);
const FadeInDirection = () => {
return (
<Spring
delay={500}
config={config.slow}
to={{
opacity: entered ? 1 : 0,
transform: entered ? 'translateY(0)' : 'translateY(50px)'
}}
>
{({ opacity, transform }) => (
<div style={{ opacity, transform }}>{children}</div>
)}
</Spring>
);
};
return (
<VisibilitySensor onChange={onChange}>
<FadeInDirection />
</VisibilitySensor>
);
};
我已经尝试过的:
1、useEffect添加setTimeouts,onChange定义同上。
2. 尝试为能见度传感器添加 scrollDelay,如下所示:
<VisibilitySensor onChange={onChange} scrollDelay={300}>
只滚动一次的解决方案来自这个帖子:
你知道是否可以做些什么来使滚动时只发生一次的动画更流畅(主要是变换)?
我认为问题是动画不工作。它只是在没有动画的情况下将不透明度从 0 切换到 1。我将它更改为基于钩子的动画并且它只是工作(仅当 useSpring 在 FadeInDirection
组件之外时)。
所以最初的问题是,FadeInDirection
定义在 FadeInContainer
里面,它没有自己的属性。它在每次渲染时都被重新定义。
创建 FadeInDirection
作为单独的组件。
我也取消了useEffect,我只在VisibilitySensor
onChange return true时设置可见。
import React, { useState } from "react";
import { useSpring, animated } from "react-spring";
import VisibilitySensor from "react-visibility-sensor";
const FadeInDirection = ({ isVisible, children }) => {
const props = useSpring({
opacity: isVisible ? 1 : 0,
transform: isVisible ? "translateY(0px)" : "translateY(50px)"
});
return <animated.div style={props}>{children}</animated.div>;
};
export const FadeInContainer = ({ children }) => {
const [isVisible, setVisibility] = useState(false);
const onChange = visiblity => {
visiblity && setVisibility(visiblity);
};
return (
<VisibilitySensor onChange={onChange}>
<FadeInDirection isVisible={isVisible}>{children}</FadeInDirection>
</VisibilitySensor>
);
};
这里有一个例子:https://codesandbox.io/s/magical-sun-oqv0v?file=/src/App.js:184-787
我有包装器 React 组件,它使用 react-spring 和 visibility-sensor 使其 children 从右侧淡入并将不透明度从 0 更改为 1。 useEffect 和 useState 都使孩子在第一次滚动后只出现一次。
问题是动画显示速度太快 - 没有从右侧到结束位置的 50px 的转换。 Image/text - 组件 children 在我滚动时弹出。
这是此组件的代码:
import React, { useEffect, useState } from 'react';
import { Spring, config } from 'react-spring/renderprops';
import VisibilitySensor from 'react-visibility-sensor';
export const FadeInContainer = ({
children
}: any) => {
const [isVisible, setVisibility] = useState(false);
const [entered, setEntered] = useState(false);
const onChange = (visiblity: any) => {
setTimeout(() => {
setVisibility(visiblity);
}, 200);
};
useEffect(() => {
if (isVisible) {
setEntered(true);
}
}, [isVisible]);
const FadeInDirection = () => {
return (
<Spring
delay={500}
config={config.slow}
to={{
opacity: entered ? 1 : 0,
transform: entered ? 'translateY(0)' : 'translateY(50px)'
}}
>
{({ opacity, transform }) => (
<div style={{ opacity, transform }}>{children}</div>
)}
</Spring>
);
};
return (
<VisibilitySensor onChange={onChange}>
<FadeInDirection />
</VisibilitySensor>
);
};
我已经尝试过的: 1、useEffect添加setTimeouts,onChange定义同上。 2. 尝试为能见度传感器添加 scrollDelay,如下所示:
<VisibilitySensor onChange={onChange} scrollDelay={300}>
只滚动一次的解决方案来自这个帖子:
你知道是否可以做些什么来使滚动时只发生一次的动画更流畅(主要是变换)?
我认为问题是动画不工作。它只是在没有动画的情况下将不透明度从 0 切换到 1。我将它更改为基于钩子的动画并且它只是工作(仅当 useSpring 在 FadeInDirection
组件之外时)。
所以最初的问题是,FadeInDirection
定义在 FadeInContainer
里面,它没有自己的属性。它在每次渲染时都被重新定义。
创建 FadeInDirection
作为单独的组件。
我也取消了useEffect,我只在VisibilitySensor
onChange return true时设置可见。
import React, { useState } from "react";
import { useSpring, animated } from "react-spring";
import VisibilitySensor from "react-visibility-sensor";
const FadeInDirection = ({ isVisible, children }) => {
const props = useSpring({
opacity: isVisible ? 1 : 0,
transform: isVisible ? "translateY(0px)" : "translateY(50px)"
});
return <animated.div style={props}>{children}</animated.div>;
};
export const FadeInContainer = ({ children }) => {
const [isVisible, setVisibility] = useState(false);
const onChange = visiblity => {
visiblity && setVisibility(visiblity);
};
return (
<VisibilitySensor onChange={onChange}>
<FadeInDirection isVisible={isVisible}>{children}</FadeInDirection>
</VisibilitySensor>
);
};
这里有一个例子:https://codesandbox.io/s/magical-sun-oqv0v?file=/src/App.js:184-787