无缝轮播两种实现方式

206 阅读1分钟

第一种实现方式(scroll)tsx部分

import React, { Component } from 'react'
import './index.scss'
export default class index extends Component {
  state = { start: 0, move: 0, index: 0, animate: 1, arr: [1, 2, 3, 4, 1] }
  componentDidUpdate() {
    ;(this.refs.app as HTMLDivElement).scrollLeft =
      this.state.index * (this.refs.app as HTMLDivElement).clientWidth
  }
  render() {
    const { start, move, index, animate, arr } = this.state
    return (
      <div
        className='app'
        ref={'app'}
        style={{ scrollBehavior: animate ? 'smooth' : undefined }}
        onTouchStart={(e) => {
          this.setState({ start: e.changedTouches[0].pageX, move: 0 })
        }}
        onTouchMove={(e) => {
          this.setState({ move: e.changedTouches[0].pageX - start })
        }}
        onTouchEnd={(e) => {
          if (move > 0) {
            if (index < 1)
              return this.setState(
                (e) => ({ index: 4, animate: 0 }),
                () => this.setState({ index: 3, animate: 1 })
              )
            this.setState({ index: index - 1 })
          } else {
            if (index > 3)
              return this.setState(
                (e) => ({ index: 0, animate: 0 }),
                () => this.setState({ index: 1, animate: 1 })
              )
            this.setState({ index: index + 1 })
          }
        }}
      >
        <div className='sub'>
          {arr.map((e) => (
            <div>{e}</div>
          ))}
        </div>
      </div>
    )
  }
}

第一种实现方式(scroll)css部分

.app {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
  .sub {
    width: 500%;
    height: 100%;
    display: flex;
    div {
      width: 100vw;
      height: 100%;
      text-align: center;
      line-height: 100vh;
      font-size: 100px;
    }
  }
}

第二种实现方式(定位)tsx部分

import React, { Component } from 'react'
import './index.scss'
export default class index extends Component {
  state = { start: 0, move: 0, index: 0, animate: 1, arr: [1, 2, 3, 4, 1] }
  onTouchEnd = (e: React.TouchEvent<HTMLDivElement>) => {}
  render() {
    const { start, move, index, animate, arr } = this.state
    console.log(index)
    return (
      <div
        className='app'
        onTouchStart={(e) => this.setState({ start: e.changedTouches[0].pageX, move: 0 })}
        onTouchMove={(e) => this.setState({ move: e.changedTouches[0].pageX - start })}
        onTouchEnd={(e) => {
          if (move > 0) {
            if (index < 1) {
              this.setState({ index: 4, animate: 0 }, () => {
                this.setState({ index: 3, animate: 1 })
              })
            } else {
              this.setState({ index: index - 1 })
            }
          } else {
            if (index > 3) {
              this.setState({ index: 0, animate: 0 }, () => {
                this.setState({ index: 1, animate: 1 })
              })
            } else {
              this.setState({ index: index + 1 })
            }
          }
        }}
      >
        <div className='sub' style={{ left: index * -375, transition: animate ? '.3s' : '' }}>
          {arr.map((e) => (
            <div>{e}</div>
          ))}
        </div>
      </div>
    )
  }
}

第二种实现方式(定位)scss部分

.app {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
  .sub {
    position: absolute;
    left: 0;
    top: 0;
    width: 500%;
    height: 100%;
    display: flex;
    div {
      width: 100vw;
      height: 100%;
      text-align: center;
      line-height: 100vh;
      font-size: 100px;
    }
  }
}