feat(christmas.html): 添加背景音乐和不蒜子统计功能

- 格式化HTML代码,提升可读性
- 添加背景音乐播放功能,支持自动播放和用户交互播放
- 集成不蒜子网站统计脚本
- 优化粒子系统和3D渲染效果
- 改进手部识别交互逻辑
- 更新默认图片文字内容
- 添加音频播放错误处理机制
- 优化CSS样式结构和动画效果
This commit is contained in:
hehh
2025-12-12 16:56:38 +08:00
parent b5974a4407
commit cada354dbe

View File

@@ -8,7 +8,8 @@
<!--SEO信息 --> <!--SEO信息 -->
<meta name="description" content="关于Honesty,关于HeHouHui,关于HeHui,关于明厚, About Me Honesty, About Me HeHouHui, About Me HeHui"> <meta name="description"
content="关于Honesty,关于HeHouHui,关于HeHui,关于明厚, About Me Honesty, About Me HeHouHui, About Me HeHui">
<meta name="keywords" content="Honesty,HeHouHui,HeHui,明厚"> <meta name="keywords" content="Honesty,HeHouHui,HeHui,明厚">
<link rel="canonical" href="https://www.hehouhui.cn/about.html"> <link rel="canonical" href="https://www.hehouhui.cn/about.html">
<meta name="author" content="Honesty"> <meta name="author" content="Honesty">
@@ -18,7 +19,8 @@
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:url" content="https://www.hehouhui.cn/christmas.html"> <meta property="og:url" content="https://www.hehouhui.cn/christmas.html">
<meta property="og:title" content="🎄圣诞快乐🎉 - Honesty的个人主页"> <meta property="og:title" content="🎄圣诞快乐🎉 - Honesty的个人主页">
<meta property="og:description" content="我是一名充满热情的Java后端开发工程师专注于AI技术的探索与应用。来自湖南现在上海工作享受在这座充满活力的城市中追求技术梦想。"> <meta property="og:description"
content="我是一名充满热情的Java后端开发工程师专注于AI技术的探索与应用。来自湖南现在上海工作享受在这座充满活力的城市中追求技术梦想。">
<meta property="og:image" content="https://www.hehouhui.cn/images/avatar.jpeg"> <meta property="og:image" content="https://www.hehouhui.cn/images/avatar.jpeg">
<meta property="og:site_name" content="Honesty的个人主页"> <meta property="og:site_name" content="Honesty的个人主页">
<meta property="og:locale" content="zh_CN"> <meta property="og:locale" content="zh_CN">
@@ -27,7 +29,8 @@
<meta property="twitter:card" content="summary_large_image"> <meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="https://www.hehouhui.cn/christmas.html"> <meta property="twitter:url" content="https://www.hehouhui.cn/christmas.html">
<meta property="twitter:title" content="🎄圣诞快乐🎉 - Honesty的个人主页"> <meta property="twitter:title" content="🎄圣诞快乐🎉 - Honesty的个人主页">
<meta property="twitter:description" content="我是一名充满热情的Java后端开发工程师专注于AI技术的探索与应用。来自湖南现在上海工作享受在这座充满活力的城市中追求技术梦想。"> <meta property="twitter:description"
content="我是一名充满热情的Java后端开发工程师专注于AI技术的探索与应用。来自湖南现在上海工作享受在这座充满活力的城市中追求技术梦想。">
<meta property="twitter:image" content="https://www.hehouhui.cn/images/avatar.jpeg"> <meta property="twitter:image" content="https://www.hehouhui.cn/images/avatar.jpeg">
<meta property="twitter:site" content="@Honesty861024"> <meta property="twitter:site" content="@Honesty861024">
<link rel="alternate" hreflang="zh-cn" href="https://www.hehouhui.cn/about.html"> <link rel="alternate" hreflang="zh-cn" href="https://www.hehouhui.cn/about.html">
@@ -40,14 +43,33 @@
<meta property="wechat:description" content="我是一名充满热情的Java后端开发工程师专注于AI技术的探索与应用。"> <meta property="wechat:description" content="我是一名充满热情的Java后端开发工程师专注于AI技术的探索与应用。">
<title>Grand Luxury Tree Final v2</title> <title>Grand Luxury Tree Final v2</title>
<style> <style>
body { margin: 0; overflow: hidden; background-color: #000000; font-family: 'Times New Roman', serif; } body {
#canvas-container { width: 100vw; height: 100vh; position: absolute; top: 0; left: 0; z-index: 1; } margin: 0;
overflow: hidden;
background-color: #000000;
font-family: 'Times New Roman', serif;
}
#canvas-container {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
/* UI Overlay - Minimalist */ /* UI Overlay - Minimalist */
#ui-layer { #ui-layer {
position: absolute; top: 0; left: 0; width: 100%; height: 100%; position: absolute;
z-index: 10; pointer-events: none; top: 0;
display: flex; flex-direction: column; left: 0;
width: 100%;
height: 100%;
z-index: 10;
pointer-events: none;
display: flex;
flex-direction: column;
align-items: center; align-items: center;
padding-top: 40px; padding-top: 40px;
box-sizing: border-box; box-sizing: border-box;
@@ -62,29 +84,58 @@
/* Loading */ /* Loading */
#loader { #loader {
position: absolute; top: 0; left: 0; width: 100%; height: 100%; position: absolute;
background: #000; z-index: 100; top: 0;
display: flex; flex-direction: column; align-items: center; justify-content: center; left: 0;
width: 100%;
height: 100%;
background: #000;
z-index: 100;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transition: opacity 0.8s ease-out; transition: opacity 0.8s ease-out;
} }
.loader-text { .loader-text {
color: #d4af37; font-size: 14px; letter-spacing: 4px; margin-top: 20px; color: #d4af37;
text-transform: uppercase; font-weight: 100; font-size: 14px;
letter-spacing: 4px;
margin-top: 20px;
text-transform: uppercase;
font-weight: 100;
} }
.spinner { .spinner {
width: 40px; height: 40px; border: 1px solid rgba(212, 175, 55, 0.2); width: 40px;
border-top: 1px solid #d4af37; border-radius: 50%; height: 40px;
border: 1px solid rgba(212, 175, 55, 0.2);
border-top: 1px solid #d4af37;
border-radius: 50%;
animation: spin 1s linear infinite; animation: spin 1s linear infinite;
} }
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* Typography - Centerpiece */ /* Typography - Centerpiece */
h1 { h1 {
color: #fceea7; font-size: 56px; margin: 0; font-weight: 400; color: #fceea7;
font-size: 56px;
margin: 0;
font-weight: 400;
letter-spacing: 6px; letter-spacing: 6px;
text-shadow: 0 0 50px rgba(252, 238, 167, 0.6); text-shadow: 0 0 50px rgba(252, 238, 167, 0.6);
background: linear-gradient(to bottom, #fff, #eebb66); background: linear-gradient(to bottom, #fff, #eebb66);
-webkit-background-clip: text; -webkit-text-fill-color: transparent; -webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-family: 'Cinzel', 'Times New Roman', serif; font-family: 'Cinzel', 'Times New Roman', serif;
opacity: 0.9; opacity: 0.9;
transition: opacity 0.5s ease; /* Ensure smooth transitions if needed */ transition: opacity 0.5s ease; /* Ensure smooth transitions if needed */
@@ -97,6 +148,7 @@
text-align: center; text-align: center;
transition: opacity 0.5s ease; /* Add transition for smooth hiding */ transition: opacity 0.5s ease; /* Add transition for smooth hiding */
} }
.upload-btn { .upload-btn {
background: rgba(20, 20, 20, 0.6); background: rgba(20, 20, 20, 0.6);
border: 1px solid rgba(212, 175, 55, 0.4); border: 1px solid rgba(212, 175, 55, 0.4);
@@ -110,11 +162,13 @@
display: inline-block; display: inline-block;
backdrop-filter: blur(5px); backdrop-filter: blur(5px);
} }
.upload-btn:hover { .upload-btn:hover {
background: #d4af37; background: #d4af37;
color: #000; color: #000;
box-shadow: 0 0 20px rgba(212, 175, 55, 0.5); box-shadow: 0 0 20px rgba(212, 175, 55, 0.5);
} }
.hint-text { .hint-text {
color: rgba(212, 175, 55, 0.5); color: rgba(212, 175, 55, 0.5);
font-size: 9px; font-size: 9px;
@@ -123,14 +177,20 @@
text-transform: uppercase; text-transform: uppercase;
} }
#file-input { display: none; } #file-input {
display: none;
}
/* Webcam feedback */ /* Webcam feedback */
#webcam-wrapper { #webcam-wrapper {
position: absolute; bottom: 40px; right: 40px; position: absolute;
width: 120px; height: 90px; bottom: 40px;
border: 1px solid rgba(255,255,255,0.1); right: 40px;
overflow: hidden; opacity: 0; /* Hidden by default but functional */ width: 120px;
height: 90px;
border: 1px solid rgba(255, 255, 255, 0.1);
overflow: hidden;
opacity: 0; /* Hidden by default but functional */
pointer-events: none; pointer-events: none;
} }
</style> </style>
@@ -178,11 +238,11 @@
<script type="module"> <script type="module">
import * as THREE from 'three'; import * as THREE from 'three';
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; import {EffectComposer} from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; import {RenderPass} from 'three/addons/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; import {UnrealBloomPass} from 'three/addons/postprocessing/UnrealBloomPass.js';
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; import {RoomEnvironment} from 'three/addons/environments/RoomEnvironment.js';
import { FilesetResolver, HandLandmarker } from '@mediapipe/tasks-vision'; import {FilesetResolver, HandLandmarker} from '@mediapipe/tasks-vision';
// --- CONFIGURATION --- // --- CONFIGURATION ---
const CONFIG = { const CONFIG = {
@@ -207,8 +267,8 @@
mode: 'SCATTER', mode: 'SCATTER',
focusIndex: -1, focusIndex: -1,
focusTarget: null, focusTarget: null,
hand: { detected: false, x: 0, y: 0 }, hand: {detected: false, x: 0, y: 0},
rotation: { x: 0, y: 0 } rotation: {x: 0, y: 0}
}; };
let scene, camera, renderer, composer; let scene, camera, renderer, composer;
@@ -231,6 +291,22 @@
setupEvents(); setupEvents();
await initMediaPipe(); await initMediaPipe();
// Play background music
const audio = document.getElementById('bg-music');
if (audio) {
// 尝试自动播放音频
try {
const playPromise = audio.play();
if (playPromise !== undefined) {
playPromise.catch(error => {
console.log("Audio autoplay failed:", error);
});
}
} catch (error) {
console.error("Error attempting to play audio:", error);
}
}
const loader = document.getElementById('loader'); const loader = document.getElementById('loader');
loader.style.opacity = 0; loader.style.opacity = 0;
setTimeout(() => loader.remove(), 800); setTimeout(() => loader.remove(), 800);
@@ -247,7 +323,7 @@
camera = new THREE.PerspectiveCamera(42, window.innerWidth / window.innerHeight, 0.1, 1000); camera = new THREE.PerspectiveCamera(42, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 2, CONFIG.camera.z); camera.position.set(0, 2, CONFIG.camera.z);
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false, powerPreference: "high-performance" }); renderer = new THREE.WebGLRenderer({antialias: true, alpha: false, powerPreference: "high-performance"});
renderer.setSize(window.innerWidth, window.innerHeight); renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.toneMapping = THREE.ReinhardToneMapping; renderer.toneMapping = THREE.ReinhardToneMapping;
@@ -300,14 +376,18 @@
function createTextures() { function createTextures() {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
canvas.width = 128; canvas.height = 128; canvas.width = 128;
canvas.height = 128;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.fillStyle = '#ffffff'; ctx.fillStyle = '#ffffff';
ctx.fillRect(0,0,128,128); ctx.fillRect(0, 0, 128, 128);
ctx.fillStyle = '#880000'; ctx.fillStyle = '#880000';
ctx.beginPath(); ctx.beginPath();
for(let i=-128; i<256; i+=32) { for (let i = -128; i < 256; i += 32) {
ctx.moveTo(i, 0); ctx.lineTo(i+32, 128); ctx.lineTo(i+16, 128); ctx.lineTo(i-16, 0); ctx.moveTo(i, 0);
ctx.lineTo(i + 32, 128);
ctx.lineTo(i + 16, 128);
ctx.lineTo(i - 16, 0);
} }
ctx.fill(); ctx.fill();
caneTexture = new THREE.CanvasTexture(canvas); caneTexture = new THREE.CanvasTexture(canvas);
@@ -353,7 +433,7 @@
this.posTree.set(Math.cos(angle) * r, y, Math.sin(angle) * r); this.posTree.set(Math.cos(angle) * r, y, Math.sin(angle) * r);
// SCATTER: 3D Sphere // SCATTER: 3D Sphere
let rScatter = this.isDust ? (12 + Math.random()*20) : (8 + Math.random()*12); let rScatter = this.isDust ? (12 + Math.random() * 20) : (8 + Math.random() * 12);
const theta = Math.random() * Math.PI * 2; const theta = Math.random() * Math.PI * 2;
const phi = Math.acos(2 * Math.random() - 1); const phi = Math.acos(2 * Math.random() - 1);
this.posScatter.set( this.posScatter.set(
@@ -410,7 +490,7 @@
else s = this.baseScale * 0.8; else s = this.baseScale * 0.8;
} }
this.mesh.scale.lerp(new THREE.Vector3(s,s,s), 4*dt); this.mesh.scale.lerp(new THREE.Vector3(s, s, s), 4 * dt);
} }
} }
@@ -445,7 +525,7 @@
emissive: 0x330000 emissive: 0x330000
}); });
const candyMat = new THREE.MeshStandardMaterial({ map: caneTexture, roughness: 0.4 }); const candyMat = new THREE.MeshStandardMaterial({map: caneTexture, roughness: 0.4});
for (let i = 0; i < CONFIG.particles.count; i++) { for (let i = 0; i < CONFIG.particles.count; i++) {
const rand = Math.random(); const rand = Math.random();
@@ -469,8 +549,8 @@
} }
const s = 0.4 + Math.random() * 0.5; const s = 0.4 + Math.random() * 0.5;
mesh.scale.set(s,s,s); mesh.scale.set(s, s, s);
mesh.rotation.set(Math.random()*6, Math.random()*6, Math.random()*6); mesh.rotation.set(Math.random() * 6, Math.random() * 6, Math.random() * 6);
mainGroup.add(mesh); mainGroup.add(mesh);
particleSystem.push(new Particle(mesh, type, false)); particleSystem.push(new Particle(mesh, type, false));
@@ -482,7 +562,7 @@
metalness: 1.0, roughness: 0 metalness: 1.0, roughness: 0
}); });
const star = new THREE.Mesh(starGeo, starMat); const star = new THREE.Mesh(starGeo, starMat);
star.position.set(0, CONFIG.particles.treeHeight/2 + 1.2, 0); star.position.set(0, CONFIG.particles.treeHeight / 2 + 1.2, 0);
mainGroup.add(star); mainGroup.add(star);
mainGroup.add(photoMeshGroup); mainGroup.add(photoMeshGroup);
@@ -490,9 +570,9 @@
function createDust() { function createDust() {
const geo = new THREE.TetrahedronGeometry(0.08, 0); const geo = new THREE.TetrahedronGeometry(0.08, 0);
const mat = new THREE.MeshBasicMaterial({ color: 0xffeebb, transparent: true, opacity: 0.8 }); const mat = new THREE.MeshBasicMaterial({color: 0xffeebb, transparent: true, opacity: 0.8});
for(let i=0; i<CONFIG.particles.dustCount; i++) { for (let i = 0; i < CONFIG.particles.dustCount; i++) {
const mesh = new THREE.Mesh(geo, mat); const mesh = new THREE.Mesh(geo, mat);
mesh.scale.setScalar(0.5 + Math.random()); mesh.scale.setScalar(0.5 + Math.random());
mainGroup.add(mesh); mainGroup.add(mesh);
@@ -502,14 +582,19 @@
function createDefaultPhotos() { function createDefaultPhotos() {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
canvas.width = 512; canvas.height = 512; canvas.width = 512;
canvas.height = 512;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.fillStyle = '#050505'; ctx.fillRect(0,0,512,512); ctx.fillStyle = '#050505';
ctx.strokeStyle = '#eebb66'; ctx.lineWidth = 15; ctx.strokeRect(20,20,472,472); ctx.fillRect(0, 0, 512, 512);
ctx.font = '500 60px Times New Roman'; ctx.fillStyle = '#eebb66'; ctx.strokeStyle = '#eebb66';
ctx.lineWidth = 15;
ctx.strokeRect(20, 20, 472, 472);
ctx.font = '500 60px Times New Roman';
ctx.fillStyle = '#eebb66';
ctx.textAlign = 'center'; ctx.textAlign = 'center';
ctx.fillText("JOYEUX", 256, 230); ctx.fillText("JOYEUX", 256, 230);
ctx.fillText("NOEL", 256, 300); ctx.fillText("W.F", 256, 300);
const tex = new THREE.CanvasTexture(canvas); const tex = new THREE.CanvasTexture(canvas);
tex.colorSpace = THREE.SRGBColorSpace; tex.colorSpace = THREE.SRGBColorSpace;
@@ -518,11 +603,15 @@
function addPhotoToScene(texture) { function addPhotoToScene(texture) {
const frameGeo = new THREE.BoxGeometry(1.4, 1.4, 0.05); const frameGeo = new THREE.BoxGeometry(1.4, 1.4, 0.05);
const frameMat = new THREE.MeshStandardMaterial({ color: CONFIG.colors.champagneGold, metalness: 1.0, roughness: 0.1 }); const frameMat = new THREE.MeshStandardMaterial({
color: CONFIG.colors.champagneGold,
metalness: 1.0,
roughness: 0.1
});
const frame = new THREE.Mesh(frameGeo, frameMat); const frame = new THREE.Mesh(frameGeo, frameMat);
const photoGeo = new THREE.PlaneGeometry(1.2, 1.2); const photoGeo = new THREE.PlaneGeometry(1.2, 1.2);
const photoMat = new THREE.MeshBasicMaterial({ map: texture }); const photoMat = new THREE.MeshBasicMaterial({map: texture});
const photo = new THREE.Mesh(photoGeo, photoMat); const photo = new THREE.Mesh(photoGeo, photoMat);
photo.position.z = 0.04; photo.position.z = 0.04;
@@ -531,7 +620,7 @@
group.add(photo); group.add(photo);
const s = 0.8; const s = 0.8;
group.scale.set(s,s,s); group.scale.set(s, s, s);
photoMeshGroup.add(group); photoMeshGroup.add(group);
particleSystem.push(new Particle(group, 'PHOTO', false)); particleSystem.push(new Particle(group, 'PHOTO', false));
@@ -539,7 +628,7 @@
function handleImageUpload(e) { function handleImageUpload(e) {
const files = e.target.files; const files = e.target.files;
if(!files.length) return; if (!files.length) return;
Array.from(files).forEach(f => { Array.from(files).forEach(f => {
const reader = new FileReader(); const reader = new FileReader();
reader.onload = (ev) => { reader.onload = (ev) => {
@@ -557,7 +646,8 @@
video = document.getElementById('webcam'); video = document.getElementById('webcam');
webcamCanvas = document.getElementById('webcam-preview'); webcamCanvas = document.getElementById('webcam-preview');
webcamCtx = webcamCanvas.getContext('2d'); webcamCtx = webcamCanvas.getContext('2d');
webcamCanvas.width = 160; webcamCanvas.height = 120; webcamCanvas.width = 160;
webcamCanvas.height = 120;
const vision = await FilesetResolver.forVisionTasks( const vision = await FilesetResolver.forVisionTasks(
"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.3/wasm" "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.3/wasm"
@@ -572,13 +662,14 @@
}); });
if (navigator.mediaDevices?.getUserMedia) { if (navigator.mediaDevices?.getUserMedia) {
const stream = await navigator.mediaDevices.getUserMedia({ video: true }); const stream = await navigator.mediaDevices.getUserMedia({video: true});
video.srcObject = stream; video.srcObject = stream;
video.addEventListener("loadeddata", predictWebcam); video.addEventListener("loadeddata", predictWebcam);
} }
} }
let lastVideoTime = -1; let lastVideoTime = -1;
async function predictWebcam() { async function predictWebcam() {
if (video.currentTime !== lastVideoTime) { if (video.currentTime !== lastVideoTime) {
lastVideoTime = video.currentTime; lastVideoTime = video.currentTime;
@@ -597,7 +688,9 @@
STATE.hand.x = (lm[9].x - 0.5) * 2; STATE.hand.x = (lm[9].x - 0.5) * 2;
STATE.hand.y = (lm[9].y - 0.5) * 2; STATE.hand.y = (lm[9].y - 0.5) * 2;
const thumb = lm[4]; const index = lm[8]; const wrist = lm[0]; const thumb = lm[4];
const index = lm[8];
const wrist = lm[0];
const pinchDist = Math.hypot(thumb.x - index.x, thumb.y - index.y); const pinchDist = Math.hypot(thumb.x - index.x, thumb.y - index.y);
const tips = [lm[8], lm[12], lm[16], lm[20]]; const tips = [lm[8], lm[12], lm[16], lm[20]];
let avgDist = 0; let avgDist = 0;
@@ -608,7 +701,7 @@
if (STATE.mode !== 'FOCUS') { if (STATE.mode !== 'FOCUS') {
STATE.mode = 'FOCUS'; STATE.mode = 'FOCUS';
const photos = particleSystem.filter(p => p.type === 'PHOTO'); const photos = particleSystem.filter(p => p.type === 'PHOTO');
if (photos.length) STATE.focusTarget = photos[Math.floor(Math.random()*photos.length)].mesh; if (photos.length) STATE.focusTarget = photos[Math.floor(Math.random() * photos.length)].mesh;
} }
} else if (avgDist < 0.25) { } else if (avgDist < 0.25) {
STATE.mode = 'TREE'; STATE.mode = 'TREE';
@@ -651,7 +744,7 @@
STATE.rotation.y += (targetRotY - STATE.rotation.y) * 3.0 * dt; STATE.rotation.y += (targetRotY - STATE.rotation.y) * 3.0 * dt;
STATE.rotation.x += (targetRotX - STATE.rotation.x) * 3.0 * dt; STATE.rotation.x += (targetRotX - STATE.rotation.x) * 3.0 * dt;
} else { } else {
if(STATE.mode === 'TREE') { if (STATE.mode === 'TREE') {
STATE.rotation.y += 0.3 * dt; STATE.rotation.y += 0.3 * dt;
STATE.rotation.x += (0 - STATE.rotation.x) * 2.0 * dt; STATE.rotation.x += (0 - STATE.rotation.x) * 2.0 * dt;
} else { } else {
@@ -668,5 +761,49 @@
init(); init();
</script> </script>
<!-- Background Music -->
<audio id="bg-music" loop preload="auto">
<source src="data/christmas.mp3" type="audio/mpeg">
</audio>
<script>
// Auto play background music
document.addEventListener('DOMContentLoaded', function () {
const audio = document.getElementById('bg-music');
try {
// 尝试自动播放
const playPromise = audio.play();
if (playPromise !== undefined) {
playPromise.then(_ => {
// 自动播放成功
console.log("Background music is playing");
}).catch(error => {
// 自动播放失败(浏览器限制),需要用户交互
console.log("Auto-play prevented by browser policy:", error);
// 添加用户交互事件来播放音频
document.body.addEventListener('click', function () {
if (audio.paused) {
audio.play();
}
}, {once: true});
});
}
} catch (error) {
console.error("Error attempting to play audio:", error);
}
});
</script>
<!-- 不蒜子统计 -->
<script>
document.addEventListener('DOMContentLoaded', function () {
// 动态加载不蒜子统计脚本
const script = document.createElement('script');
script.src = "//cdn.busuanzi.cc/busuanzi/3.6.9/busuanzi.abbr.min.js";
script.async = true;
document.head.appendChild(script);
});
</script>
</body> </body>
</html> </html>