当我在循环轮播中使用 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
我正在替换类,而不仅仅是修改值。我能够通过使用样式化组件来完成此任务
最佳答案
我认为重新排序图像不是最好的解决方案。我宁愿尝试根据“当前事件”来更改类(class)。
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 分开。它应该包含一些设置类的逻辑。一般的想法是在 currentActive
上有 "active"
类,"bottom"
用于所有下一个 "previous"
-以上所有元素都在你的案例中。此外,您可能需要一些额外的类来指定 currenActive-1
和 currentActive+1
元素。你会得到这样的模式:
.previous
- .previous.top
- .active
- .bottom.next
- .底部
(不要忘记边界条件)
比根据这个调整你的风格。
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描述的方法。尝试使用样式和过渡来实现您期望的效果
附言我已将此解决方案用于我自己的 React Carousel slider 。这是 working demo和 code source
关于javascript - 如何在 React 中使用循环旋转木马实现平滑过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49864123/