广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >基于Vue实现卡片无限滚动动画
  • 678
分享到

基于Vue实现卡片无限滚动动画

2024-04-02 19:04:59 678人浏览 八月长安
摘要

目录概要设计详细设计进阶功能功能分析概要设计详细设计完整代码概要设计 设置CSS的animation在适当的时间点重置动画来现实视觉上无限滚动的效果。 详细设计 计算动画中所需预设的

概要设计

设置CSS的animation在适当的时间点重置动画来现实视觉上无限滚动的效果。

详细设计

计算动画中所需预设的卡片dom节点个数(即视觉上最多能看到的卡片个数),如图1视窗高度为120px,卡片高度为56px,上下margin均为24px,因此一张卡片最多占据56+24*2=104px。当卡片处于视窗垂直居中的位置时,卡片上下各有(120-104)/2 = 8px的高度来承载其余卡片,因此所需预设卡片dom节点个数为3个。

图1

图2

设置动画的运动轨迹和持续时间来达到视觉上循环滚动的效果。如图3初始状态下第一张卡片位置处于距离视窗顶部24px的位置,当第二张卡片运动到距离视窗顶部24px的位置时重置动画即可达到视觉上连续滚动的效果。计算卡片需要向上滚动的公式为【初始距顶部距离 - 目标距顶部距离】即56+24*2-24=80px,因此设置动画帧的目标位置为transfORM: translateY(-80px)。

代码实现:

<template>
  <div class="wrapper">
    <div class="container">
      <div class="content" v-for="i in 3" :key="i">
        <img
          class="image"
          src="https://static-legacy.dingtalk.com/media/lADPDhmOwd9ZBQXNA8DNA8A_960_960.jpg"
          alt=""
        />
        <span>点五已获得500元京东卡</span>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent } from "Vue";
 
export default defineComponent({
  setup() {},
});
</script>
<style scoped>
.wrapper {
  height: 500px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.container {
  width: 300px;
  height: 120px;
  overflow: hidden;
  background: #ccc;
}
.content {
  width: 290px;
  height: 56px;
  display: flex;
  margin: 24px auto;
  background: #fff;
  border-radius: 100px;
  flex-flow: row nowrap;
  align-items: center;
  backdrop-filter: blur(4px);
  animation: scroll 3s linear 1s infinite;
}
.image {
  width: 36px;
  height: 36px;
  margin: auto 10px;
  border-radius: 100%;
}
span {
  font-family: PingFang SC;
  font-size: 20px;
  line-height: 20px;
  text-align: center;
}
@keyframes scroll {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(-80px);
  }
}
</style>

效果展示:

进阶功能

动态更新卡片的数据

功能分析

卡片仍保持无限滚动,但每张卡片展示的数据均不同,也就是说滚动时视窗内的dom节点不是每次都相同的。

概要设计

基于上述功能分析由此可以衍生出两个设计思路:

  • 展示多少条数据就渲染多少个dom节点,简单粗暴无需考虑动态更新数据问题;当数据量大时会导致页面性能变差,除非数据量较少否则不推荐。
  • 固定dom节点数,在dom节点移动到视窗之外即进行数据更新;需保证修改dom节点时不会导致视窗内的卡片闪烁;(采纳)

详细设计

1.根据当前视窗宽高以及卡片宽高,设置六个卡片dom节点,并将每三张卡片分一个块,这里分两个块为card1、card2(如下图)。

2.将两个块的位置重叠(为了方便设计动画),card2向上移动(56+24)*3=240px的距离。

3.计算card2动画需要延迟执行的时间。这里我设置每个card块动画移动距离为480px,执行时间为12s,那么card2延迟执行的时间公示为【延迟距离(card高度)/速度】即240/480/12 = 6s。所以动画帧设置为

@keyframes scroll1 {
  from {
    transform: translateY(0);
    left: 0;
  }
  to {
    transform: translateY(-480px);
  }
}
@keyframes scroll2 {
  from {
    transform: translateY(-240px);
    left: 0;
  }
  to {
    transform: translateY(-720px);
  }
}
.test1 {
  animation: scroll1 12s linear 0s infinite;
  margin-top: 120px;
}
.test2 {
  animation: scroll2 12s linear 6s infinite;
  transform: translateY(-240px);
}

4.监听card块,当card块移出视窗时,触发dom节点刷新。监听使用IntersectionObserver这个api

@keyframes scroll1 {
  from {
    transform: translateY(0);
    left: 0;
  }
  to {
    transform: translateY(-480px);
  }
}
@keyframes scroll2 {
  from {
    transform: translateY(-240px);
    left: 0;
  }
  to {
    transform: translateY(-720px);
  }
}
.test1 {
  animation: scroll1 12s linear 0s infinite;
  margin-top: 120px;
}
.test2 {
  animation: scroll2 12s linear 6s infinite;
  transform: translateY(-240px);
}

完整代码

以下为完整代码:

<template>
  <div class="wrapper">
    <div class="container">
      <div class="test1" id="card1">
        <div class="content" v-for="item in cardArr1" :key="item">
          <img class="image" src="Https://static-legacy.dingtalk.com/media/lADPDhmOwd9ZBQXNA8DNA8A_960_960.jpg"
          alt="" />
          <span>
            {{ item }}已获得500元京东卡
          </span>
        </div>
      </div>
      <div class="test2" id="card2">
        <div class="content" v-for="item in cardArr2" :key="item">
          <img class="image" src="https://static-legacy.dingtalk.com/media/lADPDhmOwd9ZBQXNA8DNA8A_960_960.jpg"
          alt="" />
          <span>
            {{ item }}已获得100元京东卡
          </span>
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
  import { ref, defineComponent, onMounted } from "vue";
  
  export default defineComponent({
    setup() {
      let firsrObserver = true;
      let data: any = [];
      for (let i = 1; i <= 10; i++) {
        data.push(i);
      }
      const cardArr1 = ref<Array<any>>(data.slice(0, 3));
      const cardArr2 = ref<Array<any>>(data.slice(3, 6));
      console.log(cardArr1.value, cardArr2.value);
      
      let currentIndex = 6;
      const getNewData = () => {
        if (currentIndex + 3 <= data.length) {
          return data.slice(currentIndex, (currentIndex = currentIndex + 3));
        } else {
          let rst = data.slice(currentIndex);
          currentIndex = 3 - rst.length;
          Array.prototype.push.apply(rst, data.slice(0, currentIndex));
          return rst;
        }
      };
      const observer2 = new IntersectionObserver((entry: any) => {
        // 第三第四第五加载新数据
        if (!entry[0].isIntersecting) {
          console.log(entry);
          if (entry[0].target.id === "card1") {
            cardArr1.value.splice(0, 3, ...getNewData());
          } else {
            cardArr2.value.splice(0, 3, ...getNewData());
          }
          console.log(cardArr1.value, cardArr2.value);
        }
        firsrObserver = false;
      });
      onMounted(() => {
        observer2.observe(document.getElementById("card1") as htmlElement);
        observer2.observe(document.getElementById("card2") as HTMLElement);
      });
      return {
        data,
        cardArr1,
        cardArr2,
      };
    },
  });
</script>
<style scoped>
  .wrapper {
    height: 500px;
    display: flex;
    align-items: center;
    
    justify-content: center;
  }
  .container {
    width: 300px;
    height: 120px;
    overflow: hidden;
    background: #ccc;
  }
  .test1 {
    animation: scroll1 12s linear 0s infinite;
    margin-top: 120px;
  }
  .test2 {
    animation: scroll2 12s linear 6s infinite;
    transform: translateY(-240px);
  }
  .content {
    width: 290px;
    height: 56px;
    display: flex;
    margin: 24px auto;
    background: #fff;
    border-radius: 100px;
    flex-flow: row nowrap;
    align-items: center;
    backdrop-filter: blur(4px);
  }
  .image {
    width: 36px;
    height: 36px;
    margin: auto 10px;
    border-radius: 100%;
  }
  span {
    font-family: PingFang SC;
    font-size: 20px;
    line-height: 20px;
    text-align: center;
  }
  @keyframes scroll1 {
    from {
      transform: translateY(0);
      left: 0;
    }
    to {
      transform: translateY(-480px);
    }
  }
  @keyframes scroll2 {
    from {
      transform: translateY(-240px);
      left: 0;
    }
    to {
      transform: translateY(-720px);
    }
  }
</style>

效果展示:

以上就是基于Vue实现实现卡片无限滚动动画的详细内容,更多关于Vue无限滚动动画的资料请关注编程网其它相关文章!

--结束END--

本文标题: 基于Vue实现卡片无限滚动动画

本文链接: https://www.lsjlt.com/news/148217.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 基于Vue实现卡片无限滚动动画
    目录概要设计详细设计进阶功能功能分析概要设计详细设计完整代码概要设计 设置css的animation在适当的时间点重置动画来现实视觉上无限滚动的效果。 详细设计 计算动画中所需预设的...
    99+
    2022-11-13
  • 基于vue-seamless-scroll实现无缝滚动效果
    vue中,基于vue-seamless-scroll无缝滚动,供大家参考,具体内容如下 1、安装vue-seamless-scroll npm install vue-seamles...
    99+
    2022-11-13
  • vue实现无限消息无缝滚动
    本文实例为大家分享了vue实现无限消息无缝滚动的具体代码,供大家参考,具体内容如下 一、html <div class="table_box">    <div c...
    99+
    2022-11-13
  • 基于Vue3实现无限滚动组件的示例代码
    目录为什么还要使用无限滚动组件无限滚动的优点无限滚动的缺点主要分为三个部分1.模拟 API 调用2.制作我们的内容组件3.显示我们的内容4.Vue3 无限滚动如果你在社交媒体上停留的...
    99+
    2022-11-13
  • 基于vue-seamless-scroll怎么实现无缝滚动效果
    这篇文章主要介绍了基于vue-seamless-scroll怎么实现无缝滚动效果的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于vue-seamless-scroll怎么实现无缝滚动效果文章都会有所收获,下面...
    99+
    2023-06-29
  • vue怎么实现无限消息无缝滚动
    本篇内容主要讲解“vue怎么实现无限消息无缝滚动”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue怎么实现无限消息无缝滚动”吧!一、html<div class="t...
    99+
    2023-06-29
  • vue或css动画实现列表向上无缝滚动
    本文实例为大家分享了vue或css动画实现列表向上无缝滚动的具体代码,供大家参考,具体内容如下 方法一:vue的实现方法 <div id="publishMain" clas...
    99+
    2022-11-13
  • Android简单实现无限滚动自动滚动的ViewPager
    经常我们会在应用中看到一个可以自动滚动,并且无限滚动的一个ViewPager,百度谷歌上面也有很多关于这方面的教程,但是感觉都略显麻烦,而且封装的都不是很彻底。所以试着封装一个...
    99+
    2022-06-06
    自动 viewpager Android
  • JavaScript基于定时器实现图片无缝滚动功能的方法
    这篇文章主要介绍了JavaScript基于定时器实现图片无缝滚动功能的方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体如下:一、无缝滚...
    99+
    2022-10-19
  • vue或css怎么实现列表向上无缝滚动动画
    本篇内容主要讲解“vue或css怎么实现列表向上无缝滚动动画”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue或css怎么实现列表向上无缝滚动动画”吧!效果如下:方法一:vue的实现方法<...
    99+
    2023-06-29
  • 基于vue实现循环滚动列表功能
    注意:需要给父容器一个height和:data='Array'和overfolw:hidden;左右滚动需要给ul容器一个初始化 css width。 先来介绍该组件的用法: 1.安...
    99+
    2022-11-12
  • Android实现卡片翻转动画
    最近项目上用到了卡片的翻转效果,大致研究了下,也参考了网上的一些Demo,简单实现如下: activity_main.xml <?xml version=...
    99+
    2022-06-06
    动画 Android
  • vue3实现CSS无限无缝滚动效果
    本文实例为大家分享了vue3实现CSS无限无缝滚动效果的具体代码,供大家参考,具体内容如下 template 双层div嵌套,进行隐藏滚动显示 <div class="li...
    99+
    2022-11-12
  • vue实现循环滚动图片
    本文实例为大家分享了vue实现循环滚动图片的具体代码,供大家参考,具体内容如下  效果(循环滚动,可切换方向): 轮播组件BaseSwiper.vue: <temp...
    99+
    2022-09-27
  • vue实现列表无缝滚动
    本文实例为大家分享了vue实现列表无缝滚动的具体代码,供大家参考,具体内容如下 HTML部分代码 <template> <div id="box" clas...
    99+
    2022-11-12
  • 简单方法实现Vue 无限滚动组件示例
    目录1. 前言2. 整体思路开始3. 钩子函数3.1 获取偏移初始位置的像素值3.2 获取开始滚动和结束滚动的钩子函数4. 完整代码1. 前言 对于列表类型的大量数据,前端展示往往采...
    99+
    2022-11-13
    Vue 无限滚动组件 Vue 滚动组件
  • 基于python实现MUI区域滚动
    目录1、前言2、问题描述3、解决方案4、结语本文转自微信公众号:"算法与编程之美"   Python用HBuilder创建交流社区APP   基于Python实现...
    99+
    2022-11-12
  • Unity3d实现无限循环滚动背景
    在游戏项目中我们常常看到商城的广告牌,几张广告图片循环滚动,类似跑马灯,现在我将讨论一种实现方法,并提供一个管理类,大家可以直接使用。 实现原理:背景图片循环滚动的原理很简单:两张图...
    99+
    2022-11-12
  • react实现无限循环滚动信息
    本文实例为大家分享了react实现无限循环滚动信息的具体代码,供大家参考,具体内容如下 需求 后端传递过来的数据滚动显示,鼠标移入后停止滚动,鼠标移出后继续滚动,参考公司门户的公告信...
    99+
    2022-11-12
  • vue使用动画实现滚动表格效果
    本文实例为大家分享了vue使用动画实现滚动表格效果的具体代码,供大家参考,具体内容如下 需求 在一些大屏项目中,需要使用到表格行数据滚动。本文介绍在vue项目中使用动画实现滚动表格。...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作