对于gatsby图像,我使用setInterval()
交换了一些照片并更改了src,就像这样:
componentDidMount() {
this.setState({
intervalFunction: setInterval(this.imageCycle, 10000),
});
}
componentWillUnmount() {
clearInterval(this.intervalFunction);
}
imageCycle() {
let newImage = this.state.equiptmentCurrent + 1;
if (newImage >= this.state.equiptmentImages.length) {
newImage = 0;
}
this.setState(state => ({
equiptmentCurrent: newImage,
}));
}
渲染方法:
<IMG
sizes={this.state.equiptmentImages[this.state.equiptmentCurrent]}
outerWrapperClassName="coverOuter"
position="absolute"
style={gatsbyImgStyle}
/>
当源更改时,是否有任何方法可以对此进行过渡?
答案 0 :(得分:0)
这是一种可能的方法:
position: absolute
在彼此之间堆叠两个标签transition: opacity 1s ease-in-out;
showFront: true
属性。className={"my-image-class " + (this.state.showFront ? 'seen' : 'not-seen')}
(底部图像则相反)。在样式化组件中,可以通过将showFront作为prop来实现。 答案 1 :(得分:0)
这是我的CrossFadeImage
实现。它与img
类似,不同之处在于它可以在检测到props.src
更改时为您处理动画,并具有用于自定义过渡的额外道具
import React from "react";
const usePrevious = <T extends any>(value: T) => {
const ref = React.useRef<T>();
React.useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
};
const useRequestAnimationFrame = (): [(cb: () => void) => void, Function] => {
const handles = React.useRef<number[]>([]);
const _raf = (cb: () => void) => {
handles.current.push(requestAnimationFrame(cb));
};
const _resetRaf = () => {
handles.current.forEach((id) => cancelAnimationFrame(id));
handles.current = [];
};
return [_raf, _resetRaf];
};
type ImageProps = {
src: string;
alt?: string;
transitionDuration?: number;
curve?: string;
};
const CrossFadeImage = (props: ImageProps) => {
const { src, alt, transitionDuration = 0.35, curve = "ease" } = props;
const oldSrc = usePrevious(src);
const [topSrc, setTopSrc] = React.useState<string>(src);
const [bottomSrc, setBottomSrc] = React.useState<string>("");
const [bottomOpacity, setBottomOpacity] = React.useState(0);
const [display, setDisplay] = React.useState(false);
const [raf, resetRaf] = useRequestAnimationFrame();
React.useEffect(() => {
if (src !== oldSrc) {
resetRaf();
setTopSrc("");
setBottomSrc("");
raf(() => {
setTopSrc(src);
setBottomSrc(oldSrc!);
setBottomOpacity(99);
raf(() => {
setBottomOpacity(0);
});
});
}
});
return (
<div
className="imgContainer"
style={{
position: "relative",
height: "100%"
}}
>
{topSrc && (
<img
style={{
position: "absolute",
opacity: display ? "100%" : 0,
transition: `opacity ${transitionDuration}s ${curve}`
}}
onLoad={() => setDisplay(true)}
src={topSrc}
alt={alt}
/>
)}
{bottomSrc && (
<img
style={{
position: "absolute",
opacity: bottomOpacity + "%",
transition: `opacity ${transitionDuration}s ${curve}`
}}
src={bottomSrc}
alt={alt}
/>
)}
</div>
);
};
export default CrossFadeImage;