如何通过循环旋转木马进行平滑过渡

时间:2018-04-16 18:37:07

标签: javascript css reactjs react-redux

当我在循环旋转木马中使用CSS重新定位图片时,我一直试图平稳过渡。

正如您在下面的代码中所看到的,当您按下时,只有最后一个图像平滑过渡到第一个位置,其他图像向前跳跃。

按下时,只有前四个图像平滑过渡到新位置,第一个图像跳到最后一个位置。

https://codepen.io/JeffHernandez/pen/mxJqdp

这是我的css

  -webkit-transition: all 200ms linear;
  -moz-transition: all 200ms linear;
  -ms-transition: all 200ms linear;
  -o-transition: all 200ms linear;

我认为我的问题与重新排序图像对象有关,我目前正在使用以下函数。我正在使用slice来创建一个新对象,所以我不会在当前状态下更改引用类型。

moveUp() {
  let items = this.state.items.slice();
  items.unshift(items.pop())
  this.setState({items})
}

moveDown() {
  let items = this.state.items.slice();
  items.push(items.shift())
  this.setState({items})
}

我的印象是使用一致的键值会解决这个问题,但它没有奏效。我可能需要采用另一种方法,但我不确定。

任何建议都将不胜感激。

编辑:我能够弄明白。 https://codepen.io/JeffHernandez/pen/odNeNY

我正在替换类而不是仅修改值。我能够通过使用样式化组件

来实现这一目标

1 个答案:

答案 0 :(得分:1)

我认为重新排序图片不是最好的解决方案。我宁愿尝试根据"目前有效的#34;来改变课程。

class VerticalCarousel extends React.Component {

    constructor(props) {
        super(props)
        this.state = {
          items: images,
          currentActive: 0 //initially, current active is top slide, 
                           //images[0] element
        }
    }

    changeSlide = (direction) => {
          let nextSlide;
          if (direction === 'up') {
              nextSlide = this.state.currentActive - 1
          } else {
              nextSlide = this.state.currentActive + 1
          }
         // aslo you have to set rules for boundary conditions when 
         // currentActive is [0] and "Up" button clicked
         // or currentActive is the last element in array and "Down" clicked
         this.setState({ currentActive: nextSlide });
    };

   render() {
     return(
        <div className="absolute">
            {this.state.items.map((item, index) => 
                <Image data={item} currentActive={this.state.currentActive} 
                 index={index} key={index} />
            )}             
          <div>
          <button onClick={() => 
             {this.changeSlide('up')}}className="buttonUp">Up</button>
          <button onClick={() => 
             {this.changeSlide('down')}}className="buttonDown">Down</button>
          </div>
      </div>
     )
   }
}

为避免主要组件混乱,请使用单独的Image。它应该包含一些设置类的逻辑。一般的想法是"active"上的currentActive课程,下一个"bottom"上的"previous" - 您的案例中的所有上述元素。此外,您可能还需要一些其他类来指定currenActive-1currentActive+1元素。你会得到这样的模式:

.previous - .previous.top - .active - .bottom.next - .bottom (不要忘记边界条件) 然后根据此调整你的风格。

class Image extends React.Component {
  render() {
     let position = ''
      let index = this.props.index
      let currentSlide = this.props.currentActive
       if (index === currentSlide) {
            position = 'active'
       }
       if (index > currentSlide) {
            position = 'bottom';
            if (index === currentSlide + 1) {
                position = `${position} next`
            }
       }
       if (index < currentSlide) {
                position = 'top';
                if (index === currentSlide - 1) {
                    position = `${position} previous`
                }
       }               
       let classList = `animate image ${position}`           
       return 
             <img key={this.props.key} src={this.props.data.image} className={classList}/>
      }
    }

以下是所述方法的粗略mock。使用样式和过渡来实现您期望的效果

P.S。我已将此解决方案用于我自己的反应轮播滑块。这是working democode source