Skip to content

Commit f67b107

Browse files
committed
Merge remote-tracking branch 'templeta/main'
2 parents ae820f5 + a1cc295 commit f67b107

File tree

4 files changed

+72
-53
lines changed

4 files changed

+72
-53
lines changed

.vitepress/theme/Layout.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
</main>
2020
<Footer></Footer>
2121
<Fireworks v-if="state.fireworksEnabled"></Fireworks>
22-
<SpinePlayer></SpinePlayer>
22+
<ClientOnly><SpinePlayer></SpinePlayer></ClientOnly>
2323
<ToTop></ToTop>
2424
<!-- 背景音乐元素 -->
2525
<audio id="background-music" loop>

.vitepress/theme/components/Navbar/Search-Dialog.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
</template>
2424

2525
<script setup lang="ts">
26-
import { ref, onMounted, watch } from 'vue'
26+
import { ref, onMounted } from 'vue'
2727
2828
const emit = defineEmits(['closeDialog'])
2929
const closeDialog = (): void => {

.vitepress/theme/components/Posts-List.vue

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,14 @@ const currPage = computed({
133133
set: (value) => (state.currPage = value),
134134
})
135135
136-
// 获取URL信息
137136
onMounted(() => {
137+
// 获取URL信息
138138
updatePageFromUrl()
139+
// 监听前进后退
140+
window.addEventListener('popstate', () => {
141+
updatePageFromUrl()
142+
})
139143
})
140-
const url = new URL(window.location.href)
141144
function updatePageFromUrl() {
142145
const urlParams = new URLSearchParams(window.location.search)
143146
const pageParam = urlParams.get('page')
@@ -177,13 +180,6 @@ function goToPage(page: number) {
177180
window.history.pushState({}, '', url.toString())
178181
}
179182
180-
// 监听前进后退
181-
onMounted(() => {
182-
window.addEventListener('popstate', () => {
183-
updatePageFromUrl()
184-
})
185-
})
186-
187183
// 计算要显示的页码
188184
const maxVisiblePages = 3 // 省略号两边显示的页码按钮数量
189185
const visiblePageNumbers = computed(() => {

.vitepress/theme/components/Spine-Player/index.vue

Lines changed: 65 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
@touchstart="handlePlayerClick"
1414
></div>
1515
<transition name="fade">
16-
<div v-if="showDialog" class="chatdialog">{{ currentDialog }}</div>
16+
<div v-if="showDialog" class="chatdialog-container">
17+
<div class="chatdialog-triangle"></div>
18+
<div class="chatdialog">{{ currentDialog }}</div>
19+
</div>
1720
</transition>
1821
</template>
1922
</template>
2023

2124
<script setup lang="js">
22-
import { onMounted, ref, onUnmounted, watch, computed } from 'vue'
25+
import { onMounted, ref, watch, computed } from 'vue'
2326
2427
import { useStore } from '../../store'
2528
const { state } = useStore()
@@ -132,11 +135,16 @@ const AudioManager = {
132135
context: null,
133136
buffers: new Map(),
134137
currentSource: null,
138+
gainNode: null,
135139
136140
initialize() {
137141
if (!clientReady.value) return
138142
if (!this.context) {
139143
this.context = new (window.AudioContext || window.webkitAudioContext)();
144+
// 创建增益节点,设置音量为50%
145+
this.gainNode = this.context.createGain();
146+
this.gainNode.gain.value = 0.5;
147+
this.gainNode.connect(this.context.destination);
140148
}
141149
},
142150
@@ -167,7 +175,8 @@ const AudioManager = {
167175
return new Promise((resolve) => {
168176
const source = this.context.createBufferSource();
169177
source.buffer = buffer;
170-
source.connect(this.context.destination);
178+
// 连接到增益节点而不是直接连接到目标
179+
source.connect(this.gainNode);
171180
source.onended = () => {
172181
if (this.currentSource === source) {
173182
this.currentSource = null;
@@ -216,7 +225,7 @@ const preloadAudio = async () => {
216225
}
217226
218227
const handleScroll = () => {
219-
if (!clientReady.value) return
228+
if (!clientReady.value || !playerContainer.value) return
220229
const bottomReached = window.innerHeight + window.scrollY + 1 >= document.body.offsetHeight
221230
const chatDialog = document.querySelector('.chatdialog')
222231
@@ -476,12 +485,22 @@ const isDarkMode = computed(() => state.darkMode === 'dark')
476485
const isEnabled = computed(() => state.SpinePlayerEnabled)
477486
const currentAssets = computed(() => spineAssets[currentCharacter.value])
478487
488+
// 事件委托
489+
const handleEvents = (event) => {
490+
if (event.type === 'scroll') {
491+
handleScroll()
492+
} else if (['mousemove', 'touchmove'].includes(event.type)) {
493+
moveBonesHandler?.(event)
494+
}
495+
}
496+
479497
// 统一的清理函数
480498
const cleanup = () => {
481499
if (blinkInterval) clearTimeout(blinkInterval)
482500
if (eyeControlTimer) clearTimeout(eyeControlTimer)
483501
484-
// 清理鼠标移动监听
502+
// 清理监听事件
503+
window.removeEventListener('scroll', handleEvents)
485504
if (moveBonesHandler && !isMobileDevice()) {
486505
window.removeEventListener('mousemove', moveBonesHandler)
487506
moveBonesHandler = null
@@ -525,21 +544,22 @@ const initializeCharacter = async () => {
525544
526545
const debouncedInitialize = debounce(initializeCharacter, 300)
527546
528-
// 监听器
547+
// 监听主题切换和spine开关
529548
watch([isDarkMode, isEnabled], async ([dark, enabled], [prevDark, prevEnabled]) => {
530-
if (enabled !== prevEnabled || (enabled && dark !== prevDark)) {
549+
if (enabled !== prevEnabled) {
550+
if (enabled) {
551+
// 启用时初始化
552+
debouncedInitialize()
553+
} else {
554+
// 禁用时清理资源
555+
cleanup()
556+
}
557+
} else if (enabled && dark !== prevDark) {
558+
// 主题变更且启用状态下重新初始化
531559
debouncedInitialize()
532560
}
533561
}, { immediate: true })
534562
535-
// 事件委托
536-
const handleEvents = (event) => {
537-
if (event.type === 'scroll') {
538-
handleScroll()
539-
} else if (['mousemove', 'touchmove'].includes(event.type)) {
540-
moveBonesHandler?.(event)
541-
}
542-
}
543563
544564
onMounted(() => {
545565
// 设置客户端就绪状态
@@ -556,12 +576,6 @@ onMounted(() => {
556576
debouncedInitialize()
557577
}
558578
})
559-
560-
onUnmounted(() => {
561-
window.removeEventListener('scroll', handleEvents)
562-
window.removeEventListener('mousemove', handleEvents)
563-
cleanup()
564-
})
565579
</script>
566580
567581
<style scoped lang="less">
@@ -576,33 +590,39 @@ onUnmounted(() => {
576590
transition: all 1s;
577591
cursor: pointer;
578592
}
579-
.chatdialog {
593+
.chatdialog-container {
580594
position: fixed;
581595
bottom: 10vw;
582596
left: 2vw;
597+
z-index: 101;
598+
transition: all 1s;
599+
pointer-events: none;
600+
filter: drop-shadow(0 0 3px rgba(36, 36, 36, 0.6));
601+
}
602+
603+
.chatdialog-triangle {
604+
position: absolute;
605+
left: 2vw;
606+
top: -10px;
607+
width: 0;
608+
height: 0;
609+
border-left: 10px solid transparent;
610+
border-right: 10px solid transparent;
611+
border-bottom: 10px solid rgba(255, 255, 255, 0.9);
612+
z-index: 101;
613+
}
614+
615+
.chatdialog {
583616
background-color: rgba(255, 255, 255, 0.9);
584617
border-radius: 25px;
585618
padding: 12px 24px;
586-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
587-
z-index: 101;
588619
word-wrap: break-word;
589620
white-space: pre-wrap;
590621
line-height: 1.4;
591622
color: #000000;
592623
font-size: 0.8vw;
593624
user-select: none;
594-
transition: all 1s;
595-
596-
&:after {
597-
content: '';
598-
position: absolute;
599-
left: 2vw;
600-
top: -8px;
601-
border-left: 10px solid transparent;
602-
border-right: 10px solid transparent;
603-
border-bottom: 10px solid rgba(255, 255, 255, 0.9);
604-
border-top: none;
605-
}
625+
pointer-events: auto;
606626
}
607627
608628
// 添加淡入淡出动画
@@ -617,19 +637,22 @@ onUnmounted(() => {
617637
}
618638
619639
@media (max-width: 768px) {
620-
.chatdialog {
640+
.chatdialog-container {
621641
left: 2vh;
622642
bottom: 10vh;
643+
}
644+
645+
.chatdialog {
623646
min-width: auto;
624647
padding: 12px 20px;
625648
font-size: 1vh;
626649
border-radius: 20px;
650+
}
627651
628-
&:after {
629-
left: 35px;
630-
border-width: 8px;
631-
top: -7px;
632-
}
652+
.chatdialog-triangle {
653+
left: 35px;
654+
border-width: 8px;
655+
top: -8px;
633656
}
634657
635658
.playerContainer {

0 commit comments

Comments
 (0)