vue3 + swiper carousel 滚动折叠效果

html template 部分:
 <!-- banner 滚动 -->
    <transition v-if="state.bannerList.length" name="fade">
      <swiper
        :autoplay="{
          delay: 2000,
          disableOnInteraction: false,
        }"
        :effect="'carousel'"
        :grabCursor="true"
        :slides-per-view="'auto'"
        :loop="true"
        :pagination="{
          clickable: true,
        }"
        navigation
        :modules="state.bannerModules"
        @beforeInit="onCarouselBeforeInit"
        @progress="onCarouselProgress"
        @setTransition="onCarouselSetTranistion"
      >
        <swiper-slide v-for="(item, index) in state.bannerList" :key="index">
          <div class="swiper-carousel-animate-opacity">
            <img class="image" :src="item.resourcesPicture" />
          </div>
        </swiper-slide>
      </swiper>
    </transition>

less 部分:

.swiper-carousel {
	position: relative;
	margin: 10px auto 30px;
	// max-width: @custom-screen-width;
	width: 100%;
	height: 358px;
	.swiper-slide {
		width: 900px;
		height: 358px;
		border-radius: 16px;
		background: #18212b;
		box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.2);
		// max-width: calc(100% - 48px);
	}
	.swiper-carousel-animate-opacity {
		height: 100%;
	}
	.swiper-pagination-bullets {
		bottom: 0;
	}
	img {
		width: 100%;
		height: 100%;
		display: block;
		object-fit: cover;
		border-radius: 16px;
	}
	.slide-content {
		position: absolute;
		left: 0;
		width: 100%;
		bottom: 0;
		padding: 88px 16px 24px;
		box-sizing: border-box;
		background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75));
		border-radius: 0 0 8px 8px;
	}
	@media (max-width: 640px) {
		.swiper-button-next,
		.swiper-button-prev {
			display: none !important;
		}
	}
	:deep(.swiper-pagination-bullet) {
		&-active {
			background-color: #fff;
		}
	}
	:deep(.swiper-button-prev),
	:deep(.swiper-button-next) {
		color: #fff;
	}
}

ts 部分:

import "swiper/less/navigation";
import "swiper/less/pagination";
import "swiper/less";
import { Swiper, SwiperSlide } from "swiper/vue";
import { Pagination, Navigation, Autoplay } from "swiper/modules";


const state = reactive({
  bannerList: [] as { resourcesPicture: string }[],
  bannerModules: [Pagination, Navigation, Autoplay],
})

/**
 * 主banner 加载之前
 * @returns {*}
 */
const onCarouselBeforeInit = (swiper) => {
  try {
    const currentSwiperStr = "carousel";
    if (swiper.params.effect !== currentSwiperStr) return;
    swiper.classNames.push(
      swiper.params.containerModifierClass + currentSwiperStr
    );
    const options = {
      watchSlidesProgress: !0,
      centeredSlides: !0,
    };
    Object.assign(swiper.params, options);
    Object.assign(swiper.originalParams, options);
  } catch (error) {
    console.log("swiper init", error);
  }
};
/**
 * 主banner
 * @returns {*}
 */
const onCarouselProgress = (swiper) => {
  try {
    if (swiper.params.effect !== "carousel") return;
    const slidesCount = swiper.slides.length;
    for (let index = 0; index < slidesCount; index++) {
      const currentSlide = swiper.slides[index],
        progress = swiper.slides[index].progress,
        opacity = Math.abs(progress);
      let number = 1;
      opacity > 1 && (number = 0.3 * (opacity - 1) + 1);
      const elementOpacity = currentSlide.querySelectorAll(
          ".swiper-carousel-animate-opacity"
        ),
        percenter =
          progress * number * 55 * (swiper.rtlTranslate ? -1 : 1) + "%",
        scale = 1 - 0.25 * opacity,
        zIndex = slidesCount - Math.abs(Math.round(progress));

      (currentSlide.style.transform = `translateX(${percenter}) scale(${scale})`),
        (currentSlide.style.zIndex = zIndex),
        (currentSlide.style.opacity = opacity > 3 ? 0 : 1),
        elementOpacity.forEach(
          (item) => (item.style.opacity = 1 - opacity / 3)
        );
    }
  } catch (error) {
    console.log("swiper progress", error);
  }
};
/**
 * 主banner  transition
 * @returns {*}
 */
const onCarouselSetTranistion = (swiper, time) => {
  if (swiper.params.effect !== "carousel") return;
  for (let index = 0; index < swiper.slides.length; index++) {
    const currentSlide = swiper.slides[index],
      element = currentSlide.querySelectorAll(
        ".swiper-carousel-animate-opacity"
      );
    (currentSlide.style.transitionDuration = `${time}ms`),
      element.forEach((item) => (item.style.transitionDuration = `${time}ms`));
  }
};

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值