index.vue 1.1 KB

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