VideoStylePanel.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <template>
  2. <div class="video-style-panel">
  3. <div class="title">视频预览封面</div>
  4. <div class="background-image-wrapper">
  5. <FileInput @change="files => setVideoPoster(files)">
  6. <div class="background-image">
  7. <div class="content" :style="{ backgroundImage: handleVideoElement.poster ? `url(${handleVideoElement.poster})` : '' }">
  8. <IconPlus />
  9. </div>
  10. </div>
  11. </FileInput>
  12. </div>
  13. <div class="row">
  14. <Button style="flex: 1;" @click="updateVideo({ poster: '' })">重置封面</Button>
  15. </div>
  16. <div class="row switch-row">
  17. <div style="width: 40%;">自动播放:</div>
  18. <div class="switch-wrapper" style="width: 60%;">
  19. <Switch
  20. :value="handleVideoElement.autoplay"
  21. @update:value="value => updateVideo({ autoplay: value })"
  22. />
  23. </div>
  24. </div>
  25. </div>
  26. </template>
  27. <script lang="ts" setup>
  28. import type { Ref } from 'vue'
  29. import { storeToRefs } from 'pinia'
  30. import { useMainStore, useSlidesStore } from '@/store'
  31. import type { PPTVideoElement } from '@/types/slides'
  32. import { getImageDataURL } from '@/utils/image'
  33. import useHistorySnapshot from '@/hooks/useHistorySnapshot'
  34. import FileInput from '@/components/FileInput.vue'
  35. import Button from '@/components/Button.vue'
  36. import Switch from '@/components/Switch.vue'
  37. const slidesStore = useSlidesStore()
  38. const { handleElement } = storeToRefs(useMainStore())
  39. const handleVideoElement = handleElement as Ref<PPTVideoElement>
  40. const { addHistorySnapshot } = useHistorySnapshot()
  41. const updateVideo = (props: Partial<PPTVideoElement>) => {
  42. if (!handleElement.value) return
  43. slidesStore.updateElement({ id: handleElement.value.id, props })
  44. addHistorySnapshot()
  45. }
  46. // 设置视频预览封面
  47. const setVideoPoster = (files: FileList) => {
  48. const imageFile = files[0]
  49. if (!imageFile) return
  50. getImageDataURL(imageFile).then(dataURL => updateVideo({ poster: dataURL }))
  51. }
  52. </script>
  53. <style lang="scss" scoped>
  54. .row {
  55. width: 100%;
  56. display: flex;
  57. align-items: center;
  58. margin-bottom: 10px;
  59. }
  60. .title {
  61. margin-bottom: 10px;
  62. }
  63. .background-image-wrapper {
  64. margin-bottom: 10px;
  65. }
  66. .background-image {
  67. height: 0;
  68. padding-bottom: 56.25%;
  69. border: 1px dashed $borderColor;
  70. border-radius: $borderRadius;
  71. position: relative;
  72. transition: all $transitionDelay;
  73. &:hover {
  74. border-color: $themeColor;
  75. color: $themeColor;
  76. }
  77. .content {
  78. @include absolute-0();
  79. display: flex;
  80. justify-content: center;
  81. align-items: center;
  82. background-position: center;
  83. background-size: contain;
  84. background-repeat: no-repeat;
  85. cursor: pointer;
  86. }
  87. }
  88. .switch-row {
  89. height: 32px;
  90. }
  91. .switch-wrapper {
  92. text-align: right;
  93. }
  94. </style>