响应式轮播图 高级轮播

最近看到了一个轮播效果图,来自于B站UP主山羊の前端小窝,于是照着效果封装了一个 vue组件。

顺便做了一点改进,让整个轮播前后连贯起来。

效果图

轮播效果图

应用

index.vue

<script setup lang="ts">
import Carousel from "@/components/CarouselView.vue";
// 最少需要6张图片素材 webImgs.length ≥ 6
const webImgs = Object.keys(import.meta.glob("@/assets/images/web/*.jpg"), { eager: true }));
</script><template><Carousel :list="webImgs" />
</template>

CarouselView.vue

<script lang="ts" setup>
const props = defineProps<{readonly list: string[];
}>();// 窗口大小为 7,前后补充6个素材就可以连贯起来
const supplyNum = 7 - 1;
const imglist = [...props.list];
const len = props.list.length;
imglist.unshift(...props.list.slice(len - supplyNum, len));
imglist.push(...props.list.slice(0, supplyNum));const rotate = (i: number) => {// 中间的素材没有角度偏移 左右两边的偏移35度const val = i - options.mmiddleCur;return val < 0 ? 30 : val > 0 ? -30 : 0;
};const options = reactive({// 是否启用动画过渡  这是首尾连接效果的关键isTrans: true,// 最中间素材的下标 初始值是第一张图片,但相对整个素材列表来说是第7个mmiddleCur: supplyNum,// 这里我们使用左外边距来实现平移的效果// 前面补了6个素材,隐掉了3个,所以初始左外边距是 负的 3个素材宽度// 240 是一个素材(.front)的宽度marginLeftCur: -3 * 240,
});const timer = ref<number>();/** 这一块逻辑比较绕,需要结合实操才能更好的理解 */
const toLeft = () => {// 当左滑到第四个素材时,下一个就进入末尾了if (options.mmiddleCur == 3) {// 我们在进入末尾之前,把动画过渡停掉options.isTrans = false;// 然后把素材(窗口最右侧)换成末尾之前的那个素材(其实素材是一样的,但是位置不一样),也就是// 中间素材对应的是:素材列表减掉后补的6个素材,再往前推3个options.mmiddleCur = imglist.length - 6 - 3;// 左边距是:中间素材,再往前推4个,所有素材的宽度总和options.marginLeftCur = -(options.mmiddleCur + 1 - 4) * 240;// OK,到了这一步,虽然页面上没什么变化,但其实素材位置已经变了,已经连续上了// 接下来,我们正常走上一页的逻辑就好if (timer.value) clearTimeout(timer.value);// 这里 nextTick() 不好使,我们用一个定时器来延迟一下timer.value = setTimeout(() => last(), 0);} else last();function last() {options.isTrans = true;options.mmiddleCur--;options.marginLeftCur += 240;}
};
// 下一页的逻辑是差不多的
const toRight = () => {// 当右滑到倒数第四个素材时,下一个就进入开头了if (options.mmiddleCur == imglist.length - 1 - 3) {// 我们在进入开头之前,把动画过渡停掉options.isTrans = false;// 然后把素材(窗口最左侧)换成开头之前的那个素材,也就是// 中间素材对应的是:前补的6个素材,再往后推3个,也就是第9个素材options.mmiddleCur = 6 + 3 - 1; // 下标计算 -1// 左边距是:中间(第9个)素材,再往前推4个,总共5个素材的宽度总和options.marginLeftCur = -(options.mmiddleCur + 1 - 4) * 240;if (timer.value) clearTimeout(timer.value);timer.value = setTimeout(() => next(), 0);} else next();function next() {options.isTrans = true;options.mmiddleCur++;options.marginLeftCur -= 240;}
};const inter = setInterval(toRight, 1500);onUnmounted(() => {clearTimeout(timer.value);clearInterval(inter);
});
</script><template><div class="carousel"><div class="background" :style="{ backgroundImage: `url(${imglist[options.mmiddleCur]})` }"></div><div class="carousel-scroll"><div :class="['carousel-body', options.isTrans && 'trans']"><div class="carousel-item" v-for="(img, inx) in imglist" :key="inx"><div class="carousel-per" :style="{ transform: `rotateY(${rotate(inx)}deg)` }"><div class="box front" :style="{ backgroundImage: `url(${img})` }"></div><div class="box left" :style="{ backgroundImage: `url(${img})` }"></div><div class="box right" :style="{ backgroundImage: `url(${img})` }"></div></div></div></div></div><div class="btns"><div class="btn last" @click="toLeft"></div><div class="btn next" @click="toRight"></div></div></div>
</template><style lang="scss" scoped>
.carousel {position: relative;display: flex;flex-direction: column;height: 100vh;background-position: center;background-size: 100%;transition: 1s;.background {position: absolute;left: 0;top: 0;width: 100%;height: 100%;// 高斯模糊filter: blur(3px);z-index: -1;}.carousel-scroll {width: 1720px; // 240 * 7 + 40margin: 100px auto 100px;padding: 100px 20px;box-shadow: 0 0 20px rgba($color: skyblue, $alpha: 0.5);overflow: hidden;.trans {transition: 0.5s ease-in-out;.carousel-per {transition: transform 0.5s ease-in-out;}}.carousel-body {display: flex;height: 100%;margin-left: v-bind("options.marginLeftCur + 'px'");.carousel-item {perspective: 1200px;.carousel-per {position: relative;transform-style: preserve-3d;&:hover {.box {box-shadow: 0 0 50px rgba($color: #fff, $alpha: 0.7);}}.box {height: 100%;background-position: center;background-size: cover;border: 4px solid #fff;box-shadow: 0 0 50px rgba($color: pink, $alpha: 0.7);}.front {position: relative;width: 200px;height: 300px;margin: 0 20px;transition: transform 1s ease-in-out;transform-style: preserve-3d;&:after {content: "";position: absolute;bottom: -20%;width: 100%;height: 60px;background: #ffffff1c;box-shadow: 0px 0px 15px 5px #ffffff1c;transform: rotateX(-90deg) translate3d(0, 20px, 0px);}}.left,.right {position: absolute;top: 0;width: 40px;}.left {left: 0px;transform: translate3d(1px, 0, -20px) rotateY(-90deg);}.right {right: 0px;transform: translate3d(-1px, 0, -20px) rotateY(90deg);}}}}}.btns {display: flex;justify-content: center;.btn {width: 40px;height: 60px;margin: 0 100px;background-color: orangered;transition: 0.5s;cursor: pointer;&:hover {transform: scale(1.2);}}.last {clip-path: polygon(100% 0, 0 50%, 100% 100%, 60% 50%);}.next {clip-path: polygon(0 0, 100% 50%, 0 100%, 40% 50%);}}
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能优化算法-禁忌搜索算法(TS)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 禁忌搜索优化算法 (Tabu Search, TS) 是一种基于局部搜索的元启发式优化算法&#xff0c;由Fred Glover于1986年提出。TS通过引入“禁忌表”来避免重复搜索已经访问过的解&#xff0c;从而跳出局部最优解&#…

LeetCode718:最长重复子数组

题目链接&#xff1a;718. 最长重复子数组 - 力扣&#xff08;LeetCode&#xff09; 代码如下 class Solution { public:int findLength(vector<int>& nums1, vector<int>& nums2) {//dp[i][j]是以i-1为结尾和j-1为结尾的最长重复子数组//dp[i][j] dp[i…

十四、MySQL事务日志

文章目录 1. redo日志1.1 为什么需要REDO日志1.2 REDO日志的好处、特点1.2.1 好处1.2.2 特点1.3 redo的组成1.4 redo的整体流程1.5 redo log 的刷盘策略1.6 不同刷盘策略演示1.7 写入redo log buffer 过程1.7.1 补充概念:Mini-Transaction1.7.2 redo 日志写入log buffer1.7.3 …

Java-对一个List进行groupingBy分组操作同时保持原有的排序

在Java 8中,如果你想要对一个List进行分组操作同时保持原有的排序,可以使用Stream API结合 Collectors.groupingBy方法来实现。以下是一些关键点: 保持原有顺序:为了确保分组后的结果保持原有元素的顺序,可以使用LinkedHashMap作为收集 器的目标集合。LinkedHashMap会按…

[DB] NSM

Database Workloads&#xff08;数据库工作负载&#xff09; 数据库工作负载指的是数据库在执行不同类型任务时所需的资源和计算方式&#xff0c;主要包括以下几种类型&#xff1a; 1. On-Line Transaction Processing (OLTP) 中文&#xff1a;联机事务处理解释&#xff1a;…

如何使用DockerSpy检测你的Docker镜像是否安全

关于DockerSpy DockerSpy是一款针对Docker镜像的敏感信息检测与安全审计工具&#xff0c;该工具可以帮助广大研究人员在Docker Hub上检测和搜索自己镜像的安全问题&#xff0c;并识别潜在的泄漏内容&#xff0c;例如身份验证密钥等敏感信息。 功能介绍 1、安全审计&#xff1a…

Isaac Sim sensor插件报UnicodeDecodeError错误

在使用isaac sim或isaac lab时&#xff0c;如果涉及传感器插件&#xff0c;omni.isaac.sensor&#xff0c;可能会遇到如下编码错误&#xff0c;导致传感器无法正常使用。这个错误在isaac sim历代版本里一直都存在。 2024-10-22 08:42:59 [4,085ms] [Error] [carb.scripting-py…

基于yolov10的驾驶员抽烟打电话安全带检测系统python源码+pytorch模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv10的驾驶员抽烟、打电话、安全带检测系统是一种先进的驾驶行为监测系统。该系统利用YOLOv10算法的高效性和准确性&#xff0c;实现对驾驶员行为的实时检测与识别。 YOLOv10是一种最新的实时物体检测模型&#xff0c;其通过深度学习技术&#xff0c;如卷…

【网络原理】HTTP协议

目录 前言 一.什么是HTTP HTTP报文格式 HTTP的请求格式 1.首行 2.请求头&#xff08;header&#xff09; 3.空行 4.正文&#xff08;body&#xff09; HTTP的响应格式 1.首行 2.响应头 3.空行 4.正文&#xff08;body&#xff09; 首行中的方法 GET和POST的区别 …

使用Radzen Blazor组件库开发的基于ABP框架炫酷UI主题

一、项目简介 使用过ABP框架的童鞋应该知道它也自带了一款免费的Blazor UI主题&#xff0c;它的页面是长这样的&#xff1a; 个人感觉不太美观&#xff0c;于是网上搜了很多Blazor开源组件库&#xff0c;发现有一款样式非常不错的组件库&#xff0c;名叫&#xff1a;Radzen&am…

[渗透]前端源码Chrome浏览器修改并运行

文章目录 简述本项目所使用的代码[Fir](https://so.csdn.net/so/search?qFir&spm1001.2101.3001.7020) Cloud 完整项目 原始页面修改源码本地运行前端源码修改页面布局修改请求接口 本项目请求方式 简述 好久之前&#xff0c;就已经看到&#xff0c;_无论什么样的加密&am…

10.22Python_numpy习题整合

编写一个函数&#xff0c;返回数组沿指定轴的方差。 import numpy as npdef calculate(var1,var2):arr1 np.array(var1)variance np.var(arr1, axisvar2)print(variance)calculate([[1,2,3],[4,5,6]],0)实现一个函数&#xff0c;它接受一个 NumPy 数组&#xff0c;并返回该数…

【p2p、分布式,区块链笔记 Blockchain】truffle004 测试网络项目部署

编写合约 一个简单的Solidity智能合约 Usermap 用于在以太坊区块链上管理用户的ID和名称&#xff1a; 数据存储: 使用了 mapping 和 array 两种方式存储用户信息。addUser: 添加用户&#xff08;id和对应的用户名name&#xff09;到区块链。getid: 根据用户 id 获取用户名。该函…

awk命令学习记录

awk命令 awk命令 表示将一行数据按特定分割符分割成多列&#xff0c;而从而选取特定列数的数据&#xff0c;默认分割符为空格&#xff0c;连接符默认也是空格 // 1. 更换分割符 awk -F : 1.txt // 1.txt为你的文件名 // 2. 打印多列 awk {print $1,$2} // $0为整行&#xff…

深度学习模型:原理、架构与应用

深度学习(Deep Learning)是机器学习中的一个分支,基于人工神经网络的发展,尤其是多层神经网络的研究,使其在语音识别、图像处理、自然语言处理等领域取得了显著进展。深度学习的核心是通过大量数据的训练,学习到数据的内在结构和模式,并且具备自动从复杂的输入中提取特征…

计算机组成原理一句话

文章目录 计算机系统概述存储系统 计算机系统概述 指令和数据以同等地位存储在存储器中&#xff0c;形式上没有差别&#xff0c;但计算机应能区分他们。通过指令周期的不同阶段。 完整的计算机系统包括&#xff0c;1&#xff09;软件系统&#xff1a;程序、文档和数据&#xff…

Rust使用config加载Toml配置文件

前面提到用dotenvy读取配置文件到环境变量&#xff1a;https://juejin.cn/post/7411407565357449225 这里从配置文件中读取配置 添加依赖&#xff08;这里使用yaml配置&#xff09; # 异步运行时 tokio { version "1", features ["full"] } # 序列化…

SpringBoot request.getContextPath()获取到http 而不是https的问题解决

在某些情况下&#xff0c;使用 request.getContextPath() 可能会返回 HTTP 而不是 HTTPS&#xff0c;这通常是因为应用程序运行在反向代理后面&#xff08;如 Nginx 或 Apache&#xff09;&#xff0c;而代理服务器没有正确地转发请求的协议信息。 要解决这个问题&#xff0c;…

在linux中 appimage是什么文件? 为什么能直接运行

chmod x 你的.appImage ./你的.appImagehttps://github.com/AppImage/AppImageKit/wiki/AppImages AppImage 是一种用于打包和分发 Linux 应用程序的格式。它具有以下特点&#xff1a; 可移植性&#xff1a;AppImage 包可以在不同的 Linux 发行版上运行&#xff0c;因为它将应…

【牛客刷题】笔记2

目录 1、单词搜索 2、岛屿数量 2.1 DFS 2.2 BFS 3、腐烂的橘子 1、单词搜索 单词搜索_牛客题霸_牛客网 (nowcoder.com) 这道题我们就是先遍历数组board&#xff0c;若遇到了与word[0]相等的字符&#xff0c;则以这个字符为起点进行搜索&#xff0c;搜索可以是dfs&#x…