Merge pull request #58 from LOG1997/fix-bug

fix: 性能问题
This commit is contained in:
LOG1997
2025-01-13 23:08:29 +08:00
committed by GitHub
2 changed files with 148 additions and 95 deletions

View File

@@ -1,27 +1,27 @@
import type { IPersonConfig } from '@/types/storeType' import type { IPersonConfig } from '@/types/storeType'
import { rgba } from '@/utils/color' import { rgba } from '@/utils/color'
export const useElementStyle = (element: any, person: IPersonConfig, index: number, patternList: number[], patternColor: string, cardColor: string, cardSize: { width: number, height: number }, textSize: number, mod: 'default' | 'lucky' | 'sphere' = 'default') => { export function useElementStyle(element: any, person: IPersonConfig, index: number, patternList: number[], patternColor: string, cardColor: string, cardSize: { width: number, height: number }, textSize: number, mod: 'default' | 'lucky' | 'sphere' = 'default', type: 'add' | 'change' = 'add') {
if (patternList.includes(index + 1) && mod == 'default') { if (patternList.includes(index + 1) && mod === 'default') {
element.style.backgroundColor = rgba(patternColor, Math.random() * 0.2 + 0.8) element.style.backgroundColor = rgba(patternColor, Math.random() * 0.2 + 0.8)
} }
else if (mod == 'sphere' || mod == 'default') { else if (mod === 'sphere' || mod === 'default') {
element.style.backgroundColor = rgba(cardColor, Math.random() * 0.5 + 0.25) element.style.backgroundColor = rgba(cardColor, Math.random() * 0.5 + 0.25)
} }
else if (mod == 'lucky') { else if (mod === 'lucky') {
element.style.backgroundColor = rgba(cardColor, 0.8) element.style.backgroundColor = rgba(cardColor, 0.8)
} }
element.style.border = `1px solid ${rgba(cardColor, 0.25)}` element.style.border = `1px solid ${rgba(cardColor, 0.25)}`
element.style.boxShadow = `0 0 12px ${rgba(cardColor, 0.5)}` element.style.boxShadow = `0 0 12px ${rgba(cardColor, 0.5)}`
element.style.width = `${cardSize.width}px`; element.style.width = `${cardSize.width}px`
element.style.height = `${cardSize.height}px`; element.style.height = `${cardSize.height}px`
if (mod == 'lucky') { if (mod === 'lucky') {
element.className = 'lucky-element-card' element.className = 'lucky-element-card'
} }
else { else {
element.className = 'element-card' element.className = 'element-card'
} }
// 等比放大 if (type === 'add') {
element.addEventListener('mouseenter', (ev: MouseEvent) => { element.addEventListener('mouseenter', (ev: MouseEvent) => {
const target = ev.target as HTMLElement const target = ev.target as HTMLElement
target.style.border = `1px solid ${rgba(cardColor, 0.75)}` target.style.border = `1px solid ${rgba(cardColor, 0.75)}`
@@ -32,9 +32,10 @@ export const useElementStyle = (element: any, person: IPersonConfig, index: numb
target.style.border = `1px solid ${rgba(cardColor, 0.25)}` target.style.border = `1px solid ${rgba(cardColor, 0.25)}`
target.style.boxShadow = `0 0 12px ${rgba(cardColor, 0.5)}` target.style.boxShadow = `0 0 12px ${rgba(cardColor, 0.5)}`
}) })
element.children[0].style.fontSize = textSize * 0.5 + 'px'; }
element.children[0].style.fontSize = `${textSize * 0.5}px`
if (person.uid) { if (person.uid) {
element.children[0].textContent = person.uid; element.children[0].textContent = person.uid
} }
element.children[1].style.fontSize = `${textSize}px` element.children[1].style.fontSize = `${textSize}px`
@@ -43,7 +44,6 @@ export const useElementStyle = (element: any, person: IPersonConfig, index: numb
if (person.name) { if (person.name) {
element.children[1].textContent = person.name element.children[1].textContent = person.name
} }
element.children[2].style.fontSize = `${textSize * 0.5}px` element.children[2].style.fontSize = `${textSize * 0.5}px`
if (person.department || person.identity) { if (person.department || person.identity) {
element.children[2].innerHTML = `${person.department ? person.department : ''}<br/>${person.identity ? person.identity : ''}` element.children[2].innerHTML = `${person.department ? person.department : ''}<br/>${person.identity ? person.identity : ''}`
@@ -57,19 +57,19 @@ export const useElementStyle = (element: any, person: IPersonConfig, index: numb
* 最少一个,最大十个 * 最少一个,最大十个
*/ */
// TODO:不超过5个时单行排列超过5个时6上3下37上3下48上3下59上4下510上5下5 // TODO:不超过5个时单行排列超过5个时6上3下37上3下48上3下59上4下510上5下5
export const useElementPosition = (element: any, count: number, totalCount: number, cardSize: { width: number, height: number }, windowSize: { width: number, height: number }, cardIndex: number) => { export function useElementPosition(element: any, count: number, totalCount: number, cardSize: { width: number, height: number }, windowSize: { width: number, height: number }, cardIndex: number) {
let xTable = 0 let xTable = 0
let yTable = 0 let yTable = 0
const centerPosition = { const centerPosition = {
x: 0, x: 0,
y: windowSize.height / 2 - cardSize.height / 2 y: windowSize.height / 2 - cardSize.height / 2,
} }
// 有一行为偶数的特殊数量 // 有一行为偶数的特殊数量
const specialPosition = [2, 4, 7, 9] const specialPosition = [2, 4, 7, 9]
// 不包含特殊值的 和 分两行中第一行为奇数值的 // 不包含特殊值的 和 分两行中第一行为奇数值的
if (!specialPosition.includes(totalCount) || (totalCount > 5 && cardIndex < 5)) { if (!specialPosition.includes(totalCount) || (totalCount > 5 && cardIndex < 5)) {
const index = cardIndex % 5 const index = cardIndex % 5
if (index == 0) { if (index === 0) {
xTable = centerPosition.x xTable = centerPosition.x
yTable = centerPosition.y - Math.floor(cardIndex / 5) * (cardSize.height + 60) yTable = centerPosition.y - Math.floor(cardIndex / 5) * (cardSize.height + 60)
} }
@@ -80,7 +80,7 @@ export const useElementPosition = (element: any, count: number, totalCount: numb
} }
else { else {
const index = cardIndex % 5 const index = cardIndex % 5
if (index == 0) { if (index === 0) {
xTable = centerPosition.x + (cardSize.width + 100) / 2 xTable = centerPosition.x + (cardSize.width + 100) / 2
yTable = centerPosition.y - Math.floor(cardIndex / 5) * (cardSize.height + 60) yTable = centerPosition.y - Math.floor(cardIndex / 5) * (cardSize.height + 60)
} }

View File

@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { IPersonConfig } from '@/types/storeType' import type { IPersonConfig } from '@/types/storeType'
import type { Material } from 'three'
import StarsBackground from '@/components/StarsBackground/index.vue' import StarsBackground from '@/components/StarsBackground/index.vue'
import { useElementPosition, useElementStyle } from '@/hooks/useElement' import { useElementPosition, useElementStyle } from '@/hooks/useElement'
import i18n from '@/locales/i18n' import i18n from '@/locales/i18n'
@@ -12,7 +13,7 @@ import { storeToRefs } from 'pinia'
import { Object3D, PerspectiveCamera, Scene, Vector3 } from 'three' import { Object3D, PerspectiveCamera, Scene, Vector3 } from 'three'
import { CSS3DObject, CSS3DRenderer } from 'three-css3d' import { CSS3DObject, CSS3DRenderer } from 'three-css3d'
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls.js' import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls.js'
import { onMounted, onUnmounted, ref } from 'vue' import { nextTick, onMounted, onUnmounted, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useToast } from 'vue-toast-notification' import { useToast } from 'vue-toast-notification'
@@ -268,7 +269,9 @@ function onWindowResize() {
*/ */
function animation() { function animation() {
TWEEN.update() TWEEN.update()
if (controls.value) {
controls.value.update() controls.value.update()
}
// 设置自动旋转 // 设置自动旋转
// 设置相机位置 // 设置相机位置
requestAnimationFrame(animation) requestAnimationFrame(animation)
@@ -343,7 +346,9 @@ function resetCamera() {
} }
function render() { function render() {
if (renderer.value) {
renderer.value.render(scene.value, camera.value) renderer.value.render(scene.value, camera.value)
}
} }
async function enterLottery() { async function enterLottery() {
if (!canOperate.value) { if (!canOperate.value) {
@@ -582,13 +587,12 @@ function randomBallData(mod: 'default' | 'lucky' | 'sphere' = 'default') {
if (!objects.value[cardRandomIndexArr[i]]) { if (!objects.value[cardRandomIndexArr[i]]) {
continue continue
} }
objects.value[cardRandomIndexArr[i]].element = useElementStyle(objects.value[cardRandomIndexArr[i]].element, allPersonList.value[personRandomIndexArr[i]], cardRandomIndexArr[i], patternList.value, patternColor.value, cardColor.value, { width: cardSize.value.width, height: cardSize.value.height }, textSize.value, mod) objects.value[cardRandomIndexArr[i]].element = useElementStyle(objects.value[cardRandomIndexArr[i]].element, allPersonList.value[personRandomIndexArr[i]], cardRandomIndexArr[i], patternList.value, patternColor.value, cardColor.value, { width: cardSize.value.width, height: cardSize.value.height }, textSize.value, mod, 'change')
} }
}, 200) }, 200)
} }
// 监听键盘 // 监听键盘
function listenKeyboard() { function listenKeyboard(e: any) {
window.addEventListener('keydown', (e: any) => {
if ((e.keyCode !== 32 || e.keyCode !== 27) && !canOperate.value) { if ((e.keyCode !== 32 || e.keyCode !== 27) && !canOperate.value) {
return return
} }
@@ -614,7 +618,53 @@ function listenKeyboard() {
default: default:
break break
} }
}
function cleanup() {
// animationRunning.value = false
clearInterval(intervalTimer.value)
intervalTimer.value = null
if (scene.value) {
scene.value.traverse((object: Object3D) => {
if ((object as any).material) {
if (Array.isArray((object as any).material)) {
(object as any).material.forEach((material: Material) => {
material.dispose()
}) })
}
else {
(object as any).material.dispose()
}
}
if ((object as any).geometry) {
(object as any).geometry.dispose()
}
if ((object as any).texture) {
(object as any).texture.dispose()
}
})
scene.value.clear()
}
if (objects.value) {
objects.value.forEach((object) => {
if (object.element) {
object.element.remove()
}
})
objects.value = []
}
if (controls.value) {
controls.value.removeEventListener('change')
controls.value.dispose()
}
// 移除所有事件监听
window.removeEventListener('resize', onWindowResize)
scene.value = null
camera.value = null
renderer.value = null
controls.value = null
} }
onMounted(() => { onMounted(() => {
initTableData() initTableData()
@@ -622,9 +672,12 @@ onMounted(() => {
animation() animation()
containerRef.value!.style.color = `${textColor}` containerRef.value!.style.color = `${textColor}`
randomBallData() randomBallData()
listenKeyboard() window.addEventListener('keydown', listenKeyboard)
}) })
onUnmounted(() => { onUnmounted(() => {
nextTick(() => {
cleanup()
})
clearInterval(intervalTimer.value) clearInterval(intervalTimer.value)
intervalTimer.value = null intervalTimer.value = null
window.removeEventListener('keydown', listenKeyboard) window.removeEventListener('keydown', listenKeyboard)