audio.vue 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. <template>
  2. <div :class="[ns.b()]" @click="clickHandler">
  3. <audio ref="audio" autoplay loop @play="rotation">
  4. <source :src="src" />
  5. </audio>
  6. <span
  7. v-for="random in randoms"
  8. :key="random"
  9. :style="{ '--percent': random }"
  10. />
  11. </div>
  12. </template>
  13. <script lang="ts" setup>
  14. import { defineProps, ref, watchEffect } from 'vue'
  15. import { useNamespace } from '@kankan-components/hooks'
  16. import { audioProps } from './audio'
  17. defineOptions({
  18. name: 'KkAudio',
  19. })
  20. defineProps(audioProps)
  21. const ns = useNamespace('audio')
  22. const audio = ref()
  23. const randoms = ref([1, 0.5, 1, 0.5])
  24. const playIng = ref(false)
  25. let audioTimeout: ReturnType<typeof setTimeout> | undefined
  26. const rotation = () => {
  27. if (!playIng.value) return
  28. for (let i = 0; i < randoms.value.length; i++) {
  29. randoms.value[i] = Math.random()
  30. }
  31. audioTimeout = setTimeout(rotation, 200)
  32. }
  33. watchEffect(() => {
  34. if (audio.value) {
  35. if (playIng.value) {
  36. audio.value.play()
  37. } else {
  38. audio.value.pause()
  39. }
  40. audioTimeout && clearTimeout(audioTimeout)
  41. rotation()
  42. }
  43. })
  44. const clickHandler = () => {
  45. playIng.value = !playIng.value
  46. }
  47. defineExpose({
  48. play() {
  49. playIng.value = true
  50. },
  51. pause() {
  52. playIng.value = false
  53. },
  54. })
  55. </script>