|
|
@ -29,6 +29,7 @@ import TWEEN from "@tweenjs/tween.js"; |
|
|
|
import { NUMBER_MATRIX } from "../../../utils/config.js"; |
|
|
|
import CardItem from "./CardItem.vue"; |
|
|
|
import { createApp } from "vue"; |
|
|
|
import { getUserList } from "../../../api/API"; |
|
|
|
const threeContainer = ref(null); |
|
|
|
let renderer, scene, camera, animationId; |
|
|
|
// let controls; // 移除controls |
|
|
@ -247,11 +248,20 @@ function selectCard(selectedCardIndex, currentLuckys, duration = 600) { |
|
|
|
const pageIndex = index % cardsPerPage; |
|
|
|
const pageLocate = pageLocates[cardPage][pageIndex]; |
|
|
|
|
|
|
|
// 设置初始位置:第一页的卡片正常显示,其他页的卡片从下方隐藏 |
|
|
|
let initialY; |
|
|
|
if (isVisible) { |
|
|
|
initialY = pageLocate.y; |
|
|
|
} else { |
|
|
|
// 非第一页的卡片从下方隐藏(为后续向上飞出做准备) |
|
|
|
initialY = pageLocate.y - 1000; |
|
|
|
} |
|
|
|
|
|
|
|
new TWEEN.Tween(object.position) |
|
|
|
.to( |
|
|
|
{ |
|
|
|
x: isVisible ? pageLocate.x : pageLocate.x, |
|
|
|
y: isVisible ? pageLocate.y : pageLocate.y + 1000, // 隐藏的卡片移到下方 |
|
|
|
x: pageLocate.x, |
|
|
|
y: initialY, |
|
|
|
z: 2200, |
|
|
|
}, |
|
|
|
Math.random() * duration + duration |
|
|
@ -315,16 +325,58 @@ function switchPage(direction) { |
|
|
|
const object = threeDCards[cardIndex]; |
|
|
|
const cardPage = Math.floor(index / cardsPerPage); |
|
|
|
const isVisible = cardPage === newPage; |
|
|
|
const wasVisible = cardPage === currentPage.value; |
|
|
|
|
|
|
|
// 计算在当前页中的索引 |
|
|
|
const pageIndex = index % cardsPerPage; |
|
|
|
const pageLocate = pageLocates[cardPage][pageIndex]; |
|
|
|
|
|
|
|
// 根据切换方向决定动画效果 |
|
|
|
let targetY; |
|
|
|
if (isVisible) { |
|
|
|
// 当前页要显示的卡片 |
|
|
|
if (direction === 'next') { |
|
|
|
// 索引增大:从下方飞出 |
|
|
|
targetY = pageLocate.y; |
|
|
|
} else { |
|
|
|
// 索引减少:从上方飞出 |
|
|
|
targetY = pageLocate.y; |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 当前页要隐藏的卡片 |
|
|
|
if (direction === 'next') { |
|
|
|
// 索引增大:向上飞走 |
|
|
|
targetY = pageLocate.y + 1000; |
|
|
|
} else { |
|
|
|
// 索引减少:向下飞走 |
|
|
|
targetY = pageLocate.y - 1000; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 设置起始位置 |
|
|
|
let startY; |
|
|
|
if (wasVisible) { |
|
|
|
// 当前页的卡片从当前位置开始 |
|
|
|
startY = object.position.y; |
|
|
|
} else { |
|
|
|
// 非当前页的卡片从隐藏位置开始 |
|
|
|
if (direction === 'next') { |
|
|
|
// 索引增大:从下方开始 |
|
|
|
startY = pageLocate.y - 1000; |
|
|
|
} else { |
|
|
|
// 索引减少:从上方开始 |
|
|
|
startY = pageLocate.y + 1000; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 先设置起始位置 |
|
|
|
object.position.y = startY; |
|
|
|
|
|
|
|
new TWEEN.Tween(object.position) |
|
|
|
.to( |
|
|
|
{ |
|
|
|
x: pageLocate.x, |
|
|
|
y: isVisible ? pageLocate.y : pageLocate.y + 1000, |
|
|
|
y: targetY, |
|
|
|
z: 2200, |
|
|
|
}, |
|
|
|
duration |
|
|
@ -345,58 +397,6 @@ function switchPage(direction) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// function switchPage(direction) { |
|
|
|
// if (isPageTransitioning || totalPages.value <= 1) return; |
|
|
|
|
|
|
|
// const newPage = direction === 'next' ? currentPage.value + 1 : currentPage.value - 1; |
|
|
|
// if (newPage < 0 || newPage >= totalPages.value) return; |
|
|
|
|
|
|
|
// isPageTransitioning = true; |
|
|
|
// const duration = 800; |
|
|
|
|
|
|
|
// // 使用保存的页面位置信息 |
|
|
|
// const pageLocates = window.pageLocates; |
|
|
|
// if (!pageLocates) { |
|
|
|
// console.error('页面位置信息未找到'); |
|
|
|
// isPageTransitioning = false; |
|
|
|
// return; |
|
|
|
// } |
|
|
|
|
|
|
|
// // 动画切换卡片位置 |
|
|
|
// globalCardIndexes.forEach((cardIndex, index) => { |
|
|
|
// const object = threeDCards[cardIndex]; |
|
|
|
// const cardPage = Math.floor(index / cardsPerPage); |
|
|
|
// const isVisible = cardPage === newPage; |
|
|
|
|
|
|
|
// // 计算在当前页中的索引 |
|
|
|
// const pageIndex = index % cardsPerPage; |
|
|
|
// const pageLocate = pageLocates[cardPage][pageIndex]; |
|
|
|
|
|
|
|
// // 修改目标位置以实现从上方或下方飞出的效果 |
|
|
|
// new TWEEN.Tween(object.position) |
|
|
|
// .to( |
|
|
|
// { |
|
|
|
// x: pageLocate.x, |
|
|
|
// y: isVisible ? pageLocate.y : (direction === 'next' ? pageLocate.y - 1000 : pageLocate.y + 1000), // 向下翻页时从上方下落,向上翻页时从下方飞出 |
|
|
|
// z: 2200, |
|
|
|
// }, |
|
|
|
// duration |
|
|
|
// ) |
|
|
|
// .easing(TWEEN.Easing.Cubic.InOut) |
|
|
|
// .start(); |
|
|
|
// }); |
|
|
|
|
|
|
|
// new TWEEN.Tween({}) |
|
|
|
// .to({}, duration) |
|
|
|
// .onUpdate(() => render()) |
|
|
|
// .onComplete(() => { |
|
|
|
// currentPage.value = newPage; |
|
|
|
// isPageTransitioning = false; |
|
|
|
// console.log(`切换到第 ${currentPage.value + 1} 页,共 ${totalPages.value} 页`); |
|
|
|
// }) |
|
|
|
// .start(); |
|
|
|
// } |
|
|
|
|
|
|
|
// 鼠标滚轮事件处理 |
|
|
|
function handleWheel(event) { |
|
|
|
if (isPageTransitioning || totalPages.value <= 1) return; |
|
|
@ -443,6 +443,9 @@ function resetCard(selectedCardIndex, duration = 500) { |
|
|
|
if (window.pageLocates) { |
|
|
|
delete window.pageLocates; |
|
|
|
} |
|
|
|
|
|
|
|
// 清空全局卡片索引数组 |
|
|
|
globalCardIndexes = []; |
|
|
|
|
|
|
|
selectedCardIndex.forEach((index) => { |
|
|
|
const object = threeDCards[index]; |
|
|
@ -481,6 +484,11 @@ function resetCard(selectedCardIndex, duration = 500) { |
|
|
|
.onComplete(() => { |
|
|
|
selectedCardIndex.forEach((index) => { |
|
|
|
const object = threeDCards[index]; |
|
|
|
// 恢复原始内容 |
|
|
|
if (object.element.dataset.originalContent) { |
|
|
|
object.element.innerHTML = object.element.dataset.originalContent; |
|
|
|
delete object.element.dataset.originalContent; |
|
|
|
} |
|
|
|
object.element.classList.remove("prize"); |
|
|
|
}); |
|
|
|
resolve(); |
|
|
@ -495,19 +503,22 @@ function changeCard(cardIndex, user) { |
|
|
|
} |
|
|
|
|
|
|
|
const card = threeDCards[cardIndex].element; |
|
|
|
// card.innerHTML = `<div class="company">${ |
|
|
|
// user.company || "" |
|
|
|
// }</div><div class="name">${user[1]}</div><div class="details">${ |
|
|
|
// user[0] || "" |
|
|
|
// }<br/>${user[2] || "PSST"}</div>`; |
|
|
|
|
|
|
|
card.style.setProperty('background-color', '#ffffff', 'important'); |
|
|
|
|
|
|
|
// card.style.backgroundColor = '#ffffff'; |
|
|
|
|
|
|
|
// card.style.backgroundColor = ''; |
|
|
|
|
|
|
|
|
|
|
|
// 保存原始内容,以便后续恢复 |
|
|
|
if (!card.dataset.originalContent) { |
|
|
|
card.dataset.originalContent = card.innerHTML; |
|
|
|
} |
|
|
|
|
|
|
|
// 设置中奖内容 - 适配后端返回的数据格式 |
|
|
|
// 后端返回的数据格式: { jwcode: "5412", username: "猪八戒22" } |
|
|
|
const jwcode = user.jwcode || user[0] || ""; |
|
|
|
const username = user.username || user[1] || ""; |
|
|
|
const company = user.company || user[2] || "PSST"; |
|
|
|
|
|
|
|
card.innerHTML = `<div style="font-size: 16px; font-weight: bold; color: #ffffff; text-align: center; display: flex; justify-content: center; align-items: center; width: 100%; height: 100%;">${jwcode}</div>`; |
|
|
|
|
|
|
|
// 添加中奖样式类 |
|
|
|
card.classList.add("prize"); |
|
|
|
} |
|
|
|
|
|
|
|
function changeCard1() { |
|
|
@ -528,10 +539,15 @@ function changeCard1() { |
|
|
|
|
|
|
|
globalCardIndexes.forEach(cardIndex => { |
|
|
|
const card = threeDCards[cardIndex].element; |
|
|
|
console.log('取消卡片', cardIndex, '的高光'); |
|
|
|
card.style.setProperty('background-color', 'rgba(254, 177, 48, 1)', 'important'); |
|
|
|
// console.log('取消卡片', cardIndex, '的高光'); |
|
|
|
|
|
|
|
// 恢复原始内容 |
|
|
|
if (card.dataset.originalContent) { |
|
|
|
card.innerHTML = card.dataset.originalContent; |
|
|
|
delete card.dataset.originalContent; |
|
|
|
} |
|
|
|
|
|
|
|
// 移除prize类,因为CSS规则会覆盖backgroundColor |
|
|
|
// 移除prize类,让CardItem组件的样式重新生效 |
|
|
|
card.classList.remove('prize'); |
|
|
|
}); |
|
|
|
// 清空数组 |
|
|
@ -623,7 +639,7 @@ function getTotalCards() { |
|
|
|
return threeDCards.length; |
|
|
|
} |
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
onMounted( async () => { |
|
|
|
// 初始化 3D 场景 |
|
|
|
scene = new THREE.Scene(); |
|
|
|
camera = new THREE.PerspectiveCamera( |
|
|
@ -650,88 +666,89 @@ onMounted(() => { |
|
|
|
HIGHLIGHT_CELL: highlightCells, |
|
|
|
COMPANY: "演示公司", |
|
|
|
}; |
|
|
|
const member = [ |
|
|
|
[0, "张三"], |
|
|
|
[1, "李四"], |
|
|
|
[2, "王五"], |
|
|
|
[3, "赵六"], |
|
|
|
[4, "孙七"], |
|
|
|
[5, "周八"], |
|
|
|
[6, "吴九"], |
|
|
|
[7, "郑十"], |
|
|
|
[8, "钱十一"], |
|
|
|
[9, "孙十二"], |
|
|
|
[10, "李十三"], |
|
|
|
[11, "周十四"], |
|
|
|
[12, "吴十五"], |
|
|
|
[13, "郑十六"], |
|
|
|
[14, "钱十七"], |
|
|
|
[15, "孙十八"], |
|
|
|
[16, "李十九"], |
|
|
|
[17, "周二十"], |
|
|
|
[18, "吴二一"], |
|
|
|
[19, "郑二二"], |
|
|
|
[0, "张三"], |
|
|
|
[1, "李四"], |
|
|
|
[2, "王五"], |
|
|
|
[3, "赵六"], |
|
|
|
[4, "孙七"], |
|
|
|
[5, "周八"], |
|
|
|
[6, "吴九"], |
|
|
|
[7, "郑十"], |
|
|
|
[8, "钱十一"], |
|
|
|
[9, "孙十二"], |
|
|
|
[10, "李十三"], |
|
|
|
[11, "周十四"], |
|
|
|
[12, "吴十五"], |
|
|
|
[13, "郑十六"], |
|
|
|
[14, "钱十七"], |
|
|
|
[15, "孙十八"], |
|
|
|
[16, "李十九"], |
|
|
|
[17, "周二十"], |
|
|
|
[18, "吴二一"], |
|
|
|
[19, "郑二二"], |
|
|
|
[0, "张三"], |
|
|
|
[1, "李四"], |
|
|
|
[2, "王五"], |
|
|
|
[3, "赵六"], |
|
|
|
[4, "孙七"], |
|
|
|
[5, "周八"], |
|
|
|
[6, "吴九"], |
|
|
|
[7, "郑十"], |
|
|
|
[8, "钱十一"], |
|
|
|
[9, "孙十二"], |
|
|
|
[10, "李十三"], |
|
|
|
[11, "周十四"], |
|
|
|
[12, "吴十五"], |
|
|
|
[13, "郑十六"], |
|
|
|
[14, "钱十七"], |
|
|
|
[15, "孙十八"], |
|
|
|
[16, "李十九"], |
|
|
|
[17, "周二十"], |
|
|
|
[18, "吴二一"], |
|
|
|
[19, "郑二二"], |
|
|
|
[0, "张三"], |
|
|
|
[1, "李四"], |
|
|
|
[2, "王五"], |
|
|
|
[3, "赵六"], |
|
|
|
[4, "孙七"], |
|
|
|
[5, "周八"], |
|
|
|
[6, "吴九"], |
|
|
|
[7, "郑十"], |
|
|
|
[8, "钱十一"], |
|
|
|
[9, "孙十二"], |
|
|
|
[10, "李十三"], |
|
|
|
[11, "周十四"], |
|
|
|
[12, "吴十五"], |
|
|
|
[13, "郑十六"], |
|
|
|
[14, "钱十七"], |
|
|
|
[15, "孙十八"], |
|
|
|
[16, "李十九"], |
|
|
|
[17, "周二十"], |
|
|
|
[18, "吴二一"], |
|
|
|
[19, "郑二二"], |
|
|
|
]; |
|
|
|
|
|
|
|
const userList = await getUserList(); |
|
|
|
console.log("userList", userList); |
|
|
|
// 将用户数据转换为兼容格式,用于3D卡片显示 |
|
|
|
const member = userList.data.map(item => [item.jwcode, item.username, "PSST"]); |
|
|
|
// const member = [ |
|
|
|
// [1], |
|
|
|
// [2], |
|
|
|
// [3], |
|
|
|
// [4], |
|
|
|
// [5], |
|
|
|
// [6], |
|
|
|
// [7], |
|
|
|
// [8], |
|
|
|
// [9], |
|
|
|
// [10], |
|
|
|
// [11], |
|
|
|
// [12], |
|
|
|
// [13], |
|
|
|
// [14], |
|
|
|
// [15], |
|
|
|
// [16], |
|
|
|
// [17], |
|
|
|
// [18], |
|
|
|
// [19], |
|
|
|
// [20], |
|
|
|
// [21], |
|
|
|
// [22], |
|
|
|
// [23], |
|
|
|
// [24], |
|
|
|
// [25], |
|
|
|
// [26], |
|
|
|
// [27], |
|
|
|
// [28], |
|
|
|
// [29], |
|
|
|
// [30], |
|
|
|
// [31], |
|
|
|
// [32], |
|
|
|
// [33], |
|
|
|
// [34], |
|
|
|
// [35], |
|
|
|
// [36], |
|
|
|
// [37], |
|
|
|
// [38], |
|
|
|
// [39], |
|
|
|
// [40], |
|
|
|
// [41], |
|
|
|
// [42], |
|
|
|
// [43], |
|
|
|
// [44], |
|
|
|
// [45], |
|
|
|
// [46], |
|
|
|
// [47], |
|
|
|
// [48], |
|
|
|
// [49], |
|
|
|
// [50], |
|
|
|
// [51], |
|
|
|
// [52], |
|
|
|
// [53], |
|
|
|
// [54], |
|
|
|
// [55], |
|
|
|
// [56], |
|
|
|
// [57], |
|
|
|
// [58], |
|
|
|
// [59], |
|
|
|
// [60], |
|
|
|
// [61], |
|
|
|
// [62], |
|
|
|
// [63], |
|
|
|
// [64], |
|
|
|
// [65], |
|
|
|
// [66], |
|
|
|
// [67], |
|
|
|
// [68], |
|
|
|
// [69], |
|
|
|
// [70], |
|
|
|
// [71], |
|
|
|
// [72], |
|
|
|
// [73], |
|
|
|
// [74], |
|
|
|
// [75], |
|
|
|
// [76], |
|
|
|
// ]; |
|
|
|
const length = member.length; |
|
|
|
const showTable = true; |
|
|
|
const position = { |
|
|
@ -836,6 +853,18 @@ defineExpose({ |
|
|
|
animation: fadeInOut 2s ease-in-out infinite; |
|
|
|
} |
|
|
|
|
|
|
|
.price-font{ |
|
|
|
font-size: 16px; |
|
|
|
font-weight: bold; |
|
|
|
color: #ffffff; |
|
|
|
text-align: center; |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
align-items: center; |
|
|
|
width: 100%; |
|
|
|
height: 100%; |
|
|
|
} |
|
|
|
|
|
|
|
@keyframes fadeInOut { |
|
|
|
0%, 100% { opacity: 0.6; } |
|
|
|
50% { opacity: 1; } |
|
|
|