home-banner.vue 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <script setup lang="ts">
  2. import ImageEvo from '@/components/image-evo.vue'
  3. import { unix } from 'dayjs'
  4. import { useRouter } from '../../../core/utils/router'
  5. const router = useRouter()
  6. const props = withDefaults(
  7. defineProps<{
  8. id: string | number
  9. url: string
  10. cover: string
  11. detailsType: number | string | null | undefined
  12. item: object | any
  13. }>(),
  14. {},
  15. )
  16. const emits = defineEmits<{ play: [id: string | number]; ended: [id: string | number] }>()
  17. const instance = getCurrentInstance()
  18. const playing = ref(false)
  19. const duration = ref(0)
  20. const durationText = computed(() => unix(duration.value).format('mm:ss'))
  21. const videoContext = ref<UniNamespace.VideoContext>()
  22. const handleClick = () => {
  23. if (props?.item?.url && props.item?.url?.startsWith('http')) {
  24. router.push(`/pages-sub/common/webview/index?url=${props.item.url}`)
  25. }
  26. if (props.detailsType === '1' && !props?.item?.url) {
  27. router.push(
  28. `/pages-sub/home/content/index?type=home-banner&id=${props.id}&data=${encodeURIComponent(JSON.stringify(props.item))}`,
  29. )
  30. }
  31. }
  32. const handlePlay = async () => {
  33. videoContext.value?.play()
  34. playing.value = true
  35. emits('play', props.id)
  36. }
  37. const handleLoadedMetaData = ({ detail }) => {
  38. duration.value = detail.duration
  39. }
  40. const handleEnded = () => {
  41. playing.value = false
  42. videoContext.value?.pause()
  43. emits('ended', props.id)
  44. }
  45. const handlePause = () => {
  46. playing.value = false
  47. }
  48. onMounted(async () => {
  49. videoContext.value = uni.createVideoContext(`video-${props.id}`, instance)
  50. })
  51. defineExpose({
  52. videoContext,
  53. })
  54. </script>
  55. <template>
  56. <div class="w-full h-full relative" v-if="!detailsType && item.indexPromotionalVideoImage">
  57. <div v-show="!playing" class="absolute left-0 top-0 w-full h-full bg-black">
  58. <ImageEvo :src="cover"></ImageEvo>
  59. </div>
  60. <div class="w-full h-full box-border pb-6" v-show="playing">
  61. <video
  62. class="w-full h-full"
  63. :id="`video-${id}`"
  64. :src="url"
  65. :controls="'contimg'"
  66. :show-center-play-btn="false"
  67. :enable-progress-gesture="false"
  68. :loop="false"
  69. @pause="handlePause"
  70. @ended="handleEnded"
  71. @loadedmetadata="handleLoadedMetaData"
  72. ></video>
  73. </div>
  74. <div
  75. v-if="!playing"
  76. class="w-[375px] h-[90px] bg-gradient-to-t from-black to-black/0 absolute left-0 bottom-0 w-full flex items-center"
  77. >
  78. <view class="mx-7">
  79. <wd-button
  80. plain
  81. custom-class="bg-transparent! text-white! w-20.5! min-w-20! h-8.25! border! border-solid! border-white!"
  82. @click="handlePlay()"
  83. >
  84. <div class="flex items-center">
  85. <wd-icon name="play" size="22px"></wd-icon>
  86. <div class="text-white text-[13px] font-['Gotham'] leading-[10.18px]">
  87. {{ durationText }}
  88. </div>
  89. </div>
  90. </wd-button>
  91. </view>
  92. </div>
  93. </div>
  94. <div class="w-full h-full relative" v-else @click="handleClick">
  95. <ImageEvo :src="cover"></ImageEvo>
  96. </div>
  97. </template>