如何使用Vue.js实现产品动画循环并固定左下角显示2个产品
Vue.js产品图片过渡效果优化方案
问题说明
需要实现产品图片从左侧进入→停在中间→右上角消失的过渡效果,当前遇到的问题:切换到最后一个产品时,它会从右上角反向返回;同时需要始终在左下角保留最近的2个产品。
修改后的完整代码
CSS 部分
/* import font - MONTSERRAT */ @import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); html { font-size: 16px; font-family: 'Montserrat', sans-serif; } body .writing-vertical { -webkit-writing-mode: vertical-rl; -ms-writing-mode: tb-rl; writing-mode: vertical-rl; } body .outline-text::after { position: absolute; left: 1px; top: 1px; content: attr(data-text); color: white; z-index: -1; text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; } body .outline-text-rl::after { position: absolute; left: -1px; top: 1px; content: attr(data-text); color: white; z-index: -1; text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; } .product { position: absolute; transition: 1s all; left: 0; bottom: 0; z-index: 1; } .product.centerProduct { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 10; } /* 最近的第一个历史产品(刚从中间移走) */ .product.pastProduct-1 { transform: translate(0, 0); z-index: 2; } /* 最近的第二个历史产品 */ .product.pastProduct-2 { transform: translate(-20px, 20px); z-index: 1; } /* 更早的历史产品,隐藏到视窗外 */ .product.pastProduct-hidden { transform: translate(-100%, 100%); } .product.upcomingProduct { /* 初始位置设到左侧外,确保从左侧进入 */ transform: translate(-100%, 0); } @media (min-width: 1024px) { .outline-text::after { left: 3px !important; top: 5px !important; } .outline-text-rl::after { left: -3px !important; top: 5px !important; } }
HTML & Vue.js 部分
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/custom.css"> <script src="https://cdn.tailwindcss.com"></script> <title>Document</title> </head> <body> <div id="app" class="fixed top-0 left-0 max-w-full max-h-screen min-h-screen min-w-full"> <div v-for="(product,index) in products" :key="index" :class="getProductClass(product.id)" class="product max-w-[350px] h-[60vh] w-full"> <div :style="{backgroundImage: 'url('+ product.src +')',backgroundSize:'cover',backgroundRepeat: 'no-repeat',backgroundPosition: 'center center'}" class="w-full h-full"> </div> </div> <button @click="prev()">prev</button> <button @click="next()">next</button> </div> <script src="../node_modules/jquery/dist/jquery.min.js"></script> <script src="../assets/js/app.js"></script> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script> const { createApp } = Vue createApp({ data() { return { products: [ { id: 0, src: "https://via.placeholder.com/1000", name: "产品 0", color: "red" }, { id: 1, src: "https://via.placeholder.com/1000", name: "产品 1", color: "green" }, { id: 2, src: "https://via.placeholder.com/1000", name: "产品 2", color: "gray" }, { id: 3, src: "https://via.placeholder.com/1000", name: "产品 3", color: "rebeccapurple" }, { id: 4, src: "https://via.placeholder.com/1000", name: "产品 4", color: "yellow" }, { id: 5, src: "https://via.placeholder.com/1000", name: "产品 5", color: "orangered" }, ], activeProduct: 2, } }, methods: { getProductClass(productId) { const diff = this.activeProduct - productId; if (diff === 0) { return 'centerProduct'; } else if (diff === 1) { return 'pastProduct-1'; } else if (diff === 2) { return 'pastProduct-2'; } else if (diff > 2) { return 'pastProduct-hidden'; } else { return 'upcomingProduct'; } }, next() { this.activeProduct = (this.activeProduct + 1) % this.products.length; }, prev() { this.activeProduct = (this.activeProduct - 1 + this.products.length) % this.products.length; } }, }).mount('#app') </script> </body> </html>
核心修改点
- 状态分类细化:将历史产品分为最近2个(
pastProduct-1、pastProduct-2)和更早的产品(pastProduct-hidden),分别设置位置和层级,实现左下角层叠保留2个产品的效果。 - 初始位置修正:将
upcomingProduct的初始位置改为左侧外(translate(-100%, 0)),确保切换时从左侧平滑进入。 - 切换逻辑简化:用取模运算简化
next和prev的边界判断,避免循环切换时的异常过渡。 - 层级管理:给不同状态的产品设置
z-index,确保中间产品在最上层,左下角产品按顺序层叠。
内容的提问来源于stack exchange,提问作者İsmail Cem Altekin
相关产品推荐
相关产品推荐

