feat: card music
This commit is contained in:
@@ -22,6 +22,16 @@
|
||||
{{ cardDetail?.festival || "丙午马年" }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- Music Control -->
|
||||
<view
|
||||
v-if="cardDetail?.musicUrl"
|
||||
class="music-control"
|
||||
:class="{ playing: isBgmPlaying }"
|
||||
@tap="toggleBgm"
|
||||
>
|
||||
<text class="music-icon">{{ isBgmPlaying ? "🎵" : "🔇" }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- Card Preview Area -->
|
||||
@@ -114,14 +124,50 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { onLoad, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
|
||||
import { ref, onUnmounted } from "vue";
|
||||
import {
|
||||
onLoad,
|
||||
onHide,
|
||||
onUnload,
|
||||
onShareAppMessage,
|
||||
onShareTimeline,
|
||||
} from "@dcloudio/uni-app";
|
||||
import { getPageDetail } from "@/api/system.js";
|
||||
import { getShareToken, saveViewRequest } from "@/utils/common.js";
|
||||
import NavBar from "@/components/NavBar/NavBar.vue";
|
||||
|
||||
const cardId = ref("");
|
||||
const cardDetail = ref({});
|
||||
const isBgmPlaying = ref(false);
|
||||
const innerAudioContext = uni.createInnerAudioContext();
|
||||
|
||||
const initBgm = (url) => {
|
||||
if (!url) return;
|
||||
innerAudioContext.src = url;
|
||||
innerAudioContext.loop = true;
|
||||
innerAudioContext.autoplay = true;
|
||||
innerAudioContext.onPlay(() => {
|
||||
isBgmPlaying.value = true;
|
||||
});
|
||||
innerAudioContext.onPause(() => {
|
||||
isBgmPlaying.value = false;
|
||||
});
|
||||
innerAudioContext.onStop(() => {
|
||||
isBgmPlaying.value = false;
|
||||
});
|
||||
innerAudioContext.onError((res) => {
|
||||
console.error("BGM播放错误:", res);
|
||||
isBgmPlaying.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const toggleBgm = () => {
|
||||
if (isBgmPlaying.value) {
|
||||
innerAudioContext.pause();
|
||||
} else {
|
||||
innerAudioContext.play();
|
||||
}
|
||||
};
|
||||
|
||||
onLoad(async (options) => {
|
||||
if (options.shareToken) {
|
||||
@@ -129,7 +175,21 @@ onLoad(async (options) => {
|
||||
cardId.value = card.id;
|
||||
cardDetail.value = card;
|
||||
saveViewRequest(options.shareToken, "card_generate", card.id);
|
||||
|
||||
if (card.musicUrl) {
|
||||
initBgm(card.musicUrl);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onHide(() => {
|
||||
if (isBgmPlaying.value) {
|
||||
innerAudioContext.pause();
|
||||
}
|
||||
});
|
||||
|
||||
onUnload(() => {
|
||||
innerAudioContext.destroy();
|
||||
});
|
||||
|
||||
onShareAppMessage(async () => {
|
||||
@@ -246,6 +306,39 @@ const goToWallpaper = () => {
|
||||
padding: 20rpx 30rpx 60rpx;
|
||||
}
|
||||
|
||||
/* Music Control */
|
||||
.music-control {
|
||||
margin-left: auto;
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
background: rgba(255, 59, 48, 0.05);
|
||||
border: 2rpx solid rgba(255, 59, 48, 0.1);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&.playing {
|
||||
animation: rotate 3s linear infinite;
|
||||
background: rgba(255, 59, 48, 0.1);
|
||||
border-color: rgba(255, 59, 48, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.music-icon {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* User Header */
|
||||
.user-header {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user