教你如何用VUE实现一个无缝横向滚动抽奖的效果

最近一位安卓端同事想要实现一个效果如下图,我们先看如下图:

请添加图片描述

我们看到上面想到如何实现呢?

先说下我的思路:

我先想到的是看能不能用轮播图swiper插件实现,试了下发现自己行不通,原因不是在于插件问题,在于你要很熟悉swiper 那些apis,然后再结合一些动画效果。最后看到自己还没明白实现原理,就开始想通过调用插件api去实现,结果行不通,所以后面试了一阵子,就放弃了,也许它是可以实现的。
然后我就想到之前做得一个老虎机,感觉它很像老虎机中效果,只不过老虎机一般是有三列的,而且是纵向的。我们可以先看下老虎机的效果:

请添加图片描述

看了上面的gif图之后,是不是有点灵感了?

没错,我们动态效果也是跟上面的很像,我们只用实现一列就行,而且我们是要实现的是横向的。那么我们该怎么实现的,看了下我之前老虎机的代码:

+在这里插入图片描述

发现它是用jq写的,用的是 jQuery Easing插件实现,但是里面的实现原理也是有点懵逼,加上自己想用vue实现,在vue里已经jq也不太合适。

借助自己又借助AI模型捣鼓了一段时间,还是没有思路,所以自己才开始想着实现的原理。首先它需要实现这两种效果:

1. 横向无缝滚动奖品
2. 动态滚动效果:慢-快-慢

自己的思路:

横向无缝滚动是不是要监听奖品列表中最后一个奖品快要离开右边框之后,再追加一组重复的奖品列表,实现横向无缝滚-动呢?自己想了下有点麻烦,就没有继续想下去。
动态滚动效果:可以借助贝塞尔曲线实现

在自己没什么具体思路的时候,自己在网上搜到了一个解决方案:是一位作者用uni-app实现的老虎机的效果,刚好的uni-app的语法跟vue差不多,所以很多思路都可以得到借鉴。

在这里插入图片描述

好了,怎么实现这个横向滚动呢?

为了实现横向无缝滚动奖品,作者提前放了多组重复奖品列表,比如原先奖品列表有10个奖品,我们可以放置多几组重复奖品列表,所以奖品的数量(10 * n),为了效果更逼真,如果动画时间长的话,可以适当再加几组,让效果更加逼真。

动态效果用了css3属性transform、transition-duration,那如何每次中奖的奖品居中显示呢?作者用了一个这么一个方法:

算出第一组奖品中的每个奖品到达对应最后一组奖品的每个奖品在中间位置时的距离,这句话怎么理解呢,我们详细解析下:
比如说,我们一组奖品列表,我们称为W,打算放四组,即四组一样的列表放在一起,我们可以称为为总列表,用Z来表示,那么我们点击滚动的时候,为了动画效果,自然要从第一组滚到最后一组,如我们要抽中第一个奖品,即第一组第一个奖品要滚到最后一组的第一个奖品,而且最后一组第一个奖品要在中间位置,我们可以计算好这个距离,这个距离怎么计算呢?

我们先算这个Z里的每个奖品移到中间的距离,我们先算Z里的第一个奖品移到中间的距离,我们可设为T,剩下的每个奖品移到中间的话,都可以依此类推了,因为都是T的倍数,好了,了解了这个,那 第一组奖品中的每个奖品到达对应最后一组奖品的每个奖品在中间位置时的距离 接下来怎么算?

假如我们要抽的是第一个奖品,那么滚的距离就是 (Z.length - 1) x T,我们已经知道第一个奖品要滚的距离了,所以第二个奖品就很简单了,减去2就行,即 (Z.length - 2) x T,剩下的奖品依次类推… 我们可以用一个倒序的循环来做这个逻辑:

   for (let k = Z.length - 1; k >= 0; k--) {
        // results为要抽的奖品
        if (Z[k].color == results) {
          // 要滚动的距离
          this.translateX = (k - 1) * T;
          break;
        }
      }

好了到这里我们看着没有问题,是不是还少了点什么东西?我问下大家,如果我已经抽中了第一个奖品之后,还想继续抽中第一个奖品,是不是发现继续滚动的话,就会出现一片空白?

原因是滚动还在,但是没有奖品给你滚了,因为是最后一组了!!
所以我们每次滚到最后一组时,即抽中奖品之后,要“悄悄”地把最后一组变成第一组,怎么悄悄呢?这时我们也是用到一个CSS属性了,就是transition-duration,一开始我们为了滚动的动画效果,会设置时间,所以当我们滚到要抽中的奖品之后,要以没有动画效果的形式滚到第一组,可以把transition-duration****设成0,那么transform中的translateX要滚动多少距离呢?

      const diffValue = (Z.length / W.length - 1) * W.length;
      let tolerance = diffValue * T; // 这就是transform中的translateX设置的值

所以最终的完整版效果如下:

请添加图片描述

在开发的过程中,细心小伙伴可能会发现几个问题:

  1. 当奖品数量多之后,一开始加入这么多组重复奖品列表,会不会增加GPU渲染压力

这个问题,可借鉴其他网友的虚拟滚动的思路,也可以使用vue-virtual-scroller 这个插件

  1. 还有个问题当我们要抽第一个奖品时,抽完之后,会出现这个情况,如下:

在这里插入图片描述
我们可以看到停止时,第一个奖品的左边的奖品消失了,为什么呢?
因为我们静止时,是显示第一组的奖品列表,而刚好第一个奖品的左边是没有奖品的。

当我们抽最后一个奖品会怎么样?如下:

请添加图片描述

我们可以看到停止时,最后一个奖品的右边突然多出了一个奖品,为什么呢?
首先,最后一组奖品列表里的最后一个奖品的右边是为空的,因为我们静止时,是显示第一组的奖品列表,而刚好它的最后一个奖品的右边是有奖品的。

那怎么解决以上这个问题呢?
一开始自己会想着在通过追加元素或者删除元素来解决,但是发现这样很鸡肋,因为会影响之前计算好的滚动的距离,用定位好像也可以,不过还要控制显示和隐藏,个人觉得比较麻烦,所以想到了一个这样的方法:

将原先滚动到最后一组,改成滚到倒数第二组,将滚动静止时显示第一组,改成显示第二组

这样不就解决了?!不过注意一个问题就是,奖品列表组数最少不能少于4组,否则无法解决上面的问题。

好了,告一段落了,总结下这次的开发:

  1. 对css3的transform属性不够熟悉,导致在思考时无法串联起来。
  2. 过于依赖AI模型,有急于要结果,不要思考过程的坏习惯。

代码已放在自己的gitee上面,欢迎star~:vue2实现横向滚动动画抽奖

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/604744.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

How Linux Works I - How Linux Start Up

目录 Linux如何启动? 启动信息 内核启动初始化与启动选项 写在前面:上一个专栏中我写完了内核源码层面看Linux,我们把抽象层拉高一点,看看Linux是如何工作的! Linux如何启动? BIOS(Basic Inpu…

05-08 周三 FastBuild FastAPI 引入并发支持和全局捕获异常

时间版本修改人描述2024年5月8日20:41:03V0.1宋全恒新建文档 简介 由于FastBuild之前花费了大概5天的时间优化,但最近重新部署,又发现了一些问题,就很痛苦,五一之后,自己又花了三天的时间系统的进行了优化。 上一波优…

刷题训练之模拟

> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:熟练掌握模拟算法。 > 毒鸡汤:学习,学习,再学习 ! 学,然后知不足。 > 专栏选自:刷题训…

华为车BU迈入新阶段,新任CEO对智能车的3个预判

作者 |张马也 编辑 |德新 4月24日,北京车展前夕,华为召开了新一年的智能汽车解决方案新品发布会。 这次发布会,也是华为智能汽车解决方案BU(简称「车BU」)CEO 靳玉志的公开首秀。 一开场,靳玉志即抛出了…

损失一件外套?

2024/05/07,晴 碎碎念一波! 早上洗漱完要出门时,发现自己昨天穿的外套不见了!!!外套上身效果很不错,买了1年多穿的频率非常高,现在丢了还真挺可惜。 衣服口袋有一个耳机&#xff0…

信创基础软件之数据库

一、数据库概述 数据库是一种用于存储和管理拥有固定格式和结构数据的仓库型数据管理系统。其主要用于业务数据的存储和业务逻辑运算,具体负责保障数据的安全性、完整性、多用户对数据的并发使用以及发生故障后的系统恢复。 二、数据库的体系架构 数据库内核:对数…

Java中next()与nextLine()的区别[不废话,直接讲例子]

在使用牛客进行刷题时,我们很多时候会遇到这样的情况: 区别很简单,如果你要输入用空格或者回车分开的数据如: abc_def_ghi 这三组数据( _ 是空格) 用hasNext: 执行结果: 如果只用换行符号进行…

返回链表的中间节点题目讲解(超快方法)

一:题目 二:思路讲解 采用快慢指针方法来解决 1:slow指针一次跳一个节点,fast指针一次跳两个节点,这样当fast到尾节点的时候,slow刚好到中间节点,但是奇数个的时候,fast不会刚好的…

Java | Leetcode Java题解之第59题螺旋矩阵II

题目&#xff1a; 题解&#xff1a; class Solution {public int[][] generateMatrix(int n) {int num 1;int[][] matrix new int[n][n];int left 0, right n - 1, top 0, bottom n - 1;while (left < right && top < bottom) {for (int column left; co…

DenseCLIP环境配置

直接看raoyongming/DenseCLIP: [CVPR 2022] DenseCLIP: Language-Guided Dense Prediction with Context-Aware Prompting (github.com) 但这里的环境配置可能和现在不太适配&#xff0c;自己配了好久没弄好 后面尝试了另外的版本的&#xff08;但这个版本少了一些内容&#…

MySQL-ELK基础

1&#xff1a;什么是 ELK ELK是由一家elastic公司开发的三个开源项目的首字母缩写&#xff0c;这三个项目分别是&#xff1a;Elasticsearch、Logstash 和 Kibana。三个项目各有不同的功能&#xff0c;之后又增加了许多新项目, 于是 从5.X版本后改名为Elastic Stack Elastic S…

电脑屏幕监控软件都有哪些 | 五大好用屏幕监控软件盘点

电脑屏幕监控软件在企业管理、家庭教育等方面发挥着越来越重要的作用。 这些软件通过实时监控电脑屏幕活动&#xff0c;为用户提供了强大的管理和监控功能。 本文将为您盘点五大好用的电脑屏幕监控软件&#xff0c;帮助您更好地了解并选择适合自己的软件。 电脑屏幕监控软件都…

J1019基于SpringBoot的护肤品推荐系统设计与实现(源码+包运行+技术指导)

项目描述 临近学期结束&#xff0c;开始毕业设计制作&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉的困难吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于SpringBoot的护…

Visual Studio C++ 2019进行安装

Visual Studio C 2019进行下载安装 链接&#xff1a;https://my.visualstudio.com/Downloads?qvisual%20studio%202017&wt.mc_idomsftvscom~older-downloads

Linux网站服务

1.概念:HTML:超级文本编辑语言 网页:使用HTML,PHP,JAVA语言格式书写的文件。 主页:网页中呈现用户的第一个界面。 网站:多个网页组合而成的一台网站服务器。 URL:统一资源定位符&#xff0c;访问网站的地址。 网站架构:LAMP: LinuxApacheMYSQLPHP(系统服务器程序数据管理…

Mamba结构的Demo源码解读

文章目录 前言一、mamba结构构建辅助函数解读1、dataclass方法解读2、Norm归一化LayerNormRMSNormRMSNorm源码 3、nn.Parameter方法解读 二、mamba原理二、mamba模型构建1、主函数入口源码解读2、Mamba类源码解读 三、ResidualBlock的mamba结构源码解读四、MambaBlock构成Resid…

【C++】二叉搜索树(手撕插入、删除、寻找)

一、什么是二叉搜索树 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值它的左…

collections模块

tuple的功能 只有可哈希的对象才可以作为字典的key&#xff0c;而immutable的对象是可哈希的 tuple的拆包&#xff0c;分别进行映射 拆包的灵活用法 tuple的不可变不是绝对的 nametuple的详解 __slots__是用于限制class里面有那些属性值的&#xff0c;可以自行去了解一下 f…

Python基础详解三

一&#xff0c;函数的多返回值 def methodReturn():return 1,2x,ymethodReturn() print(x,y) 1 2 二&#xff0c;函数的多种参数使用形式 缺省参数&#xff1a; def method7(name,age,address"淄博"):print("name:"name",age"str(age)&quo…

你需要知道vim操作 源头都在vimtutor里

vim之源&#xff1a;vimtutor vim的五种模式Normal mode&#xff08;正常模式&#xff09;Insert mode&#xff08;插入模式&#xff09;Visual mode&#xff08;可视模式&#xff09;Replace mode&#xff08;替换模式&#xff09;Command-line mode&#xff08;命令行模式&am…
最新文章