Compare commits
30 Commits
master
...
577c9d967d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
577c9d967d | ||
| c351c887b9 | |||
|
|
899d0d04fa | ||
|
|
c7cd36ff05 | ||
|
|
3118a84750 | ||
|
|
b334998413 | ||
|
|
1334fa197f | ||
|
|
8d664fcbea | ||
| 7bf9b3af82 | |||
| c7a37c5a42 | |||
| 551b282e41 | |||
| 5293e7e295 | |||
|
|
f692fbcc05 | ||
|
|
c057fb2f1d | ||
|
|
f1aa3a5d4a | ||
|
|
bccccacad8 | ||
|
|
478e1c357c | ||
|
|
84b0725720 | ||
|
|
e378e383f6 | ||
|
|
d61f57ed71 | ||
|
|
a034c3e6cf | ||
|
|
a2ee6e8e1f | ||
|
|
08053e2211 | ||
|
|
c124ea1a29 | ||
|
|
755bd09000 | ||
|
|
6f6d9ee487 | ||
|
|
55cd29620c | ||
|
|
1658c40097 | ||
|
|
523547871e | ||
|
|
c5abafdc86 |
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.mp4
|
||||
*.mp3
|
||||
*.m4a
|
||||
node_modules/
|
||||
dist/
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"liveServer.settings.port": 5501
|
||||
}
|
||||
607
h5/thousands.html
Normal file
607
h5/thousands.html
Normal file
@@ -0,0 +1,607 @@
|
||||
<!DOCTYPE html><html lang="zh-CN"><head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>千军万马保永昌 - 温州抗倭史诗</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;700&family=Noto+Sans+SC:wght@300;400;500&display=swap" rel="stylesheet"/>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Noto Sans SC', sans-serif;
|
||||
background: linear-gradient(135deg, #FFF8DC 0%, #F5F5DC 100%);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.hero-title {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
background: linear-gradient(45deg, #8B4513, #CD7F32);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.lyrics-text {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
color: #8B4513;
|
||||
line-height: 2;
|
||||
}
|
||||
.bg-canvas {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
.content-overlay {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
.nav-item {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.nav-item:hover {
|
||||
transform: translateY(-2px);
|
||||
color: #DC143C;
|
||||
}
|
||||
.card-hover {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.card-hover:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 20px 40px rgba(139, 69, 19, 0.2);
|
||||
}
|
||||
.pulse-animation {
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.7; }
|
||||
}
|
||||
.fade-in {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
.hero-image {
|
||||
background-image: url('https://pjoss.x-php.com/20251210/f551cd20d2f0c2036c42d22b00711b05.png');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 背景动画画布 -->
|
||||
<div id="bg-canvas" class="bg-canvas"></div>
|
||||
|
||||
<!-- 导航栏 -->
|
||||
<nav class="fixed top-0 w-full bg-white/90 backdrop-blur-sm z-50 shadow-sm">
|
||||
<div class="max-w-7xl mx-auto px-6 py-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="hero-title text-2xl font-bold">千军万马保永昌</div>
|
||||
<div class="flex space-x-8">
|
||||
<a href="#home" class="nav-item cursor-pointer">首页</a>
|
||||
<a href="#lyrics" class="nav-item cursor-pointer">歌词</a>
|
||||
<a href="#history" class="nav-item cursor-pointer">历史</a>
|
||||
<a href="#music" class="nav-item cursor-pointer">音乐</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 主要内容 -->
|
||||
<div class="content-overlay">
|
||||
<!-- 英雄区域 -->
|
||||
<section id="home" class="hero-image min-h-screen flex items-center justify-center relative">
|
||||
<div class="absolute inset-0 bg-black/30"></div>
|
||||
<div class="relative z-10 text-center text-white px-6">
|
||||
<h1 class="text-6xl md:text-8xl font-bold mb-6 fade-in" style="font-family: 'Noto Serif SC', serif;">千军万马保永昌</h1>
|
||||
<p class="text-xl md:text-2xl mb-8 fade-in">温州抗倭史诗 · 非遗鼓词传承</p>
|
||||
<div class="flex flex-col md:flex-row gap-4 justify-center fade-in">
|
||||
<button onclick="playMusic()" class="bg-red-600 hover:bg-red-700 text-white px-8 py-3 rounded-full text-lg font-medium transition-all duration-300 transform hover:scale-105">
|
||||
播放音乐
|
||||
</button>
|
||||
<button onclick="scrollToSection('lyrics')" class="bg-transparent border-2 border-white text-white hover:bg-white hover:text-gray-800 px-8 py-3 rounded-full text-lg font-medium transition-all duration-300">
|
||||
查看古词
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 歌词展示区域 -->
|
||||
<section id="lyrics" class="py-20 px-6">
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<h2 class="text-4xl font-bold text-center mb-16 hero-title fade-in">古词欣赏</h2>
|
||||
|
||||
<!-- 歌词卡片 -->
|
||||
<div class="bg-white/80 backdrop-blur-sm rounded-2xl p-8 shadow-lg card-hover fade-in mb-8">
|
||||
<div class="text-center mb-8">
|
||||
<h3 class="text-2xl font-bold lyrics-text mb-4">【开篇】</h3>
|
||||
<p class="lyrics-text text-lg">公元一五五八年,倭寇越来越嚣张。</p>
|
||||
<p class="lyrics-text text-lg">烧杀抢掠恶做尽,沿海百姓遭祸殃。</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-8">
|
||||
<h3 class="text-2xl font-bold lyrics-text mb-4">【第一幕】</h3>
|
||||
<p class="lyrics-text text-lg">王沛王德俩叔侄,满腔热血保家乡。</p>
|
||||
<p class="lyrics-text text-lg">身中数矛热血涌,赤胆忠魂震东洋。</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-8">
|
||||
<h3 class="text-2xl font-bold lyrics-text mb-4">【第二幕】</h3>
|
||||
<p class="lyrics-text text-lg">叔果叔杲意志强,筹款要建护城墙。</p>
|
||||
<p class="lyrics-text text-lg">王氏遗孀倾囊助,为保家园添力量。</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-8">
|
||||
<h3 class="text-2xl font-bold lyrics-text mb-4">【第三幕】</h3>
|
||||
<p class="lyrics-text text-lg">城堡坚固厚城墙,倭寇围困日久长。</p>
|
||||
<p class="lyrics-text text-lg">砻糠替谷河面运,砻糠之计退敌强。</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-8">
|
||||
<h3 class="text-2xl font-bold lyrics-text mb-4">【第四幕】</h3>
|
||||
<p class="lyrics-text text-lg">遗孀乘机率众出,突袭敌营上战场。</p>
|
||||
<p class="lyrics-text text-lg">战鼓声声号角响,杀的倭寇魂魄消。</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-8">
|
||||
<h3 class="text-2xl font-bold lyrics-text mb-4">【结尾】</h3>
|
||||
<p class="lyrics-text text-lg">一段鼓词情难尽,古人壮举永传扬。</p>
|
||||
<p class="lyrics-text text-lg">家国安宁民康泰,温州处处保永昌。</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<p class="lyrics-text text-sm">作者:陈继宁(温州市鼓词研究会会长)</p>
|
||||
<p class="lyrics-text text-sm">2025-12-01</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 音乐控制 -->
|
||||
<div class="text-center">
|
||||
<div class="bg-white/60 backdrop-blur-sm rounded-full px-8 py-4 inline-flex items-center space-x-6 shadow-lg">
|
||||
<button id="playBtn" onclick="togglePlay()" class="w-12 h-12 bg-red-600 hover:bg-red-700 text-white rounded-full flex items-center justify-center transition-all duration-300">
|
||||
▶
|
||||
</button>
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-sm text-gray-600">00:00</span>
|
||||
<div class="w-64 h-2 bg-gray-300 rounded-full">
|
||||
<div id="progressBar" class="h-full bg-red-600 rounded-full" style="width: 0%"></div>
|
||||
</div>
|
||||
<span class="text-sm text-gray-600">04:32</span>
|
||||
</div>
|
||||
<button onclick="toggleMute()" class="w-10 h-10 bg-gray-200 hover:bg-gray-300 rounded-full flex items-center justify-center transition-all duration-300">
|
||||
🔊
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 历史背景区域 -->
|
||||
<section id="history" class="py-20 px-6 bg-gradient-to-b from-transparent to-white/50">
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<h2 class="text-4xl font-bold text-center mb-16 hero-title fade-in">历史背景</h2>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-12 items-center mb-16">
|
||||
<div class="fade-in">
|
||||
<img src="https://pjoss.x-php.com/20251210/de589ced94b90b32165b55673479aa52.png" alt="温州古城" class="w-full rounded-2xl shadow-lg"/>
|
||||
</div>
|
||||
<div class="fade-in">
|
||||
<h3 class="text-2xl font-bold lyrics-text mb-6">温州抗倭历史</h3>
|
||||
<p class="text-gray-700 leading-relaxed mb-4">
|
||||
明朝洪武二年(1369年),倭寇首次进犯温州地区,从此开启了温州人民长达数百年的抗倭斗争。
|
||||
温州地处浙南沿海,拥有众多岛屿,成为倭寇侵扰的重灾区。
|
||||
</p>
|
||||
<p class="text-gray-700 leading-relaxed mb-4">
|
||||
在这场艰苦卓绝的斗争中,涌现出无数英雄人物。王沛、王德叔侄率领乡勇抗倭,
|
||||
最终壮烈牺牲;戚继光将军更是在温州地区屡败倭寇,创造了鸳鸯阵法,
|
||||
为抗倭战争作出了巨大贡献。
|
||||
</p>
|
||||
<p class="text-gray-700 leading-relaxed">
|
||||
温州人民用血肉之躯筑起了一道保卫家园的钢铁长城,
|
||||
体现了中华民族团结抗倭的爱国主义精神和不怕牺牲的高尚品格。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 历史时间轴 -->
|
||||
<div class="fade-in">
|
||||
<h3 class="text-2xl font-bold text-center lyrics-text mb-12">重要历史节点</h3>
|
||||
<div class="relative">
|
||||
<div class="absolute left-1/2 transform -translate-x-1/2 h-full w-1 bg-gradient-to-b from-red-600 to-yellow-600"></div>
|
||||
|
||||
<div class="space-y-12">
|
||||
<div class="flex items-center">
|
||||
<div class="w-1/2 pr-8 text-right">
|
||||
<div class="bg-white/80 backdrop-blur-sm rounded-lg p-6 shadow-lg card-hover">
|
||||
<h4 class="text-xl font-bold text-red-600 mb-2">1369年</h4>
|
||||
<p class="text-gray-700">倭寇首次进犯温州,攻击永嘉、乐清等地</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-4 h-4 bg-red-600 rounded-full border-4 border-white shadow-lg"></div>
|
||||
<div class="w-1/2 pl-8"></div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center">
|
||||
<div class="w-1/2 pr-8"></div>
|
||||
<div class="w-4 h-4 bg-yellow-600 rounded-full border-4 border-white shadow-lg"></div>
|
||||
<div class="w-1/2 pl-8">
|
||||
<div class="bg-white/80 backdrop-blur-sm rounded-lg p-6 shadow-lg card-hover">
|
||||
<h4 class="text-xl font-bold text-yellow-600 mb-2">1558年</h4>
|
||||
<p class="text-gray-700">王沛、王德叔侄壮烈牺牲,英桥王氏建造永昌堡</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center">
|
||||
<div class="w-1/2 pr-8 text-right">
|
||||
<div class="bg-white/80 backdrop-blur-sm rounded-lg p-6 shadow-lg card-hover">
|
||||
<h4 class="text-xl font-bold text-red-600 mb-2">1560年代</h4>
|
||||
<p class="text-gray-700">戚继光率戚家军在温州地区屡败倭寇</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-4 h-4 bg-red-600 rounded-full border-4 border-white shadow-lg"></div>
|
||||
<div class="w-1/2 pl-8"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 音乐文化区域 -->
|
||||
<section id="music" class="py-20 px-6">
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<h2 class="text-4xl font-bold text-center mb-16 hero-title fade-in">音乐文化</h2>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-12 items-center mb-16">
|
||||
<div class="fade-in">
|
||||
<h3 class="text-2xl font-bold lyrics-text mb-6">陈继宁</h3>
|
||||
<p class="text-gray-700 leading-relaxed mb-4">
|
||||
温州学传播大使,温州市社科联理事,温州市鼓词研究会会长,国家级非遗温州鼓词陈派传人
|
||||
</p>
|
||||
|
||||
<h3 class="text-2xl font-bold lyrics-text mb-6">温州鼓词</h3>
|
||||
<p class="text-gray-700 leading-relaxed mb-4">
|
||||
温州鼓词是国家级非物质文化遗产,流行于浙江温州及其毗邻地区,
|
||||
用温州方言表演,具有浓厚的地方色彩和独特的艺术风格。
|
||||
</p>
|
||||
<p class="text-gray-700 leading-relaxed mb-4">
|
||||
表演形式以一人"单档"为主,艺人自弹牛筋琴伴奏说唱。
|
||||
牛筋琴是温州独有的乐器,音色浑厚柔美,为鼓词赋予了无可替代的声韵特质。
|
||||
</p>
|
||||
<p class="text-gray-700 leading-relaxed">
|
||||
《千军万马保永昌》这首歌融合了温州鼓词的元素,
|
||||
通过现代音乐手法重新演绎传统文化,
|
||||
让年轻一代能够更好地理解和传承这一宝贵的文化遗产。
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class="fade-in">
|
||||
<img src="https://pjoss.x-php.com/20251210/1bfead1f41b7e0b4a291ab2da46400f7.jpg" alt="传统乐器" class="w-full rounded-2xl shadow-lg"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 音乐特色 -->
|
||||
<div class="grid md:grid-cols-3 gap-8 fade-in">
|
||||
<div class="bg-white/80 backdrop-blur-sm rounded-2xl p-6 text-center shadow-lg card-hover">
|
||||
<div class="w-16 h-16 bg-red-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<span class="text-2xl">🎵</span>
|
||||
</div>
|
||||
<h4 class="text-xl font-bold lyrics-text mb-3">民歌长调</h4>
|
||||
<p class="text-gray-700 text-sm">悠扬婉转的旋律,体现温州山水的灵秀之气</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white/80 backdrop-blur-sm rounded-2xl p-6 text-center shadow-lg card-hover">
|
||||
<div class="w-16 h-16 bg-yellow-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<span class="text-2xl">🎸</span>
|
||||
</div>
|
||||
<h4 class="text-xl font-bold lyrics-text mb-3">摇滚力量</h4>
|
||||
<p class="text-gray-700 text-sm">现代摇滚的节奏感,展现抗倭斗争的激昂斗志</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white/80 backdrop-blur-sm rounded-2xl p-6 text-center shadow-lg card-hover">
|
||||
<div class="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<span class="text-2xl">🥁</span>
|
||||
</div>
|
||||
<h4 class="text-xl font-bold lyrics-text mb-3">鼓词韵律</h4>
|
||||
<p class="text-gray-700 text-sm">传统鼓词的独特韵味,传承非遗文化精髓</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<footer class="bg-gray-800 text-white py-12">
|
||||
<div class="max-w-6xl mx-auto px-6 text-center">
|
||||
<div class="hero-title text-2xl font-bold mb-4">千军万马保永昌</div>
|
||||
<p class="text-gray-400 mb-6">传承温州抗倭精神,弘扬非遗鼓词文化</p>
|
||||
<div class="text-sm text-gray-500">
|
||||
© 2025龙湾之光AI数字偶像大赛项目. 致敬历史,传承文化,创新发展.
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 背景动画
|
||||
let bgSketch = function(p) {
|
||||
let particles = [];
|
||||
let numParticles = 50;
|
||||
|
||||
p.setup = function() {
|
||||
let canvas = p.createCanvas(p.windowWidth, p.windowHeight);
|
||||
canvas.parent('bg-canvas');
|
||||
|
||||
// 初始化粒子
|
||||
for (let i = 0; i < numParticles; i++) {
|
||||
particles.push({
|
||||
x: p.random(p.width),
|
||||
y: p.random(p.height),
|
||||
vx: p.random(-0.5, 0.5),
|
||||
vy: p.random(-0.5, 0.5),
|
||||
size: p.random(2, 6),
|
||||
alpha: p.random(50, 150)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
p.draw = function() {
|
||||
p.clear();
|
||||
|
||||
// 绘制流动粒子
|
||||
for (let particle of particles) {
|
||||
p.fill(139, 69, 19, particle.alpha);
|
||||
p.noStroke();
|
||||
p.ellipse(particle.x, particle.y, particle.size);
|
||||
|
||||
// 更新位置
|
||||
particle.x += particle.vx;
|
||||
particle.y += particle.vy;
|
||||
|
||||
// 边界检测
|
||||
if (particle.x < 0 || particle.x > p.width) particle.vx *= -1;
|
||||
if (particle.y < 0 || particle.y > p.height) particle.vy *= -1;
|
||||
}
|
||||
|
||||
// 绘制连接线
|
||||
for (let i = 0; i < particles.length; i++) {
|
||||
for (let j = i + 1; j < particles.length; j++) {
|
||||
let dist = p.dist(particles[i].x, particles[i].y, particles[j].x, particles[j].y);
|
||||
if (dist < 100) {
|
||||
p.stroke(139, 69, 19, 50 * (1 - dist / 100));
|
||||
p.strokeWeight(1);
|
||||
p.line(particles[i].x, particles[i].y, particles[j].x, particles[j].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
p.windowResized = function() {
|
||||
p.resizeCanvas(p.windowWidth, p.windowHeight);
|
||||
};
|
||||
};
|
||||
|
||||
// 初始化背景动画
|
||||
new p5(bgSketch);
|
||||
|
||||
// 页面加载完成后的动画
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// 淡入动画
|
||||
const fadeElements = document.querySelectorAll('.fade-in');
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
anime({
|
||||
targets: entry.target,
|
||||
opacity: [0, 1],
|
||||
translateY: [30, 0],
|
||||
duration: 800,
|
||||
easing: 'easeOutQuart',
|
||||
delay: anime.stagger(200)
|
||||
});
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
fadeElements.forEach(el => {
|
||||
observer.observe(el);
|
||||
});
|
||||
|
||||
// 平滑滚动
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(this.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 音乐播放控制
|
||||
const AUDIO_URL = 'https://pjoss.x-php.com/20251210/1f5b3890c2c336bec63f9af90fe40ae2.mp3';
|
||||
let isPlaying = false;
|
||||
let isMuted = false;
|
||||
let duration = 0;
|
||||
const audio = new Audio(AUDIO_URL);
|
||||
audio.preload = 'metadata';
|
||||
|
||||
audio.addEventListener('loadedmetadata', () => {
|
||||
duration = isFinite(audio.duration) ? Math.floor(audio.duration) : 0;
|
||||
const timeEls = document.querySelectorAll('.text-sm.text-gray-600');
|
||||
if (timeEls[1]) {
|
||||
timeEls[1].textContent = formatTime(duration);
|
||||
}
|
||||
});
|
||||
|
||||
audio.addEventListener('timeupdate', () => {
|
||||
updateProgress();
|
||||
});
|
||||
|
||||
audio.addEventListener('ended', () => {
|
||||
isPlaying = false;
|
||||
updatePlayButton();
|
||||
updateProgress();
|
||||
});
|
||||
|
||||
audio.addEventListener('error', () => {
|
||||
showNotification('音频加载或播放失败');
|
||||
});
|
||||
|
||||
function playMusic() {
|
||||
audio.play().then(() => {
|
||||
isPlaying = true;
|
||||
updatePlayButton();
|
||||
showNotification('音乐播放中...');
|
||||
}).catch(() => {
|
||||
showNotification('无法自动播放,请手动点击播放');
|
||||
});
|
||||
}
|
||||
|
||||
function togglePlay() {
|
||||
if (isPlaying) {
|
||||
pauseMusic();
|
||||
} else {
|
||||
playMusic();
|
||||
}
|
||||
}
|
||||
|
||||
function pauseMusic() {
|
||||
audio.pause();
|
||||
isPlaying = false;
|
||||
updatePlayButton();
|
||||
}
|
||||
|
||||
function toggleMute() {
|
||||
isMuted = !isMuted;
|
||||
audio.muted = isMuted;
|
||||
const muteBtn = document.querySelector('button[onclick="toggleMute()"]');
|
||||
muteBtn.textContent = isMuted ? '🔇' : '🔊';
|
||||
}
|
||||
|
||||
function updatePlayButton() {
|
||||
const playBtn = document.getElementById('playBtn');
|
||||
playBtn.textContent = isPlaying ? '⏸' : '▶';
|
||||
}
|
||||
|
||||
function updateProgress() {
|
||||
const progressBar = document.getElementById('progressBar');
|
||||
const d = duration || (isFinite(audio.duration) ? Math.floor(audio.duration) : 0);
|
||||
const ct = Math.floor(audio.currentTime || 0);
|
||||
const progress = d ? (ct / d) * 100 : 0;
|
||||
progressBar.style.width = progress + '%';
|
||||
|
||||
const timeEls = document.querySelectorAll('.text-sm.text-gray-600');
|
||||
if (timeEls[0]) {
|
||||
timeEls[0].textContent = formatTime(ct);
|
||||
}
|
||||
if (timeEls[1] && d) {
|
||||
timeEls[1].textContent = formatTime(d);
|
||||
}
|
||||
}
|
||||
|
||||
function formatTime(seconds) {
|
||||
const mins = Math.floor(seconds / 60);
|
||||
const secs = seconds % 60;
|
||||
return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
function scrollToSection(sectionId) {
|
||||
const section = document.getElementById(sectionId);
|
||||
if (section) {
|
||||
section.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function showNotification(message) {
|
||||
// 创建通知元素
|
||||
const notification = document.createElement('div');
|
||||
notification.className = 'fixed top-24 right-6 bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg z-50 transform translate-x-full transition-transform duration-300';
|
||||
notification.textContent = message;
|
||||
|
||||
document.body.appendChild(notification);
|
||||
|
||||
// 显示动画
|
||||
setTimeout(() => {
|
||||
notification.classList.remove('translate-x-full');
|
||||
}, 100);
|
||||
|
||||
// 隐藏动画
|
||||
setTimeout(() => {
|
||||
notification.classList.add('translate-x-full');
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(notification);
|
||||
}, 300);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// 滚动时的视差效果
|
||||
window.addEventListener('scroll', function() {
|
||||
const scrolled = window.pageYOffset;
|
||||
const parallax = document.querySelector('.hero-image');
|
||||
if (parallax) {
|
||||
const speed = scrolled * 0.5;
|
||||
parallax.style.transform = `translateY(${speed}px)`;
|
||||
}
|
||||
});
|
||||
|
||||
// 导航栏滚动效果
|
||||
let lastScrollTop = 0;
|
||||
window.addEventListener('scroll', function() {
|
||||
const nav = document.querySelector('nav');
|
||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||
|
||||
if (scrollTop > lastScrollTop && scrollTop > 100) {
|
||||
// 向下滚动,隐藏导航栏
|
||||
nav.style.transform = 'translateY(-100%)';
|
||||
} else {
|
||||
// 向上滚动,显示导航栏
|
||||
nav.style.transform = 'translateY(0)';
|
||||
}
|
||||
|
||||
lastScrollTop = scrollTop;
|
||||
});
|
||||
|
||||
// 键盘快捷键
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.code === 'Space') {
|
||||
e.preventDefault();
|
||||
togglePlay();
|
||||
} else if (e.code === 'KeyM') {
|
||||
e.preventDefault();
|
||||
toggleMute();
|
||||
}
|
||||
});
|
||||
|
||||
// 页面可见性变化处理
|
||||
document.addEventListener('visibilitychange', function() {
|
||||
if (document.hidden && isPlaying) {
|
||||
// 页面隐藏时暂停音乐
|
||||
pauseMusic();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 页面加载时预加载资源
|
||||
window.addEventListener('load', function() {
|
||||
// preloadImages();
|
||||
|
||||
// 添加加载完成动画
|
||||
anime({
|
||||
targets: 'body',
|
||||
opacity: [0, 1],
|
||||
duration: 1000,
|
||||
easing: 'easeOutQuart'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</body></html>
|
||||
46
index.html
46
index.html
@@ -1,14 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- 基本元数据 -->
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>朴见潮音官网</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="format-detection" content="telephone=no,email=no,address=no" />
|
||||
<meta name="renderer" content="webkit" />
|
||||
<meta name="force-rendering" content="webkit" />
|
||||
<meta name="theme-color" content="#1e135e" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
|
||||
<!-- 网站标题和描述 -->
|
||||
<title>朴见潮音官网 - AI音乐创作先锋品牌</title>
|
||||
<meta name="description" content="朴见潮音是国内领先的AI音乐创作品牌,致力于通过人工智能技术推动音乐创作的创新与发展。" />
|
||||
<meta name="keywords" content="朴见潮音,AI音乐,人工智能音乐,音乐创作,AI作曲" />
|
||||
<meta name="author" content="朴见潮音" />
|
||||
|
||||
<!-- 社交媒体元数据 -->
|
||||
<meta property="og:title" content="朴见潮音官网 - AI音乐创作先锋品牌" />
|
||||
<meta property="og:description" content="朴见潮音是国内领先的AI音乐创作品牌,致力于通过人工智能技术推动音乐创作的创新与发展。" />
|
||||
<meta property="og:image" content="./static/img/logo.png" />
|
||||
<meta property="og:url" content="https://www.pujian.com" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:site_name" content="朴见潮音" />
|
||||
|
||||
<!-- 网站图标 -->
|
||||
<link rel="shortcut icon" href="./static/img/favicon.ico" type="image/x-icon" />
|
||||
<link rel="apple-touch-icon" href="./static/img/logo.png" />
|
||||
<link rel="icon" href="./static/img/favicon.ico" type="image/x-icon" />
|
||||
|
||||
<script src="./static/js/vue.global.js"></script>
|
||||
<script src="./static/js/artplayer.js"></script>
|
||||
<script src="./static/js/axios.min.js"></script>
|
||||
<link rel="stylesheet" href="./static/css/index.css" />
|
||||
<link rel="icon" href="./static/img/favicon.ico" type="image/x-icon" />
|
||||
<style>
|
||||
[v-cloak] {
|
||||
display: none;
|
||||
@@ -127,7 +153,7 @@
|
||||
<div class="operate flexcenter">
|
||||
<img class="speed left" src="./static/img/speed-left.png" @click="fastForward('slow')" />
|
||||
<img v-if="item.state" class="play" @click="closeAll()" src="./static/img/pause-black-icon.svg" />
|
||||
<img v-else class="play" @click="manageAudio(item.playurl, 'works')" src="./static/img/play-black-icon.svg" />
|
||||
<img v-else class="play" @click="judgmentPlayUrl(item.playurl, 'works', index)" src="./static/img/play-black-icon.svg" />
|
||||
<img class="speed right" src="./static/img/speed-right.png" @click="fastForward('fast')" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -140,7 +166,7 @@
|
||||
<div class="custom" ref="customRef">
|
||||
<div class="custom-box mar1200 flexflex">
|
||||
<img class="title" src="./static/img/custom-title.png" />
|
||||
<div class="subtitle">往事可成追忆,把你的故事谱成歌</div>
|
||||
<div class="subtitle">释放音乐本能,用词曲表达人生</div>
|
||||
<div class="list flexflex mar1200">
|
||||
<div class="item flexacenter" v-for="(item, index) in customList" :key="index">
|
||||
<div class="info flexflex">
|
||||
@@ -153,7 +179,7 @@
|
||||
<div class="operate flexcenter">
|
||||
<img class="speed left" @click="fastForward('slow')" src="./static/img/speed-left.png" />
|
||||
<img v-if="item.state" class="play" @click="closeAll()" src="./static/img/pause-black-icon.svg" />
|
||||
<img v-else class="play" @click="item.playurl ? manageAudio(item.playurl, 'custom') : getPlayUrl(index, 'custom')" src="./static/img/play-black-icon.svg" />
|
||||
<img v-else class="play" @click="judgmentPlayUrl(item.playurl, 'custom', index)" src="./static/img/play-black-icon.svg" />
|
||||
<img class="speed right" @click="fastForward('fast')" src="./static/img/speed-right.png" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -190,7 +216,7 @@
|
||||
<img class="cut left" src="./static/img/cut-left.svg" @click="cutSong('up', zeroOrderStudents.order)" />
|
||||
<img class="speed left" src="./static/img/speed-white-left.png" @click="fastForward('slow')" />
|
||||
<img v-if="zeroOrderStudents.state" class="play" @click="closeAll()" src="./static/img/pause-white-icon.svg" />
|
||||
<img v-else class="play" @click="zeroOrderStudents.playurl ? manageAudio(zeroOrderStudents.playurl, 'student') : getPlayUrl(index, 'student')" src="./static/img/play-white-icon.svg" />
|
||||
<img v-else class="play" @click="judgmentPlayUrl(zeroOrderStudents.playurl, 'student', index)" src="./static/img/play-white-icon.svg" />
|
||||
<img class="speed right" src="./static/img/speed-white-right.png" @click="fastForward('fast')" />
|
||||
<img class="cut right" src="./static/img/cut-right.svg" @click="cutSong('down', zeroOrderStudents.order)" />
|
||||
</div>
|
||||
@@ -207,7 +233,7 @@
|
||||
|
||||
<div class="footer flexcenter">
|
||||
<img class="logo" src="./static/img/ai-title.png" />
|
||||
<div class="text">广州九微科技有限公司 | Copyright 2001-2025 GTER All Rights Reserved | 粤ICP备14050432号</div>
|
||||
<div class="text">广州朴见潮音工作室 | Copyright 2025 PUJIANCHAOYIN All Rights Reserved</div>
|
||||
</div>
|
||||
|
||||
<div v-if="previewState" class="preview flexcenter" @click="closePreview()">
|
||||
@@ -224,8 +250,8 @@
|
||||
<div class="bottom-middle flexcenter">
|
||||
<div class="flexacenter" style="margin-bottom: 10px">
|
||||
<div class="time-display">{{ currentTimeFormatted }}</div>
|
||||
<div class="progress-bar flexacenter" @click="handleBarDragBottomClick">
|
||||
<div class="bar white" :style="{ width: progress + '%' }" @mousedown="startBarDragBottom"></div>
|
||||
<div class="progress-bar flexacenter" @mousedown="startBarDragBottom">
|
||||
<div class="bar white" :style="{ width: progress + '%' }"></div>
|
||||
<div class="bar black flex1"></div>
|
||||
</div>
|
||||
<div class="time-display">{{ durationFormatted }}</div>
|
||||
|
||||
2448
player.html
Normal file
2448
player.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -47,7 +47,9 @@
|
||||
<div class="fill-item" v-for="(item, index) in tagsFill" :key="index" :class="[`item${ item.type }`]"></div>
|
||||
</div>
|
||||
<div class="list" id="bubbleContainer" ref="container">
|
||||
<div class="tag-item" v-for="(item, index) in tags" :key="index" :class="[`item${ item.type }`, {'red': item.isred}]" @click="clickSongs(item.songs)" @mouseleave="handleMouseleave" @mouseenter="handleMouseenter">{{ item.tag }}</div>
|
||||
<div class="tag-item" v-for="(item, index) in tags" :key="index" :class="[`item${ item.type }`, {'red': item.isred},{'show': playData?.tag == item.tag}]" @click="clickSongs(item.tag, item.songs)" @mouseleave="handleMouseleave" @mouseenter="handleMouseenter">
|
||||
<div class="tag-text">{{ item.tag }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
}
|
||||
:root {
|
||||
--base-height: 500px;
|
||||
@@ -39,7 +40,7 @@
|
||||
}
|
||||
.container .container-box {
|
||||
padding-top: 24px;
|
||||
height: 100vh;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -53,13 +54,14 @@
|
||||
position: relative;
|
||||
width: 1200px;
|
||||
height: 280px;
|
||||
min-height: 280px;
|
||||
border-radius: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.container .container-box .header::after {
|
||||
content: "";
|
||||
width: 1200px;
|
||||
height: 280px;
|
||||
height: 100%;
|
||||
background: linear-gradient(180deg, #7d4bf8 0%, #5241b0 100%);
|
||||
border-radius: 20px;
|
||||
position: absolute;
|
||||
@@ -218,7 +220,6 @@
|
||||
left: 997px;
|
||||
}
|
||||
.container .container-box .details {
|
||||
max-height: 500px;
|
||||
margin-bottom: 40px;
|
||||
width: 1200px;
|
||||
border-radius: 20px;
|
||||
@@ -228,6 +229,7 @@
|
||||
padding: 3px;
|
||||
overflow: hidden;
|
||||
height: var(--base-height);
|
||||
min-height: var(--base-height);
|
||||
}
|
||||
.container .container-box .details::after {
|
||||
content: "";
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
}
|
||||
|
||||
:root {
|
||||
@@ -48,7 +49,7 @@
|
||||
|
||||
.container-box {
|
||||
padding-top: 24px;
|
||||
height: 100vh;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -63,6 +64,7 @@
|
||||
position: relative;
|
||||
width: 1200px;
|
||||
height: 280px;
|
||||
min-height: 280px;
|
||||
// background: linear-gradient(180deg, #7d4bf8 0%, #5241b0 100%);
|
||||
border-radius: 20px;
|
||||
margin-bottom: 20px;
|
||||
@@ -70,7 +72,7 @@
|
||||
&::after {
|
||||
content: "";
|
||||
width: 1200px;
|
||||
height: 280px;
|
||||
height: 100%;
|
||||
background: linear-gradient(180deg, rgba(125, 75, 248, 1) 0%, rgba(82, 65, 176, 1) 100%);
|
||||
border-radius: 20px;
|
||||
position: absolute;
|
||||
@@ -251,7 +253,7 @@
|
||||
.details {
|
||||
// height: 500px;
|
||||
// flex: 1;
|
||||
max-height: 500px;
|
||||
// max-height: 500px;
|
||||
margin-bottom: 40px;
|
||||
width: 1200px;
|
||||
border-radius: 20px;
|
||||
@@ -261,6 +263,7 @@
|
||||
padding: 3px;
|
||||
overflow: hidden;
|
||||
height: var(--base-height);
|
||||
min-height: var(--base-height);
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
}
|
||||
.content .flexflex {
|
||||
display: flex;
|
||||
@@ -80,6 +81,7 @@
|
||||
.content .introduce .box .info .award {
|
||||
flex-direction: column;
|
||||
margin-bottom: 177px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.content .introduce .box .info .award .title {
|
||||
width: 101px;
|
||||
@@ -87,8 +89,11 @@
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.content .introduce .box .info .award .name {
|
||||
height: 65px;
|
||||
max-height: 65px;
|
||||
max-width: 340px;
|
||||
margin-bottom: 30px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.content .introduce .box .info .award .explain {
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
@@ -137,6 +142,9 @@
|
||||
border-radius: 15px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.content .introduce .box .album .album-box .item:hover .img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
.content .introduce .box .album .album-box .item .bj.bj3 {
|
||||
width: 101%;
|
||||
height: 101%;
|
||||
@@ -158,6 +166,7 @@
|
||||
.content .introduce .box .album .album-box .item .img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.content .introduce .box .album .album-box .item .play {
|
||||
width: 26px;
|
||||
@@ -274,6 +283,9 @@
|
||||
width: 402px;
|
||||
height: 64px;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.content .works .name-box .bj {
|
||||
position: absolute;
|
||||
@@ -283,11 +295,6 @@
|
||||
z-index: -1;
|
||||
}
|
||||
.content .works .name-box .title {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 208px;
|
||||
height: 49px;
|
||||
}
|
||||
.content .works .name-box .line {
|
||||
@@ -352,7 +359,7 @@
|
||||
}
|
||||
.content .works .mv-box .item .serial {
|
||||
height: 44px;
|
||||
font-family: "AlibabaPuHuiTiB", "Alibaba PuHuiTi Bold", "Alibaba PuHuiTi Heavy", "Alibaba PuHuiTi", sans-serif;
|
||||
font-family: "AlibabaPuHuiTiB", "Alibaba PuHuiTi Bold", "Alibaba PuHuiTi Heavy", "Alibaba PuHuiTi", "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
color: #000000;
|
||||
@@ -446,7 +453,7 @@
|
||||
}
|
||||
.content .works .audio-box .item .serial {
|
||||
height: 44px;
|
||||
font-family: "AlibabaPuHuiTiB", "Alibaba PuHuiTi Bold", "Alibaba PuHuiTi Heavy", "Alibaba PuHuiTi", sans-serif;
|
||||
font-family: "AlibabaPuHuiTiB", "Alibaba PuHuiTi Bold", "Alibaba PuHuiTi Heavy", "Alibaba PuHuiTi", "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
color: #000000;
|
||||
@@ -492,6 +499,7 @@
|
||||
font-size: 14px;
|
||||
color: #555555;
|
||||
margin-bottom: 8px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.content .works .audio-box .item .content .info .time {
|
||||
font-size: 14px;
|
||||
@@ -532,6 +540,12 @@
|
||||
background-color: #000000;
|
||||
border-radius: 0 10px 10px 0;
|
||||
}
|
||||
.content .works .audio-box .item .content .info .operate {
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.content .works .audio-box .item .content .info .operate > img:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.content .works .audio-box .item .content .info .operate .speed {
|
||||
width: 16px;
|
||||
height: 12px;
|
||||
@@ -611,6 +625,7 @@
|
||||
font-size: 14px;
|
||||
color: #555555;
|
||||
margin-bottom: 18px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.content .custom .list .item .info .progress-bar {
|
||||
width: 260px;
|
||||
@@ -646,6 +661,12 @@
|
||||
background-color: #000000;
|
||||
border-radius: 0 10px 10px 0;
|
||||
}
|
||||
.content .custom .list .item .info .operate {
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.content .custom .list .item .info .operate > img:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.content .custom .list .item .info .operate .speed {
|
||||
width: 16px;
|
||||
height: 12px;
|
||||
@@ -661,6 +682,7 @@
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
filter: drop-shadow(5px 5px 2.5px rgba(0, 0, 0, 0.35));
|
||||
border-radius: 10px;
|
||||
}
|
||||
.content .custom .bottom {
|
||||
position: absolute;
|
||||
@@ -703,6 +725,9 @@
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.content .student .student-box .list .img:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.content .student .student-box .list .img.img5 {
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
@@ -792,6 +817,12 @@
|
||||
background-color: #ffffff;
|
||||
border-radius: 0 10px 10px 0;
|
||||
}
|
||||
.content .student .student-box .operate {
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.content .student .student-box .operate > img:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.content .student .student-box .operate .cut {
|
||||
width: 14px;
|
||||
height: 12px;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
}
|
||||
|
||||
.content {
|
||||
@@ -91,6 +92,8 @@
|
||||
.award {
|
||||
flex-direction: column;
|
||||
margin-bottom: 177px;
|
||||
align-items: flex-start;
|
||||
|
||||
.title {
|
||||
width: 101px;
|
||||
height: 24px;
|
||||
@@ -98,9 +101,11 @@
|
||||
}
|
||||
|
||||
.name {
|
||||
// width: min-content;
|
||||
height: 65px;
|
||||
max-height: 65px;
|
||||
max-width: 340px;
|
||||
margin-bottom: 30px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.explain {
|
||||
@@ -154,6 +159,12 @@
|
||||
border-radius: 15px;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
.img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
.bj {
|
||||
&.bj3 {
|
||||
width: 101%;
|
||||
@@ -180,6 +191,7 @@
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.play {
|
||||
@@ -315,6 +327,9 @@
|
||||
width: 402px;
|
||||
height: 64px;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.bj {
|
||||
position: absolute;
|
||||
@@ -325,11 +340,11 @@
|
||||
}
|
||||
|
||||
.title {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 208px;
|
||||
// position: absolute;
|
||||
// top: 50%;
|
||||
// left: 50%;
|
||||
// transform: translate(-50%, -50%);
|
||||
// width: 208px;
|
||||
height: 49px;
|
||||
}
|
||||
|
||||
@@ -406,7 +421,7 @@
|
||||
|
||||
.serial {
|
||||
height: 44px;
|
||||
font-family: "AlibabaPuHuiTiB", "Alibaba PuHuiTi Bold", "Alibaba PuHuiTi Heavy", "Alibaba PuHuiTi", sans-serif;
|
||||
font-family: "AlibabaPuHuiTiB", "Alibaba PuHuiTi Bold", "Alibaba PuHuiTi Heavy", "Alibaba PuHuiTi", "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
color: #000000;
|
||||
@@ -470,7 +485,6 @@
|
||||
height: 100%;
|
||||
border-radius: 10px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
}
|
||||
|
||||
.play {
|
||||
@@ -516,7 +530,7 @@
|
||||
|
||||
.serial {
|
||||
height: 44px;
|
||||
font-family: "AlibabaPuHuiTiB", "Alibaba PuHuiTi Bold", "Alibaba PuHuiTi Heavy", "Alibaba PuHuiTi", sans-serif;
|
||||
font-family: "AlibabaPuHuiTiB", "Alibaba PuHuiTi Bold", "Alibaba PuHuiTi Heavy", "Alibaba PuHuiTi", "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
color: #000000;
|
||||
@@ -566,6 +580,7 @@
|
||||
font-size: 14px;
|
||||
color: #555555;
|
||||
margin-bottom: 8px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.time {
|
||||
@@ -614,6 +629,11 @@
|
||||
}
|
||||
|
||||
.operate {
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
> img:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.speed {
|
||||
width: 16px;
|
||||
height: 12px;
|
||||
@@ -706,6 +726,7 @@
|
||||
font-size: 14px;
|
||||
color: #555555;
|
||||
margin-bottom: 18px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
@@ -748,6 +769,12 @@
|
||||
}
|
||||
|
||||
.operate {
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
> img:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.speed {
|
||||
width: 16px;
|
||||
height: 12px;
|
||||
@@ -767,6 +794,12 @@
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
filter: drop-shadow(5px 5px 2.5px rgba(0, 0, 0, 0.35));
|
||||
// transition: all 0.3s ease-in-out;
|
||||
border-radius: 10px;
|
||||
|
||||
// &:hover {
|
||||
// transform: scale(1.05);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -815,6 +848,10 @@
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
&.img5 {
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
@@ -922,6 +959,10 @@
|
||||
}
|
||||
|
||||
.operate {
|
||||
transition: all 0.3s ease-in-out;
|
||||
> img:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.cut {
|
||||
width: 14px;
|
||||
height: 12px;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
}
|
||||
.container {
|
||||
width: 100%;
|
||||
@@ -299,51 +300,89 @@
|
||||
border-radius: 18px;
|
||||
}
|
||||
.tag-item {
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
height: 66px;
|
||||
border-radius: 12px;
|
||||
background: #d5e7f7;
|
||||
position: absolute;
|
||||
font-size: 20px !important;
|
||||
color: #1c3e5e;
|
||||
padding: 0 25px;
|
||||
width: fit-content;
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 0 0 3px rgba(255, 255, 255, 0.223529);
|
||||
background: rgba(255, 255, 255, 0.223529);
|
||||
opacity: 1 !important;
|
||||
padding: 3px;
|
||||
}
|
||||
.tag-item.show::after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(var(--rotate), #db4743, #ffffff 43%, #c28846);
|
||||
animation: bg 1.3s infinite linear;
|
||||
}
|
||||
@property --rotate {
|
||||
syntax: "<angle>";
|
||||
initial-value: 0deg;
|
||||
inherits: false;
|
||||
}
|
||||
@keyframes bg {
|
||||
0% {
|
||||
--rotate: 0deg;
|
||||
}
|
||||
100% {
|
||||
--rotate: 360deg;
|
||||
}
|
||||
}
|
||||
.tag-item .tag-text {
|
||||
background: #d5e7f7;
|
||||
padding: 0 25px;
|
||||
border-radius: 10px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: background 0.3s, color 0.3s, z-index 0.3s, font-weight 0.3s;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.tag-item:hover {
|
||||
font-weight: 650;
|
||||
color: #583a05 !important;
|
||||
background: #f19a04 !important;
|
||||
z-index: 100 !important;
|
||||
}
|
||||
.tag-item:hover .tag-text {
|
||||
background: #f19a04 !important;
|
||||
}
|
||||
.tag-item.item2 {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
height: 56px;
|
||||
color: #1c3e5e;
|
||||
padding: 0 20px;
|
||||
font-size: 18px !important;
|
||||
}
|
||||
.tag-item.item2 .tag-text {
|
||||
padding: 0 20px;
|
||||
background: #d5e7f7;
|
||||
}
|
||||
.tag-item.item3 {
|
||||
height: 47px;
|
||||
line-height: 47px;
|
||||
height: 53px;
|
||||
color: #1c3e5e;
|
||||
padding: 0 16px;
|
||||
font-size: 16px !important;
|
||||
}
|
||||
.tag-item.item3 .tag-text {
|
||||
padding: 0 16px;
|
||||
background: #d5e7f7;
|
||||
}
|
||||
.tag-item.item4 {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
height: 36px;
|
||||
color: #1c3e5e;
|
||||
padding: 0 10px;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.tag-item.item4 .tag-text {
|
||||
padding: 0 10px;
|
||||
background: #d5e7f7;
|
||||
}
|
||||
.tag-item.red {
|
||||
.tag-item.red .tag-text {
|
||||
color: #62263c !important;
|
||||
background: linear-gradient(180deg, #ff8eba 0%, #f4458c 100%);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
}
|
||||
|
||||
.container {
|
||||
@@ -355,70 +356,111 @@
|
||||
}
|
||||
|
||||
.tag-item {
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
// border-radius: 30px;
|
||||
height: 66px;
|
||||
// line-height: 60px;
|
||||
border-radius: 12px;
|
||||
background: #d5e7f7;
|
||||
// background: #d5e7f7;
|
||||
position: absolute;
|
||||
font-size: 20px !important;
|
||||
color: #1c3e5e;
|
||||
padding: 0 25px;
|
||||
width: fit-content;
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 0 0 3px rgba(255, 255, 255, 0.223529);
|
||||
// box-shadow: 0px 0 0 3px rgba(255, 255, 255, 0.223529);
|
||||
background: rgba(255, 255, 255, 0.223529);
|
||||
opacity: 1 !important;
|
||||
transition: background 0.3s, color 0.3s, z-index 0.3s, font-weight 0.3s;
|
||||
// transition: background 0.3s, color 0.3s, z-index 0.3s, font-weight 0.3s;
|
||||
padding: 3px;
|
||||
|
||||
&.show::after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 12px;
|
||||
|
||||
background: linear-gradient(var(--rotate), #db4743, #ffffff 43%, #c28846);
|
||||
animation: bg 1.3s infinite linear;
|
||||
}
|
||||
|
||||
@property --rotate {
|
||||
syntax: "<angle>";
|
||||
initial-value: 0deg;
|
||||
inherits: false;
|
||||
}
|
||||
|
||||
@keyframes bg {
|
||||
0% {
|
||||
--rotate: 0deg;
|
||||
}
|
||||
|
||||
100% {
|
||||
--rotate: 360deg;
|
||||
}
|
||||
}
|
||||
|
||||
.tag-text {
|
||||
background: #d5e7f7;
|
||||
padding: 0 25px;
|
||||
border-radius: 10px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: background 0.3s, color 0.3s, z-index 0.3s, font-weight 0.3s;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
font-weight: 650;
|
||||
color: #583a05 !important;
|
||||
background: rgba(241, 154, 4, 1) !important;
|
||||
z-index: 100 !important;
|
||||
.tag-text {
|
||||
background: rgba(241, 154, 4, 1) !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.item2 {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
// border-radius: 25px;
|
||||
height: 56px;
|
||||
color: #1c3e5e;
|
||||
padding: 0 20px;
|
||||
font-size: 18px !important;
|
||||
background: #d5e7f7;
|
||||
|
||||
.tag-text {
|
||||
padding: 0 20px;
|
||||
background: #d5e7f7;
|
||||
}
|
||||
}
|
||||
|
||||
&.item3 {
|
||||
height: 47px;
|
||||
line-height: 47px;
|
||||
// border-radius: 25px;
|
||||
height: 53px;
|
||||
color: #1c3e5e;
|
||||
padding: 0 16px;
|
||||
font-size: 16px !important;
|
||||
background: #d5e7f7;
|
||||
|
||||
.tag-text {
|
||||
padding: 0 16px;
|
||||
background: #d5e7f7;
|
||||
}
|
||||
}
|
||||
|
||||
&.item4 {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
// border-radius: 30px;
|
||||
height: 36px;
|
||||
color: #1c3e5e;
|
||||
padding: 0 10px;
|
||||
font-size: 14px !important;
|
||||
background: #d5e7f7;
|
||||
|
||||
.tag-text {
|
||||
padding: 0 10px;
|
||||
background: #d5e7f7;
|
||||
}
|
||||
}
|
||||
|
||||
&.red {
|
||||
color: #62263c !important;
|
||||
background: linear-gradient(180deg, #ff8eba 0%, #f4458c 100%);
|
||||
.tag-text {
|
||||
color: #62263c !important;
|
||||
background: linear-gradient(180deg, #ff8eba 0%, #f4458c 100%);
|
||||
}
|
||||
}
|
||||
|
||||
// &.red:hover {
|
||||
// font-weight: 650;
|
||||
// color: #583a05 !important;
|
||||
// // background-color: rgba(241, 154, 4, 1) !important;
|
||||
// background-color: rgb(255, 255, 255) !important;
|
||||
// z-index: 100 !important;
|
||||
// }
|
||||
}
|
||||
|
||||
.bottom-play {
|
||||
|
||||
12
static/img/guess-bj-2.svg
Normal file
12
static/img/guess-bj-2.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="360px" height="128px" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient gradientUnits="userSpaceOnUse" x1="181" y1="128" x2="292" y2="128" id="LinearGradient289">
|
||||
<stop id="Stop290" stop-color="#9f2c39" offset="0" />
|
||||
<stop id="Stop291" stop-color="#be3946" offset="1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g transform="matrix(1 0 0 1 -385 -1255 )">
|
||||
<path d="M 151 128 L 0 97 L 347 0 L 360 128 L 151 128 Z " fill-rule="nonzero" fill="url(#LinearGradient289)" stroke="none" transform="matrix(1 0 0 1 385 1255 )" />
|
||||
</g>
|
||||
</svg>
|
||||
12
static/img/guess-bj.svg
Normal file
12
static/img/guess-bj.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="1064px" height="280px" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient gradientUnits="userSpaceOnUse" x1="115" y1="0" x2="1064" y2="280" id="LinearGradient295">
|
||||
<stop id="Stop296" stop-color="#f3974a" offset="0" />
|
||||
<stop id="Stop297" stop-color="#d73942" offset="1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g transform="matrix(1 0 0 1 -496 -1103 )">
|
||||
<path d="M 184 280 L 0 237.125 L 104 0 L 1064 215.125 L 1064 262.5 C 1064 272.3 1055.2 280 1044 280 L 184 280 Z " fill-rule="nonzero" fill="url(#LinearGradient295)" stroke="none" transform="matrix(1 0 0 1 496 1103 )" />
|
||||
</g>
|
||||
</svg>
|
||||
12
static/img/guess-love-big.svg
Normal file
12
static/img/guess-love-big.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="298px" height="256px" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient gradientUnits="userSpaceOnUse" x1="271.334774788104" y1="21.570942662449" x2="0" y2="256" id="LinearGradient298">
|
||||
<stop id="Stop299" stop-color="#c3454c" offset="0" />
|
||||
<stop id="Stop300" stop-color="#eea058" offset="1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g transform="matrix(1 0 0 1 -424 -1125 )">
|
||||
<path d="M 156.316964285714 253 C 154.321428571429 255 151.88244047619 256 149 256 C 146.11755952381 256 143.678571428571 255 141.683035714286 253 L 37.9151785714286 152.666666666667 C 36.8065476190476 151.777777777778 35.2821800595238 150.333333333333 33.3420758928571 148.333333333333 C 31.4019717261905 146.333333333333 28.3255208333333 142.694444444444 24.1127232142857 137.416666666667 C 19.8999255952381 132.138888888889 16.1305803571429 126.722222222222 12.8046875 121.166666666667 C 9.47879464285714 115.611111111111 6.5132068452381 108.888888888889 3.90792410714286 101 C 1.30264136904762 93.1111111111111 0 85.4444444444444 0 78 C 0 53.5555555555555 7.03980654761905 34.4444444444444 21.1194196428571 20.6666666666667 C 35.1990327380952 6.88888888888889 54.6555059523809 0 79.4888392857143 0 C 86.3623511904762 0 93.3744419642857 1.19444444444443 100.525111607143 3.58333333333334 C 107.67578125 5.9722222222222 114.327566964286 9.19444444444443 120.48046875 13.25 C 126.633370535714 17.3055555555555 131.927083333333 21.1111111111111 136.361607142857 24.6666666666667 C 140.796130952381 28.2222222222222 145.008928571429 32 149 36 C 152.991071428571 32 157.203869047619 28.2222222222222 161.638392857143 24.6666666666667 C 166.072916666667 21.1111111111111 171.366629464286 17.3055555555555 177.51953125 13.25 C 183.672433035714 9.19444444444443 190.32421875 5.9722222222222 197.474888392857 3.58333333333334 C 204.625558035714 1.19444444444443 211.637648809524 0 218.511160714286 0 C 243.344494047619 0 262.800967261905 6.88888888888889 276.880580357143 20.6666666666667 C 290.960193452381 34.4444444444444 298 53.5555555555555 298 78 C 298 102.555555555556 285.306175595238 127.555555555556 259.918526785714 153 L 156.316964285714 253 Z " fill-rule="nonzero" fill="url(#LinearGradient298)" stroke="none" transform="matrix(1 0 0 1 424 1125 )" />
|
||||
</g>
|
||||
</svg>
|
||||
12
static/img/guess-love-little.svg
Normal file
12
static/img/guess-love-little.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="173px" height="148px" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient gradientUnits="userSpaceOnUse" x1="45.5970992552194" y1="109.588769917092" x2="167.736885267016" y2="22.4597723935139" id="LinearGradient292">
|
||||
<stop id="Stop293" stop-color="#c03c49" offset="0" />
|
||||
<stop id="Stop294" stop-color="#eed680" offset="1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g transform="matrix(1 0 0 1 -351 -1223 )">
|
||||
<path d="M 90.7477678571428 146.265625 C 89.5892857142857 147.421875 88.1733630952381 148 86.5 148 C 84.8266369047619 148 83.4107142857143 147.421875 82.2522321428571 146.265625 L 22.0111607142857 88.2604166666667 C 21.3675595238095 87.7465277777778 20.4826078869048 86.9114583333333 19.3563058035714 85.7552083333333 C 18.2300037202381 84.5989583333333 16.4440104166667 82.4952256944445 13.9983258928571 79.4440104166667 C 11.5526413690476 76.3927951388889 9.36439732142857 73.2612847222222 7.43359375 70.0494791666667 C 5.50279017857143 66.8376736111111 3.78115699404762 62.9513888888889 2.26869419642857 58.390625 C 0.756231398809524 53.8298611111111 0 49.3975694444444 0 45.09375 C 0 30.9618055555556 4.08686755952381 19.9131944444444 12.2606026785714 11.9479166666667 C 20.4343377976191 3.98263888888889 31.7295386904762 0 46.1462053571429 0 C 50.1365327380952 0 54.2073102678571 0.690538194444435 58.3585379464286 2.07161458333334 C 62.509765625 3.45269097222221 66.3713727678571 5.31553819444444 69.943359375 7.66015625 C 73.5153459821429 10.0047743055555 76.5885416666667 12.2048611111111 79.1629464285714 14.2604166666667 C 81.7373511904762 16.3159722222222 84.1830357142857 18.5 86.5 20.8125 C 88.8169642857143 18.5 91.2626488095238 16.3159722222222 93.8370535714286 14.2604166666667 C 96.4114583333333 12.2048611111111 99.4846540178572 10.0047743055555 103.056640625 7.66015625 C 106.628627232143 5.31553819444444 110.490234375 3.45269097222221 114.641462053571 2.07161458333334 C 118.792689732143 0.690538194444435 122.863467261905 0 126.853794642857 0 C 141.270461309524 0 152.565662202381 3.98263888888889 160.739397321429 11.9479166666667 C 168.913132440476 19.9131944444444 173 30.9618055555556 173 45.09375 C 173 59.2899305555556 165.630766369048 73.7430555555555 150.892299107143 88.453125 L 90.7477678571428 146.265625 Z " fill-rule="nonzero" fill="url(#LinearGradient292)" stroke="none" transform="matrix(1 0 0 1 351 1223 )" />
|
||||
</g>
|
||||
</svg>
|
||||
18
static/img/guess-text.svg
Normal file
18
static/img/guess-text.svg
Normal file
File diff suppressed because one or more lines are too long
BIN
static/img/guess/figure-one.png
Normal file
BIN
static/img/guess/figure-one.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
static/img/guess/figure-three.png
Normal file
BIN
static/img/guess/figure-three.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
BIN
static/img/guess/figure-two.png
Normal file
BIN
static/img/guess/figure-two.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
BIN
static/img/question-mark.png
Normal file
BIN
static/img/question-mark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 114 KiB |
1
static/js/ffmpeg.min.js
vendored
Normal file
1
static/js/ffmpeg.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FFmpegWASM=t():e.FFmpegWASM=t()}(self,()=>(()=>{"use strict";var i={m:{},d:(e,t)=>{for(var s in t)i.o(t,s)&&!i.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},u:e=>e+".ffmpeg.js"};i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.g.importScripts&&(e=i.g.location+"");var e,t=i.g.document;if(!e&&t&&!(e=t.currentScript?t.currentScript.src:e)){var s=t.getElementsByTagName("script");if(s.length)for(var a=s.length-1;-1<a&&!e;)e=s[a--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),i.p=e,i.b=document.baseURI||self.location.href;var r,o,n,t={};i.r(t),i.d(t,{FFFSType:()=>o,FFmpeg:()=>c}),(n=r=r||{}).LOAD="LOAD",n.EXEC="EXEC",n.FFPROBE="FFPROBE",n.WRITE_FILE="WRITE_FILE",n.READ_FILE="READ_FILE",n.DELETE_FILE="DELETE_FILE",n.RENAME="RENAME",n.CREATE_DIR="CREATE_DIR",n.LIST_DIR="LIST_DIR",n.DELETE_DIR="DELETE_DIR",n.ERROR="ERROR",n.DOWNLOAD="DOWNLOAD",n.PROGRESS="PROGRESS",n.LOG="LOG",n.MOUNT="MOUNT",n.UNMOUNT="UNMOUNT";const E=(()=>{let e=0;return()=>e++})(),p=(new Error("unknown message type"),new Error("ffmpeg is not loaded, call `await ffmpeg.load()` first")),d=new Error("called FFmpeg.terminate()");new Error("failed to import ffmpeg-core.js");class c{#e=null;#t={};#s={};#r=[];#a=[];loaded=!1;#o=()=>{this.#e&&(this.#e.onmessage=({data:{id:e,type:t,data:s}})=>{switch(t){case r.LOAD:this.loaded=!0,this.#t[e](s);break;case r.MOUNT:case r.UNMOUNT:case r.EXEC:case r.FFPROBE:case r.WRITE_FILE:case r.READ_FILE:case r.DELETE_FILE:case r.RENAME:case r.CREATE_DIR:case r.LIST_DIR:case r.DELETE_DIR:this.#t[e](s);break;case r.LOG:this.#r.forEach(e=>e(s));break;case r.PROGRESS:this.#a.forEach(e=>e(s));break;case r.ERROR:this.#s[e](s)}delete this.#t[e],delete this.#s[e]})};#i=({type:i,data:a},r=[],o)=>this.#e?new Promise((e,t)=>{const s=E();this.#e&&this.#e.postMessage({id:s,type:i,data:a},r),this.#t[s]=e,this.#s[s]=t,o?.addEventListener("abort",()=>{t(new DOMException(`Message # ${s} was aborted`,"AbortError"))},{once:!0})}):Promise.reject(p);on(e,t){"log"===e?this.#r.push(t):"progress"===e&&this.#a.push(t)}off(e,t){"log"===e?this.#r=this.#r.filter(e=>e!==t):"progress"===e&&(this.#a=this.#a.filter(e=>e!==t))}load=({classWorkerURL:e,...t}={},{signal:s}={})=>(this.#e||(this.#e=e?new Worker(new URL(e,"file:///Users/focus/Projects/ffmpeg.wasm/packages/ffmpeg/dist/esm/classes.js"),{type:"module"}):new Worker(new URL(i.p+i.u(814),i.b),{type:void 0}),this.#o()),this.#i({type:r.LOAD,data:t},void 0,s));exec=(e,t=-1,{signal:s}={})=>this.#i({type:r.EXEC,data:{args:e,timeout:t}},void 0,s);ffprobe=(e,t=-1,{signal:s}={})=>this.#i({type:r.FFPROBE,data:{args:e,timeout:t}},void 0,s);terminate=()=>{for(const e of Object.keys(this.#s))this.#s[e](d),delete this.#s[e],delete this.#t[e];this.#e&&(this.#e.terminate(),this.#e=null,this.loaded=!1)};writeFile=(e,t,{signal:s}={})=>{const i=[];return t instanceof Uint8Array&&i.push(t.buffer),this.#i({type:r.WRITE_FILE,data:{path:e,data:t}},i,s)};mount=(e,t,s)=>this.#i({type:r.MOUNT,data:{fsType:e,options:t,mountPoint:s}},[]);unmount=e=>this.#i({type:r.UNMOUNT,data:{mountPoint:e}},[]);readFile=(e,t="binary",{signal:s}={})=>this.#i({type:r.READ_FILE,data:{path:e,encoding:t}},void 0,s);deleteFile=(e,{signal:t}={})=>this.#i({type:r.DELETE_FILE,data:{path:e}},void 0,t);rename=(e,t,{signal:s}={})=>this.#i({type:r.RENAME,data:{oldPath:e,newPath:t}},void 0,s);createDir=(e,{signal:t}={})=>this.#i({type:r.CREATE_DIR,data:{path:e}},void 0,t);listDir=(e,{signal:t}={})=>this.#i({type:r.LIST_DIR,data:{path:e}},void 0,t);deleteDir=(e,{signal:t}={})=>this.#i({type:r.DELETE_DIR,data:{path:e}},void 0,t)}return(n=o=o||{}).MEMFS="MEMFS",n.NODEFS="NODEFS",n.NODERAWFS="NODERAWFS",n.IDBFS="IDBFS",n.WORKERFS="WORKERFS",n.PROXYFS="PROXYFS",t})());
|
||||
@@ -1,5 +1,5 @@
|
||||
const { createApp, ref, onMounted, nextTick, onUnmounted, computed } = Vue;
|
||||
const search = createApp({
|
||||
createApp({
|
||||
setup() {
|
||||
const musicData = ref([
|
||||
["A组 世界在转动.MP3", "A组《来吧,占领我的无私》.MP3"],
|
||||
@@ -14,6 +14,11 @@ const search = createApp({
|
||||
let isAnswer = ref(false);
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener("resize", () => {
|
||||
// 重新计算 detailsHeight
|
||||
const windowHeight = window.innerHeight;
|
||||
detailsHeight.value = Math.max(windowHeight - 379 - 40, 350);
|
||||
});
|
||||
init();
|
||||
|
||||
// 获取可是窗口高度
|
||||
@@ -74,8 +79,6 @@ const search = createApp({
|
||||
let autoTimer = null;
|
||||
const audioEnd = (item) => {
|
||||
const nextItem = findNextItem(audiozSrc.value);
|
||||
console.log("nextItem", nextItem);
|
||||
|
||||
if (nextItem) autoTimer = setTimeout(() => play(nextItem), 500);
|
||||
audiozSrc.value = "";
|
||||
};
|
||||
@@ -144,18 +147,11 @@ const search = createApp({
|
||||
|
||||
let fluctuate = ref([]);
|
||||
|
||||
onMounted(() => {
|
||||
// setInterval(() => {
|
||||
// randomFluctuate();
|
||||
// }, 150);
|
||||
});
|
||||
|
||||
const randomFluctuate = () => {
|
||||
fluctuate.value = []
|
||||
fluctuate.value = [];
|
||||
for (let i = 0; i < 30; i++) {
|
||||
fluctuate.value.push(Math.floor(Math.random() * 10) + 1);
|
||||
}
|
||||
console.log("fluctuate", fluctuate.value);
|
||||
};
|
||||
|
||||
return { fluctuate, isAnswer, detailsHeight, detailsRef, audioEnd, playSucceed, stop, audiozSrc, audioPlayer, backHome, select, loseState, winState, replyState, play, step, begin, musicData, nextStep };
|
||||
|
||||
2
static/js/html-to-image.js
Normal file
2
static/js/html-to-image.js
Normal file
File diff suppressed because one or more lines are too long
20
static/js/html2canvas.min.js
vendored
Normal file
20
static/js/html2canvas.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
const { createApp, ref, onMounted, nextTick, onUnmounted, computed } = Vue;
|
||||
const search = createApp({
|
||||
const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch } = Vue;
|
||||
createApp({
|
||||
setup() {
|
||||
const trait = [
|
||||
{
|
||||
@@ -118,10 +118,6 @@ const search = createApp({
|
||||
bannerList.value = data.banner;
|
||||
awardMVList.value = data.awardMVList;
|
||||
|
||||
data.awardAudioList.forEach((item, index) => {
|
||||
item["playurl"] = `https://app.gter.net/image/miniApp/mp3/${index + 1}.mp3`;
|
||||
});
|
||||
|
||||
awardAudioList.value = data.awardAudioList;
|
||||
|
||||
customList.value = data.customAudioList;
|
||||
@@ -215,6 +211,8 @@ const search = createApp({
|
||||
const src = playData.value?.playurl || "";
|
||||
const area = playData.value?.area || "";
|
||||
|
||||
console.log(audioPlayer.value.src, src);
|
||||
|
||||
if (audioPlayer.value.src != src) {
|
||||
manageAudio(src, area);
|
||||
return;
|
||||
@@ -235,7 +233,9 @@ const search = createApp({
|
||||
// 管理音频播放
|
||||
const manageAudio = (src, area) => {
|
||||
const audio = audioPlayer.value;
|
||||
|
||||
closeAll();
|
||||
|
||||
setTimeout(() => {
|
||||
if (audio?.src != src) audio.src = src;
|
||||
audio.play().then(() => {
|
||||
@@ -262,7 +262,7 @@ const search = createApp({
|
||||
playData.value = { ...zeroOrderStudents.value, area };
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
}, 800);
|
||||
};
|
||||
|
||||
// 重新播放
|
||||
@@ -494,6 +494,11 @@ const search = createApp({
|
||||
id = item.id;
|
||||
}
|
||||
|
||||
if (area == "works") {
|
||||
const item = awardAudioList.value[index];
|
||||
id = item.id;
|
||||
}
|
||||
|
||||
ajax("https://pujianchaoyin.com/api/getMusicDetail", {
|
||||
id,
|
||||
}).then((res) => {
|
||||
@@ -508,9 +513,25 @@ const search = createApp({
|
||||
customList.value[index] = { ...data, ...customList.value[index] };
|
||||
manageAudio(data.playurl, area);
|
||||
}
|
||||
|
||||
if (area == "works") {
|
||||
awardAudioList.value[index] = { ...data, ...awardAudioList.value[index] };
|
||||
manageAudio(data.playurl, area);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return { cutSong, getPlayUrl, handleBarDragBottomClick, startBarDragBottom, volumeShow, handleVolumeHide, handleVolumeShow, zeroOrderStudents, rePlay, playData, awardAudioList, changeInterval, awardMVList, bannerList, albumBoxRef, volume, handleVolumeClick, handleVolumeDrag, startDrag, stopDrag, volume, cutStudent, studentList, studentIndex, scrollToPrevious, scrollToNext, changePointer, pointerIndex, visibleRef, studentRef, customRef, formatTime, currentTimeFormatted, durationFormatted, worksRef, introduceRef, customList, closeAll, manageAudio, progress, closePreview, openPreview, previewState, audioPlayer, trait, fastForward };
|
||||
const judgmentPlayUrl = (url, area, index) => {
|
||||
if (url) manageAudio(url, area);
|
||||
else getPlayUrl(index, area);
|
||||
};
|
||||
|
||||
// 监听 previewState 如果为 true body.style.overflow = 'hidden'
|
||||
watch(previewState, (newVal) => {
|
||||
if (newVal) document.body.style.overflow = "hidden";
|
||||
else document.body.style.overflow = "auto";
|
||||
});
|
||||
|
||||
return { judgmentPlayUrl, cutSong, getPlayUrl, handleBarDragBottomClick, startBarDragBottom, volumeShow, handleVolumeHide, handleVolumeShow, zeroOrderStudents, rePlay, playData, awardAudioList, changeInterval, awardMVList, bannerList, albumBoxRef, volume, handleVolumeClick, handleVolumeDrag, startDrag, stopDrag, volume, cutStudent, studentList, studentIndex, scrollToPrevious, scrollToNext, changePointer, pointerIndex, visibleRef, studentRef, customRef, formatTime, currentTimeFormatted, durationFormatted, worksRef, introduceRef, customList, closeAll, manageAudio, progress, closePreview, openPreview, previewState, audioPlayer, trait, fastForward };
|
||||
},
|
||||
}).mount("#appIndex");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const { createApp, ref, onMounted, nextTick, onUnmounted, computed } = Vue;
|
||||
const search = createApp({
|
||||
createApp({
|
||||
setup() {
|
||||
// 标签数据
|
||||
let tags = ref([]);
|
||||
@@ -16,412 +16,254 @@ const search = createApp({
|
||||
return { containerWidth, containerHeight };
|
||||
};
|
||||
|
||||
let bubbleContainer = null;
|
||||
let bubbleContainerFill = null;
|
||||
|
||||
// 初始创建标签
|
||||
const init = () => {
|
||||
let tagsData = [
|
||||
{
|
||||
tag: "彩虹泡泡",
|
||||
songs: [
|
||||
{ name: "彩虹的微笑", path: "/music/rainbow_smile.mp3" },
|
||||
{ name: "泡泡飞舞", path: "/music/bubble_dance.mp3" },
|
||||
{ name: "七彩梦境", path: "/music/colorful_dream.mp3" },
|
||||
{ name: "泡泡糖世界", path: "/music/bubblegum_world.mp3" },
|
||||
{ name: "彩虹之光", path: "/music/rainbow_light.mp3" },
|
||||
],
|
||||
name: "孤独角落的守望",
|
||||
path: "孤独角落的守望.MP3",
|
||||
tags: ["浪漫", "爱情", "悲伤的角落", "复古旋律", "流行"],
|
||||
},
|
||||
{
|
||||
tag: "星际漫游",
|
||||
songs: [
|
||||
{ name: "银河漫步", path: "/music/galaxy_walk.mp3" },
|
||||
{ name: "宇宙之旅", path: "/music/space_journey.mp3" },
|
||||
{ name: "星际迷航", path: "/music/star_trek.mp3" },
|
||||
{ name: "太空漫步", path: "/music/space_walk.mp3" },
|
||||
{ name: "银河系边缘", path: "/music/galaxy_edge.mp3" },
|
||||
{ name: "星际穿越", path: "/music/interstellar.mp3" },
|
||||
],
|
||||
name: "碎梦残爱",
|
||||
path: "碎梦残爱.MP3",
|
||||
tags: ["浪漫", "爱情", "悲伤的角落", "复古旋律", "流行"],
|
||||
},
|
||||
{
|
||||
tag: "开心到飞起",
|
||||
songs: [
|
||||
{ name: "快乐飞翔", path: "/music/happy_flying.mp3" },
|
||||
{ name: "笑到飞起", path: "/music/laugh_high.mp3" },
|
||||
{ name: "开心每一天", path: "/music/happy_everyday.mp3" },
|
||||
{ name: "飞向快乐", path: "/music/fly_to_happy.mp3" },
|
||||
],
|
||||
name: "心碎的声音",
|
||||
path: "心碎的声音.MP3",
|
||||
tags: ["浪漫", "爱情", "悲伤的角落", "复古旋律", "流行"],
|
||||
},
|
||||
{
|
||||
tag: "甜蜜时光",
|
||||
songs: [
|
||||
{ name: "甜蜜约定", path: "/music/sweet_promise.mp3" },
|
||||
{ name: "时光慢递", path: "/music/slow_time.mp3" },
|
||||
{ name: "甜蜜回忆", path: "/music/sweet_memory.mp3" },
|
||||
{ name: "蜜糖时光", path: "/music/honey_time.mp3" },
|
||||
{ name: "温柔时刻", path: "/music/gentle_moment.mp3" },
|
||||
{ name: "甜蜜陪伴", path: "/music/sweet_company.mp3" },
|
||||
{ name: "幸福时光", path: "/music/happy_time.mp3" },
|
||||
],
|
||||
name: "夜尽破晓",
|
||||
path: "夜尽破晓.MP3",
|
||||
tags: ["浪漫", "爱情", "悲伤的角落", "梦幻", "自由鼓点", "赛博心跳", "自由摇摆", "微风轻轻吹"],
|
||||
},
|
||||
{
|
||||
tag: "探险",
|
||||
songs: [
|
||||
{ name: "丛林探险", path: "/music/jungle_adventure.mp3" },
|
||||
{ name: "未知旅程", path: "/music/unknown_journey.mp3" },
|
||||
{ name: "探索新世界", path: "/music/explore_new_world.mp3" },
|
||||
{ name: "勇往直前", path: "/music/brave_forward.mp3" },
|
||||
{ name: "神秘岛屿", path: "/music/mystery_island.mp3" },
|
||||
],
|
||||
name: "秋江别",
|
||||
path: "秋江别.mp3",
|
||||
tags: ["浪漫", "爱情", "相思", "古风", "江湖", "悲伤的角落", "温柔女声"],
|
||||
},
|
||||
{
|
||||
tag: "梦幻",
|
||||
songs: [
|
||||
{ name: "梦幻旋律", path: "/music/dream_melody.mp3" },
|
||||
{ name: "幻想曲", path: "/music/fantasy.mp3" },
|
||||
{ name: "梦中的世界", path: "/music/dream_world.mp3" },
|
||||
{ name: "梦幻泡影", path: "/music/dream_bubble.mp3" },
|
||||
],
|
||||
name: "锁心劫",
|
||||
path: "锁心劫.mp3",
|
||||
tags: ["浪漫", "爱情", "相思", "古风", "江湖", "悲伤的角落", "温柔女声"],
|
||||
},
|
||||
{
|
||||
tag: "幻想曲",
|
||||
songs: [
|
||||
{ name: "幻想交响曲", path: "/music/fantasy_symphony.mp3" },
|
||||
{ name: "幻想即兴曲", path: "/music/fantasy_impromptu.mp3" },
|
||||
{ name: "幻想变奏曲", path: "/music/fantasy_variations.mp3" },
|
||||
{ name: "幻想小夜曲", path: "/music/fantasy_serenade.mp3" },
|
||||
{ name: "幻想曲集", path: "/music/fantasy_collection.mp3" },
|
||||
{ name: "幻想奏鸣曲", path: "/music/fantasy_sonata.mp3" },
|
||||
],
|
||||
name: "大提琴与钢琴",
|
||||
path: "《大提琴与钢琴》纯音乐.m4a",
|
||||
tags: ["浪漫", "温柔", "幻想曲", "梦幻", "纯音乐", "自由摇摆", "微风轻轻吹"],
|
||||
},
|
||||
{
|
||||
tag: "自由摇摆",
|
||||
songs: [
|
||||
{ name: "自由舞动", path: "/music/free_dance.mp3" },
|
||||
{ name: "摇摆节奏", path: "/music/swing_rhythm.mp3" },
|
||||
{ name: "自由爵士", path: "/music/free_jazz.mp3" },
|
||||
{ name: "摇摆人生", path: "/music/swing_life.mp3" },
|
||||
{ name: "自由即兴", path: "/music/free_improvisation.mp3" },
|
||||
],
|
||||
name: "经典游戏怀旧关卡",
|
||||
path: "《经典游戏怀旧关卡》纯音乐.mp3",
|
||||
tags: ["幻想曲", "梦幻", "纯音乐", "节奏大师", "快乐节拍", "自由鼓点", "赛博心跳", "赛博空间"],
|
||||
},
|
||||
{
|
||||
tag: "夏日狂欢",
|
||||
songs: [
|
||||
{ name: "夏日派对", path: "/music/summer_party.mp3" },
|
||||
{ name: "阳光沙滩", path: "/music/sunny_beach.mp3" },
|
||||
{ name: "海边狂欢", path: "/music/beach_carnival.mp3" },
|
||||
{ name: "夏日冰饮", path: "/music/summer_drink.mp3" },
|
||||
{ name: "热带风情", path: "/music/tropical_style.mp3" },
|
||||
{ name: "夏夜星空", path: "/music/summer_night_sky.mp3" },
|
||||
],
|
||||
name: "灵动琴音点亮旅行Vlog之旅",
|
||||
path: "《灵动琴音点亮旅行Vlog之旅》纯音乐.mp3",
|
||||
tags: ["彩虹泡泡", "幻想曲", "梦幻", "纯音乐", "节奏大师", "快乐节拍", "自由鼓点", "赛博心跳", "赛博空间"],
|
||||
},
|
||||
{
|
||||
tag: "微风轻轻吹",
|
||||
songs: [
|
||||
{ name: "微风拂面", path: "/music/breeze_face.mp3" },
|
||||
{ name: "轻风细雨", path: "/music/gentle_rain.mp3" },
|
||||
{ name: "风中絮语", path: "/music/wind_whisper.mp3" },
|
||||
{ name: "微风山谷", path: "/music/breeze_valley.mp3" },
|
||||
{ name: "风的私语", path: "/music/wind_secret.mp3" },
|
||||
],
|
||||
name: "品牌创新科技",
|
||||
path: "《品牌创新科技》纯音乐.mp3",
|
||||
tags: ["纯音乐", "节奏大师", "快乐节拍", "自由鼓点", "赛博心跳", "赛博空间"],
|
||||
},
|
||||
{
|
||||
tag: "江湖",
|
||||
songs: [
|
||||
{ name: "侠客行", path: "/music/knight_journey.mp3" },
|
||||
{ name: "刀剑如梦", path: "/music/sword_dream.mp3" },
|
||||
{ name: "笑傲江湖", path: "/music/laugh_jianghu.mp3" },
|
||||
{ name: "侠义情深", path: "/music/knight_love.mp3" },
|
||||
{ name: "江湖夜雨", path: "/music/jianghu_night_rain.mp3" },
|
||||
{ name: "沧海一声笑", path: "/music/sea_laugh.mp3" },
|
||||
],
|
||||
name: "琴音交织的青春动画恋曲",
|
||||
path: "《琴音交织的青春动画恋曲》纯音乐.mp3",
|
||||
tags: ["彩虹泡泡", "浪漫", "温柔", "幻想曲", "梦幻", "纯音乐", "自由摇摆", "微风轻轻吹", "阳光正好", "青草香"],
|
||||
},
|
||||
{
|
||||
tag: "浪漫",
|
||||
songs: [
|
||||
{ name: "浪漫星空", path: "/music/romantic_sky.mp3" },
|
||||
{ name: "浪漫时光", path: "/music/romantic_time.mp3" },
|
||||
{ name: "浪漫邂逅", path: "/music/romantic_encounter.mp3" },
|
||||
{ name: "浪漫旋律", path: "/music/romantic_melody.mp3" },
|
||||
{ name: "浪漫之夜", path: "/music/romantic_night.mp3" },
|
||||
],
|
||||
name: "我的金属心跳",
|
||||
path: "《我的金属心跳》.mp3",
|
||||
tags: ["流行", "自由摇摆", "赛博心跳", "节奏大师", "摇滚"],
|
||||
},
|
||||
{
|
||||
tag: "阳光正好",
|
||||
songs: [
|
||||
{ name: "阳光灿烂", path: "/music/sunshine_bright.mp3" },
|
||||
{ name: "正好遇见你", path: "/music/just_meet_you.mp3" },
|
||||
{ name: "阳光路上", path: "/music/sunshine_road.mp3" },
|
||||
{ name: "温暖阳光", path: "/music/warm_sunshine.mp3" },
|
||||
{ name: "阳光照进心里", path: "/music/sunshine_heart.mp3" },
|
||||
],
|
||||
name: "向前跑",
|
||||
path: "《向前跑》.mp3",
|
||||
tags: ["流行", "自由摇摆"],
|
||||
},
|
||||
{
|
||||
tag: "青草香",
|
||||
songs: [
|
||||
{ name: "草原晨曲", path: "/music/grassland_morning.mp3" },
|
||||
{ name: "青草地", path: "/music/grass_land.mp3" },
|
||||
{ name: "草香四溢", path: "/music/grass_fragrance.mp3" },
|
||||
{ name: "青草摇曳", path: "/music/grass_swing.mp3" },
|
||||
{ name: "草原牧歌", path: "/music/grassland_song.mp3" },
|
||||
],
|
||||
name: "战斗氛围",
|
||||
path: "《战斗氛围》纯音乐.m4a",
|
||||
tags: ["纯音乐", "节奏大师", "快乐节拍", "自由鼓点", "赛博心跳", "赛博空间", "摇滚"],
|
||||
},
|
||||
{
|
||||
tag: "赛博心跳",
|
||||
songs: [
|
||||
{ name: "电子脉冲", path: "/music/electronic_pulse.mp3" },
|
||||
{ name: "数字心跳", path: "/music/digital_heartbeat.mp3" },
|
||||
{ name: "机械律动", path: "/music/mechanical_rhythm.mp3" },
|
||||
{ name: "电流涌动", path: "/music/current_surge.mp3" },
|
||||
{ name: "赛博都市", path: "/music/cyber_city.mp3" },
|
||||
{ name: "数据流", path: "/music/data_flow.mp3" },
|
||||
],
|
||||
name: "长安三万里",
|
||||
path: "《长安三万里》纯音乐.mp3",
|
||||
tags: ["彩虹泡泡", "浪漫", "温柔", "幻想曲", "梦幻", "纯音乐", "星际漫游", "自由摇摆", "微风轻轻吹", "古风", "青草香", "阳光正好"],
|
||||
},
|
||||
{
|
||||
tag: "赛博空间",
|
||||
songs: [
|
||||
{ name: "虚拟现实", path: "/music/virtual_reality.mp3" },
|
||||
{ name: "网络漫游", path: "/music/network_roaming.mp3" },
|
||||
{ name: "数据海洋", path: "/music/data_ocean.mp3" },
|
||||
{ name: "赛博迷宫", path: "/music/cyber_maze.mp3" },
|
||||
{ name: "电子宇宙", path: "/music/electronic_universe.mp3" },
|
||||
],
|
||||
name: "助眠",
|
||||
path: "《助眠》纯音乐.mp3",
|
||||
tags: ["彩虹泡泡", "浪漫", "温柔", "幻想曲", "梦幻", "纯音乐", "星际漫游"],
|
||||
},
|
||||
{
|
||||
tag: "节奏大师",
|
||||
songs: [
|
||||
{ name: "节奏之王", path: "/music/rhythm_king.mp3" },
|
||||
{ name: "鼓点狂欢", path: "/music/drum_carnival.mp3" },
|
||||
{ name: "节奏游戏", path: "/music/rhythm_game.mp3" },
|
||||
{ name: "律动人生", path: "/music/rhythm_life.mp3" },
|
||||
{ name: "节奏与灵魂", path: "/music/rhythm_soul.mp3" },
|
||||
],
|
||||
name: "Compass Heart(中文版)",
|
||||
path: "Compass Heart(中文版).mp3",
|
||||
tags: ["浪漫", "爱情", "相思", "流行", "悲伤的角落", "温柔女声", "自由鼓点"],
|
||||
},
|
||||
{
|
||||
tag: "快乐节拍",
|
||||
songs: [
|
||||
{ name: "欢乐节拍", path: "/music/happy_beat.mp3" },
|
||||
{ name: "快乐舞曲", path: "/music/happy_dance.mp3" },
|
||||
{ name: "节拍欢歌", path: "/music/beat_song.mp3" },
|
||||
{ name: "快乐音符", path: "/music/happy_note.mp3" },
|
||||
{ name: "跳跃节奏", path: "/music/jumping_rhythm.mp3" },
|
||||
],
|
||||
name: "I Remember",
|
||||
path: "I Remember.mp3",
|
||||
tags: ["彩虹泡泡", "浪漫", "温柔", "幻想曲", "梦幻", "自由摇摆", "微风轻轻吹", "温柔女声", "青草香", "阳光正好"],
|
||||
},
|
||||
{
|
||||
tag: "自由鼓点",
|
||||
songs: [
|
||||
{ name: "自由敲击", path: "/music/free_hit.mp3" },
|
||||
{ name: "鼓点狂想", path: "/music/drum_fantasy.mp3" },
|
||||
{ name: "自由节奏", path: "/music/free_rhythm.mp3" },
|
||||
{ name: "鼓点即兴", path: "/music/drum_improvisation.mp3" },
|
||||
{ name: "自由打击", path: "/music/free_percussion.mp3" },
|
||||
],
|
||||
name: "炒股的人不听慢歌",
|
||||
path: "炒股的人不听慢歌.MP3",
|
||||
tags: ["节奏大师", "快乐节拍", "自由鼓点", "赛博心跳", "赛博空间", "摇滚"],
|
||||
},
|
||||
{
|
||||
tag: "悲伤的角落",
|
||||
songs: [
|
||||
{ name: "角落里的泪", path: "/music/corner_tears.mp3" },
|
||||
{ name: "悲伤回忆", path: "/music/sad_memory.mp3" },
|
||||
{ name: "孤独空间", path: "/music/lonely_space.mp3" },
|
||||
{ name: "泪的痕迹", path: "/music/tear_trace.mp3" },
|
||||
{ name: "心碎角落", path: "/music/heartbreak_corner.mp3" },
|
||||
],
|
||||
name: "成都真香故事",
|
||||
path: "成都真香故事.mp3",
|
||||
tags: ["生日祝福"],
|
||||
},
|
||||
{
|
||||
tag: "一个人的狂欢",
|
||||
songs: [
|
||||
{ name: "独自狂欢", path: "/music/alone_carnival.mp3" },
|
||||
{ name: "一人派对", path: "/music/one_person_party.mp3" },
|
||||
{ name: "孤独欢乐", path: "/music/lonely_joy.mp3" },
|
||||
{ name: "一个人的舞台", path: "/music/one_person_stage.mp3" },
|
||||
{ name: "独自摇摆", path: "/music/alone_swing.mp3" },
|
||||
],
|
||||
name: "大闹天宫",
|
||||
path: "大闹天宫.mp3",
|
||||
tags: ["自由摇摆", "解压宣泄", "影视配乐", "在路上"],
|
||||
},
|
||||
{
|
||||
tag: "经典金曲",
|
||||
songs: [
|
||||
{ name: "永恒经典", path: "/music/eternal_classic.mp3" },
|
||||
{ name: "金曲回放", path: "/music/golden_replay.mp3" },
|
||||
{ name: "不朽名曲", path: "/music/immortal_song.mp3" },
|
||||
{ name: "经典重现", path: "/music/classic_reproduction.mp3" },
|
||||
{ name: "金曲珍藏", path: "/music/golden_collection.mp3" },
|
||||
{ name: "经典传承", path: "/music/classic_inheritance.mp3" },
|
||||
],
|
||||
name: "都市周末狂欢夜",
|
||||
path: "都市周末狂欢夜.mp3",
|
||||
tags: ["阳光正好", "自由摇摆", "摇滚", "解压宣泄", "派对聚会"],
|
||||
},
|
||||
{
|
||||
tag: "民谣",
|
||||
songs: [
|
||||
{ name: "乡间小路", path: "/music/country_road.mp3" },
|
||||
{ name: "吉他与诗", path: "/music/guitar_poem.mp3" },
|
||||
{ name: "民谣故事", path: "/music/folk_story.mp3" },
|
||||
{ name: "城市民谣", path: "/music/city_folk.mp3" },
|
||||
{ name: "民谣之声", path: "/music/folk_voice.mp3" },
|
||||
{ name: "木吉他旋律", path: "/music/acoustic_melody.mp3" },
|
||||
],
|
||||
name: "光耀华夏",
|
||||
path: "光耀华夏.mp3",
|
||||
tags: ["江湖", "影视配乐", "相思", "在路上", "流行金曲"],
|
||||
},
|
||||
{
|
||||
tag: "摇滚",
|
||||
songs: [
|
||||
{ name: "摇滚精神", path: "/music/rock_spirit.mp3" },
|
||||
{ name: "电吉他之声", path: "/music/electric_guitar.mp3" },
|
||||
{ name: "摇滚革命", path: "/music/rock_revolution.mp3" },
|
||||
{ name: "硬摇滚", path: "/music/hard_rock.mp3" },
|
||||
{ name: "摇滚青春", path: "/music/rock_youth.mp3" },
|
||||
{ name: "摇滚传奇", path: "/music/rock_legend.mp3" },
|
||||
],
|
||||
name: "广州",
|
||||
path: "广州.mp3",
|
||||
tags: ["浪漫", "在路上", "甜蜜时光"],
|
||||
},
|
||||
{
|
||||
tag: "古风",
|
||||
songs: [
|
||||
{ name: "千年之约", path: "/music/thousand_year_promise.mp3" },
|
||||
{ name: "墨香古韵", path: "/music/ink_ancient_rhyme.mp3" },
|
||||
{ name: "青丝白发", path: "/music/black_white_hair.mp3" },
|
||||
{ name: "琴瑟和鸣", path: "/music/instruments_harmony.mp3" },
|
||||
{ name: "长安忆", path: "/music/changan_memory.mp3" },
|
||||
{ name: "山水清音", path: "/music/landscape_sound.mp3" },
|
||||
],
|
||||
name: "蝴蝶与坦克",
|
||||
path: "蝴蝶与坦克.mp3",
|
||||
tags: ["星际漫游", "幻想曲", "赛博心跳", "赛博空间", "节奏大师", "快乐节拍", "自由鼓点"],
|
||||
},
|
||||
{
|
||||
tag: "去旅行",
|
||||
songs: [
|
||||
{ name: "旅行的意义", path: "/music/travel_meaning.mp3" },
|
||||
{ name: "背包客", path: "/music/backpacker.mp3" },
|
||||
{ name: "远方的呼唤", path: "/music/distant_call.mp3" },
|
||||
{ name: "旅途中", path: "/music/on_journey.mp3" },
|
||||
{ name: "出发吧", path: "/music/lets_go.mp3" },
|
||||
],
|
||||
name: "加速心跳",
|
||||
path: "加速心跳.mp3",
|
||||
tags: ["幻想曲", "运动健身", "节奏大师", "快乐节拍"],
|
||||
},
|
||||
{
|
||||
tag: "在路上",
|
||||
songs: [
|
||||
{ name: "公路之歌", path: "/music/highway_song.mp3" },
|
||||
{ name: "一路向前", path: "/music/forward.mp3" },
|
||||
{ name: "旅途风景", path: "/music/journey_scenery.mp3" },
|
||||
{ name: "在路上", path: "/music/on_the_road.mp3" },
|
||||
{ name: "行走的力量", path: "/music/walking_power.mp3" },
|
||||
],
|
||||
name: "脚步写下自由",
|
||||
path: "脚步写下自由.mp3",
|
||||
tags: ["开心到飞起", "微风轻轻吹", "解压宣泄", "通勤路上"],
|
||||
},
|
||||
{
|
||||
tag: "学习BGM",
|
||||
songs: [
|
||||
{ name: "专注时刻", path: "/music/focus_moment.mp3" },
|
||||
{ name: "学习氛围", path: "/music/study_atmosphere.mp3" },
|
||||
{ name: "思考空间", path: "/music/thinking_space.mp3" },
|
||||
{ name: "安静阅读", path: "/music/quiet_reading.mp3" },
|
||||
{ name: "效率提升", path: "/music/efficiency_improvement.mp3" },
|
||||
],
|
||||
name: "经纬线",
|
||||
path: "经纬线.mp3",
|
||||
tags: ["温柔", "温柔女声", "民谣", "悲伤的角落", "助眠放松"],
|
||||
},
|
||||
{
|
||||
tag: "运动健身",
|
||||
songs: [
|
||||
{ name: "热血沸腾", path: "/music/hot_blood.mp3" },
|
||||
{ name: "健身节奏", path: "/music/fitness_rhythm.mp3" },
|
||||
{ name: "运动激情", path: "/music/sports_passion.mp3" },
|
||||
{ name: "跑步节拍", path: "/music/running_beat.mp3" },
|
||||
{ name: "力量训练", path: "/music/strength_training.mp3" },
|
||||
{ name: "健身房热曲", path: "/music/gym_hot_song.mp3" },
|
||||
],
|
||||
name: "旧唱片",
|
||||
path: "旧唱片.mp3",
|
||||
tags: ["爱情", "相思", "约会浪漫", "悲伤的角落"],
|
||||
},
|
||||
{
|
||||
tag: "派对聚会",
|
||||
songs: [
|
||||
{ name: "派对之王", path: "/music/party_king.mp3" },
|
||||
{ name: "聚会舞曲", path: "/music/party_dance.mp3" },
|
||||
{ name: "欢乐时光", path: "/music/happy_time.mp3" },
|
||||
{ name: "派对节奏", path: "/music/party_rhythm.mp3" },
|
||||
{ name: "狂欢之夜", path: "/music/carnival_night.mp3" },
|
||||
{ name: "聚会必备", path: "/music/party_essential.mp3" },
|
||||
],
|
||||
name: "快乐广场舞",
|
||||
path: "快乐广场舞.mp3",
|
||||
tags: ["复古旋律", "节奏大师", "快乐节拍"],
|
||||
},
|
||||
{
|
||||
tag: "约会浪漫",
|
||||
songs: [
|
||||
{ name: "浪漫晚餐", path: "/music/romantic_dinner.mp3" },
|
||||
{ name: "约会之夜", path: "/music/date_night.mp3" },
|
||||
{ name: "烛光晚餐", path: "/music/candle_dinner.mp3" },
|
||||
{ name: "浪漫时刻", path: "/music/romantic_moment.mp3" },
|
||||
{ name: "甜蜜约会", path: "/music/sweet_date.mp3" },
|
||||
],
|
||||
name: "梅雨季",
|
||||
path: "梅雨季.mp3",
|
||||
tags: ["浪漫", "爱情", "悲伤的角落", "民谣", "微风轻轻吹", "去旅行", "在路上", "学习BGM"],
|
||||
},
|
||||
{
|
||||
tag: "旅行路上",
|
||||
songs: [
|
||||
{ name: "旅途风景", path: "/music/journey_scenery.mp3" },
|
||||
{ name: "公路之歌", path: "/music/highway_song.mp3" },
|
||||
{ name: "旅行日记", path: "/music/travel_diary.mp3" },
|
||||
{ name: "异国风情", path: "/music/exotic_style.mp3" },
|
||||
{ name: "旅途中的歌", path: "/music/song_on_journey.mp3" },
|
||||
],
|
||||
name: "人生的过客",
|
||||
path: "人生的过客.mp3",
|
||||
tags: ["民谣", "旅行路上", "微风轻轻吹", "在路上", "专注工作/学习"],
|
||||
},
|
||||
{
|
||||
tag: "助眠放松",
|
||||
songs: [
|
||||
{ name: "深度睡眠", path: "/music/deep_sleep.mp3" },
|
||||
{ name: "轻松入眠", path: "/music/easy_sleep.mp3" },
|
||||
{ name: "安眠曲", path: "/music/lullaby.mp3" },
|
||||
{ name: "夜晚静谧", path: "/music/night_quiet.mp3" },
|
||||
{ name: "舒缓心灵", path: "/music/soothe_mind.mp3" },
|
||||
],
|
||||
name: "殇",
|
||||
path: "殇.mp3",
|
||||
tags: ["复古旋律", "相思", "江湖"],
|
||||
},
|
||||
{
|
||||
tag: "专注工作/学习",
|
||||
songs: [
|
||||
{ name: "专注时刻", path: "/music/focus_moment.mp3" },
|
||||
{ name: "高效工作", path: "/music/efficient_work.mp3" },
|
||||
{ name: "思维空间", path: "/music/thinking_space.mp3" },
|
||||
{ name: "学习氛围", path: "/music/study_atmosphere.mp3" },
|
||||
{ name: "专注力提升", path: "/music/focus_improvement.mp3" },
|
||||
],
|
||||
name: "深夜咖啡馆",
|
||||
path: "深夜咖啡馆.mp3",
|
||||
tags: ["浪漫", "爱情", "相思", "悲伤的角落", "助眠放松", "通勤路上"],
|
||||
},
|
||||
{
|
||||
tag: "通勤路上",
|
||||
songs: [
|
||||
{ name: "早晨通勤", path: "/music/morning_commute.mp3" },
|
||||
{ name: "城市节奏", path: "/music/city_rhythm.mp3" },
|
||||
{ name: "地铁之声", path: "/music/subway_sound.mp3" },
|
||||
{ name: "公交旅程", path: "/music/bus_journey.mp3" },
|
||||
{ name: "上下班音乐", path: "/music/commute_music.mp3" },
|
||||
],
|
||||
name: "世界在转动",
|
||||
path: "世界在转动.mp3",
|
||||
tags: ["温柔", "阳光正好", "解压宣泄", "甜蜜时光"],
|
||||
},
|
||||
{
|
||||
tag: "解压宣泄",
|
||||
songs: [
|
||||
{ name: "压力释放", path: "/music/pressure_release.mp3" },
|
||||
{ name: "情绪宣泄", path: "/music/emotion_vent.mp3" },
|
||||
{ name: "怒吼一声", path: "/music/roar.mp3" },
|
||||
{ name: "释放自我", path: "/music/release_self.mp3" },
|
||||
{ name: "压力消除", path: "/music/pressure_elimination.mp3" },
|
||||
],
|
||||
name: "她说",
|
||||
path: "她说.mp3",
|
||||
tags: ["悲伤的角落", "温柔女声", "青草香"],
|
||||
},
|
||||
{
|
||||
tag: "生日祝福",
|
||||
songs: [
|
||||
{ name: "生日快乐", path: "/music/happy_birthday.mp3" },
|
||||
{ name: "温馨祝福", path: "/music/warm_blessing.mp3" },
|
||||
{ name: "生日派对", path: "/music/birthday_party.mp3" },
|
||||
{ name: "祝福之歌", path: "/music/blessing_song.mp3" },
|
||||
{ name: "幸福时刻", path: "/music/happy_moment.mp3" },
|
||||
],
|
||||
name: "天平行者",
|
||||
path: "天平行者 .mp3",
|
||||
tags: ["生日祝福"],
|
||||
},
|
||||
{
|
||||
tag: "影视配乐",
|
||||
songs: [
|
||||
{ name: "电影主题", path: "/music/movie_theme.mp3" },
|
||||
{ name: "剧情转折", path: "/music/plot_twist.mp3" },
|
||||
{ name: "情感渲染", path: "/music/emotion_rendering.mp3" },
|
||||
{ name: "史诗场景", path: "/music/epic_scene.mp3" },
|
||||
{ name: "温情时刻", path: "/music/warm_moment.mp3" },
|
||||
],
|
||||
name: "跳楼机-上班版",
|
||||
path: "跳楼机-上班版.MP3",
|
||||
tags: ["专注工作/学习", "通勤路上", "解压宣泄"],
|
||||
},
|
||||
{
|
||||
tag: "绘本音乐",
|
||||
songs: [
|
||||
{ name: "童话世界", path: "/music/fairy_tale_world.mp3" },
|
||||
{ name: "绘本旋律", path: "/music/picture_book_melody.mp3" },
|
||||
{ name: "想象空间", path: "/music/imagination_space.mp3" },
|
||||
{ name: "童年回忆", path: "/music/childhood_memory.mp3" },
|
||||
{ name: "故事音乐", path: "/music/story_music.mp3" },
|
||||
],
|
||||
name: "童年时光机",
|
||||
path: "童年时光机.mp3",
|
||||
tags: ["快乐节拍", "生日祝福", "绘本音乐"],
|
||||
},
|
||||
{
|
||||
name: "无题",
|
||||
path: "无题.mp3",
|
||||
tags: ["节奏大师", "自由鼓点", "幻想曲", "纯音乐"],
|
||||
},
|
||||
{
|
||||
name: "五星闪耀(青春)",
|
||||
path: "五星闪耀(青春).mp3",
|
||||
tags: ["专注工作/学习", "快乐节拍", "学习BGM"],
|
||||
},
|
||||
{
|
||||
name: "吸烟区",
|
||||
path: "吸烟区.mp3",
|
||||
tags: ["通勤路上", "运动健身", "自由摇摆"],
|
||||
},
|
||||
{
|
||||
name: "下一站旅行",
|
||||
path: "下一站旅行.MP3",
|
||||
tags: ["旅行路上", "微风轻轻吹"],
|
||||
},
|
||||
{
|
||||
name: "尊重·成长·共赢",
|
||||
path: "尊重·成长·共赢.mp3",
|
||||
tags: ["派对聚会", "节奏大师"],
|
||||
},
|
||||
{
|
||||
name: "Phantom in the Code",
|
||||
path: "Phantom in the Code.mp3",
|
||||
tags: ["彩虹泡泡", "温柔女声", "影视配乐"],
|
||||
},
|
||||
{
|
||||
name: "We are family",
|
||||
path: "We are family.MP3",
|
||||
tags: ["通勤路上", "在路上", "派对聚会"],
|
||||
},
|
||||
{
|
||||
name: "班味退散",
|
||||
path: "班味退散.MP3",
|
||||
tags: ["解压宣泄", "通勤路上", "开心到飞起", "自由摇摆"],
|
||||
},
|
||||
]; // 提取 tags 数组
|
||||
|
||||
// 执行转换
|
||||
tagsData = transformMusicData(tagsData);
|
||||
|
||||
console.log(tagsData);
|
||||
|
||||
const redCount = Math.min(5, tagsData.length);
|
||||
const redIndexes = [];
|
||||
while (redIndexes.length < redCount) {
|
||||
@@ -446,10 +288,13 @@ const search = createApp({
|
||||
|
||||
tagsFill.value = tagAll;
|
||||
|
||||
bubbleContainer?.[0]?.destroy();
|
||||
bubbleContainerFill?.[0]?.destroy();
|
||||
|
||||
nextTick(() => {
|
||||
const { containerWidth, containerHeight } = getContainerDimensions();
|
||||
|
||||
tagCloud({
|
||||
|
||||
bubbleContainerFill = tagCloud({
|
||||
selector: "#bubbleContainerFill", // 元素选择器,id 或 class
|
||||
radius: [containerWidth / 2, containerHeight / 2], // 滚动横/纵轴半径, 默认60,单位px,取值60,[60],[60, 60]
|
||||
mspeed: "normal", // 滚动最大速度, 取值: slow, normal(默认), fast
|
||||
@@ -459,7 +304,7 @@ const search = createApp({
|
||||
multicolour: false, // 彩色字体,颜色随机,取值:true(默认),false
|
||||
});
|
||||
|
||||
tagCloud({
|
||||
bubbleContainer = tagCloud({
|
||||
selector: "#bubbleContainer", // 元素选择器,id 或 class
|
||||
radius: [containerWidth / 2, containerHeight / 2],
|
||||
mspeed: "normal",
|
||||
@@ -471,6 +316,36 @@ const search = createApp({
|
||||
});
|
||||
};
|
||||
|
||||
const transformMusicData = (data) => {
|
||||
// 使用Map存储标签和对应的歌曲
|
||||
const tagMap = new Map();
|
||||
|
||||
// 遍历每首歌
|
||||
data.forEach((song) => {
|
||||
// 遍历当前歌曲的所有标签
|
||||
song.tags.forEach((tag) => {
|
||||
// 准备歌曲信息(仅包含name和path)
|
||||
const songInfo = {
|
||||
name: song.name,
|
||||
path: song.path,
|
||||
};
|
||||
|
||||
// 如果标签已存在于Map中,添加歌曲;否则创建新条目
|
||||
if (tagMap.has(tag)) {
|
||||
tagMap.get(tag).push(songInfo);
|
||||
} else {
|
||||
tagMap.set(tag, [songInfo]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 将Map转换为目标格式的数组
|
||||
return Array.from(tagMap).map(([tag, songs]) => ({
|
||||
tag,
|
||||
songs,
|
||||
}));
|
||||
};
|
||||
|
||||
// 生成单次随机结果的函数
|
||||
const getRandomOutcome = () => {
|
||||
const random = Math.random(); // 生成0-1之间的随机数
|
||||
@@ -488,6 +363,10 @@ const search = createApp({
|
||||
onMounted(() => {
|
||||
init();
|
||||
|
||||
window.addEventListener("resize", () => {
|
||||
init();
|
||||
});
|
||||
|
||||
// 添加进度更新事件监听器
|
||||
if (audioPlayer.value) {
|
||||
volume.value = audioPlayer.value.volume * 100;
|
||||
@@ -512,9 +391,9 @@ const search = createApp({
|
||||
|
||||
const audioPlayer = ref(null);
|
||||
|
||||
const clickSongs = (songs) => {
|
||||
const clickSongs = (tag, songs) => {
|
||||
const randomIndex = Math.floor(Math.random() * songs.length);
|
||||
const item = songs[randomIndex];
|
||||
const item = { ...songs[randomIndex], tag };
|
||||
manageAudio(item);
|
||||
};
|
||||
|
||||
@@ -523,11 +402,10 @@ const search = createApp({
|
||||
const audio = audioPlayer.value;
|
||||
closeAll();
|
||||
setTimeout(() => {
|
||||
console.log("item", item);
|
||||
if (audio?.src != item.path) audio.src = item.path;
|
||||
audio.src = "https://app.gter.net/image/miniApp/mp3/1.mp3";
|
||||
// audio.src = "/static/mp3/1.MP3";
|
||||
if (audio?.src != item.path) audio.src = `./static/mp3/station/${item.path}`;
|
||||
audio.play().then(() => (playData.value = { ...item, state: true }));
|
||||
|
||||
console.log("playData.value", playData.value);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
@@ -638,25 +516,21 @@ const search = createApp({
|
||||
durationFormatted.value = formatTime(duration);
|
||||
};
|
||||
|
||||
// 快进 和 后退 10秒
|
||||
// 切换下一首 或 上一首
|
||||
const fastForward = (type = "fast") => {
|
||||
if (!audioPlayer.value) return;
|
||||
console.log("playData.value", playData.value);
|
||||
|
||||
const src = playData.value?.path || "";
|
||||
tags.value.forEach((item) => {
|
||||
if (item.tag == playData.value.tag) {
|
||||
const songs = item.songs || [];
|
||||
const index = songs.findIndex((song) => song.name == playData.value.name);
|
||||
// 通过下标 type = "fast" 为下一首 否则为上一首 并且需要轮回播放
|
||||
const newIndex = type == "fast" ? (index + 1) % songs.length : (index - 1 + songs.length) % songs.length;
|
||||
|
||||
if (audioPlayer.value.src != src) {
|
||||
manageAudio(playData.value);
|
||||
return;
|
||||
}
|
||||
|
||||
let currentTime = audioPlayer.value.currentTime || 0;
|
||||
const duration = audioPlayer.value.duration || 0;
|
||||
let newTime = 0;
|
||||
if (type == "fast") newTime = Math.min(currentTime + 10, duration);
|
||||
else newTime = Math.max(currentTime - 10, 0);
|
||||
audioPlayer.value.currentTime = newTime;
|
||||
getProgress();
|
||||
const data = { ...songs[newIndex], tag: item.tag };
|
||||
manageAudio(data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 关闭所有播放
|
||||
@@ -704,7 +578,6 @@ const search = createApp({
|
||||
// 获取音量进度条元素
|
||||
const progressBar = document.querySelector(".bottom-play .bottom-middle .progress-bar");
|
||||
if (!progressBar) return;
|
||||
console.log("14111111111");
|
||||
|
||||
const rect = progressBar.getBoundingClientRect();
|
||||
|
||||
|
||||
162
未命名 (4).html
Normal file
162
未命名 (4).html
Normal file
@@ -0,0 +1,162 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Chrome 原生 API 屏幕录制</title>
|
||||
<style>
|
||||
.control-panel { margin: 20px 0; }
|
||||
button { padding: 8px 16px; margin-right: 10px; cursor: pointer; }
|
||||
#preview { border: 1px solid #ccc; width: 800px; height: 450px; margin: 10px 0; }
|
||||
.status { color: #666; margin: 10px 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="control-panel">
|
||||
<button id="startBtn">开始录制</button>
|
||||
<button id="pauseBtn" disabled>暂停录制</button>
|
||||
<button id="resumeBtn" disabled>继续录制</button>
|
||||
<button id="stopBtn" disabled>停止录制</button>
|
||||
</div>
|
||||
<div class="status" id="status">状态:未开始</div>
|
||||
<video id="preview" autoplay muted></video>
|
||||
|
||||
<script>
|
||||
// 核心变量
|
||||
let mediaStream = null; // 屏幕捕获流
|
||||
let mediaRecorder = null; // 录制器实例
|
||||
let recordedChunks = []; // 录制的视频数据块
|
||||
let isPaused = false; // 录制暂停状态
|
||||
|
||||
// DOM 元素
|
||||
const startBtn = document.getElementById('startBtn');
|
||||
const pauseBtn = document.getElementById('pauseBtn');
|
||||
const resumeBtn = document.getElementById('resumeBtn');
|
||||
const stopBtn = document.getElementById('stopBtn');
|
||||
const preview = document.getElementById('preview');
|
||||
const status = document.getElementById('status');
|
||||
|
||||
// 1. 开始录制:捕获屏幕流 + 初始化录制器
|
||||
startBtn.addEventListener('click', async () => {
|
||||
try {
|
||||
// 步骤1:请求屏幕捕获权限(用户选择录制范围:全屏/窗口/标签页)
|
||||
mediaStream = await navigator.mediaDevices.getDisplayMedia({
|
||||
video: {
|
||||
cursor: 'always', // 显示鼠标光标(可选:never/hidden)
|
||||
frameRate: { ideal: 30, max: 60 } // 录制帧率(理想30帧,最大60帧)
|
||||
},
|
||||
audio: true // 同时捕获系统音频(需浏览器支持,Chrome需开启实验性功能)
|
||||
});
|
||||
|
||||
// 步骤2:绑定流到预览窗口
|
||||
preview.srcObject = mediaStream;
|
||||
|
||||
// 步骤3:初始化 MediaRecorder(指定录制格式为webm,Chrome 默认支持)
|
||||
const options = {
|
||||
mimeType: 'video/webm; codecs=vp9', // 推荐vp9编码(体积小、画质好)
|
||||
// 可选:设置码率(根据需求调整,越高画质越好但体积越大)
|
||||
// videoBitsPerSecond: 2500000 // 2.5Mbps
|
||||
};
|
||||
mediaRecorder = new MediaRecorder(mediaStream, options);
|
||||
|
||||
// 步骤4:监听录制数据(每块数据存入数组)
|
||||
mediaRecorder.ondataavailable = (e) => {
|
||||
if (e.data.size > 0) {
|
||||
recordedChunks.push(e.data);
|
||||
}
|
||||
};
|
||||
|
||||
// 步骤5:监听录制结束(自动下载视频)
|
||||
mediaRecorder.onstop = () => {
|
||||
// 合并数据块为 Blob 视频文件
|
||||
const blob = new Blob(recordedChunks, { type: 'video/webm' });
|
||||
// 生成视频下载链接
|
||||
const videoUrl = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = videoUrl;
|
||||
a.download = `录制视频_${new Date().getTime()}.webm`;
|
||||
a.click();
|
||||
// 释放资源
|
||||
URL.revokeObjectURL(videoUrl);
|
||||
recordedChunks = [];
|
||||
|
||||
// 重置状态
|
||||
resetRecordingState();
|
||||
status.textContent = '状态:录制已停止,视频已下载';
|
||||
};
|
||||
|
||||
// 步骤6:启动录制
|
||||
mediaRecorder.start(1000); // 每1秒生成一个数据块(可选)
|
||||
status.textContent = '状态:正在录制...';
|
||||
|
||||
// 更新按钮状态
|
||||
startBtn.disabled = true;
|
||||
pauseBtn.disabled = false;
|
||||
stopBtn.disabled = false;
|
||||
|
||||
// 监听流结束(用户手动关闭捕获窗口)
|
||||
mediaStream.getTracks().forEach(track => {
|
||||
track.addEventListener('ended', () => {
|
||||
if (mediaRecorder.state !== 'inactive') {
|
||||
mediaRecorder.stop();
|
||||
}
|
||||
status.textContent = '状态:用户终止了屏幕捕获';
|
||||
resetRecordingState();
|
||||
});
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('录制启动失败:', error);
|
||||
status.textContent = `状态:启动失败 - ${error.message}`;
|
||||
resetRecordingState();
|
||||
}
|
||||
});
|
||||
|
||||
// 2. 暂停录制
|
||||
pauseBtn.addEventListener('click', () => {
|
||||
if (mediaRecorder.state === 'recording') {
|
||||
mediaRecorder.pause();
|
||||
isPaused = true;
|
||||
status.textContent = '状态:录制已暂停';
|
||||
pauseBtn.disabled = true;
|
||||
resumeBtn.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
// 3. 继续录制
|
||||
resumeBtn.addEventListener('click', () => {
|
||||
if (mediaRecorder.state === 'paused') {
|
||||
mediaRecorder.resume();
|
||||
isPaused = false;
|
||||
status.textContent = '状态:正在录制...';
|
||||
pauseBtn.disabled = false;
|
||||
resumeBtn.disabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
// 4. 停止录制
|
||||
stopBtn.addEventListener('click', () => {
|
||||
if (mediaRecorder.state !== 'inactive') {
|
||||
// 停止录制器
|
||||
mediaRecorder.stop();
|
||||
// 停止所有流轨道(释放屏幕捕获)
|
||||
mediaStream.getTracks().forEach(track => track.stop());
|
||||
status.textContent = '状态:正在处理视频...';
|
||||
}
|
||||
});
|
||||
|
||||
// 辅助函数:重置录制状态
|
||||
function resetRecordingState() {
|
||||
mediaStream = null;
|
||||
mediaRecorder = null;
|
||||
isPaused = false;
|
||||
preview.srcObject = null;
|
||||
|
||||
// 重置按钮
|
||||
startBtn.disabled = false;
|
||||
pauseBtn.disabled = true;
|
||||
resumeBtn.disabled = true;
|
||||
stopBtn.disabled = true;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user