记录--你还在用传统轮播组件吗?来看看遮罩轮播组件

这篇具有很好参考价值的文章主要介绍了记录--你还在用传统轮播组件吗?来看看遮罩轮播组件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--你还在用传统轮播组件吗?来看看遮罩轮播组件

 

背景

最近有一个页面改版的需求,在UI走查阶段,设计师说原来的轮播组件和新版页面UI整体风格不搭,所以要换掉。

这里就涉及到两种轮播组件,一种是传统的轮播组件,一种是设计师要的那种。

传统的轮播组件,大家都见过,原理也清楚,就是把要轮播的图片横向排成一个队列,把他们当成一个整体,每次轮换,其实是把这个队列整体往左平移X像素,这里的X通常就是一个图片的宽度。 这种效果可以参见vant组件库里的swipe组件

而我们设计师要的轮播效果是另外一种,因为我利用端午假期已经做好了一个雏形,所以大家可以直接看Demo。

当然你也可以直接打开 腾讯视频APP 首页,顶部的轮播,就是我们设计师要的效果。

需求分析

新式轮播,涉及要两个知识点:

  • 图片层叠
  • 揭开效果

与传统轮播效果一个最明显的不同是,新的轮播效果需要把N张待轮播的图片在Z轴上重叠放置,每次揭开其中的一张,下一张是自然漏出来的。这里的实现方式也有多种,但最先想到的还是用zindex的方案。

第二个问题是如何实现揭开的效果。这里就要使用到css3的新属性mask。 mask是一系列css的简化属性。包括mask-image, mask-position等。 因为mask的系列属性还有一定的兼容性,所以一部分浏览器需要带上-webkit-前缀才能生效。

还有少数浏览器不支持mask属性,退化的情况是轮播必须有效,但是没有轮换的动效。

实现

有了以上的分析,就可以把效果做出来了。核心代码如下:

<script setup lang="ts">
 import { ref, onMounted, watch } from "vue";
 // 定义属性
const props = defineProps([
  'imgList',
  'duration', 
  'transitionDuration',
  'maskPositionFrom', 
  'maskPositionTo',
  'maskImageUrl'
]);
 // 定义响应式变量
const currentIndex = ref(0);
const oldCurrentIndex = ref(0);
const imgList = ref([...props.imgList, props.imgList[0]]);
const getInitZindex = () => {
  const arr = [1];
  for (let i = imgList.value.length - 1; i >= 1; i--) {
    arr.unshift(arr[0] + 1);
  }
  return arr;
}
const zIndexArr = ref([...getInitZindex()]);
const maskPosition = ref(props.maskPositionFrom || 'left');
const transition = ref(`all ${props.transitionDuration || 1}s`);
 // 设置动画参数
const transitionDuration = props.transitionDuration || 1000;
const duration = props.duration || 3000;

 // 监听currentIndex变化
watch(currentIndex, () => {
  if (currentIndex.value === 0) {
    zIndexArr.value = [...getInitZindex()];
  }
  maskPosition.value = props.maskPositionFrom || 'left';
  transition.value = 'none';
})
 // 执行动画
const execAnimation = () => {
  transition.value = `all ${props.transitionDuration || 1}s`;
  maskPosition.value = props.maskPositionFrom || 'left';
  maskPosition.value = props.maskPositionTo || 'right';
  oldCurrentIndex.value = (currentIndex.value + 1) % (imgList.value.length - 1);
   setTimeout(() => {
    zIndexArr.value[currentIndex.value] = 1;
    currentIndex.value = (currentIndex.value + 1) % (imgList.value.length - 1);
  }, 1000)
}
 // 挂载时执行动画
onMounted(() => {
  const firstDelay = duration - transitionDuration;
  function animate() {
    execAnimation();
    setTimeout(animate, duration);
  }
  setTimeout(animate, firstDelay);
})
 </script>
 <template>
  <div class="fly-swipe-container">
    <div class="swipe-item"
         :class="{'swipe-item-mask': index === currentIndex}"
         v-for="(url, index) in imgList"
         :key="index"
         :style="{ zIndex: zIndexArr[index],
         'transition': index === currentIndex ? transition : 'none',
         'mask-image': index === currentIndex ? `url(${maskImageUrl})` : '',
         '-webkit-mask-image': index === currentIndex ? `url(${maskImageUrl})`: '',
         'mask-position':  index === currentIndex ? maskPosition: '',
         '-webkit-mask-position':  index === currentIndex ? maskPosition: '' }">
      <img :src="url" alt="">
    </div>
    <div class="fly-indicator">
      <div class="fly-indicator-item"
           :class="{'fly-indicator-item-active': index === oldCurrentIndex}"
           v-for="(_, index) in imgList.slice(0, imgList.length - 1)"
           :key="index"></div>
    </div>
  </div>
</template>
 <style lang="less" scoped>
.fly-swipe-container {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: inherit;
   .swipe-item:first-child {
    position: relative;
  }
  .swipe-item {
    position: absolute;
    width: 100%;
    top: 0;
    left: 0;
     img {
      display: block;
      width: 100%;
      object-fit: cover;
    }
  }
   .swipe-item-mask {
    mask-repeat: no-repeat;
    -webkit-mask-repeat: no-repeat;
    mask-size: cover;
    -webkit-mask-size: cover;
  }
   .fly-indicator {
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 666;
    position: relative;
    top: -20px;
    .fly-indicator-item {
      margin: 0 5px;
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: gray;
    }
    .fly-indicator-item-active {
      background: #fff;
    }
  }
}
</style>

这是一个使用 Vue 3 构建的图片轮播组件。在这个组件中,我们可以通过传入一组图片列表、切换动画的持续时间、过渡动画的持续时间、遮罩层的起始位置、遮罩层的结束位置以及遮罩层的图片 URL 来自定义轮播效果。

组件首先通过 defineProps 定义了一系列的属性,并使用 ref 创建了一些响应式变量,如 currentIndexoldCurrentIndeximgListzIndexArr 等。

onMounted 钩子函数中,我们设置了一个定时器,用于每隔一段时间执行一次轮播动画。 在模板部分,我们使用了一个 v-for 指令来遍历图片列表,并根据当前图片的索引值为每个图片元素设置相应的样式。同时,我们还为每个图片元素添加了遮罩层,以实现轮播动画的效果。

在样式部分,我们定义了一些基本的样式,如轮播容器的大小、图片元素的位置等。此外,我们还为遮罩层设置了一些样式,包括遮罩图片的 URL、遮罩层的位置等。

总之,这是一个功能丰富的图片轮播组件,可以根据传入的参数自定义轮播效果。

后续

因为mask可以做的效果还有很多,后续该组件可以封装更多轮播效果,比如从多个方向的揭开效果,各种渐变方式揭开效果。欢迎使用和提建议。

仓库地址:github.com/cunzaizhuyi…

本文转载于:

https://juejin.cn/post/7251564871510163512

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--你还在用传统轮播组件吗?来看看遮罩轮播组件文章来源地址https://www.toymoban.com/news/detail-582806.html

到了这里,关于记录--你还在用传统轮播组件吗?来看看遮罩轮播组件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • React 你还在用 Redux 吗?更简化的状态管理工具(Recoil)

    以往传统的 Redux 状态管理工具使用起来代码太过于复杂。 你需要通过纯函数触发 action 再去修改 data 中定义的数据,而且要通过接口请求数据还需要借助 redux - think 这个中间件才能完成。。。 更加方便使用的工具:Recoil ~   由 facebook 推出契合 React 的状态管理 它的定义方式

    2024年02月06日
    浏览(41)
  • Java 你还在用list.contain做去重? 你是故意的还是不小心的?

    最近又是一轮代码review , 发现了一些实现去重的代码,在使用 lsit.contain ...... 如: 我沉思,是不是其实很多初学者也存在这种去重使用问题? 所以我选择把这个事情整出来,分享一下。 首先是造出一个 ListString 模拟数据,一共2W条,里面有一半数据1W条是重复的: 先看看 我们

    2024年02月14日
    浏览(28)
  • 你还在用 Postman?IDEA REST Client 好用到爆,Postman 可以扔了

    语法部分 演示POST请求 POST {{baseUrl}}}get?show_env=1 Accept: application/json { “name”:“a” } 演示GET请求 GET {{baseUrl}}}/post Content-Type: application/x-www-form-urlencoded id=999value=content 首先通过###三个井号键来分开每个请求体,然后请求url和header参数是紧紧挨着的,请求参数不管是POST的body传参

    2024年04月12日
    浏览(33)
  • office2021与365你还在纠结吗?快来看看

    有不少小伙伴跟我说自己用的 Office 存在各种问题。 比如字体颜色下拉菜单点不动; ​文件打不开; ​ 或者经常卡顿、闪退等。 ​ 出现这些问题,多半是因为装了盗版 Office,或者没有将 Office 更新至最新版。 所以,解决这些问题的根本方法还是使用正版 Office ,并及时更

    2024年02月08日
    浏览(33)
  • 【优雅的参数验证@Validated】@Validated参数校验的使用及注解详解——你还在用if做条件验证?

    请先看看下面代码:(简单举个例子,代码并不规范) 以上代码主要是为了对用户user实体进行条件验证。 但是那么多的if, 写得纯纯得小白一个,也使得代码显得臃肿不美观不优雅! 接下来,让我们学习使用优雅的参数验证@Validated! @Valid和@Validated是Spring Validation框架提供

    2024年02月02日
    浏览(30)
  • javaer你还在手写分表分库?来看看这个框架怎么做的 干货满满

    高并发三驾马车:分库分表、MQ、缓存。今天给大家带来的就是分库分表的干货解决方案,哪怕你不用我的框架也可以从中听到不一样的结局方案和实现。 一款支持自动分表分库的orm框架 easy-query 帮助您解脱跨库带来的复杂业务代码,并且提供多种结局方案和自定义路由来实现比

    2024年02月06日
    浏览(34)
  • 【CocosCreator入门】CocosCreator组件 | Mask(遮罩)组件

              Cocos Creator 是一款流行的游戏开发引擎,具有丰富的组件和工具,其中Mask组件可用于创建如圆形、矩形和任意形状的遮罩效果,以限制节点显示的范围。这对于创建具有复杂布局的UI元素非常有用,例如只显示图片的一部分或控制文本显示的区域。         使

    2024年02月12日
    浏览(36)
  • Unity UGUI的Mask(遮罩)组件的介绍及使用

    Mask(遮罩)组件是Unity UGUI中的一个重要组件,用于限制子对象的可见区域。通过设置遮罩组件,可以实现一些特殊效果,如显示部分图片、裁剪文本等。 Mask组件通过将子对象与遮罩对象进行比较,只显示与遮罩对象重叠的部分,从而实现遮罩效果。遮罩对象可以是任意形状

    2024年02月13日
    浏览(48)
  • 记录--你还在使用websocket实现实时消息推送吗?

    在日常的开发中,我们经常能碰见服务端需要主动推送给客户端数据的业务场景,比如数据大屏的实时数据,比如消息中心的未读消息,比如聊天功能等等。 本文主要介绍SSE的使用场景和如何使用SSE。 我们常规实现这些需求的方案有以下三种 轮询 websocket SSE 在很久很久以前

    2024年02月19日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包