1. 实现效果图:
2.实现代码:
css:
<style lang="scss" scoped>
.bottomContainer{
width: 1200px;
height: 400px;
display: flex;
justify-content: center;
position: relative;
margin:200px auto;
align-items: center;
// background-image: url("@/assets/image/test/rote_center_bg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
.bottomboxtest{
position: absolute;
width: 1000px;
height: 1000px;
background:radial-gradient(rgba(181, 214, 243, 0.5) 30%, rgb(108, 165, 230) 80%);
left: 50%;
margin-left: -500px;
transform: rotateX(90deg);
margin-top: -300px;
border-radius: 50%;
}
.arrow-img {
position: absolute;
width: 22px;
height: 22px;
// top: calc(50% + 60px);
top:calc(50% - 66px);
cursor: pointer;
z-index: 10;
&.left {
left: 40px;
}
&.right {
right: 40px;
}
}
.device-list-container{
// position: absolute;
display: flex;
transform-style: preserve-3d;
// transform: rotateX(-20deg);
transform: rotateX(-10deg);
width: 940px;
height: 200px;
.device-list {
position: absolute;
transform-origin: center center;
transform-style: preserve-3d;
transform: rotateY(-8deg);
transition: all .8s;
// margin-top: 75px;
width: 940px;
height: 400px;
// left: 10%;
left: -10px;
display: flex;
justify-content:center;
.device-item {
position: absolute;
font-size: 16px;
color: #FFFFFF;
text-align: center;
margin-top: 10px;
.iconBox{
width: 80px;
height: 80px;
margin:0 auto;
// background: radial-gradient( circle, #E2F1FF,#A8D4FD);
background: #A8D4FD;
border-radius: 50%;
border: 2px solid #E5F2FF;
text-align: center;
line-height: 80px;
.roateIcon{
color:#58A0F5;
font-size: 32px;
}
}
.groupName {
color:#2E5480;
font-size: 16px;
margin-top:8px;
}
}
}
}
}
</style>
html:
<div class="bottomContainer">
<div class="device-list-container">
<div class="device-list" ref="deviceListRef">
<div class="device-item" v-for="(item,index) in roteList">
<div class="iconBox">
test
<!-- <i class="iconfont icon-baojing roateIcon"></i> -->
</div>
<p class="groupName">test</p>
</div>
<div class="bottomboxtest"></div>
</div>
</div>
<img class="arrow-img left" src="@/assets/image/test/arrow-left.png" @click="rotate(true)" alt="">
<img class="arrow-img right" src="@/assets/image/test/arrow-right.png" @click="rotate(false)" alt="">
</div>
js:
<script setup lang="ts">
const roteList= ref([
{},{},{},{},{},{}
]);
const deviceListRef = ref<HTMLDivElement>();
const imgList = ref<NodeListOf<Element>>();
let timer: NodeJS.Timer;
let timeout: NodeJS.Timeout;
let current = 2;
let angle = 360 / 4;
let rotateDeg = 1 ;
const previewCount = roteList.value!.length;
onMounted(async () => {
rotate(true);
})
function rotate(isPlus: boolean) {
imgList.value = imgList.value ?? deviceListRef.value!.querySelectorAll('.device-item');
const SIZE = imgList.value!.length;
current += isPlus ? 1 : -1;
current = (current + SIZE) % SIZE;
const index = getDisplayCard(current, Math.ceil(previewCount/2), SIZE);
angle = 360/SIZE;
rotateDeg -= angle * (isPlus ? 1 : -1);
deviceListRef.value!.style.transform = `rotateY(${rotateDeg}deg)`;
// deviceListRef.value!.style.transform = `rotateY(${rotateDeg}deg)`;
imgList.value!.forEach((v: any, i: number) => {
(v as HTMLDivElement).style.opacity = '0';
if (index.includes(i)) {
(v as HTMLDivElement).style.opacity = '1';
}
(v as HTMLDivElement).style.transform = `rotateY(${(i - 2) * angle}deg) translateZ(370px)`;
})
function getDisplayCard(current: number, num: number, size: number) {
const offset = Math.trunc(num / 2);
const res = [current];
for (let i = 1; i <= offset; i++) {
const pos1 = current + i;
const pos2 = current - i < 0 ? current - i + size : current - i;
res.push(pos1, pos2);
}
return res.map(v => v % size);
}
}
</script>