层叠轮播图、小程序3D轮播图、小程序轮播图、折叠轮播图、叠式轮播图、微信小程序叠式轮播图实现、小程序层叠轮播图swiper、Taro层叠轮播图、Taro叠式轮播图

博主在项目中有叠式轮播需求,尝试改造TaroUI和小程序自带的swiper未成功,于是自己编写。实现了可左右滑动、可点击滑动至对应swiperItem的效果,还给出了html(tsx)和Css代码,提供了github地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

好久没写博客了,最近这项目中有个叠式轮播的需求 在网上找了一堆 都没有自己想要的 

最开始被 TaroUI和小程序 自带的swiper困扰 一直以为是swpier的升级版 

试了好久 也没改造成功

干脆自己写一个吧!

上个最终样式图:

最初版的demo图

最终效果:

可左右滑动、可点击滑动至对应 swiperItem

跳转事件注释了 需要的自己打开

上代码啦:

html(tsx):

import Taro, { Component, Config } from "@tarojs/taro";
import { View, Text, Image } from "@tarojs/components";
import classnames from 'classnames'
import "./swiperSL.scss";
export default class SwiperSL extends Component {
  static defaultProps = {
          swiperData:[
            {img:'https://pic.meetao.com/images/admin/2531edf0b7e34c299892ceace72b2c81.jpg',title:'干啥啥都行',amount:'68.55',remark:'累计收益'},
            {img:'https://pic.meetao.com/images/admin/2e71e98cf50a409ab9f04d9cb3b19de4.png',title:'吃饭第一名',amount:'68.55',remark:'参与次数'},
            {img:'https://pic.meetao.com/images/admin/bc28dfc4a9ae470e86eed8f743a3d97a.png',title:'啊啊啊啊啊',amount:'68.55',remark:'勋章数量'},
            {img:'https://pic.meetao.com/images/admin/1070701b82e8416d940c558f5fb61ad2.jpg',title:'明天放假啦',amount:'68.55',remark:'累计勋章'},
            {img:'https://pic.meetao.com/images/admin/5a454819dabd469991c62c72e348c49b.jpg',title:'哈哈哈哈哈',amount:'68.55',remark:'勋章大小'}
          ],
        }
  constructor(props) {
    super(props);
    this.state = {
      leftWidth: 246,
      cacheIndex: 0,
      cardCur: 0,
      left: 0,
      screenRate: 1,
      isMove: false,
    };
  }
  componentWillMount() {}

  componentDidMount() {
    Taro.getSystemInfo({
      success: (res) => {
        // 750除以屏幕宽度,得到转换比。因为API用的和得到的大部分的单位都是px,所以还是要转一下
        this.setState({
          screenRate: (750/res.screenWidth)
        })
      },
    })
  }

  componentWillUnmount() {

  }

  componentDidShow() {}

  componentDidHide() {}
  /**
   * 指定config的类型声明为: Taro.Config
   *
   * 由于 typescript 对于 object 类型推导只能推出 Key 的基本类型
   * 对于像 navigationBarTextStyle: 'black' 这样的推导出的类型是 string
   * 提示和声明 navigationBarTextStyle: 'black' | 'white' 类型冲突, 需要显示声明类型
   */
  swiperClick(index){
    this.setState({
      cardCur:index
    },()=>{
        // Taro.navigateTo({
        //   url: '../login/login?from=' + fromadress
        // }):""
    })
  }
  tapLeft(){
    // 0 -> 4
    let cardCur=this.state.cardCur;
    this.setState({
      cardCur: cardCur==0?4:(cardCur-1)
    })
  },
  tapRight(){
    let cardCur=this.state.cardCur;
    this.setState({
      cardCur: cardCur==4?0:(cardCur+1)
    })
  }
  touchstart(e) {
    this.setState({
      left : e.touches[0].pageX
    })
  },
  touchmove(e) {
    // 频率控制,一次移动完成后,才能进行下一次
    if (this.state.isMove) {
      return
    }
    let moveLength = (e.touches[0].pageX - this.state.left) * this.state.screenRate
    moveLength = moveLength > 60 ? 60 : moveLength
    moveLength = moveLength < -60 ? -60 : moveLength
    let rate = moveLength / 60
    if (rate == 1) {
      //从右往左滑
      this.setState({
        isMove : true
      },()=>{
        this.tapRight()
      });
    } else if (rate == -1) {
      //从左往右滑
      this.setState({
        isMove : true
      },()=>{
        this.tapLeft()
      });
    }
  },
  touchend() {
    setTimeout(() => {
      this.setState({
        isMove:false
      })
    }, 500)
  },
  render() {
    return (
      <View className="swiperSL">
        <View
          className='cardSwiper'
          onTouchstart={this.touchstart.bind(this)}
          onTouchmove={this.touchmove}
          onTouchend={this.touchend}
          >
          {this.props.swiperData.map((item,index)=>{
            return (
              <View
              onClick={this.swiperClick.bind(this, index)}
              className={classnames(this.state.cardCur==index&&'cur',((this.state.cardCur==4&&index==0)||(this.state.cardCur==0&&index==4)||this.state.cardCur+1==index||this.state.cardCur-1==index)&&'curs',((this.state.cardCur==4&&index==0)||this.state.cardCur+1==index)&&'curRight',((this.state.cardCur==0&&index==4)||this.state.cardCur-1==index)&&'curLeft',((this.state.cardCur==0&&index==3)||(this.state.cardCur==1&&index==4)||this.state.cardCur-2==index)&&'cursLt',((this.state.cardCur==3&&index==0)||(this.state.cardCur==4&&index==1)||this.state.cardCur+2==index)&&'cursRt','swiper-item')}
              style={{ 'position':'absolute','left':this.state.leftWidth + 'rpx','transform': (this.state.cardCur==0&&index==4||this.state.cardCur-1==index)?'translate(50%, 0px) translateZ(0px)':(this.state.cardCur==4&&index==0||this.state.cardCur+1==index)?'translate(-50%, 0px) translateZ(0px)':(this.state.cardCur==3&&index==0||this.state.cardCur+2==index)?'translate(-100%, 0px) translateZ(0px)':(this.state.cardCur==0&&index==3||this.state.cardCur-2==index)?'translate(100%, 0px) translateZ(0px)':'translate(0%, 0px) translateZ(0px)';}}
              key={item}>
                <View className={classnames('swiper-view','swiper-view'+index)}>
                  <Image className="header" src={item.img}></Image>
                  <View className="title">{item.title}</View>
                  <View className="amount">{item.amount}</View>
                  <View className="remark">{item.remark}</View>
                </View>
              </View>
            )
          })}
        </View>
      </View>
    );
  }
}

Css:

.swiperSL {
  background: #ffffff;
  position: relative;
  overflow: hidden;
  width: 100%;
  margin: 0 auto;
}

// 轮播图样式
.cardSwiper {
  width: 100%;
  height: 420rpx !important;
  background: #ffffff;
  position: relative;
}

.swiper-item {
  width: 258px !important;
  border-radius: 10px;

  left: 246rpx;
  overflow: hidden;
  box-sizing: border-box;
  // padding: 40rpx 0rpx 70rpx;
}

.swiper-view {
  width: 258px !important;
  height: 372px !important;

  display: block;
  border-radius: 10rpx;
  transform: scale(0.74);
  transition: all 0.2s ease-in 0s;
  overflow: hidden;
  background: #FFFBEF;
  text-align: center;
  font-family: PingFangSC-Regular,
    PingFang SC;
}

.swiper-item.cur {
  z-index: 10;
  position: absolute;
  width: 100%;
  height: 100%;
  left: 246rpx;

}

.swiper-item.curs {
  z-index: 9;
  transform: translate(50%, 0px) translateZ(0px) !important;
  position: absolute;
  width: 100%;
  height: 100%;
}

.swiper-item.curLeft {
  z-index: 9;
  transform: translate(50%, 0px) translateZ(0px) !important;
}

.swiper-item.curRight {
  z-index: 9;
  transform: translate(-50%, 0px) translateZ(0px) !important;
}

.swiper-item.cursLt {
  z-index: 6;
  transform: translate(100%, 0px) translateZ(0px) !important;
}

.swiper-item.cursRt {
  z-index: 6;
  transform: translate(-100%, 0px) translateZ(0px) !important;
}

.swiper-item.cur .swiper-view {
  transform: none;
  transition: all 0.2s ease-in 0s;
  background: #FFF5D4;
  box-shadow: 0px 2px 4px 0px #FFF5D4;
}

.swiper-item.curs .swiper-view {
  transform: none;
  transform: scale(0.85);
  transition: all 0.2s ease-in 0s;
  background: #FFF9E6;
}

// cell 样式
.header {
  display: block;
  margin: 0 auto;
  width: 130rpx;
  height: 130rpx;
  border-radius: 50%;
  margin-top: 41rpx;
}

.title {
  width: 100%;
  font-size: 34rpx;
  font-weight: 400;
  color: #333333;
  padding-top: 17rpx;
  line-height: 48rpx;
}

.amount {
  font-size: 36rpx;
  font-family: Helvetica-Bold, Helvetica;
  font-weight: bold;
  color: #FF5F43;
  padding-top: 14rpx;
  line-height: 43rpx;
}

.remark {
  font-size: 24px;
  font-weight: 400;
  color: #999999;
  padding-top: 4rpx;
  line-height: 33rpx;
}
组件目录放置层级

组件目录放置层级如上

github地址:

https://github.com/JSL8023/SwiperSL

有用到的 给个star 😯

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值