hldy_app_mini/component/public/donghua.vue

150 lines
3.6 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 使用示例 已经全局暴露直接用就行 注意这个组件的性能不如用AE写的动画-->
<!-- <donghua :width="`1300rpx`" :height="`900rpx`" :links="blueArray" :playing="photoplay" :loop="true" :interval="120" /> -->
<!-- 注意看参数是什么意思 -->
<!-- 通用的生成函数 这个方法可以快速让你写出图片数组
function genPaths(base, prefix, count, ext = 'png', startIndex = 0, pad = false) {
return Array.from({ length: count }, (_, i) => {
const idx = pad
? String(i + startIndex).padStart(2, '0')
: i + startIndex
return `${base}/${prefix}${idx}.${ext}`
})
} -->
<!-- 数组的示例
const leftArray = ref(genPaths(
'/static/index/newindex/leftmenu',地址
'',图片前缀
3, // 一共加一起多少张图片
'png', 类型
0, // 起始索引
false // 不补零
)) -->
<template>
<view>
<image :src="isError ? defaultImage : links[currentIndex]" :style="{ width: width, height: height }"
:mode="objectFit" @error="isError = true" @load="isError = false" />
<button v-if="showButton" @click="$emit('update:playing', !playing)">
{{ playing ? '停止播放' : '开始播放' }}
</button>
</view>
</template>
<script setup>
import {
ref,
watch,
onUnmounted
} from 'vue'
// 定义组件的 props
const props = defineProps({
// links是图片地址所组成的数组
links: {
type: Array,
default: () => []
},
// 长宽的值可以传任何类型
width: {
type: String,
default: '65rpx'
},
height: {
type: String,
default: '65rpx'
},
// 展示的动画中每一帧的图片类型
objectFit: {
type: String,
default: 'aspectFill'
},
// 动画如果加载失败,展示的图片
defaultImage: {
type: String,
default: ''
},
// 注意这是每一帧图片的间隔,这个值越小加载的越快
interval: {
type: Number,
default: 80
},
// 注意因为这是监听的机制所以默认转态必须是false然后在mounted这类钩子或按钮变成true来播放
playing: {
type: Boolean,
default: false
},
// 展示是否停止、开启动画的按钮
showButton: {
type: Boolean,
default: false
},
// 重要:动画时候会不停的循环
loop: {
type: Boolean,
default: false
}
})
// 定义组件发出的事件
const emit = defineEmits(['update:playing'])
// 组件内部状态
const currentIndex = ref(0) // 当前播放的图片索引
const isPlaying = ref(false) // 是否正在播放
const isError = ref(false) // 当前图片是否加载失败
let timer = null // 定时器
// 开始播放
const startPlay = () => {
if (isPlaying.value) return
isPlaying.value = true
timer = setInterval(() => {
if (props.loop) {
// 循环播放:使用模运算循环索引
currentIndex.value = (currentIndex.value + 1) % props.links.length
isError.value = false
} else {
// 非循环播放:到末尾时停止
if (currentIndex.value < props.links.length - 1) {
currentIndex.value++
isError.value = false
} else {
stopPlay()
}
}
}, props.interval)
}
// 停止播放
const stopPlay = () => {
isPlaying.value = false
clearInterval(timer)
}
// 监听 playing 属性变化
watch(() => props.playing, (val) => {
currentIndex.value = 0
if (val) {
startPlay()
} else {
stopPlay()
setTimeout(() => currentIndex.value = 0, 50)
}
})
// 监听 links 数组变化
watch(() => props.links, () => {
currentIndex.value = 0
isError.value = false
if (isPlaying.value) {
stopPlay()
}
}, {
deep: true
})
// 组件销毁时清理定时器
onUnmounted(() => {
stopPlay()
})
</script>