实现效果
2020-09-10_095743.png
js部分
import React, { Component } from 'react'
import { LeftOutlined, RightOutlined} from '@ant-design/icons'
class Home extends Component {
constructor(props) {
super(props);
this.state = {
currentIndex: 0,
carouselStyle: {},
imageWidth: 500,
imageHeight: 500,
slideStyle: {},
imgStyle: {
transform: 'scale(1.1)',
transition: 'all linear .3s'
},
defaultImgStyle: {
transform: 'scale(1)',
transition: 'all linear .3s'
},
speed: 0 // 不需要鼠标移入时可设置speed的值为2
};
}
turn = () =>{ // 轮播
if(this.timer) {
clearInterval(this.timer)
}
this.timer = setInterval(()=>{
this.go(1)
},2 * 1000);
}
go = (step) => { // 去哪 传入要动几个
console.log(this.state.currentIndex, 'currentIndex')
let currentIndex = this.state.currentIndex + step;// 先加
if(currentIndex >= this.itemsLength){ // 当等于最后一张时 越界回到0
this.ul.style.transitionDuration ='0s';
this.ul.style.left =0;
setTimeout(()=>{// 等动画移除后并且回到了0点 再增加回动画时间(dom刷新一般是30s)
this.ul.style.transitionDuration = this.state.speed + 's';// 再增加回来这个动画
currentIndex = 0;// 下一次到第一张图
this.setState({currentIndex});
},30)
return;//因为设置了setTimeout所以要等待setTimeout后再设置最新状态
}
if(currentIndex < 0){// 当小于第一张时 回到最后一张
this.ul.style.transitionDuration = '';// 清除ul上的动画
this.ul.style.left = (this.itemsLength -1) * -1 * this.state.imageWidth + 'px';
setTimeout(()=>{
this.ul.style.transitionDuration = this.state.speed + 's';
currentIndex = this.itemsLength -1; // 小于第一张时跳转到最后一张
this.setState({currentIndex});
},30);
return
}
this.ul.style.transitionDuration = this.state.speed + 's';
const slideStyle = this.state.slideStyle
this.setState({
currentIndex,
slideStyle: Object.assign(slideStyle, {
left: -1 * this.state.imageWidth * currentIndex + 'px',
})
})
}
stop = () => {
clearInterval(this.timer)
this.timer = null
}
handleMouseEnter = (e, index) => {
e.preventDefault()
this.stop()
if(index) {
this.setState({
imgStyle: {
transform: 'scale(1.1)',
transition: 'all linear .3s'
}
})
this.hoverIndex = index - 1
}else {
this.hoverIndex = null
}
}
handleMouseLeave = (e, index) => {
e.preventDefault()
this.turn(true)
this.ul.style.transitionDuration = this.state.speed + 's';
if(index) {
this.setState({
imgStyle: {
transform: 'scale(1)',
transition: 'all linear .3s'
}
})
}
this.hoverIndex = null
}
linkToProduct = (id) => {
console.log(id,this.$route, 'id')
clearInterval(this.timer)
this.timer = null
window.location.hash = `#/products/${id}`
}
componentDidMount() {
this.items = [
{id: 1, src: require('../../assets/images/tu9.png')},
{id: 2, src: require('../../assets/images/tu8.png')},
{id: 3, src: require('../../assets/images/tu7.png')},
{id: 4, src: require('../../assets/images/tu6.png')},
{id: 5, src: require('../../assets/images/tu5.png')},
{id: 6, src: require('../../assets/images/tu4.png')},
{id: 7, src: require('../../assets/images/tu3.png')}
]
this.itemsLength = this.items.length
this.setState({
carouselStyle: {
width: this.state.imageWidth + 'px',
},
slideStyle: {
// 宽度增加1倍
width: this.state.imageWidth * this.items.length * 2 + 'px',
left: 0
}
})
this.hoverIndex = null
this.turn()
}
componentWillUnmount() {
clearInterval(this.timer)
this.timer = null
}
render(){
if(this.items && this.items.length) {
return (
<div className={'home-box'}>
<div
className={'carousel'} style={ Object.assign({overflow: 'hidden', heigth: this.imageHeight + 'px', width: '100%',marginTop: '20px'})}>
<ul className='slide' style={Object.assign({padding: 0}, this.state.slideStyle)} ref={(ul)=>{this.ul=ul;}}>
{this.items && this.items.map((item,index) => {
return <li key={item.id} className={'img-box'} style={{width: this.state.imageWidth}}
onMouseEnter={(e) => {this.handleMouseEnter(e, index + 1)}}
onMouseLeave={(e) => {this.handleMouseLeave(e, index + 1)}}
onClick={() => {this.linkToProduct(item.id)}}
>
<img alt={index} src={item.src} style={this.hoverIndex === index ? this.state.imgStyle : this.state.defaultImgStyle}/>
</li>
})}
{this.items && this.items.map((item,index) => {
return <li key={'back_' + item.id} className={'img-box'} style={{width: this.state.imageWidth}}
onMouseEnter={(e) => {this.handleMouseEnter(e, this.itemsLength + index + 1)}}
onMouseLeave={(e) => {this.handleMouseLeave(e, this.itemsLength + index + 1)}}
onClick={() => {this.linkToProduct(item.id)}}
>
<img alt={index} src={item.src} style={this.hoverIndex === this.itemsLength + index ? this.state.imgStyle : this.state.defaultImgStyle}/>
</li>
})}
</ul>
<div className={'left-control'} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} onClick={() => {this.go(1)}}><LeftOutlined /></div>
<div className={'right-control'} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} onClick={() => {this.go(-1)}}><RightOutlined /></div>
</div>
</div>
)
}else{
return null
}
}
}
Home.defaultProps = {
}
export default Home
css部分
.home-box{
background-image: url('../../images/timg.jpg');
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
/* background-position: center; */
background-position: 0 4vh;
min-height: 100vh;
}
.home-box .carousel{
position: relative;
height: 400px;
}
.home-box .carousel .slide{
position: absolute;
height: 400px;
-webkit-transition-timing-function: linear; /*之前是ease-out*/
-moz-transition-timing-function: linear;
-ms-transition-timing-function: linear;
-o-transition-timing-function: linear;
transition-timing-function: linear;
margin: 0 auto;
}
.img-box{
height: 400px;
float: left;
}
.img-box img{
width: 100%;
cursor: pointer;
}
.left-control,
.right-control{
position: absolute;
width: 50px;
height: 100%;
top: 0;
font-size: 40px;
background: transparent;
align-items:center;
display: flex;
cursor: pointer;
color: rgb(0,98,148);
opacity: 0;
}
.left-control{
left: 0
}
.right-control{
right: 0;
}
.carousel:hover .left-control,
.carousel:hover .right-control{
opacity: 1;
}
网友评论