我一直在尝试制作一个具有连续淡入效果的 Masonry 画廊,以便图片一张一张地淡入。还有一个随机播放功能,可以使图像随机化,并且在随机播放后它们会再次淡入。
这是演示和代码:
https://codesandbox.io/s/objective-swartz-tuo1t
第一次访问页面时,动画是正确的。然而一旦我们点击了随机播放按钮,奇怪的事情发生了:经常有一些图片在淡入之前的图像之后并没有依次淡入,甚至没有淡入动画,它们只是从订单。
我实现这个动画的方法是根据图像的索引添加一个延迟过渡,并使用 ref
来跟踪图像。
首先我初始化ref
let refs = {};
for (let i = 0; i < images.length; i++) {
refs[i] = useRef(null);
}
然后我渲染图库
<Mansory gap={"1em"} minWidth={minWidth}>
{imgs.map((img, i) => {
return (
<PicContainer
index={img.index}
selected={isSelected}
key={img.index}
>
<Enlarger
src={img.url}
index={img.index}
setIsSelected={setIsSelected}
onLoad={() => {
refs[i].current.toggleOpacity(1); <--- start with zero opacity images till those are loaded
}}
ref={refs[i]}
realIndex={i}
/>
</PicContainer>
);
})}
</Mansory>
对于每个图像组件
class ZoomImg extends React.Component {
state = { zoomed: false, opacity: 0 };
toggleOpacity = o => {
console.log("here");
this.setState({ opacity: o }); <-- a setter function to change the opacity state via refs:
};
render() {
const {
realIndex,
index,
src,
enlargedSrc,
setIsSelected,
onLoad
} = this.props;
return (
<div style={{ margin: "0.25rem" }} onLoad={onLoad}>
<Image
style={{
opacity: this.state.opacity,
transition: "opacity 0.5s cubic-bezier(0.25,0.46,0.45,0.94)",
transitionDelay: `${realIndex * 0.1}s` <--- add a delay transition based on the index of the image.
}}
zoomed={this.state.zoomed}
src={src}
enlargedSrc={enlargedSrc}
onClick={() => {
this.setState({ zoomed: true });
setIsSelected(index);
}}
onRequestClose={() => {
this.setState({ zoomed: false });
setIsSelected(null);
}}
renderLoading={
<div
style={{
position: "absolute",
top: "50%",
color: "white",
left: "50%",
transform: "translateY(-50%} translateX(-50%)"
}}
>
Loading!
</div>
}
/>
</div>
);
}
}
我在 setter 函数中使用了 console.log("here");
,它将被调用以通过 refs 更改不透明度状态。有16张图片,所以最初调用了16次。但是当我点击随机播放按钮时,你可以看到它被调用了 少于 16 次,因为有些图片没有淡入就直接显示了。
我已经为这个问题苦苦挣扎了好几天,真的希望有人能给我一些提示。
最佳答案
问题是您在 shuffle 方法中只添加了一些新图像,一种方法是首先将 0 不透明度应用于所有 refs,然后等待几毫秒再次添加 1 不透明度,如 here .
但是,我会推荐一种更好的动画方法,我喜欢 shifty及其 Tweenable 模块。
关于javascript - react : Trying to achieve a sequential fade-in effect with a Masonry layout but it's out of order,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57671489/