小程序轮播,上下两层图片,底层渐变淡入淡出,上层动画划入效果

先看效果: 如果大家有喜茶小程序,可以进入查看首页轮播效果图,大概就是那个效果。

捋一下我开发过程的思路,一共有两个。

第一个思路: 用微信小程序的组件,swiper实现上层透明照片的轮播效果,底层的照片根据swiper组件的bindchange,bindtransition,bindanimationfinish三个方法组合使用来实现轮播左右滑动的过程中,opacity的变化以及上下索引的变化,进而根据索引来更换底层的照片,底层是写了两层图片,动态手动的更换背景图以及处理opacity的值的变化。由于swiper在切换过程中,其实有两个索引,一个是当前的一个是下一个的,分别是index 与 current , 他们会在某一个时刻不同但是更多时候索引是相同的,导致opacity在轮播自动播放的情况下,淡入淡出的效果不明显。所以最终效果实现了90%,最后10%的效果没有解决思路,虽然产品说实在没办法也可以但是自己依然觉得不太好。

第二个思路: 上层的透明图片部分依然不变,使用微信小程序组件swiper实现轮播的变换,但是底层的照片淡入淡出效果直接使用一个数组填充底层图片的地址来显示,根据轮播的索引,直接底层图片的索引与上层轮播的索引对应上的时候直接opacity展示为1,其他索引下的opacity则为0。原理类似前端经常用active来设置选中的项目展示不同的样式。此种方法简便效果100%,可惜自己一开始没有想到。

重点代码如下:

<view wx:if="{{swiperImgs.length}}" style="position: relative">
  <!-- 这里单独开一层,用于处理底层轮播图,需要定位位置、根据下面的轮播来处理对应的数据 -->
  <view class="qm-banner-underImg uperUderImg">
    <view class="aaaa" wx:for="{{underImgList}}" wx:key="index" style="opacity:{{index == currentIndex?'1':'0'}};">
      <image lazy-load src="{{item.underImg}}" style="width: 100%"></image>
    </view>
  </view>
  <swiper
    class="v-qm-banner"
    style="{{miniStyle}}"
    autoplay="{{true}}"
    circular
    indicator-active-color="{{indicatorStyle}}"
    data-index="{{currentIndex}}"
    bindchange="swiperChange"
  >
    <swiper-item class="swiper-item" wx:for="{{ swiperImgs}}" wx:key="index">
      <view catchtap="bindLink" data-item="{{item}}" style="height:{{filter.styleToObj(data.miniStyle).height}};">
        <image lazy-load mode="widthFix" class="image" src="{{item.img}}"></image>
      </view>
    </swiper-item>
  </swiper>
</view>

import { $component } from '@/libs/mpext'
import { getSwiperImages } from './banner'
const app = getApp()

$component({
  mapState: [],
})({
  properties: {
    data: {
      type: Object,
      value: {},
      observer(val) {
        if (!val) return
        this.handleSwiperData()
      },
    },
    index: {
      type: Number,
      value: 0,
    },
  },
  data: {
    currentIndex: 0,
  },
  pageLifetimes: {
    show() {
      this.handleSwiperData()
    },
  },
  methods: {
    handleSwiperData() {
      const { data } = this.data
      const imgs = data?.propsValue?.imgs || []

      // 过滤下当前可显示的数据
      const swiperImgs = getSwiperImages(imgs)
      const underImgList = []
      swiperImgs.forEach((ele, index) => {
        underImgList.push({ index: index, underImg: ele.underImg })
      })
      this.setData({
        underImgList,
      })
    },

    // 轮播变动
    swiperChange(currnet) {
      const currentIndex = currnet.detail.current
      this.setData({
        currentIndex,
      })
    },
  },
})

// banner
.v-qm-banner {
  z-index: 999;
  background: transparent;

  .image {
    width: 100%;
  }

  .qm-banner-swiper-item {
    position: relative;
  }

  .underImg {
    position: absolute;
    top: 0;
    left: 0;
    z-index: -1;
    width: 100%;
    height: 390rpx;
  }

  .qm-banner-swiper-item-box {
    background-size: cover;
    opacity: 0;
    transition-property: opacity;
  }
}

.qm-banner-underImg {
  position: absolute;
  left: 50%;
  transform: translate(-50%);
}

.uperUderImg {
  width: 100%;
  height: 100%;
}

.aaaa {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  transform: translate(0%, 0) translateZ(0);
  transition: 1s;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值