【问题标题】:Crossfade between Gatsby Images盖茨比图像之间的淡入淡出
【发布时间】:2019-02-16 06:27:42
【问题描述】:

使用 gatsby-image,我正在使用 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}
 />

当源更改时,有什么方法可以对此进行转换?

【问题讨论】:

    标签: javascript reactjs image css-transitions gatsby


    【解决方案1】:

    这是我的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;
    

    现场演示

    【讨论】:

      【解决方案2】:

      这是一种可能的方法:

      1. 通过position: absolute将两个标签堆叠在一起
      2. 使用transition: opacity 1s ease-in-out; 为它们设置样式
      3. 在 this.state 上放置一个新的 showFront: true 属性。
      4. 在 componentDidMount 间隔挂钩上:
        1. 为未激活的组件更新下一个图像大小(通过状态 obj)。
        2. 根据 showFront 的值,在每个组件上分别添加 1 和 0 的不透明度。您可以有条件地添加一个新类,例如:className={"my-image-class " + (this.state.showFront ? 'seen' : 'not-seen')}(并为底部图像反转)。在 styled-components 中,可以通过将 showFront 作为道具传递来做到这一点。
      5. 通过 componentDidMount setInterval 挂钩切换 showFront。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-24
        • 1970-01-01
        • 2011-10-20
        • 1970-01-01
        • 1970-01-01
        • 2013-12-19
        • 1970-01-01
        相关资源
        最近更新 更多