const { createApp, ref, onMounted, nextTick, onUnmounted, computed } = Vue; const search = createApp({ setup() { const trait = [ { icon: "./img/headset-icon.png", title: "音乐创作", text: "朴见潮音,2024 年成立于广州,是专注 AI 音乐领域的创新工作室。短短一年便跻身于AI音乐浪潮先锋品牌!", }, { icon: "./img/mv-icon.png", title: "MV创作", text: "以 AI 技术为核心,整合音乐创作、MV 制作、教学培训、发行级重制等业务,为创作者和爱好者打造一站式平台。", }, { icon: "./img/train-icon.png", title: "教学培训", text: "工作室运用多种 AI 工具,突破传统创作局限,支持流行、摇滚等多元风格创作,满足个性化需求。", }, { icon: "./img/remake-icon.png", title: "发行级重制", text: "构建全流程服务体系,从 AI 音乐创作、MV 视觉呈现,到零基础教学,再到发行级重制提升品质,实现作品价值最大化。", }, ]; const text = `中国AIGC产业联盟(AIGCxChina) 温州市社科联 温州市新闻媒体中心 第一届AI音乐春晚 正选节目`; const audioPlayer = ref(null); const progress = ref(20); // 播放进度百分比 // 更新进度的函数 const getProgress = () => { if (!audioPlayer.value) return; const currentTime = audioPlayer.value.currentTime || 0; const duration = audioPlayer.value.duration || 0; const progress = duration > 0 ? (currentTime / duration) * 100 : 0; setProgress(progress, audioPlayer.value.src); }; const setProgress = (val, src) => { audioList.value.forEach((item) => { if (item.url === src) item.progress = val; }); customList.value.forEach((item) => { if (item.src === src) item.progress = val; }); }; const introduceRef = ref(null); const worksRef = ref(null); const customRef = ref(null); const studentRef = ref(null); let pointerState = ref("introduce"); const elements = ref([ { isVisible: false, ref: introduceRef, title: "介绍", state: "introduce", }, { isVisible: false, ref: worksRef, title: "作品", state: "works", }, { isVisible: false, ref: customRef, title: "定制", state: "custom", }, { isVisible: false, ref: studentRef, title: "学生", state: "student", }, ]); // 点击侧边栏 const changePointer = (state) => { const element = document.querySelector(`.${state}`); if (!element) return; element.scrollIntoView({ behavior: "smooth", }); }; // 向上滚动到上一页 const scrollToPrevious = () => { const currentIndex = ['introduce', 'works', 'custom', 'student'].indexOf(pointerState.value); if (currentIndex > 0) { const prevState = ['introduce', 'works', 'custom', 'student'][currentIndex - 1]; changePointer(prevState); } }; // 向下滚动到下一页 const scrollToNext = () => { const currentIndex = ['introduce', 'works', 'custom', 'student'].indexOf(pointerState.value); if (currentIndex < 3) { const nextState = ['introduce', 'works', 'custom', 'student'][currentIndex + 1]; changePointer(nextState); } }; // 获取当前在可视窗口中的元素ref const visibleRef = computed(() => { const visibleElement = elements.value.find((el) => el.isVisible); return visibleElement ? visibleElement.ref : null; }); const observer = ref(null); // 初始化观察器 const initObserver = () => { observer.value = new IntersectionObserver( (entries) => { entries.forEach((entry) => { // 找到对应的元素状态并更新 const targetEl = elements.value.find((el) => el.ref === entry.target); if (targetEl) { targetEl.isVisible = entry.isIntersecting; if (entry.isIntersecting) pointerState.value = targetEl.state; } }); }, { root: null, // 视口作为根元素 rootMargin: "0px", threshold: 0.3, // 可见比例达到10%时触发 } ); // 开启监听 - 对所有预定义的元素执行observe elements.value.forEach((element) => { if (element.ref && element.ref) observer.value.observe(element.ref); }); console.log(observer.value); }; // 添加元素到监听列表 const addElement = (elRef) => { if (elRef.value) { // 存储元素ref和其可见状态 elements.value.push({ ref: elRef.value, isVisible: false, }); // 开始监听 observer.value?.observe(elRef.value); } }; onMounted(() => { setTimeout(() => { initObserver(); }, 1000); // 添加进度更新事件监听器 if (audioPlayer.value) { audioPlayer.value.addEventListener("timeupdate", getProgress); audioPlayer.value.addEventListener("loadedmetadata", getProgress); } }); // 组件卸载时清理事件监听器 onUnmounted(() => { observer.value?.disconnect(); audioPlayer?.value?.removeEventListener("timeupdate", getProgress); audioPlayer?.value?.removeEventListener("loadedmetadata", getProgress); }); // 头部播放状态 let audioHeadState = ref(false); // 头部播放 - 开启 const playHead = () => { closeAll(); nextTick(() => { audioPlayer.value.src = "./static/mp3/1.MP3"; audioPlayer.value.play().then(() => (audioHeadState.value = true)); }); }; // 头部播放 - 暂停 const pauseHead = () => { audioPlayer.value.pause(); audioHeadState.value = false; }; // 播放 组件状态 let previewState = ref(false); let art = null; // 开启播放 MV const openPreview = () => { previewState.value = true; nextTick(() => { art = new Artplayer({ container: ".artplayer-app", url: "https://o.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-c-JoqdX_qqsgFptxhcq_cQnrlc6Z1CwMUBq_D-81qNDQyOQ~~", autoplay: true, poster: "https://o.x-php.com/thumb/UHkZOgUVDvP9z7rPV2rT1kE22Zf1QEiLggt9OPnf5hC7a-QU5l8VTqiP5awMLv2DMEUiOUl03dK1PW0Yzf8ZPfpa7ZTTgV-PZGNjZQ~~", }); art.play(); }); }; // 关闭播放 MV const closePreview = () => { previewState.value = false; art?.destroy(); art = null; }; let audioList = ref([ { url: "https://app.gter.net/image/miniApp/mp3/1.mp3", }, { url: "https://app.gter.net/image/miniApp/mp3/2.mp3", }, { url: "https://app.gter.net/image/miniApp/mp3/3.mp3", }, { url: "https://app.gter.net/image/miniApp/mp3/4.mp3", }, ]); const playAudio = (index) => { closeAll(); nextTick(() => { let target = audioList.value[index]; const url = target.url; if (audioPlayer.value?.src != url) audioPlayer.value.src = url; audioPlayer.value.play().then(() => { target["state"] = true; }); }); }; const pauseAudio = (index) => { let target = audioList.value[index]; target["state"] = false; audioPlayer.value.pause(); }; // 快进 和 后退 10秒 const fastForward = (type = "fast", src, area) => { if (!audioPlayer.value) return; console.log("src", src, "audioPlayer", audioPlayer.value); if (audioPlayer.value.src != src) { manageAudio(src, area); 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 manageAudio = (src, area) => { const audio = audioPlayer.value; closeAll(); nextTick(() => { if (area == "head") { if (audio?.src != src) audio.src = src; audio.play().then(() => (audioHeadState.value = true)); } if (area == "works") { if (audio?.src != src) audio.src = src; audio.play().then(() => { audioList.value.forEach((item) => { if (item.url == src) item["state"] = true; }); }); } console.log("area", area, src); if (area == "custom") { if (audio?.src != src) audio.src = src; audio.play().then(() => { customList.value.forEach((item) => { if (item.src == src) item["state"] = true; }); }); } }); }; const closeAll = () => { audioPlayer.value.pause(); audioHeadState.value = false; audioList.value.forEach((item) => { item["progress"] = 0; item["state"] = false; }); customList.value.forEach((item) => { item["progress"] = 0; item["state"] = false; }); }; let customList = ref([ { src: "https://app.gter.net/image/miniApp/mp3/1.mp3", }, { src: "https://app.gter.net/image/miniApp/mp3/2.mp3", }, { src: "https://app.gter.net/image/miniApp/mp3/3.mp3", }, { src: "https://app.gter.net/image/miniApp/mp3/4.mp3", }, ]); return { scrollToPrevious, scrollToNext, changePointer, pointerState, visibleRef, studentRef, customRef, worksRef, introduceRef, customList, closeAll, manageAudio, progress, pauseAudio, playAudio, audioList, closePreview, openPreview, previewState, audioHeadState, pauseHead, playHead, audioPlayer, text, trait, fastForward }; }, }).mount("#appIndex");