小程序之3d滑动

axml

<swiper style="height:{{moduleHeight}}rpx;max-height:1190rpx;">
  <swiper-item>
    <scroll-view catchTouchStart="catchstart" catchTouchMove="catchmove" catchTouchEnd="catchend">
      <!-- 3d多图滑动 -->
      <view style="width:714rpx;background-color:{{moduleBgColor}};margin:0 auto;display:flex;flex-wrap:wrap;justify-content:center">
        <!-- logo -->
        <view a:if="{{isLogo==1?true:false}}">
          <view style="width:678rpx;display:flex;justify-content:center">
            <view style="width:{{logoWidth}}rpx;height:{{logoHeight}}rpx;margin-top:{{logoTop}}rpx">
              <image mode="scaleToFill" src="{{(logoMod=='1')?(logoArr[logoIndex-1].image):(logoImg||logoImage)}}" style="width:100%;height:100%;background-size:100% 100%;"/>
            </view>
          </view>
        </view>
        <!-- 3d -->
        <view style="position:relative;width:714rpx;height:{{swiperHeight}}rpx;margin:{{swiperTop}}rpx 0 {{swiperBottom}}rpx 0;overflow:hidden">
          <!-- 多图滚动 -->
          <view style="display:flex;position:relative;perspective:600px;transform-style: preserve-3d;height:{{swiperHeight}}rpx;">
            <block a:for="{{picArr}}">
              <view style="width:{{picWidth}}rpx;
                       height:{{swiperHeight}}rpx;
                       position:absolute;
                       left:{{animation[index].left}}rpx;
                       opacity:{{animation[index].opacity}};
                       transition-property:transform,left,opacity;
                       transition-duration:{{animation[index].time}}s,{{animation[index].time}}s,{{animation[index].time}}s;
                       transition-timing-function:linear,linear;
                       z-index:{{animation[index].zIndex}};
                       transform:scale({{animation[index].scale}}) rotateY({{animation[index].rotateY}}deg)">
                <view style="width:{{picWidth}}rpx;position:relative;">
                  <!-- 图片 -->
                  <view style="width:{{picWidth}}rpx;height:{{picHeight}}rpx;">
                    <image mode="scaleToFill" src="{{(item)?(item.img||item.image):''}}" style="width:100%;height:100%;background-size:100% 100%"/>
                  </view>
                  <!-- 标题 -->
                  <view style="width:{{picWidth}}rpx;">
                    <!-- 价格 -->
                    <view style="display:flex;justify-content:center;">
                      <view style="align-items:center;height:{{titleHeight}}rpx;font-size:{{titleFontSize}}rpx;color:{{titleFontColor}};width:{{picWidth-40}}rpx;display:flex;justify-content:space-between">
                        <!-- 现价 -->
                        <view style="display:flex;align-items:flex-end;height:{{fontSize}}rpx;font-size:{{priceFontSize}}rpx;color:{{priceFontColor}}">¥{{item.nowPrice||'258.00'}}</view>
                        <!-- 原价 -->
                        <view a:if="{{isPrice==1?true:false}}">
                          <view style="text-decoration: line-through;display:flex;align-items:flex-end;height:{{fontSize}}rpx;">¥{{item.price||'288.00'}}</view>
                        </view>
                        <!-- 销量 -->
                        <view a:if="{{isSale==1?true:false}}">
                          <view style="display:flex;align-items:flex-end;height:{{fontSize}}rpx;">售{{item.sale||666}}</view>
                        </view>
                        <!-- buy -->
                        <view a:if="{{isBuy==1?true:false}}">
                          <view style="width:{{buyWidth}}rpx;height:{{buyHeight}}rpx;margin-top:{{buyTop}}rpx">
                            <image mode="scaleToFill" src="{{(buyMod=='1')?(buyArr[buyIndex-1].image):(buyImg||buyImage)}}" style="width:100%;height:100%;background-size:100% 100%;"/>
                          </view>
                        </view>
                      </view>
                    </view>
                    <!-- 标题介绍 -->
                    <view a:if="{{isTitleName==1?true:false}}">
                      <view style="overflow:hidden;text-overflow: ellipsis;white-space:nowrap;font-size:{{titleFontSize}}rpx;color:{{titleFontColor}};height:{{titleHeight}}rpx;">{{item.title||'时尚镂空长款秋冬款长袖连衣裙'}}</view>
                    </view>
                  </view>
                  <!-- 热区 -->
                  <block a:for="{{item.requ}}" a:for-item="item1">
                    <view style="background-color:{{isMc==1?'rgba(0,0,0,0.4)':''}};position:absolute;height:{{picHeight/item.image_height*item1.height}}rpx;top:{{picHeight/item.image_height*item1.top}}rpx;width:{{picWidth/item.image_width*item1.width}}rpx;left:{{picWidth/item.image_width*item1.left}}rpx" data-url="{{item1.href}}" onTap="onClickBaby"></view>
                  </block>
                </view>
              </view>
            </block>
          </view>
          <!-- 提示 -->
          <view a:if="{{isPoint==1?true:false}}">
            <view style="width:{{pointWidth}}rpx;height:{{pointHeight}}rpx;position:fixed;left:0;top:50%;">
               <image mode="scaleToFill" src="https://img.alicdn.com/imgextra/i3/39767794/O1CN01fMd2Ji27Rhaqi2gWh_!!39767794.png" style="width:100%;height:100%;background-size:100% 100%"/>
            </view>
          </view>
        </view>
      </view>
    </scroll-view>
  </swiper-item>
  <swiper-item>
  </swiper-item>
</swiper>

js

import { enhanceComponent } from 'tb-shop-enhance';

Component(enhanceComponent({
  data: {
    distance: 0,
    gap: 0,
    rightIndex: 0,
    leftIndex: 0,
    animation1: [],
    animation2: [],
    animation: [],
    buyArr: [
      {
        "image": "https://img.alicdn.com/imgextra/i4/39767794/O1CN01524uJd27Rha3UTviS_!!39767794.png"
      },
      {
        "image": "https://img.alicdn.com/imgextra/i4/39767794/O1CN01HTb5mu27Rhapp92R3_!!39767794.png"
      },
      {
        "image": "https://img.alicdn.com/imgextra/i2/39767794/O1CN01YRCvXM27RhaszKrt7_!!39767794.png"
      },
      {
        "image": "https://img.alicdn.com/imgextra/i1/39767794/O1CN01HKtN2N27RhaszJasn_!!39767794.png"
      }
    ],
    picArr: [
      {
        "title": "时尚镂空长款秋冬款长袖连衣裙",
        "price": "288.00",
        "nowPrice": "258.00",
        "sale": "888",
        "image": "https://img.alicdn.com/imgextra/i1/39767794/O1CN015Jjolj27Rha0iQNWR_!!39767794.png",
        "image_width": 250,
        "image_height": 400,
        "requ": [
          {
            "left": 0,
            "top": 0,
            "width": 250,
            "height": 400,
            "href": "//h5.m.taobao.com/awp/core/detail.htm?id=39574078846"
          }
        ]
      },
      {
        "title": "时尚镂空长款秋冬款长袖连衣裙",
        "price": "288.00",
        "nowPrice": "258.00",
        "sale": "888",
        "image": "https://img.alicdn.com/imgextra/i2/39767794/O1CN01rB711227RhZzsr1fU_!!39767794.png",
        "image_width": 250,
        "image_height": 400,
        "requ": [
          {
            "left": 0,
            "top": 0,
            "width": 250,
            "height": 400,
            "href": "//h5.m.taobao.com/awp/core/detail.htm?id=39574078846"
          }
        ]
      },
      {
        "title": "时尚镂空长款秋冬款长袖连衣裙",
        "price": "288.00",
        "nowPrice": "258.00",
        "sale": "888",
        "image": "https://img.alicdn.com/imgextra/i1/39767794/O1CN01sM4mVx27Rha5vK5J5_!!39767794.png",
        "image_width": 250,
        "image_height": 400,
        "requ": [
          {
            "left": 0,
            "top": 0,
            "width": 250,
            "height": 400,
            "href": "//h5.m.taobao.com/awp/core/detail.htm?id=39574078846"
          }
        ]
      },
      {
        "title": "时尚镂空长款秋冬款长袖连衣裙",
        "price": "288.00",
        "nowPrice": "258.00",
        "sale": "888",
        "image": "https://img.alicdn.com/imgextra/i3/39767794/O1CN01ZcjF8M27Rha2hBU2x_!!39767794.png",
        "image_width": 250,
        "image_height": 400,
        "requ": [
          {
            "left": 0,
            "top": 0,
            "width": 250,
            "height": 400,
            "href": "//h5.m.taobao.com/awp/core/detail.htm?id=39574078846"
          }
        ]
      },
      {
        "title": "时尚镂空长款秋冬款长袖连衣裙",
        "price": "288.00",
        "nowPrice": "258.00",
        "sale": "888",
        "image": "https://img.alicdn.com/imgextra/i1/39767794/O1CN01ExY22R27RhZxt0G98_!!39767794.png",
        "image_width": 250,
        "image_height": 400,
        "requ": [
          {
            "left": 0,
            "top": 0,
            "width": 250,
            "height": 400,
            "href": "//h5.m.taobao.com/awp/core/detail.htm?id=39574078846"
          }
        ]
      }
    ],
    logoArr: [
      {
        "image": "https://img.alicdn.com/imgextra/i2/39767794/O1CN01F9BLIt27Rhajw7yt0_!!39767794.png"
      },
      {
        "image": "https://img.alicdn.com/imgextra/i2/39767794/O1CN01QLwzVe27RhaqJ6E8r_!!39767794.png"
      },
      {
        "image": "https://img.alicdn.com/imgextra/i2/39767794/O1CN01fQO9Uu27RhabOGplS_!!39767794.png"
      }
    ]
  },

  onInit() {
    // mock数据需要修改client文件夹中的page文件
    // 正常运行过程中模块总是默认传入data参数
  },

  didMount() {
    // 加载成功后可以异步获取数据更新数据展示,例如请求接口等操作
    const { gdc = {}, mds = {}, modUtils } = this.props.data;
    let data = mds.moduleData
    this.setData({
      moduleBgColor: data.moduleBgColor || '#fff',
      // logo
      isLogo: data.isLogo || 1,
      logoSize: data.logoSize || '340,120,20',
      logoMod: data.logoMod || '1',
      logoIndex: data.logoIndex || 1,
      logoImg: data.logoImg,
      logoImage: data.logoImage,
      // 3d
      swiperSize: data.swiperSize || '250,400,40,20,0',//250-714
      titleFontSize: data.titleFontSize || '16,20',
      titleFontColor: data.titleFontColor || '#ccc,#000',
      swiperMode: data.swiperMode || '1',
      angle: data.angle || '40',
      isTitleName: data.isTitleName || '1',
      isPrice: data.isPrice || '1',
      isSale: data.isSale || '1',
      // buy
      isBuy: data.isBuy || '2',
      buySize: data.buySize || '40,50,-10',
      buyMod: data.buyMod || '1',
      buyIndex: data.buyIndex || '1',
      buyImg: data.buyImg,
      buyImage: data.buyImage,
      animationTime: data.animationTime || '1,3',
      isMc: data.isMc || '2',
      // 提示
      isPoint: data.isPoint || 1,
      pointSize: data.pointSize || '40,200',
      isAuto: data.isAuto || '1'
    });
    // 3d数组设置
    if (!data.picArr || !data.picArr[0] || !data.picArr[0].image || data.picArr[0].image == '') {
      this.setData({ picArr: this.data.picArr })
    } else {
      this.setData({ picArr: data.picArr })
    }
    // logo宽,高,上间距
    let logoSize = this.data.logoSize.split(",");
    this.setData({ logoWidth: parseInt(logoSize[0]), logoHeight: parseInt(logoSize[1]), logoTop: parseInt(logoSize[2]) });
    // 3d宽,高,上间距,下间距
    let swiperSize = this.data.swiperSize.split(",");
    this.setData({ picWidth: (parseInt(swiperSize[0]) <= 250) ? 250 : parseInt(swiperSize[0]), picHeight: parseInt(swiperSize[1]), titleHeight: parseInt(swiperSize[2]), swiperTop: parseInt(swiperSize[3]), swiperBottom: parseInt(swiperSize[4]) })
    // 标题默认字体大小,价格字体大小
    let titleFontSize = this.data.titleFontSize.split(",");
    this.setData({ titleFontSize: parseInt(titleFontSize[0]), priceFontSize: parseInt(titleFontSize[1]) });
    // 比较字体大小
    if (this.data.titleFontSize >= this.data.priceFontSize) {
      this.setData({ fontSize: this.data.titleFontSize })
    } else {
      this.setData({ fontSize: this.data.priceFontSize })
    }
    // 标题默认字体颜色,价格字体颜色
    let titleFontColor = this.data.titleFontColor.split(",");
    this.setData({ titleFontColor: titleFontColor[0], priceFontColor: titleFontColor[1] });
    // buy宽,高,上边距
    let buySize = this.data.buySize.split(',');
    this.setData({ buyWidth: parseInt(buySize[0]), buyHeight: parseInt(buySize[1]), buyTop: parseInt(buySize[2]) });
    //  动画切换时间,展示时间
    let animationTime = this.data.animationTime.split(",");
    this.setData({ duration: animationTime[0], interval: animationTime[1] });
    // 提示宽,高
    let pointSize = this.data.pointSize.split(",");
    this.setData({ pointWidth: parseInt(pointSize[0]), pointHeight: parseInt(pointSize[1]) })
    // 轮播高度
    this.setData({ swiperHeight: this.data.picHeight + this.data.titleHeight + (this.data.isTitleName == 1 ? this.data.titleHeight : 0) })
    // 模块高度
    this.setData({ moduleHeight: this.data.logoHeight + this.data.logoTop + this.data.swiperHeight + this.data.swiperTop + this.data.swiperBottom })
    // 3d预设1
    if (this.data.swiperMode == '1') {
      let picArr = this.data.picArr.concat(this.data.picArr);
      this.data.picArr = this.data.picArr.concat(picArr);
      this.setData({ picArr: this.data.picArr });
      this.setData({ picLes: this.data.picArr.length })
      this.data.picArr.map((item, index) => {
        // 左边
        if (index < (this.data.picLes / 3)) {
          this.data.animation1[index] = {
            "left": (this.data.picWidth * 0.5 + (index - this.data.picLes / 3) * this.data.picWidth),
            "scale": (1 - (this.data.picLes / 3 - index) * 0.2),
            "opacity": ((index < (this.data.picLes / 3) - 1) ? 0 : 1),
            "zIndex": 1,
            "rotateY": 0,
            "time": this.data.duration
          }
        }
        // 中间
        else if (index >= (this.data.picLes / 3)) {
          this.data.distance += (index > this.data.picLes / 3) ? (1 - (index - 1 - this.data.picLes / 3) * 0.2) * this.data.picWidth : 0
          this.data.animation1[index] = {
            "left": (this.data.picWidth * 0.5 + this.data.distance),
            "scale": (1 - (index - this.data.picLes / 3) * 0.2),
            "opacity": ((index >= (this.data.picLes / 3)) && (index < this.data.picLes * 2 / 3)) ? 1 : 0,
            "zIndex": 1,
            "rotateY": 0,
            "time": this.data.duration
          }
        }
      });
      this.setData({ animation1: this.data.animation1 });
      this.setData({ leftIndex: this.data.picLes - 1 })
    }
    // 预设2
    else if (this.data.swiperMode == '2') {
      //判断数组是否奇数
      if ((this.data.picArr.length % 2) != 1) {
        this.data.picArr.push(this.data.picArr[1])
      };
      // 让第一张图片弄到数组中间
      for (let i = 0; i < Math.ceil(this.data.picArr.length / 2); i++) {
        let firstArr = this.data.picArr.shift();
        this.data.picArr.push(firstArr);
      }
      this.setData({ picArr: this.data.picArr })
      let picArr = this.data.picArr.concat(this.data.picArr);
      this.data.picArr = this.data.picArr.concat(picArr);
      this.setData({ picArr: this.data.picArr });
      this.data.picArr.map((item, index) => {
        this.data.animation2[index] = {
          "left": `${(714 - this.data.picWidth) / 2 - this.data.picWidth / 2 * (parseInt(this.data.picArr.length / 2) - index)}`,
          "zIndex": `${(index > parseInt(this.data.picArr.length / 2)) ? (this.data.picArr.length - 1 - index) : index}`,
          "scale": `${1 - ((index <= parseInt(this.data.picArr.length / 2)) ? (0.2 * parseInt(this.data.picArr.length / 2) - 0.2 * index) : (0.2 * (index - parseInt(this.data.picArr.length / 2))))}`,
          "rotateY": `${(index != parseInt(this.data.picArr.length / 2)) ? ((index < parseInt(this.data.picArr.length / 2)) ? this.data.angle : -this.data.angle) : 0}`,
          "opacity": (index >= this.data.picArr.length / 3 && index < this.data.picArr.length * 2 / 3) ? 1 : 0,
          "time": `${this.data.duration}`
        }
      })

      this.setData({ animation2: this.data.animation2 });
      // // 数组长度
      this.setData({ leftIndex: this.data.picArr.length - 1 });
    }
    this.setData({ animation: (this.data.swiperMode == '1') ? this.data.animation1 : this.data.animation2 });
    // 是否自动滚动
    if (this.data.isAuto == '1') {
      this.timer = setInterval(() => {
        this.left()
      }, this.data.interval * 1000)
    }
  },

  methods: {
    // 触摸开始
    catchstart(e) {
      this.setData({ start: e.changedTouches[0].clientX });
      clearInterval(this.timer)
    },
    // 触摸结束
    catchend(e) {
      if (this.data.isAuto == '1') {
        this.timer = setInterval(() => {
          this.left()
        }, this.data.interval * 1000)
      }
      this.setData({ gap: e.changedTouches[0].clientX - this.data.start });
      if (this.data.gap < 0) {
        this.left()
      } else if (this.data.gap > 0) {
        this.right()
      }
    },
    // 向左
    left() {
      if (this.data.leftIndex + 1 > this.data.picArr.length - 1) {
        this.setData({ leftIndex: 0 })
      } else {
        this.setData({ leftIndex: ++this.data.leftIndex })
      }
      if (this.data.rightIndex + 1 > this.data.picArr.length - 1) {
        this.setData({ rightIndex: 0 })
      } else {
        this.setData({ rightIndex: ++this.data.rightIndex })
      }
      let leftArr = this.data.animation.pop();
      this.data.animation.unshift(leftArr);
      this.data.animation.map((item, index) => {
        if (index == this.data.leftIndex) {
          this.data.animation[index].time = 0;
          this.data.animation[index].opacity = 0;
        } else {
          this.data.animation[index].time = this.data.duration;
        }
      })
      this.setData({ animation: this.data.animation });
      // console.log(this.data.animation);
    },
    // 向右
    right() {
      if (this.data.rightIndex - 1 < 0) {
        this.setData({ rightIndex: this.data.picArr.length - 1 })
      } else {
        this.setData({ rightIndex: --this.data.rightIndex })
      }
      if (this.data.leftIndex - 1 < 0) {
        this.setData({ leftIndex: this.data.picArr.length - 1 })
      } else {
        this.setData({ leftIndex: --this.data.leftIndex })
      }
      let rightArr = this.data.animation.shift();
      this.data.animation.push(rightArr);
      this.data.animation.map((item, index) => {
        if (index == this.data.rightIndex) {
          this.data.animation[index].time = 0;
          this.data.animation[index].opacity = 0;
        } else {
          this.data.animation[index].time = this.data.duration;
        }
      })
      this.setData({ animation: this.data.animation });
    },
    // 移动
    catchmove(e) {

    },
    /**
     * 宝贝点击跳转
     * @param {宝贝链接} url 
     */
    onClickBaby(e) {
      const { mds = {} } = this.props.data;
      console.log(e.currentTarget.dataset.url)
      let gotoObj = {
        url: e.currentTarget.dataset.url, //字符串,可以是小程序内部url,也可以是H5/WEEX url,也可以是其他小程序url
        mds: mds,//必填,从props.data下发的模块moduleData
        config: {
          spmd: 0,//spm参数D位,默认为0(就是之前的nid)
          type: "",//跳转方式,默认为空,如果有定制需求,可以传递:replace/replaceAll/switchTab
        }
      }
      this.props.data.modUtils.router.navigateToUrl(gotoObj.url, gotoObj.mds, gotoObj.config);
    }
  }
}));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值