refactor(播放器): 优化音频播放逻辑和学生切换功能
- 重构音频播放管理逻辑,简化播放状态控制 - 改进学生切换功能,使用索引代替顺序号 - 移除冗余代码,优化音量控制实现 - 调整CSS布局样式,增强页面展示效果
This commit is contained in:
14
index.html
14
index.html
@@ -57,7 +57,7 @@
|
||||
<img class="bj bj1" src="./static/img/album-bj1.svg" />
|
||||
<img class="bj bj2" src="./static/img/album-bj2.svg" />
|
||||
<div class="album-box" ref="albumBoxRef">
|
||||
<div class="item" v-for="(item, index) in bannerList" :key="index" @click="openPreview(item.id, item.img)">
|
||||
<div class="item" v-for="(item, index) in bannerList" :key="index" @click="openPreview(item.id)">
|
||||
<img class="img" :src="item.img" />
|
||||
<img class="bj bj3" src="./static/img/album-bj3.svg" />
|
||||
<img class="bj bj4" src="./static/img/album-bj4.png" />
|
||||
@@ -68,7 +68,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="trait flexflex mar1200">
|
||||
<div class="item flexflex flex1" v-for="(item, index) in trait" :key="index">
|
||||
<div class="item flexflex" v-for="(item, index) in trait" :key="index">
|
||||
<img class="icon" :src="item.icon" />
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div class="text">{{ item.text }}</div>
|
||||
@@ -99,7 +99,7 @@
|
||||
<div class="time">{{ item.date }}</div>
|
||||
</div>
|
||||
|
||||
<div class="media" @click="openPreview(item.id, item.img)">
|
||||
<div class="media" @click="openPreview(item.id)">
|
||||
<img class="img" :src="item.img" />
|
||||
<img class="play" src="./static/img/play-white-icon.svg" />
|
||||
</div>
|
||||
@@ -119,7 +119,7 @@
|
||||
<div class="name">{{ item.title }}</div>
|
||||
<div class="subtitle">{{ item.desc }}</div>
|
||||
<div class="time">{{ item.date }}</div>
|
||||
<div class="progress-bar flexacenter">
|
||||
<div class="progress-bar flexacenter" @click="handleBarDragBottomClick">
|
||||
<div class="bar white" :style="{ width: item.progress + '%' }"></div>
|
||||
<div class="bar black flex1"></div>
|
||||
</div>
|
||||
@@ -145,7 +145,7 @@
|
||||
<div class="info flexflex">
|
||||
<div class="name">{{ item.title }}</div>
|
||||
<div class="lyric">{{ item.desc }}</div>
|
||||
<div class="progress-bar flexacenter">
|
||||
<div class="progress-bar flexacenter" @click="handleBarDragBottomClick">
|
||||
<div class="bar white" :style="{ width: item.progress + '%' }"></div>
|
||||
<div class="bar black flex1"></div>
|
||||
</div>
|
||||
@@ -172,7 +172,7 @@
|
||||
<div class="student-box flexflex">
|
||||
<img class="title" src="./static/img/student-title.png" alt="" />
|
||||
<div class="list flexacenter">
|
||||
<img class="img" :class="[`img${ item.order }`]" v-for="(item, index) in studentList" :src="item.img" :key="index" @click="cutStudent(item.order)" />
|
||||
<img class="img" :class="[`img${ item.order }`]" v-for="(item, index) in studentList" :src="item.img" :key="index" @click="cutStudent(index, item.order)" />
|
||||
</div>
|
||||
<div class="name">《{{ zeroOrderStudents.title }}》</div>
|
||||
<div class="info flexacenter">
|
||||
@@ -180,7 +180,7 @@
|
||||
{{ zeroOrderStudents.name }} | {{ zeroOrderStudents.age }}岁 | {{ zeroOrderStudents.city }}
|
||||
</div>
|
||||
|
||||
<div class="progress-bar flexacenter">
|
||||
<div class="progress-bar flexacenter" @click="handleBarDragBottomClick">
|
||||
<div class="bar white" :style="{ width: zeroOrderStudents.progress + '%' }"></div>
|
||||
<div class="bar black flex1"></div>
|
||||
</div>
|
||||
|
||||
@@ -224,6 +224,7 @@
|
||||
.content .introduce .trait {
|
||||
background-color: #ffffff;
|
||||
height: 420px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.content .introduce .trait .item {
|
||||
padding-top: 98px;
|
||||
@@ -244,7 +245,7 @@
|
||||
margin-bottom: 42px;
|
||||
}
|
||||
.content .introduce .trait .item .text {
|
||||
width: 266px;
|
||||
width: 270px;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
.trait {
|
||||
background-color: #ffffff;
|
||||
height: 420px;
|
||||
|
||||
justify-content: space-between;
|
||||
.item {
|
||||
padding-top: 98px;
|
||||
flex-direction: column;
|
||||
@@ -276,7 +276,7 @@
|
||||
}
|
||||
|
||||
.text {
|
||||
width: 266px;
|
||||
width: 270px;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
|
||||
@@ -64,7 +64,9 @@ const search = createApp({
|
||||
if (item.playurl == src) item.progress = val;
|
||||
});
|
||||
|
||||
if (zeroOrderStudents.value?.playurl == src) zeroOrderStudents.value["progress"] = val;
|
||||
if (zeroOrderStudents.value?.playurl == src) {
|
||||
zeroOrderStudents.value["progress"] = val;
|
||||
}
|
||||
};
|
||||
|
||||
const introduceRef = ref(null);
|
||||
@@ -108,6 +110,7 @@ const search = createApp({
|
||||
|
||||
const init = () => {
|
||||
ajax("https://pujianchaoyin.com/api/getHomeData").then((res) => {
|
||||
// ajax("https://pujianchaoyin.com/index/api").then((res) => {
|
||||
if (res.code != 200) return;
|
||||
const data = res.data;
|
||||
console.log("data", data);
|
||||
@@ -136,7 +139,9 @@ const search = createApp({
|
||||
};
|
||||
|
||||
let bannerSwiperTimer = null;
|
||||
// 头部轮播图 定时器
|
||||
const bannerSwiper = () => {
|
||||
clearTimeout(bannerSwiperTimer);
|
||||
bannerSwiperTimer = setTimeout(() => {
|
||||
let index = pointerIndex.value + 1;
|
||||
if (index > bannerList.value.length - 1) index = 0;
|
||||
@@ -145,6 +150,7 @@ const search = createApp({
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
// 头部轮播图 - 切换 定时器
|
||||
const changeInterval = (type) => {
|
||||
if (type) clearTimeout(bannerSwiperTimer);
|
||||
else bannerSwiper();
|
||||
@@ -172,7 +178,7 @@ const search = createApp({
|
||||
|
||||
let art = null;
|
||||
// 开启播放 MV
|
||||
const openPreview = (id, poster = "") => {
|
||||
const openPreview = (id) => {
|
||||
ajax("https://pujianchaoyin.com/api/getMvDetail", {
|
||||
id,
|
||||
}).then((res) => {
|
||||
@@ -180,12 +186,13 @@ const search = createApp({
|
||||
const data = res.data;
|
||||
|
||||
previewState.value = true;
|
||||
|
||||
nextTick(() => {
|
||||
art = new Artplayer({
|
||||
container: ".artplayer-app",
|
||||
url: data.playurl,
|
||||
autoplay: true,
|
||||
poster,
|
||||
poster: data.img || "",
|
||||
fullscreen: true,
|
||||
});
|
||||
art.play();
|
||||
@@ -220,13 +227,16 @@ const search = createApp({
|
||||
getProgress();
|
||||
};
|
||||
|
||||
// 播放 组件数据
|
||||
let playData = ref(null);
|
||||
|
||||
// 管理音频播放
|
||||
const manageAudio = (src, area) => {
|
||||
const audio = audioPlayer.value;
|
||||
closeAll();
|
||||
nextTick(() => {
|
||||
if (audio?.src != src) audio.src = src;
|
||||
console.log("audio", audio);
|
||||
|
||||
audio.play().then(() => {
|
||||
if (area == "works") {
|
||||
@@ -262,6 +272,7 @@ const search = createApp({
|
||||
manageAudio(playurl, area);
|
||||
};
|
||||
|
||||
// 关闭所有播放
|
||||
const closeAll = () => {
|
||||
audioPlayer.value.pause();
|
||||
|
||||
@@ -275,46 +286,44 @@ const search = createApp({
|
||||
|
||||
zeroOrderStudents.value["state"] = false;
|
||||
|
||||
console.log("playData", playData);
|
||||
|
||||
playData.value && (playData.value.state = false);
|
||||
};
|
||||
|
||||
// 定制音乐 数据
|
||||
let customList = ref([]);
|
||||
|
||||
let studentIndex = ref(0);
|
||||
let zeroOrderStudents = ref({});
|
||||
let studentList = ref([]); // 学生数据
|
||||
let studentIndex = ref(0); // 学生下标
|
||||
let zeroOrderStudents = ref({}); // 学生 选中播放 数据
|
||||
|
||||
let studentList = ref([]);
|
||||
|
||||
const cutStudent = (order) => {
|
||||
// 切换学生 播放
|
||||
const cutStudent = (index) => {
|
||||
// 找到目标元素和第一个元素
|
||||
const [target, first] = [studentList.value.find((item) => item.order == order), studentList.value.find((item) => item.order == 0)];
|
||||
const [target, first] = [studentList.value[index], studentList.value.find((item) => item.order == 0)];
|
||||
// 交换order值
|
||||
if (target && first && target !== first) [target.order, first.order] = [first.order, target.order];
|
||||
|
||||
console.log("studentList.value", studentList.value);
|
||||
|
||||
zeroOrderStudents.value = target;
|
||||
|
||||
studentIndex.value = index;
|
||||
target.playurl ? manageAudio(target.playurl, "student") : getPlayUrl(0, "student");
|
||||
};
|
||||
|
||||
// 响应式数据:音量值、是否静音
|
||||
const volume = ref(84);
|
||||
const isMuted = ref(false);
|
||||
// 切换学生 歌曲 上\下一首
|
||||
const cutSong = (type) => {
|
||||
const listLength = studentList.value.length;
|
||||
const index = studentIndex.value;
|
||||
let newIndex = 0;
|
||||
|
||||
// 切换静音状态的方法
|
||||
const toggleMute = () => {
|
||||
isMuted.value = !isMuted.value;
|
||||
if (audioPlayer.value) {
|
||||
audioPlayer.value.muted = isMuted.value;
|
||||
}
|
||||
if (type === "up") newIndex = index - 1 < 0 ? listLength - 1 : index - 1;
|
||||
else if (type === "down") newIndex = index + 1 >= listLength ? 0 : index + 1;
|
||||
cutStudent(newIndex);
|
||||
};
|
||||
|
||||
// 响应式数据:音量值、是否静音
|
||||
let volume = ref(100);
|
||||
|
||||
// 计算并设置音量百分比
|
||||
const setVolumePercentage = (percentage) => {
|
||||
// 确保百分比在0-100之间
|
||||
const volumePercent = Math.max(0, Math.min(100, percentage));
|
||||
volume.value = Math.abs(~~volumePercent);
|
||||
|
||||
@@ -328,11 +337,8 @@ const search = createApp({
|
||||
const progressBar = event.currentTarget;
|
||||
const rect = progressBar.getBoundingClientRect();
|
||||
|
||||
// 计算点击位置相对于进度条的比例
|
||||
// 因为是垂直进度条,所以用clientY
|
||||
const clickPosition = rect.bottom - event.clientY;
|
||||
const percentage = (clickPosition / rect.height) * 100;
|
||||
console.log("percentage", percentage);
|
||||
|
||||
setVolumePercentage(percentage);
|
||||
};
|
||||
@@ -436,6 +442,7 @@ const search = createApp({
|
||||
document.removeEventListener("mouseup", stopBarDragBottom);
|
||||
};
|
||||
|
||||
// 直接点击进度条 跳转
|
||||
const handleBarDragBottomClick = (event) => {
|
||||
// 获取进度条元素
|
||||
const progressBar = event.currentTarget;
|
||||
@@ -476,11 +483,9 @@ const search = createApp({
|
||||
};
|
||||
|
||||
const getPlayUrl = (index, area) => {
|
||||
console.log("index", index);
|
||||
let id = null;
|
||||
if (area == "student") {
|
||||
const item = zeroOrderStudents.value;
|
||||
console.log("item", item.id);
|
||||
id = item.id;
|
||||
}
|
||||
|
||||
@@ -489,31 +494,14 @@ const search = createApp({
|
||||
}).then((res) => {
|
||||
if (res.code != 200) return;
|
||||
const data = res.data;
|
||||
console.log("data", data);
|
||||
|
||||
zeroOrderStudents.value = { ...data, ...zeroOrderStudents.value };
|
||||
|
||||
manageAudio(data.playurl, area);
|
||||
|
||||
console.log(zeroOrderStudents.value, "zeroOrderStudents");
|
||||
if (area == "student") {
|
||||
zeroOrderStudents.value = { ...data, ...zeroOrderStudents.value };
|
||||
manageAudio(data.playurl, area);
|
||||
console.log(zeroOrderStudents.value, "zeroOrderStudents");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const cutSong = (type, order) => {
|
||||
const listLength = studentList.value.length;
|
||||
let newOrder = 0;
|
||||
|
||||
if (type === "up") {
|
||||
// 上一首:order减1,如果小于0则设置为列表最后一个元素的order
|
||||
newOrder = order - 1 < 0 ? listLength - 1 : order - 1;
|
||||
} else if (type === "down") {
|
||||
// 下一首:order加1,如果大于等于列表长度则设置为0
|
||||
newOrder = order + 1 >= listLength ? 0 : order + 1;
|
||||
}
|
||||
|
||||
cutStudent(newOrder);
|
||||
};
|
||||
|
||||
return { cutSong, getPlayUrl, handleBarDragBottomClick, startBarDragBottom, volumeShow, handleVolumeHide, handleVolumeShow, zeroOrderStudents, rePlay, playData, awardAudioList, changeInterval, awardMVList, bannerList, albumBoxRef, volume, handleVolumeClick, handleVolumeDrag, startDrag, stopDrag, toggleMute, isMuted, 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 };
|
||||
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 };
|
||||
},
|
||||
}).mount("#appIndex");
|
||||
|
||||
Reference in New Issue
Block a user