vue 实现旋转木马
实现旋转木马效果的核心思路
使用Vue实现旋转木马(Carousel)效果通常需要结合CSS 3D变换和动态数据绑定。核心是通过计算每个元素的位置、旋转角度和层级关系,形成环形排列的视觉效果。
基础HTML结构
<template>
<div class="carousel-container">
<div class="carousel-track" :style="trackStyle">
<div
v-for="(item, index) in items"
:key="index"
class="carousel-item"
:style="getItemStyle(index)"
>
{{ item }}
</div>
</div>
<button @click="rotate(-1)">Prev</button>
<button @click="rotate(1)">Next</button>
</div>
</template>
Vue组件脚本部分
<script>
export default {
data() {
return {
items: ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'],
currentAngle: 0,
radius: 200 // 旋转半径
}
},
computed: {
trackStyle() {
return {
transform: `rotateY(${this.currentAngle}deg)`
}
}
},
methods: {
getItemStyle(index) {
const angle = (360 / this.items.length) * index;
const radian = (angle * Math.PI) / 180;
return {
transform: `rotateY(${angle}deg) translateZ(${this.radius}px)`,
opacity: this.calculateOpacity(angle)
}
},
calculateOpacity(angle) {
const diff = Math.abs(((angle - this.currentAngle + 180) % 360) - 180);
return 1 - Math.min(diff / 90, 1);
},
rotate(direction) {
this.currentAngle += direction * (360 / this.items.length);
}
}
}
</script>
关键CSS样式
.carousel-container {
perspective: 1000px;
width: 100%;
height: 300px;
}
.carousel-track {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 1s ease;
}
.carousel-item {
position: absolute;
width: 200px;
height: 200px;
background: #3498db;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
color: white;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
transition: opacity 0.3s ease;
}
实现3D空间定位
每个项目的定位通过以下公式计算:
- 角度 = (360° / 项目总数) × 索引位置
- X轴位置 = radius × sin(角度)
- Z轴位置 = radius × cos(角度)
在Vue中简化为:
transform: rotateY(${angle}deg) translateZ(${radius}px)
动态透明度控制
通过计算当前项目与正对视角的角度差来控制透明度:
const diff = Math.abs(((angle - currentAngle + 180) % 360) - 180);
opacity = 1 - Math.min(diff / 90, 1);
响应式调整
添加窗口大小变化的监听,动态调整半径:
mounted() {
window.addEventListener('resize', this.handleResize);
this.handleResize();
},
methods: {
handleResize() {
this.radius = Math.min(window.innerWidth, window.innerHeight) * 0.3;
}
}
自动旋转功能
添加自动旋转逻辑:
data() {
return {
autoRotateInterval: null
}
},
mounted() {
this.startAutoRotate();
},
methods: {
startAutoRotate() {
this.autoRotateInterval = setInterval(() => {
this.rotate(1);
}, 3000);
}
}
触摸事件支持
添加移动端触摸支持:
<div
class="carousel-track"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
methods: {
handleTouchStart(e) {
this.touchStartX = e.touches[0].clientX;
},
handleTouchMove(e) {
const deltaX = e.touches[0].clientX - this.touchStartX;
if (Math.abs(deltaX) > 10) {
this.currentAngle += deltaX * 0.2;
}
},
handleTouchEnd(e) {
// 滑动结束后对齐到最近的项目位置
}
}






