fix: 完成视频组件,并支持属性实时控制video状态

This commit is contained in:
tnt group 2022-09-19 12:32:27 +08:00
parent 25077b91ca
commit 73bb93f166
3 changed files with 83 additions and 81 deletions

View File

@ -3,15 +3,22 @@ import { CreateComponentType } from '@/packages/index.d'
import { VideoConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
export const VideoList = [
{ label: '数字楼宇', value: 'https://video.699pic.com/videos/76/09/36/b_D4DKnb48qdCI1631760936.mp4' },
{ label: '旋转魔方', value: 'https://video.699pic.com/videos/90/02/69/b_YjJAJZMT6vRK1554900269.mp4' },
{ label: '旋转地球', value: 'https://video.699pic.com/videos/32/13/12/b_7dng21IHECP51553321312.mp4' },
{ label: '声音示例', value: 'https://video.699pic.com/videos/80/62/39/a_qmbxMqNvK9jr1583806239.mp4' }
]
export const option = {
// 视频路径
dataset: '',
// 适应方式
fit: 'contain',
// 圆角
borderRadius: 0,
// 透明度
opacity: 1
// 循环播放
loop: true,
// 自动播放
autoplay: true,
// 静音
muted: true
}
export default class Config extends PublicConfigClass implements CreateComponentType {

View File

@ -1,26 +1,40 @@
<!-- eslint-disable vue/multi-word-component-names -->
<!-- eslint-disable vue/no-mutating-props -->
<template>
<collapse-item name="属性" :expanded="true">
<setting-item-box name="路径" :alone="true">
<setting-item>
<collapse-item name="视频" expanded>
<setting-item-box name="源" alone>
<setting-item name="自定义视频源">
<n-input v-model:value="optionData.dataset" size="small"></n-input>
</setting-item>
<setting-item>
<n-upload action="https://www.mocky.io/v2/5e4bafc63100007100d8b70f" @finish="handleFinish">
<setting-item name="使用内置视频">
<n-select
v-model:value="optionData.dataset"
size="small"
placeholder="自定义或选择内置视频"
clearable
:options="VideoList"
></n-select>
</setting-item>
<!-- <setting-item>
<n-upload
action="https://www.mocky.io/v2/5e4bafc63100007100d8b70f"
accept="video/*"
@finish="finishHandleFinish"
>
<n-button size="small">本地上传</n-button>
</n-upload>
</setting-item>
</setting-item> -->
</setting-item-box>
<setting-item-box name="样式">
<setting-item name="类型">
<n-select v-model:value="optionData.fit" size="small" :options="fitList"></n-select>
<setting-item-box name="控制">
<setting-item>
<n-checkbox v-model:checked="optionData.autoplay" size="small">自动播放</n-checkbox>
</setting-item>
<setting-item name="圆角">
<n-input-number
v-model:value="optionData.borderRadius"
size="small"
:min="0"
placeholder="圆角"
></n-input-number>
<setting-item>
<n-checkbox v-model:checked="optionData.loop" size="small">循环播放</n-checkbox>
</setting-item>
<setting-item>
<n-checkbox v-model:checked="optionData.muted" size="small">静音</n-checkbox>
</setting-item>
</setting-item-box>
</collapse-item>
@ -28,9 +42,10 @@
<script setup lang="ts">
import { PropType } from 'vue'
import { option } from './config'
import { option, VideoList } from './config'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
// eslint-disable-next-line no-unused-vars
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
@ -38,27 +53,8 @@ const props = defineProps({
}
})
//
const fitList = [
{
value: 'fill',
label: 'fill'
},
{
value: 'contain',
label: 'contain'
},
{
value: 'cover',
label: 'cover'
},
{
value: 'scale-down',
label: 'scale-down'
},
{
value: 'none',
label: 'none'
}
]
// eslint-disable-next-line no-unused-vars
const finishHandleFinish = () => {
// console.log()
}
</script>

View File

@ -1,25 +1,25 @@
<!-- eslint-disable vue/multi-word-component-names -->
<template>
<div :style="getStyle(borderRadius)">
<video
class="video-background"
preload="auto"
loop
playsinline
autoplay
muted
src="https://video.699pic.com/videos/76/09/36/b_D4DKnb48qdCI1631760936.mp4"
:width="w"
:height="h"
></video>
</div>
<video
ref="vVideoRef"
class="go-video"
preload="auto"
playsinline
:loop="option.loop"
:autoplay="option.autoplay"
:muted="option.muted"
:width="w"
:height="h"
:src="option.dataset"
></video>
</template>
<script setup lang="ts">
import { PropType, shallowReactive, watch, toRefs } from 'vue'
import { PropType, toRefs, shallowReactive, watch, ref } from 'vue'
import { useChartDataFetch } from '@/hooks'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { option } from './config'
import { option as configOption } from './config'
const props = defineProps({
chartConfig: {
@ -29,41 +29,40 @@ const props = defineProps({
})
const { w, h } = toRefs(props.chartConfig.attr)
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
let option = shallowReactive({ ...configOption })
const option = shallowReactive({
dataset: ''
//
const vVideoRef = ref(null)
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
option = newData
})
const getStyle = (radius: number) => {
return {
borderRadius: `${radius}px`,
overflow: 'hidden'
}
}
//
watch(
() => props.chartConfig.option.dataset,
() => props.chartConfig.option,
(newData: any) => {
option.dataset = newData
option = newData
if (!vVideoRef.value) return
const video: any = vVideoRef.value
video.loop = option.loop
video.autoplay = option.autoplay
video.muted = option.muted
//
!option.autoplay && (video.pause(), (video.currentTime = 0))
option.autoplay && video.play()
},
{
immediate: true,
deep: false
deep: true
}
)
//
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
option.dataset = newData
})
</script>
<style lang="scss" scoped>
.video-background {
@include go('video') {
display: block;
object-fit: cover;
mix-blend-mode: screen;
opacity: 1;
}
</style>