184 lines
3.8 KiB
Plaintext
184 lines
3.8 KiB
Plaintext
<template>
|
|
<div @mousemove="handleMouseMove">
|
|
<ul id="ul1">
|
|
<li class="ation-li" v-for="(item, index) in props.dataE" :key="index" ref="cards">
|
|
<div class="pt10px pb10px text-15px title">{{item.title}}</div>
|
|
<div class="text-12px leading-15px sub-title" @click="downloadHandle(item)">{{item.content}}</div>
|
|
</li>
|
|
<div id="earth" class="earth"></div>
|
|
</ul>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { nextTick } from 'vue'
|
|
|
|
const emit = defineEmits(['downloadHandle'])
|
|
const downloadHandle = (item) => {
|
|
emit('downloadHandle', item, 5)
|
|
}
|
|
|
|
|
|
const props = defineProps({//对象写法
|
|
dataE:{
|
|
type:Array,//接受的数据类型
|
|
default:[],//接受默认数据
|
|
}
|
|
})
|
|
|
|
|
|
|
|
const numCards = ref(10);
|
|
const mouseX = ref(0);
|
|
const mouseY = ref(0);
|
|
const isDragging = ref(false);
|
|
|
|
const handleMouseMove = (event) => {
|
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
mouseX.value = event.clientX - rect.left;
|
|
mouseY.value = event.clientY - rect.top;
|
|
};
|
|
|
|
watch(
|
|
() => props.dataE,
|
|
(newValue, oldValue) => {
|
|
nextTick(() => {
|
|
updateRotation();
|
|
// autoRotate();
|
|
})
|
|
|
|
}
|
|
)
|
|
|
|
const updateRotation = () => {
|
|
const cardRefs = ref([]);
|
|
const earth = ref(null);
|
|
|
|
cardRefs.value = document.querySelectorAll('#ul1 li');
|
|
earth.value = document.getElementById('earth');
|
|
console.log(cardRefs, 1111)
|
|
setInterval(() => {
|
|
numCards.value = cardRefs.value.length;
|
|
cardRefs.value.forEach((card, index) => {
|
|
const d = (360 / numCards.value) * index + mouseX.value / 10;
|
|
let radian = d * Math.PI / 180;
|
|
let opacity = (Math.cos(radian) + 1) / 2;
|
|
card.style.transform = `rotateY(${d}deg) translateZ(280px) rotateY(${-d}deg)`;
|
|
card.style.opacity = opacity * opacity;
|
|
|
|
if (Math.abs(d) < 30) {
|
|
card.style.zIndex = 2;
|
|
if (earth.value) {
|
|
earth.value.style.transform = 'translateZ(-400px)';
|
|
}
|
|
} else {
|
|
card.style.zIndex = -1;
|
|
if (earth.value) {
|
|
earth.value.style.transform = 'translateZ(400px)';
|
|
}
|
|
}
|
|
});
|
|
}, 30);
|
|
};
|
|
|
|
const autoRotate = () => {
|
|
const interval = setInterval(() => {
|
|
if (!isDragging.value) {
|
|
// 自动旋转的速度
|
|
mouseY.value += 1;
|
|
}
|
|
}, 30);
|
|
|
|
onMounted(() => {
|
|
clearInterval(interval);
|
|
});
|
|
};
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<style lang="less">
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
}
|
|
|
|
html {
|
|
overflow: hidden;
|
|
}
|
|
|
|
body {
|
|
background: #000;
|
|
}
|
|
|
|
#ul1 {
|
|
position: relative;
|
|
width: 139px;
|
|
height: 121px;
|
|
margin: 190px auto;
|
|
background: none;
|
|
transform-style: preserve-3d;
|
|
transform: perspective(1320px) rotateX(-15deg) rotateY(0deg);
|
|
}
|
|
|
|
#ul1 li {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 40px;
|
|
width: 100%;
|
|
height: 100%;
|
|
transition: 1s all ease;
|
|
transform: rotateY(0deg) translateZ(0px);
|
|
border-radius: 10px;
|
|
overflow: hidden;
|
|
// background: rgba(14, 116, 238, 0.8);
|
|
background-image: url("./images/biaoq.png");
|
|
color: rgb(255, 255, 255);
|
|
line-height: 10px;
|
|
text-align: center;
|
|
padding: 8px 8px 40px;
|
|
/* font-size: 30px; */
|
|
p{
|
|
font-size: 15px;
|
|
|
|
}
|
|
}
|
|
|
|
#ul1 li img {
|
|
width: 100%;
|
|
}
|
|
|
|
#earth {
|
|
position: absolute;
|
|
top: 2%;
|
|
left: 50%;
|
|
width: 260px;
|
|
height: 260px;
|
|
margin-top: -222px;
|
|
margin-left: -130px;
|
|
border-radius: 50%;
|
|
background-image: url('./images/diqiu.png');
|
|
background-size: cover;
|
|
transform-style: preserve-3d;
|
|
transform: translateZ(400px);
|
|
z-index: 1;
|
|
transition: transform 0.5s ease;
|
|
}
|
|
.ation-li {
|
|
display: flex;
|
|
align-items: center;
|
|
// justify-content: center;
|
|
flex-direction: column;
|
|
.title {
|
|
color: white;
|
|
}
|
|
.sub-title {
|
|
color: #00E4FF;
|
|
text-align: start;
|
|
}
|
|
}
|
|
</style>
|