|
- <template>
- <view class="imt-audio" :class="[`${theme}`]" v-if="audiolist.length > 0">
-
- <template v-if="theme == 'theme4'">
- <view class="imt-audios">
- <view class="top">
- <view class="audio-control-wrapper">
- <image :src="require('./static/loading.png')" v-if="loading" class="play loading"></image>
- <template v-else>
- <image :src="require('./static/pausebtn.png')" alt="" @click="operate" class="play"
- v-if="renderData('paused')"></image>
- <image :src="require('./static/playbtn.png')" alt="" @click="operate" class="play" v-else>
- </image>
- </template>
- </view>
- </view>
- <view class="audio-wrapper">
- <view class="audio-flex">
- <text>
- {{renderData('current')}}
- </text>
- <slider class="audio-slider" :activeColor="themeColor" block-size="16"
- :value="renderData('current_value')" :max="renderData('duration_value')" @change="change"
- :disabled="!renderIsPlay"></slider>
- <text v-if="!duration">
- {{renderData('duration')}}
- </text>
- <text v-else>{{ duration }}</text>
- </view>
- </view>
- </view>
- </template>
- <template v-if="theme == 'theme3'">
- <slider class="audio-slider" :activeColor="themeColor" block-size="0" :value="renderData('current_value')"
- :max="renderData('duration_value')" @change="change" :disabled="!renderIsPlay"></slider>
-
- <view class="top">
- <view class="audio-control-wrapper">
- <image :src="renderData('coverImgUrl')" mode="aspectFill" class="cover"
- :class="{ on: !renderData('paused') }"></image>
-
- <image :src="require('./static/loading.png')" v-if="loading" class="play loading"></image>
- <template v-else>
- <image :src="require('./static/pausebtn.png')" alt="" @click="operate" class="play"
- v-if="renderData('paused')"></image>
- <image :src="require('./static/playbtn.png')" alt="" @click="operate" class="play" v-else>
- </image>
- </template>
- </view>
- </view>
- <view class="audio-wrapper">
- <view class="titlebox">
- <view class="title">{{ renderData('title') }}</view>
- <view class="singer">{{ renderData('singer') }}</view>
- </view>
-
- <view class="slidebox">
- <view>{{ renderData('current') }}/ {{ renderData('duration') }}</view>
- <view>
- <text @click="changeplay(-1)">上一首</text>
- <text @click="changeplay(1)">下一首</text>
- </view>
- </view>
- </view>
- </template>
-
- <template v-if="theme == 'theme2'">
- <view class="top">
- <view class="audio-control-wrapper" :style="{backgroundImage: `url(${renderData('coverImgUrl')})`}">
- <image :src="require('./static/loading.png')" v-if="loading" class="play loading"></image>
- <template v-else>
- <image :src="require('./static/pausebtn.png')" alt="" @click="operate" class="play"
- v-if="renderData('paused')"></image>
- <image :src="require('./static/playbtn.png')" alt="" @click="operate" class="play" v-else>
- </image>
- </template>
- </view>
-
- <view>
- <view class="title">
- <text>{{ renderData('title') }}</text>
- <view class="audio-number">{{ renderData('current') }}/{{ renderData('duration') }}</view>
- </view>
- <view class="singer">{{ renderData('singer') }}</view>
- </view>
- </view>
- </template>
-
- <template v-if="theme == 'theme1'">
- <view class="top">
- <view class="audio-control-wrapper">
- <image :src="renderData('coverImgUrl')" mode="aspectFill" class="cover"
- :class="{ on: !renderData('paused') }"></image>
- </view>
-
- <view>
- <view class="title">{{ renderData('title') }}</view>
- <view class="singer">{{ renderData('singer') }}</view>
- </view>
- </view>
- <view class="audio-wrapper">
- <view class="audio-number">{{ renderData('current') }}</view>
- <slider class="audio-slider" :activeColor="themeColor" block-size="16"
- :value="renderData('current_value')" :max="renderData('duration_value')" @change="change"
- :disabled="!renderIsPlay"></slider>
- <view class="audio-number">{{ renderData('duration') }}</view>
- </view>
-
- <view class="audio-button-box">
- <!-- 块退15s -->
- <image :src="require('./static/prev.png')" class="prevbtn" @click="stepPlay(-15)" mode="widthFix">
- </image>
- <!-- 上一首 -->
- <image :src="require('./static/go.png')" class="prevplay" @click="changeplay(-1)" mode="widthFix">
- </image>
- <div class="playbox">
- <image :src="require('./static/loading2.png')" v-if="loading" class="play loading"></image>
- <template v-else>
- <!-- 播放 -->
- <image :src="require('./static/playbtn2.png')" alt="" @click="operate" class="play"
- v-if="renderData('paused')"></image>
- <!-- 暂停 -->
- <image :src="require('./static/pausebtn2.png')" alt="" @click="operate" class="pause" v-else>
- </image>
- </template>
- </div>
- <!-- 下一首 -->
- <image :src="require('./static/go.png')" class="nextplay" @click="changeplay(1)" mode="widthFix">
- </image>
- <!-- 快进15s -->
- <image :src="require('./static/next.png')" class="nextbtn" @click="stepPlay(15)" mode="widthFix">
- </image>
- </view>
- </template>
-
- </view>
- </template>
-
- <script>
- export default {
- props: {
- theme: {
- type: String, // 主题 'theme1' or 'theme2'
- default: 'theme1'
- },
- themeColor: {
- type: String,
- default: '#2671E2'
- },
- duration: {
- type: String,
- default: ""
- }
- },
- data() {
- return {
- playinfo: this.$zaudio.playinfo,
- audiolist: this.$zaudio.audiolist,
- paused: this.$zaudio.paused,
- renderIsPlay: this.$zaudio.renderIsPlay,
- audio: this.$zaudio.renderinfo,
- loading: this.$zaudio.loading,
- action: Symbol('zaudio')
- };
- },
- computed: {
- renderData() {
- return name => {
- if (!this.renderIsPlay) {
- if (name == 'paused') {
- return true;
- }
- return this.audio[name];
- } else {
- if (name == 'paused') {
- return this.paused;
- }
- return this.playinfo[name];
- }
- };
- }
- },
- mounted() {
- this.$nextTick(() => {
- let action = this.action;
- this.$zaudio.syncStateOn(action, ({
- audiolist,
- paused,
- playinfo,
- renderIsPlay,
- renderinfo,
- loading,
- }) => {
- this.audiolist = audiolist;
- this.paused = paused;
- this.playinfo = playinfo;
- this.renderIsPlay = renderIsPlay;
- this.audio = renderinfo;
- this.loading = loading;
- });
- this.$zaudio.syncRender()
- });
- },
- methods: {
- // 转换时间
- formatSeconds(seconds) {
- var result = typeof seconds === "string" ? parseFloat(seconds) : seconds;
- if (isNaN(result)) return "";
- let h = Math.floor(result / 3600) < 10 ?
- "0" + Math.floor(result / 3600) :
- Math.floor(result / 3600);
- let m = Math.floor((result / 60) % 60) < 10 ?
- "0" + Math.floor((result / 60) % 60) :
- Math.floor((result / 60) % 60) + h * 60;
- let s = Math.floor(result % 60) < 10 ?
- "0" + Math.floor(result % 60) :
- Math.floor(result % 60);
- return `${h}:${m}:${s}`;
- },
-
- //播放or暂停
- operate() {
- this.$zaudio.operate();
- },
- //进度拖到
- change(event) {
- if (this.renderIsPlay) {
- this.$zaudio.seek(event.detail.value);
- }
- },
- //快进
- stepPlay(value) {
- this.$zaudio.stepPlay(value);
- },
- //切歌
- changeplay(count) {
- this.$zaudio.changeplay(count);
- }
- },
- beforeDestroy() {
- this.$zaudio.playinfo.duration = '00:00:00'
- this.$zaudio.playinfo.duration_value = '00:00:00'
- //组件卸载时卸载业务逻辑
- let action = this.action;
- this.$zaudio.syncStateOff(action)
- this.$zaudio.stop()
- }
- };
- </script>
-
- <style scoped lang="scss">
- @import './index.scss';
-
- // #ifdef MP-WEIXIN
- .theme3 .audio-slider {
- margin-top: -8px !important;
- }
-
- // #endif
-
-
- @mixin textoverflow() {
- display: -webkit-box;
- overflow: hidden;
- text-overflow: ellipsis;
- -webkit-box-orient: vertical;
- -webkit-line-clamp: 1;
- }
-
- @keyframes rowup {
- 0% {
- -webkit-transform: translate(-50%, -50%) rotate(0deg);
- transform-origin: center center;
- }
-
- 100% {
- -webkit-transform: translate(-50%, -50%) rotate(360deg);
- transform-origin: center center;
- }
- }
-
- .imt-audios {
- position: relative;
- width: 100%;
- height: 81rpx;
- display: flex;
- box-sizing: border-box;
- background: #fff;
-
- .top {
- position: relative;
- width: 100rpx;
- }
-
- .audio-wrapper {
- position: relative;
- padding: 0 20rpx;
- display: flex;
- flex: 1;
- color: #fff;
-
- .popup {
- position: absolute;
- right: 32rpx;
- top: -122rpx;
- z-index: 100;
- width: 136rpx;
- height: 122rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- background: #fff;
- border: 1rpx solid #E0E0E0;
- transition: all 0.25s linear;
- opacity: 0;
-
- image {
- width: 32rpx;
- height: 32rpx;
- }
-
- text {
- margin-top: 10rpx;
- color: #333;
- font-size: 24rpx;
- }
-
- .act-test {
- color: #2671E2;
- }
- }
-
- .close {
- opacity: 1;
- }
- }
-
- .slidebox {
- flex-shrink: 0;
- display: flex;
- align-items: center;
-
- .slide-img {
- width: 32rpx;
- height: 8rpx;
- }
- }
-
- /deep/ .uni-slider-tap-area {
- padding: 0;
- }
-
- /deep/ .uni-slider-wrapper {
- min-height: 0;
- }
-
- /deep/ .uni-slider-handle-wrapper {
- height: 6px;
- }
-
- .audio-slider {
- flex-grow: 1;
- }
-
- .play {
- width: 44rpx;
- height: 44rpx;
- z-index: 99;
- border-radius: 50%;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
-
- &.loading {
- width: 48rpx;
- height: 48rpx;
- animation: rotating_theme3 2s linear infinite;
- }
- }
- }
-
- .audio-flex {
- padding: 0 32rpx 0 0;
- flex-grow: 1;
- display: flex;
- align-items: center;
-
- text {
- color: #70798D;
- }
- }
-
- @keyframes rotating {
- 0% {
- transform: rotateZ(0deg)
- }
-
- 100% {
- transform: rotateZ(360deg)
- }
- }
-
- @keyframes rotating_theme3 {
- 0% {
- transform: translate(-50%, -50%) rotateZ(0deg)
- }
-
- 100% {
- transform: translate(-50%, -50%) rotateZ(360deg)
- }
- }
- </style>
|