在一段时间后图像发生变化时如何动画图像?

时间:2017-07-23 03:32:29

标签: javascript reactjs react-native redux react-router

我正在尝试制作一个图像滑块,其中image在5000秒后发生变化。 我在这里检查http://mumbaimirror.indiatimes.com/。这个网站实现了这个功能。 我试图在反应中实现相同。我能够做到这一点,但我的图像不是幻灯片(从右到左)换句话说,当第二张图像显示n时,图像不显示动画 这是我的代码 https://codesandbox.io/s/YrO0LvAA

 constructor(){
    super();
    this.pre=this.pre.bind(this);
     this.next=this.next.bind(this);
    this.state ={
      currentSlide :0
    }
     setInterval(()=>{
       var current = this.state.currentSlide;
    var next = current + 1;
    if (next > this.props.stories.items.length - 1) {
      next = 0;
    }
          this.setState({ currentSlide: next });

     }, 5000);


  }

2 个答案:

答案 0 :(得分:3)

执行此操作的一种方法是始终在右侧准备好未来图像(下一张图像),这样您就可以将其转换到左侧,同时将当前图像转换为左侧。所以他们都在一起。

在React中,这意味着您需要存储当前图像和下一个图像的索引,并且每个X秒都需要将它们向左移动(或根据您的操作向右移动)

这是一个概念证明:

https://codepen.io/nashio/pen/xLKepZ

const pics = [
  'https://cdn.pixabay.com/photo/2017/06/19/07/12/water-lily-2418339__480.jpg',
  'https://cdn.pixabay.com/photo/2017/07/18/18/24/dove-2516641__480.jpg',
  'https://cdn.pixabay.com/photo/2017/07/14/17/44/frog-2504507__480.jpg',
  'https://cdn.pixabay.com/photo/2016/09/04/13/08/bread-1643951__480.jpg',
];

class App extends React.Component {
  constructor(props) {
    super(props);
    const idxStart = 0;
    this.state = {
      index: idxStart,
      next: this.getNextIndex(idxStart),
      move: false,
    };
  }

  getNextIndex(idx) {
    if (idx >= pics.length - 1) {
      return 0;
    }
    return idx + 1;
  }

  setIndexes(idx) {
    this.setState({
      index: idx,
      next: this.getNextIndex(idx)
    });
  }

  componentDidMount() {        
    setInterval(() => {
      // on
      this.setState({
        move: true
      });
      // off
      setTimeout(() => {
        this.setState({
          move: false
        });
        this.setIndexes(this.getNextIndex(this.state.index));
      }, 500); // same delay as in the css transition here

    }, 2000); // next slide delay
  }
  render() {
    const move = this.state.move ? 'move' : '';
    if (this.state.move) {

    }
    return (
      <div className="mask">
        <div className="pic-wrapper">
          <div className={`current pic ${move}`}>
            {this.state.index}
            <img src={pics[this.state.index]} alt="" />
          </div>
          <div className={`next pic ${move}`}>
            {this.state.next}
            <img src={pics[this.state.next]} alt="" />
          </div>
        </div>
      </div>
    );
  }
}

React.render(<App />, document.getElementById('root'));


// CSS

.pic {
  display: inline-block;
  width: 100px;
  height: 100px;
  position: absolute;
  img {
    width: 100px;
    height: 100px;
  }
}

.current {
  left: 100px;
}

.current.move {
  left: 0;
  transition: all .5s ease;
}

.next {
  left: 200px;
}

.next.move {
  left: 100px;
  transition: all .5s ease;
}

.pic-wrapper {
  background: lightgray;
  left: -100px;
  position: absolute;

}

.mask {
  left: 50px;
  overflow: hidden;
  width: 100px;
  height: 120px;
  position: absolute;
}

编辑:更新了POC以处理左右导航,请参阅完整内容HERE

答案 1 :(得分:0)

这绝不是一个优雅的解决方案,但它会在第一次出现时从左侧滑动图像:https://codesandbox.io/s/xWyEN9Yz

我认为你遇到的问题是因为你只是渲染当前的故事,但你的大部分代码似乎都假设会有一个滚动的故事轮播,你可以像卷轴一样动画

使用滚动轮播方法,它就像动画左侧CSS属性一样简单,并根据当前可见的故事进行调整。即在你的组件中维护一些当前索引的状态,然后设置&#39; left&#39;故事容器的样式属性为该索引的倍数。 E.g:

const getLeftForIndex = index => ((index*325) + 'px');

<div className="ImageSlider" style={{ left: getLeftForIndex(currentStory) }}>
  <Stories />
</div>