| @@ -150,3 +150,29 @@ export function personPatchApi(id) { | |||||
| method: 'get' | method: 'get' | ||||
| }) | }) | ||||
| } | } | ||||
| /** | |||||
| * @description:保存或修改用户作品 | |||||
| * @param {object} data | |||||
| * @return data | |||||
| */ | |||||
| export function saveOrUpdateApi(data) { | |||||
| return request({ | |||||
| url: `/api/userVideo/saveOrUpdate`, | |||||
| method: 'post', | |||||
| data: data | |||||
| }) | |||||
| } | |||||
| /** | |||||
| * @description 生成视频 | |||||
| * @param {object} id | |||||
| * @returns id | |||||
| */ | |||||
| export function createVideoApi(id) { | |||||
| return request({ | |||||
| url: `/api/userVideo/createVideo`, | |||||
| method: 'post', | |||||
| data: { id } | |||||
| }) | |||||
| } | |||||
| @@ -6,9 +6,16 @@ import request from "@/utils/request.js"; | |||||
| * @params pageNum, pageSize | * @params pageNum, pageSize | ||||
| * @returns data | * @returns data | ||||
| */ | */ | ||||
| // export function userPhotoVideoList(pageNum, pageSize, title) { | |||||
| // return request({ | |||||
| // url: `/api/userPhotoVideo/list?pageNum=${pageNum}&pageSize=${pageSize}&title=${title}`, | |||||
| // method: 'get' | |||||
| // }) | |||||
| // } | |||||
| export function userPhotoVideoList(pageNum, pageSize, title) { | export function userPhotoVideoList(pageNum, pageSize, title) { | ||||
| let videoStatuss = [1, 2, 3, 4, 5, 6] | |||||
| return request({ | return request({ | ||||
| url: `/api/userPhotoVideo/list?pageNum=${pageNum}&pageSize=${pageSize}&title=${title}`, | |||||
| url: `/api/userVideo/list?pageNum=${pageNum}&pageSize=${pageSize}&title=${title}&videoType=-1&videoStatuss=${videoStatuss}`, | |||||
| method: 'get' | method: 'get' | ||||
| }) | }) | ||||
| } | } | ||||
| @@ -23,4 +30,17 @@ export function delUserPhotoVideoByID(videoID) { | |||||
| url: `/api/userPhotoVideo/del?id=${videoID}`, | url: `/api/userPhotoVideo/del?id=${videoID}`, | ||||
| method: 'get' | method: 'get' | ||||
| }) | }) | ||||
| } | |||||
| /** | |||||
| * @description 获取作品列表 | |||||
| * @param {number} pageParams (pageNum, pageSize) | |||||
| * @returns data | |||||
| */ | |||||
| export function getVideoList(pageNum, pageSize, videoType, videoStatuss) { | |||||
| return request({ | |||||
| url: `/api/userVideo/list?pageNum=${pageNum}&pageSize=${pageSize}&videoType=${videoType}&videoStatuss=${videoStatuss}`, | |||||
| method: 'get' | |||||
| }) | |||||
| } | } | ||||
| @@ -15,15 +15,74 @@ | |||||
| :style="virtualStyle" | :style="virtualStyle" | ||||
| > | > | ||||
| <img id="virtualImg" :src="materialList.virtual.material" alt="" /> | <img id="virtualImg" :src="materialList.virtual.material" alt="" /> | ||||
| <div class="stretchBox box1"></div> | |||||
| <div ref="box1" class="stretchBox box1"></div> | |||||
| <div class="stretchBox box2"></div> | <div class="stretchBox box2"></div> | ||||
| <div class="stretchBox box3"></div> | <div class="stretchBox box3"></div> | ||||
| <div class="stretchBox box4"></div> | |||||
| <div | |||||
| v-show="showBorderActive == materialList.virtual.id" | |||||
| ref="box4" | |||||
| @mousedown.stop="changeScale" | |||||
| class="stretchBox box4" | |||||
| > | |||||
| <img | |||||
| style="width: 100px; height: 100px" | |||||
| src="../assets/img/Scale.png" | |||||
| alt="" | |||||
| /> | |||||
| </div> | |||||
| </div> | |||||
| <!-- 素材图的图片 --> | |||||
| <div | |||||
| v-for="(item, index) in materialList.scList" | |||||
| :key="item.id" | |||||
| class="scListItem" | |||||
| :class="showBorderActive == item.id ? 'border' : ''" | |||||
| @mousedown="handleDragSc(item.id, index, $event)" | |||||
| :style="{ | |||||
| top: item.y + 'px', | |||||
| left: item.x + 'px', | |||||
| transform: 'scale(' + item.w / props.proportion + ') ', | |||||
| transformOrigin: 'top left', | |||||
| zIndex: item.z, | |||||
| }" | |||||
| > | |||||
| <img id="scListItemImg" :src="item.material" alt="" /> | |||||
| <div ref="box1" class="stretchBox box1"></div> | |||||
| <div | |||||
| v-show="showBorderActive == item.id" | |||||
| class="stretchBox box2" | |||||
| @click="delScListItem(index)" | |||||
| > | |||||
| <img | |||||
| style="width: 100px; height: 100px" | |||||
| src="../assets/img/delete2.png" | |||||
| alt="" | |||||
| /> | |||||
| </div> | |||||
| <div class="stretchBox box3"></div> | |||||
| <div | |||||
| v-show="showBorderActive == item.id" | |||||
| ref="box4" | |||||
| @mousedown.stop="changeScaleSc(index, $event)" | |||||
| class="stretchBox box4" | |||||
| > | |||||
| <img | |||||
| style="width: 100px; height: 100px" | |||||
| src="../assets/img/Scale.png" | |||||
| alt="" | |||||
| /> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| <script setup> | <script setup> | ||||
| //#region 导入 | |||||
| import { useI18n } from "vue-i18n"; | |||||
| //#endregion -------------------------- | |||||
| const { locale } = useI18n(); | |||||
| const lanChange = ref(locale); | |||||
| //#region 父组件传参 | //#region 父组件传参 | ||||
| const props = defineProps({ | const props = defineProps({ | ||||
| // isLoading: { | // isLoading: { | ||||
| @@ -38,6 +97,9 @@ const props = defineProps({ | |||||
| proportion: { | proportion: { | ||||
| required: true, | required: true, | ||||
| }, | }, | ||||
| showImgInfo: { | |||||
| required: true, | |||||
| }, | |||||
| }); | }); | ||||
| //#endregion -------------------------- | //#endregion -------------------------- | ||||
| @@ -63,6 +125,7 @@ const virtualStyle = computed(() => { | |||||
| transform: | transform: | ||||
| "scale(" + props.materialList.virtual.w / props.proportion + ") ", | "scale(" + props.materialList.virtual.w / props.proportion + ") ", | ||||
| transformOrigin: "top left", | transformOrigin: "top left", | ||||
| zIndex: props.materialList.virtual.z, | |||||
| }; | }; | ||||
| }); | }); | ||||
| // 拖动盒子 | // 拖动盒子 | ||||
| @@ -94,6 +157,248 @@ const handleDrag = (id, event) => { | |||||
| document.addEventListener("mousemove", onMouseMove); | document.addEventListener("mousemove", onMouseMove); | ||||
| document.addEventListener("mouseup", onMouseUp); | document.addEventListener("mouseup", onMouseUp); | ||||
| }; | }; | ||||
| // 缩放盒子 | |||||
| const touchStart = ref({ | |||||
| pageX: null, | |||||
| pageY: null, | |||||
| }); | |||||
| const touchOver = ref({ | |||||
| pageX: null, | |||||
| pageY: null, | |||||
| }); | |||||
| const scaleNum = ref(0.004); | |||||
| // 初始版 | |||||
| // function changeScale(event) { | |||||
| // event.preventDefault(); | |||||
| // const x = event.clientX; | |||||
| // const y = event.clientY; | |||||
| // // touchStart = { | |||||
| // // pageX: x, | |||||
| // // pageY: y, | |||||
| // // }; | |||||
| // touchStart.pageX = x; | |||||
| // touchStart.pageY = y; | |||||
| // // 鼠标移动 | |||||
| // const onMouseMove = (event) => { | |||||
| // const MoveX = event.clientX; | |||||
| // const MoveY = event.clientY; | |||||
| // const flag = Math.sign(x - touchStart.pageX) == -1 ? true : false; | |||||
| // if (flag) { | |||||
| // // 限制最大缩放系数 | |||||
| // if (props.materialList.virtual.w > 1.3) return; | |||||
| // props.materialList.virtual.w += scaleNum.value; | |||||
| // // 更新坐标位置 | |||||
| // // touchStart = { | |||||
| // // pageX: MoveX, | |||||
| // // pageY: MoveY, | |||||
| // // }; | |||||
| // touchStart.pageX = MoveX; | |||||
| // touchStart.pageY = MoveY; | |||||
| // } else { | |||||
| // // 限制最小缩放系数 | |||||
| // if (props.materialList.virtual.w < 0.4) return; | |||||
| // props.materialList.virtual.w -= scaleNum.value; | |||||
| // // 更新坐标位置 | |||||
| // // touchStart = { | |||||
| // // pageX: MoveX, | |||||
| // // pageY: MoveY, | |||||
| // // }; | |||||
| // touchStart.pageX = MoveX; | |||||
| // touchStart.pageY = MoveY; | |||||
| // } | |||||
| // }; | |||||
| // // 鼠标抬起 | |||||
| // const onMouseUp = () => { | |||||
| // document.removeEventListener("mousemove", onMouseMove); | |||||
| // document.removeEventListener("mouseup", onMouseUp); | |||||
| // }; | |||||
| // document.addEventListener("mousemove", onMouseMove); | |||||
| // document.addEventListener("mouseup", onMouseUp); | |||||
| // } | |||||
| // 改动版 | |||||
| function changeScale(event) { | |||||
| event.preventDefault(); | |||||
| const x = event.clientX; | |||||
| const y = event.clientY; | |||||
| touchStart.pageX = x; | |||||
| touchStart.pageY = y; | |||||
| // 鼠标移动 | |||||
| const onMouseMove = (event) => { | |||||
| const MoveX = event.clientX; | |||||
| const MoveY = event.clientY; | |||||
| let flag = Math.sign(x - touchStart.pageX) == -1 ? true : false; | |||||
| if (flag) { | |||||
| // 限制最大缩放系数 | |||||
| if (props.materialList.virtual.w > 1.3) return; | |||||
| props.materialList.virtual.w += scaleNum.value; | |||||
| // 更新坐标位置 | |||||
| touchStart.pageX = MoveX; | |||||
| touchStart.pageY = MoveY; | |||||
| } else { | |||||
| // 限制最小缩放系数 | |||||
| if (props.materialList.virtual.w < 0.4) return; | |||||
| props.materialList.virtual.w -= scaleNum.value; | |||||
| // 更新坐标位置 | |||||
| touchStart.pageX = MoveX; | |||||
| touchStart.pageY = MoveY; | |||||
| } | |||||
| }; | |||||
| // 鼠标抬起 | |||||
| const onMouseUp = () => { | |||||
| document.removeEventListener("mousemove", onMouseMove); | |||||
| document.removeEventListener("mouseup", onMouseUp); | |||||
| }; | |||||
| document.addEventListener("mousemove", onMouseMove); | |||||
| document.addEventListener("mouseup", onMouseUp); | |||||
| } | |||||
| const box1 = ref(null); | |||||
| const box2 = ref(null); | |||||
| const box3 = ref(null); | |||||
| const box4 = ref(null); | |||||
| // 距离版 | |||||
| // function changeScale(event) { | |||||
| // const box1Element = box1.value; | |||||
| // const box4Element = box4.value; | |||||
| // if (!box1Element || !box4Element) { | |||||
| // return; | |||||
| // } | |||||
| // touchStart.pageX = event.clientX; | |||||
| // touchStart.pageY = event.clientY; | |||||
| // const box1Rect = box1Element.getBoundingClientRect(); | |||||
| // const box4Rect = box4Element.getBoundingClientRect(); | |||||
| // const boxDistance = Math.sqrt( | |||||
| // (box1Rect.left - box4Rect.left) ** 2 + (box1Rect.top - box4Rect.top) ** 2 | |||||
| // ).toFixed(0); | |||||
| // const onMouseMove = (event) => { | |||||
| // const x = event.clientX; | |||||
| // const y = event.clientY; | |||||
| // const deltaX = touchStart.pageX - x; | |||||
| // const deltaY = touchStart.pageY - y; | |||||
| // const boxDistance2 = Math.sqrt(deltaX ** 2 + deltaY ** 2).toFixed(0); | |||||
| // if (deltaX < 0) { | |||||
| // props.materialList.virtual.w = Math.min( | |||||
| // Math.max((boxDistance + boxDistance2) / boxDistance, 0.4), | |||||
| // 1.3 | |||||
| // ); | |||||
| // } else { | |||||
| // props.materialList.virtual.w = Math.min( | |||||
| // Math.max((boxDistance - boxDistance2) / boxDistance, 0.4), | |||||
| // 1.3 | |||||
| // ); | |||||
| // } | |||||
| // // touchOver.pageX = event.clientX; | |||||
| // // touchOver.pageY = event.clientY; | |||||
| // }; | |||||
| // // 鼠标抬起 | |||||
| // const onMouseUp = () => { | |||||
| // // touchStart.pageX = touchOver.pageX; | |||||
| // // touchStart.pageY = touchOver.pageY; | |||||
| // document.removeEventListener("mousemove", onMouseMove); | |||||
| // document.removeEventListener("mouseup", onMouseUp); | |||||
| // }; | |||||
| // document.addEventListener("mousemove", onMouseMove); | |||||
| // document.addEventListener("mouseup", onMouseUp); | |||||
| // } | |||||
| //#endregion -------------------------- | |||||
| //#region 素材图逻辑 | |||||
| const handleDragSc = (id, index, event) => { | |||||
| showBorderActive.value = id; | |||||
| event.preventDefault(); | |||||
| const imageElement = fatherBox.value; | |||||
| const startX = event.clientX; //保存初始值,避免闪烁 | |||||
| const startY = event.clientY; | |||||
| const startLeft = props.materialList.scList[index].x; | |||||
| const startTop = props.materialList.scList[index].y; | |||||
| // 鼠标移动 | |||||
| const onMouseMove = (event) => { | |||||
| const deltaX = event.clientX - startX; | |||||
| const deltaY = event.clientY - startY; | |||||
| props.materialList.scList[index].x = startLeft + deltaX; | |||||
| props.materialList.scList[index].y = startTop + deltaY; | |||||
| }; | |||||
| // 鼠标抬起 | |||||
| const onMouseUp = () => { | |||||
| document.removeEventListener("mousemove", onMouseMove); | |||||
| document.removeEventListener("mouseup", onMouseUp); | |||||
| }; | |||||
| document.addEventListener("mousemove", onMouseMove); | |||||
| document.addEventListener("mouseup", onMouseUp); | |||||
| }; | |||||
| function changeScaleSc(index, event) { | |||||
| event.preventDefault(); | |||||
| const x = event.clientX; | |||||
| const y = event.clientY; | |||||
| touchStart.pageX = x; | |||||
| touchStart.pageY = y; | |||||
| // 鼠标移动 | |||||
| const onMouseMove = (event) => { | |||||
| let MoveX = event.clientX; | |||||
| let MoveY = event.clientY; | |||||
| let flag = Math.sign(x - touchStart.pageX) == -1 ? true : false; | |||||
| if (flag) { | |||||
| // 限制最大缩放系数 | |||||
| if (props.materialList.scList[index].w > 1.3) return; | |||||
| props.materialList.scList[index].w += scaleNum.value; | |||||
| // 更新坐标位置 | |||||
| touchStart.pageX = MoveX; | |||||
| touchStart.pageY = MoveY; | |||||
| } else { | |||||
| // 限制最小缩放系数 | |||||
| if (props.materialList.scList[index].w < 0.4) return; | |||||
| props.materialList.scList[index].w -= scaleNum.value; | |||||
| // 更新坐标位置 | |||||
| touchStart.pageX = MoveX; | |||||
| touchStart.pageY = MoveY; | |||||
| } | |||||
| }; | |||||
| // 鼠标抬起 | |||||
| const onMouseUp = () => { | |||||
| document.removeEventListener("mousemove", onMouseMove); | |||||
| document.removeEventListener("mouseup", onMouseUp); | |||||
| }; | |||||
| document.addEventListener("mousemove", onMouseMove); | |||||
| document.addEventListener("mouseup", onMouseUp); | |||||
| } | |||||
| function delScListItem(index) { | |||||
| const msg = | |||||
| lanChange.value == "zh-cn" | |||||
| ? "确定删除素材吗吗?" | |||||
| : "Are you sure you want to delete the footage?"; | |||||
| const notice = lanChange.value == "zh-cn" ? "提示" : "Notice"; | |||||
| const confirm = lanChange.value == "zh-cn" ? "确定" : "Confirm"; | |||||
| const cancel = lanChange.value == "zh-cn" ? "取消" : "Cancel"; | |||||
| ElMessageBox.confirm(msg, notice, { | |||||
| confirmButtonText: confirm, | |||||
| cancelButtonText: cancel, | |||||
| }).then(() => { | |||||
| props.materialList.scList.splice(index, 1); | |||||
| }); | |||||
| } | |||||
| //#endregion -------------------------- | |||||
| //#region 控制台回显 | |||||
| watch( | |||||
| () => showBorderActive.value, | |||||
| (newValue, oldValue) => { | |||||
| props.showImgInfo.id = showBorderActive.value; | |||||
| }, | |||||
| { deep: true } | |||||
| ); | |||||
| //#endregion -------------------------- | //#endregion -------------------------- | ||||
| //#region | //#region | ||||
| @@ -122,6 +427,11 @@ const handleDrag = (id, event) => { | |||||
| user-select: none; | user-select: none; | ||||
| border: rgba(0, 0, 0, 0) 5px solid; | border: rgba(0, 0, 0, 0) 5px solid; | ||||
| } | } | ||||
| .scListItem { | |||||
| position: absolute; | |||||
| user-select: none; | |||||
| border: rgba(0, 0, 0, 0) 5px solid; | |||||
| } | |||||
| .border { | .border { | ||||
| border: 5px solid #00ff00; | border: 5px solid #00ff00; | ||||
| .stretchBox { | .stretchBox { | ||||
| @@ -135,25 +445,48 @@ const handleDrag = (id, event) => { | |||||
| top: -10px; | top: -10px; | ||||
| left: -10px; | left: -10px; | ||||
| cursor: nwse-resize; | cursor: nwse-resize; | ||||
| display: none; | |||||
| } | } | ||||
| .box2 { | .box2 { | ||||
| top: -10px; | |||||
| top: -50px; | |||||
| left: 100%; | left: 100%; | ||||
| transform: translateX(-10px); | |||||
| cursor: nesw-resize; | |||||
| transform: translateX(-50px); | |||||
| // cursor: nesw-resize; | |||||
| cursor: pointer; | |||||
| background-color: rgba(0, 0, 0, 0); | |||||
| width: 100px; | |||||
| height: 100px; | |||||
| img { | |||||
| width: 100px; | |||||
| height: 100px; | |||||
| } | |||||
| } | } | ||||
| .box3 { | .box3 { | ||||
| top: 100%; | top: 100%; | ||||
| left: -10px; | left: -10px; | ||||
| transform: translateY(-10px); | transform: translateY(-10px); | ||||
| cursor: nesw-resize; | cursor: nesw-resize; | ||||
| display: none; | |||||
| } | } | ||||
| .box4 { | .box4 { | ||||
| top: 100%; | top: 100%; | ||||
| left: 100%; | left: 100%; | ||||
| transform: translate(-10px, -10px); | |||||
| transform: translate(-50px, -50px); | |||||
| cursor: nwse-resize; | cursor: nwse-resize; | ||||
| // background-color: rgba(0, 0, 0, 0); | |||||
| background-color: #fff; | |||||
| width: 100px; | |||||
| height: 100px; | |||||
| border-radius: 50px; | |||||
| img { | |||||
| position: absolute; | |||||
| top: 50%; | |||||
| left: 50%; | |||||
| transform: translate(-50%, -50%) rotate(90deg); | |||||
| max-width: 65px; | |||||
| max-height: 65px; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| </style> | </style> | ||||
| @@ -15,15 +15,74 @@ | |||||
| :style="virtualStyle" | :style="virtualStyle" | ||||
| > | > | ||||
| <img id="virtualImg" :src="materialList.virtual.material" alt="" /> | <img id="virtualImg" :src="materialList.virtual.material" alt="" /> | ||||
| <div class="stretchBox box1"></div> | |||||
| <div ref="box1" class="stretchBox box1"></div> | |||||
| <div class="stretchBox box2"></div> | <div class="stretchBox box2"></div> | ||||
| <div class="stretchBox box3"></div> | <div class="stretchBox box3"></div> | ||||
| <div @mousedown.stop="changeScale" class="stretchBox box4"></div> | |||||
| <div | |||||
| v-show="showBorderActive == materialList.virtual.id" | |||||
| ref="box4" | |||||
| @mousedown.stop="changeScale" | |||||
| class="stretchBox box4" | |||||
| > | |||||
| <img | |||||
| style="width: 100px; height: 100px" | |||||
| src="../assets/img/Scale.png" | |||||
| alt="" | |||||
| /> | |||||
| </div> | |||||
| </div> | |||||
| <!-- 素材图的图片 --> | |||||
| <div | |||||
| v-for="(item, index) in materialList.scList" | |||||
| :key="item.id" | |||||
| class="scListItem" | |||||
| :class="showBorderActive == item.id ? 'border' : ''" | |||||
| @mousedown="handleDragSc(item.id, index, $event)" | |||||
| :style="{ | |||||
| top: item.y / props.proportion + 'px', | |||||
| left: item.x / props.proportion + 'px', | |||||
| transform: 'scale(' + item.w / props.proportion + ') ', | |||||
| transformOrigin: 'top left', | |||||
| zIndex: item.z, | |||||
| }" | |||||
| > | |||||
| <img id="scListItemImg" :src="item.material" alt="" /> | |||||
| <div ref="box1" class="stretchBox box1"></div> | |||||
| <div | |||||
| v-show="showBorderActive == item.id" | |||||
| class="stretchBox box2" | |||||
| @click="delScListItem(index)" | |||||
| > | |||||
| <img | |||||
| style="width: 100px; height: 100px" | |||||
| src="../assets/img/delete2.png" | |||||
| alt="" | |||||
| /> | |||||
| </div> | |||||
| <div class="stretchBox box3"></div> | |||||
| <div | |||||
| v-show="showBorderActive == item.id" | |||||
| ref="box4" | |||||
| @mousedown.stop="changeScaleSc(index, $event)" | |||||
| class="stretchBox box4" | |||||
| > | |||||
| <img | |||||
| style="width: 100px; height: 100px" | |||||
| src="../assets/img/Scale.png" | |||||
| alt="" | |||||
| /> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| <script setup> | <script setup> | ||||
| //#region 导入 | |||||
| import { useI18n } from "vue-i18n"; | |||||
| //#endregion -------------------------- | |||||
| const { locale } = useI18n(); | |||||
| const lanChange = ref(locale); | |||||
| //#region 父组件传参 | //#region 父组件传参 | ||||
| const props = defineProps({ | const props = defineProps({ | ||||
| // isLoading: { | // isLoading: { | ||||
| @@ -38,6 +97,9 @@ const props = defineProps({ | |||||
| proportion: { | proportion: { | ||||
| required: true, | required: true, | ||||
| }, | }, | ||||
| showImgInfo: { | |||||
| required: true, | |||||
| }, | |||||
| }); | }); | ||||
| //#endregion -------------------------- | //#endregion -------------------------- | ||||
| @@ -58,11 +120,12 @@ const bgStyle = computed(() => { | |||||
| // 计算属性来计算盒子位置和大小 | // 计算属性来计算盒子位置和大小 | ||||
| const virtualStyle = computed(() => { | const virtualStyle = computed(() => { | ||||
| return { | return { | ||||
| top: props.materialList.virtual.y + "px", | |||||
| left: props.materialList.virtual.x + "px", | |||||
| top: props.materialList.virtual.y / props.proportion + "px", | |||||
| left: props.materialList.virtual.x / props.proportion + "px", | |||||
| transform: | transform: | ||||
| "scale(" + props.materialList.virtual.w / props.proportion + ") ", | "scale(" + props.materialList.virtual.w / props.proportion + ") ", | ||||
| transformOrigin: "top left", | transformOrigin: "top left", | ||||
| zIndex: props.materialList.virtual.z, | |||||
| }; | }; | ||||
| }); | }); | ||||
| // 拖动盒子 | // 拖动盒子 | ||||
| @@ -81,8 +144,8 @@ const handleDrag = (id, event) => { | |||||
| const onMouseMove = (event) => { | const onMouseMove = (event) => { | ||||
| const deltaX = event.clientX - startX; | const deltaX = event.clientX - startX; | ||||
| const deltaY = event.clientY - startY; | const deltaY = event.clientY - startY; | ||||
| props.materialList.virtual.x = startLeft + deltaX; | |||||
| props.materialList.virtual.y = startTop + deltaY; | |||||
| props.materialList.virtual.x = startLeft + deltaX * props.proportion; | |||||
| props.materialList.virtual.y = startTop + deltaY * props.proportion; | |||||
| }; | }; | ||||
| // 鼠标抬起 | // 鼠标抬起 | ||||
| @@ -95,42 +158,92 @@ const handleDrag = (id, event) => { | |||||
| document.addEventListener("mouseup", onMouseUp); | document.addEventListener("mouseup", onMouseUp); | ||||
| }; | }; | ||||
| // 缩放盒子 | // 缩放盒子 | ||||
| let touchStart = reactive({ | |||||
| const touchStart = ref({ | |||||
| pageX: null, | |||||
| pageY: null, | |||||
| }); | |||||
| const touchOver = ref({ | |||||
| pageX: null, | pageX: null, | ||||
| pageY: null, | pageY: null, | ||||
| }); | }); | ||||
| const scaleNum = ref(0.003); | |||||
| const scaleNum = ref(0.004); | |||||
| // 初始版 | |||||
| // function changeScale(event) { | |||||
| // event.preventDefault(); | |||||
| // const x = event.clientX; | |||||
| // const y = event.clientY; | |||||
| // // touchStart = { | |||||
| // // pageX: x, | |||||
| // // pageY: y, | |||||
| // // }; | |||||
| // touchStart.pageX = x; | |||||
| // touchStart.pageY = y; | |||||
| // // 鼠标移动 | |||||
| // const onMouseMove = (event) => { | |||||
| // const MoveX = event.clientX; | |||||
| // const MoveY = event.clientY; | |||||
| // const flag = Math.sign(x - touchStart.pageX) == -1 ? true : false; | |||||
| // if (flag) { | |||||
| // // 限制最大缩放系数 | |||||
| // if (props.materialList.virtual.w > 1.3) return; | |||||
| // props.materialList.virtual.w += scaleNum.value; | |||||
| // // 更新坐标位置 | |||||
| // // touchStart = { | |||||
| // // pageX: MoveX, | |||||
| // // pageY: MoveY, | |||||
| // // }; | |||||
| // touchStart.pageX = MoveX; | |||||
| // touchStart.pageY = MoveY; | |||||
| // } else { | |||||
| // // 限制最小缩放系数 | |||||
| // if (props.materialList.virtual.w < 0.4) return; | |||||
| // props.materialList.virtual.w -= scaleNum.value; | |||||
| // // 更新坐标位置 | |||||
| // // touchStart = { | |||||
| // // pageX: MoveX, | |||||
| // // pageY: MoveY, | |||||
| // // }; | |||||
| // touchStart.pageX = MoveX; | |||||
| // touchStart.pageY = MoveY; | |||||
| // } | |||||
| // }; | |||||
| // // 鼠标抬起 | |||||
| // const onMouseUp = () => { | |||||
| // document.removeEventListener("mousemove", onMouseMove); | |||||
| // document.removeEventListener("mouseup", onMouseUp); | |||||
| // }; | |||||
| // document.addEventListener("mousemove", onMouseMove); | |||||
| // document.addEventListener("mouseup", onMouseUp); | |||||
| // } | |||||
| // 改动版 | |||||
| function changeScale(event) { | function changeScale(event) { | ||||
| event.preventDefault(); | event.preventDefault(); | ||||
| const x = event.clientX; | const x = event.clientX; | ||||
| const y = event.clientY; | const y = event.clientY; | ||||
| touchStart = { | |||||
| pageX: x, | |||||
| pageY: y, | |||||
| }; | |||||
| touchStart.pageX = x; | |||||
| touchStart.pageY = y; | |||||
| // 鼠标移动 | // 鼠标移动 | ||||
| const onMouseMove = (event) => { | const onMouseMove = (event) => { | ||||
| const MoveX = event.clientX; | const MoveX = event.clientX; | ||||
| const MoveY = event.clientY; | const MoveY = event.clientY; | ||||
| const flag = Math.sign(x - touchStart.pageX) == -1 ? true : false; | |||||
| let flag = Math.sign(x - touchStart.pageX) == -1 ? true : false; | |||||
| if (flag) { | if (flag) { | ||||
| // 限制最大缩放系数 | // 限制最大缩放系数 | ||||
| if (props.materialList.virtual.w > 1.3) return; | if (props.materialList.virtual.w > 1.3) return; | ||||
| props.materialList.virtual.w += scaleNum.value; | props.materialList.virtual.w += scaleNum.value; | ||||
| // 更新坐标位置 | // 更新坐标位置 | ||||
| touchStart = { | |||||
| pageX: MoveX, | |||||
| pageY: MoveY, | |||||
| }; | |||||
| touchStart.pageX = MoveX; | |||||
| touchStart.pageY = MoveY; | |||||
| } else { | } else { | ||||
| // 限制最小缩放系数 | // 限制最小缩放系数 | ||||
| if (props.materialList.virtual.w < 0.4) return; | if (props.materialList.virtual.w < 0.4) return; | ||||
| props.materialList.virtual.w -= scaleNum.value; | props.materialList.virtual.w -= scaleNum.value; | ||||
| // 更新坐标位置 | // 更新坐标位置 | ||||
| touchStart = { | |||||
| pageX: MoveX, | |||||
| pageY: MoveY, | |||||
| }; | |||||
| touchStart.pageX = MoveX; | |||||
| touchStart.pageY = MoveY; | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -143,6 +256,149 @@ function changeScale(event) { | |||||
| document.addEventListener("mousemove", onMouseMove); | document.addEventListener("mousemove", onMouseMove); | ||||
| document.addEventListener("mouseup", onMouseUp); | document.addEventListener("mouseup", onMouseUp); | ||||
| } | } | ||||
| const box1 = ref(null); | |||||
| const box2 = ref(null); | |||||
| const box3 = ref(null); | |||||
| const box4 = ref(null); | |||||
| // 距离版 | |||||
| // function changeScale(event) { | |||||
| // const box1Element = box1.value; | |||||
| // const box4Element = box4.value; | |||||
| // if (!box1Element || !box4Element) { | |||||
| // return; | |||||
| // } | |||||
| // touchStart.pageX = event.clientX; | |||||
| // touchStart.pageY = event.clientY; | |||||
| // const box1Rect = box1Element.getBoundingClientRect(); | |||||
| // const box4Rect = box4Element.getBoundingClientRect(); | |||||
| // const boxDistance = Math.sqrt( | |||||
| // (box1Rect.left - box4Rect.left) ** 2 + (box1Rect.top - box4Rect.top) ** 2 | |||||
| // ).toFixed(0); | |||||
| // const onMouseMove = (event) => { | |||||
| // const x = event.clientX; | |||||
| // const y = event.clientY; | |||||
| // const deltaX = touchStart.pageX - x; | |||||
| // const deltaY = touchStart.pageY - y; | |||||
| // const boxDistance2 = Math.sqrt(deltaX ** 2 + deltaY ** 2).toFixed(0); | |||||
| // if (deltaX < 0) { | |||||
| // props.materialList.virtual.w = Math.min( | |||||
| // Math.max((boxDistance + boxDistance2) / boxDistance, 0.4), | |||||
| // 1.3 | |||||
| // ); | |||||
| // } else { | |||||
| // props.materialList.virtual.w = Math.min( | |||||
| // Math.max((boxDistance - boxDistance2) / boxDistance, 0.4), | |||||
| // 1.3 | |||||
| // ); | |||||
| // } | |||||
| // // touchOver.pageX = event.clientX; | |||||
| // // touchOver.pageY = event.clientY; | |||||
| // }; | |||||
| // // 鼠标抬起 | |||||
| // const onMouseUp = () => { | |||||
| // // touchStart.pageX = touchOver.pageX; | |||||
| // // touchStart.pageY = touchOver.pageY; | |||||
| // document.removeEventListener("mousemove", onMouseMove); | |||||
| // document.removeEventListener("mouseup", onMouseUp); | |||||
| // }; | |||||
| // document.addEventListener("mousemove", onMouseMove); | |||||
| // document.addEventListener("mouseup", onMouseUp); | |||||
| // } | |||||
| //#endregion -------------------------- | |||||
| //#region 素材图逻辑 | |||||
| const handleDragSc = (id, index, event) => { | |||||
| showBorderActive.value = id; | |||||
| event.preventDefault(); | |||||
| const imageElement = fatherBox.value; | |||||
| const startX = event.clientX; //保存初始值,避免闪烁 | |||||
| const startY = event.clientY; | |||||
| const startLeft = props.materialList.scList[index].x; | |||||
| const startTop = props.materialList.scList[index].y; | |||||
| // 鼠标移动 | |||||
| const onMouseMove = (event) => { | |||||
| const deltaX = event.clientX - startX; | |||||
| const deltaY = event.clientY - startY; | |||||
| props.materialList.scList[index].x = startLeft + deltaX * props.proportion; | |||||
| props.materialList.scList[index].y = startTop + deltaY * props.proportion; | |||||
| }; | |||||
| // 鼠标抬起 | |||||
| const onMouseUp = () => { | |||||
| document.removeEventListener("mousemove", onMouseMove); | |||||
| document.removeEventListener("mouseup", onMouseUp); | |||||
| }; | |||||
| document.addEventListener("mousemove", onMouseMove); | |||||
| document.addEventListener("mouseup", onMouseUp); | |||||
| }; | |||||
| function changeScaleSc(index, event) { | |||||
| event.preventDefault(); | |||||
| const x = event.clientX; | |||||
| const y = event.clientY; | |||||
| touchStart.pageX = x; | |||||
| touchStart.pageY = y; | |||||
| // 鼠标移动 | |||||
| const onMouseMove = (event) => { | |||||
| let MoveX = event.clientX; | |||||
| let MoveY = event.clientY; | |||||
| let flag = Math.sign(x - touchStart.pageX) == -1 ? true : false; | |||||
| if (flag) { | |||||
| // 限制最大缩放系数 | |||||
| if (props.materialList.scList[index].w > 1.3) return; | |||||
| props.materialList.scList[index].w += scaleNum.value; | |||||
| // 更新坐标位置 | |||||
| touchStart.pageX = MoveX; | |||||
| touchStart.pageY = MoveY; | |||||
| } else { | |||||
| // 限制最小缩放系数 | |||||
| if (props.materialList.scList[index].w < 0.4) return; | |||||
| props.materialList.scList[index].w -= scaleNum.value; | |||||
| // 更新坐标位置 | |||||
| touchStart.pageX = MoveX; | |||||
| touchStart.pageY = MoveY; | |||||
| } | |||||
| }; | |||||
| // 鼠标抬起 | |||||
| const onMouseUp = () => { | |||||
| document.removeEventListener("mousemove", onMouseMove); | |||||
| document.removeEventListener("mouseup", onMouseUp); | |||||
| }; | |||||
| document.addEventListener("mousemove", onMouseMove); | |||||
| document.addEventListener("mouseup", onMouseUp); | |||||
| } | |||||
| function delScListItem(index) { | |||||
| const msg = | |||||
| lanChange.value == "zh-cn" | |||||
| ? "确定删除素材吗吗?" | |||||
| : "Are you sure you want to delete the footage?"; | |||||
| const notice = lanChange.value == "zh-cn" ? "提示" : "Notice"; | |||||
| const confirm = lanChange.value == "zh-cn" ? "确定" : "Confirm"; | |||||
| const cancel = lanChange.value == "zh-cn" ? "取消" : "Cancel"; | |||||
| ElMessageBox.confirm(msg, notice, { | |||||
| confirmButtonText: confirm, | |||||
| cancelButtonText: cancel, | |||||
| }).then(() => { | |||||
| props.materialList.scList.splice(index, 1); | |||||
| }); | |||||
| } | |||||
| //#endregion -------------------------- | |||||
| //#region 控制台回显 | |||||
| watch( | |||||
| () => showBorderActive.value, | |||||
| (newValue, oldValue) => { | |||||
| props.showImgInfo.id = showBorderActive.value; | |||||
| }, | |||||
| { deep: true } | |||||
| ); | |||||
| //#endregion -------------------------- | //#endregion -------------------------- | ||||
| //#region | //#region | ||||
| @@ -153,17 +409,23 @@ function changeScale(event) { | |||||
| .myPage { | .myPage { | ||||
| // height: 768px; | // height: 768px; | ||||
| // width: 432px; | // width: 432px; | ||||
| width: 100%; | |||||
| height: 100%; | |||||
| } | } | ||||
| .content1 { | .content1 { | ||||
| position: relative; | position: relative; | ||||
| height: 768px; | |||||
| width: 432px; | |||||
| // height: 768px; | |||||
| // width: 432px; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| overflow: hidden; | overflow: hidden; | ||||
| } | } | ||||
| .content2 { | .content2 { | ||||
| position: relative; | position: relative; | ||||
| height: 432px; | |||||
| width: 768px; | |||||
| // height: 432px; | |||||
| // width: 768px; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| overflow: hidden; | overflow: hidden; | ||||
| } | } | ||||
| .virtual { | .virtual { | ||||
| @@ -171,6 +433,11 @@ function changeScale(event) { | |||||
| user-select: none; | user-select: none; | ||||
| border: rgba(0, 0, 0, 0) 5px solid; | border: rgba(0, 0, 0, 0) 5px solid; | ||||
| } | } | ||||
| .scListItem { | |||||
| position: absolute; | |||||
| user-select: none; | |||||
| border: rgba(0, 0, 0, 0) 5px solid; | |||||
| } | |||||
| .border { | .border { | ||||
| border: 5px solid #00ff00; | border: 5px solid #00ff00; | ||||
| .stretchBox { | .stretchBox { | ||||
| @@ -184,25 +451,48 @@ function changeScale(event) { | |||||
| top: -10px; | top: -10px; | ||||
| left: -10px; | left: -10px; | ||||
| cursor: nwse-resize; | cursor: nwse-resize; | ||||
| display: none; | |||||
| } | } | ||||
| .box2 { | .box2 { | ||||
| top: -10px; | |||||
| top: -50px; | |||||
| left: 100%; | left: 100%; | ||||
| transform: translateX(-10px); | |||||
| cursor: nesw-resize; | |||||
| transform: translateX(-50px); | |||||
| // cursor: nesw-resize; | |||||
| cursor: pointer; | |||||
| background-color: rgba(0, 0, 0, 0); | |||||
| width: 100px; | |||||
| height: 100px; | |||||
| img { | |||||
| width: 100px; | |||||
| height: 100px; | |||||
| } | |||||
| } | } | ||||
| .box3 { | .box3 { | ||||
| top: 100%; | top: 100%; | ||||
| left: -10px; | left: -10px; | ||||
| transform: translateY(-10px); | transform: translateY(-10px); | ||||
| cursor: nesw-resize; | cursor: nesw-resize; | ||||
| display: none; | |||||
| } | } | ||||
| .box4 { | .box4 { | ||||
| top: 100%; | top: 100%; | ||||
| left: 100%; | left: 100%; | ||||
| transform: translate(-10px, -10px); | |||||
| transform: translate(-50px, -50px); | |||||
| cursor: nwse-resize; | cursor: nwse-resize; | ||||
| // background-color: rgba(0, 0, 0, 0); | |||||
| background-color: #fff; | |||||
| width: 100px; | |||||
| height: 100px; | |||||
| border-radius: 50px; | |||||
| img { | |||||
| position: absolute; | |||||
| top: 50%; | |||||
| left: 50%; | |||||
| transform: translate(-50%, -50%) rotate(90deg); | |||||
| max-width: 65px; | |||||
| max-height: 65px; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| </style> | </style> | ||||
| @@ -17,12 +17,12 @@ | |||||
| </div> | </div> | ||||
| {{ $t("createVideo.title") }} | {{ $t("createVideo.title") }} | ||||
| </div> | </div> | ||||
| <div class="myRouter-item" @click="router.push('/moveImg')"> | |||||
| <!-- <div class="myRouter-item" @click="router.push('/myCreating')"> | |||||
| <div class="icon"> | <div class="icon"> | ||||
| <el-icon><i-ep-edit /></el-icon> | <el-icon><i-ep-edit /></el-icon> | ||||
| </div> | </div> | ||||
| {{ $t("createVideo.title") }} | |||||
| </div> | |||||
| {{ $t("myCreating.title") }} | |||||
| </div> --> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <!-- 右边显示部分 --> | <!-- 右边显示部分 --> | ||||
| @@ -24,6 +24,7 @@ declare module '@vue/runtime-core' { | |||||
| ElFormItem: typeof import('element-plus/es')['ElFormItem'] | ElFormItem: typeof import('element-plus/es')['ElFormItem'] | ||||
| ElIcon: typeof import('element-plus/es')['ElIcon'] | ElIcon: typeof import('element-plus/es')['ElIcon'] | ||||
| ElInput: typeof import('element-plus/es')['ElInput'] | ElInput: typeof import('element-plus/es')['ElInput'] | ||||
| ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] | |||||
| ElOption: typeof import('element-plus/es')['ElOption'] | ElOption: typeof import('element-plus/es')['ElOption'] | ||||
| ElPagination: typeof import('element-plus/es')['ElPagination'] | ElPagination: typeof import('element-plus/es')['ElPagination'] | ||||
| ElRow: typeof import('element-plus/es')['ElRow'] | ElRow: typeof import('element-plus/es')['ElRow'] | ||||
| @@ -92,20 +92,68 @@ | |||||
| <div class="showModelImgBox"> | <div class="showModelImgBox"> | ||||
| <!-- <img :src="modelImg" alt="" /> --> | <!-- <img :src="modelImg" alt="" /> --> | ||||
| <!-- 编辑图片位置组件 --> | <!-- 编辑图片位置组件 --> | ||||
| <EditPosition | |||||
| id="editPosition" | |||||
| class="EditPosition" | |||||
| :materialList="materialList" | |||||
| :videoType="videoType" | |||||
| :proportion="proportion" | |||||
| <div | |||||
| :class="videoType == 1 ? 'EditPositionBox1' : 'EditPositionBox2'" | |||||
| class="" | |||||
| > | > | ||||
| </EditPosition> | |||||
| <EditPosition | |||||
| id="editPosition" | |||||
| :materialList="materialList" | |||||
| :videoType="videoType" | |||||
| :proportion="proportion" | |||||
| :showImgInfo="showImgInfo" | |||||
| > | |||||
| </EditPosition> | |||||
| </div> | |||||
| <!-- 控制台 --> | |||||
| <div v-if="showImgInfo.data" class="showImgInfoBox"> | |||||
| <!-- <div class="infoItem"> | |||||
| </div> --> | |||||
| <div class="ItemName">横坐标</div> | |||||
| <div class="ItemValue"> | |||||
| <el-input-number | |||||
| v-model="showImgInfo.data.x" | |||||
| size="large" | |||||
| controls-position="right" | |||||
| /> | |||||
| </div> | |||||
| <div class="ItemName">纵坐标</div> | |||||
| <div class="ItemValue"> | |||||
| <el-input-number | |||||
| v-model="showImgInfo.data.y" | |||||
| size="large" | |||||
| controls-position="right" | |||||
| /> | |||||
| </div> | |||||
| <div class="ItemName">层级</div> | |||||
| <div class="ItemValue"> | |||||
| <el-input-number | |||||
| v-model="showImgInfo.data.z" | |||||
| :min="1" | |||||
| :max="10" | |||||
| size="large" | |||||
| controls-position="right" | |||||
| /> | |||||
| </div> | |||||
| <div class="ItemName">缩放倍率</div> | |||||
| <div class="ItemValue"> | |||||
| <el-input-number | |||||
| v-model="showImgInfo.data.w" | |||||
| :min="0.4" | |||||
| :max="1.3" | |||||
| size="large" | |||||
| controls-position="right" | |||||
| /> | |||||
| </div> | |||||
| </div> | |||||
| <!-- 保存视频和生成视频 --> | <!-- 保存视频和生成视频 --> | ||||
| <div class="btnBox" v-show="!showChooseModel"> | <div class="btnBox" v-show="!showChooseModel"> | ||||
| <div class="customBtn" style="margin-right: 15px"> | <div class="customBtn" style="margin-right: 15px"> | ||||
| {{ $t("createVideo.saveVideo") }} | {{ $t("createVideo.saveVideo") }} | ||||
| </div> | </div> | ||||
| <div class="customBtn">{{ $t("createVideo.generateVideo") }}</div> | |||||
| <div class="customBtn"> | |||||
| {{ $t("createVideo.generateVideo") }} | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -416,6 +464,8 @@ import { | |||||
| personSCIListApi, | personSCIListApi, | ||||
| delImgApi, | delImgApi, | ||||
| personPatchApi, | personPatchApi, | ||||
| saveOrUpdateApi, | |||||
| createVideoApi, | |||||
| } from "@/apis/createVideo"; | } from "@/apis/createVideo"; | ||||
| import { useI18n } from "vue-i18n"; | import { useI18n } from "vue-i18n"; | ||||
| import Recorder from "js-audio-recorder"; //mp3插件 | import Recorder from "js-audio-recorder"; //mp3插件 | ||||
| @@ -534,7 +584,8 @@ const tabItemActive = ref(1); | |||||
| //#endregion ---------------------------- | //#endregion ---------------------------- | ||||
| //#region 文案及其音频 | //#region 文案及其音频 | ||||
| const title = ref(null); | |||||
| const title = | |||||
| lanChange.value == "zh-cn" ? ref("未定义标题") : ref("Undefined Title"); | |||||
| const textareaContent = ref(""); | const textareaContent = ref(""); | ||||
| function insertIcon() { | function insertIcon() { | ||||
| const textarea = document.getElementById("textInputId"); | const textarea = document.getElementById("textInputId"); | ||||
| @@ -743,6 +794,8 @@ async function reGetpersonBGIList() { | |||||
| const bjImgActive = ref(null); | const bjImgActive = ref(null); | ||||
| function selectBjImg(img) { | function selectBjImg(img) { | ||||
| bjImgActive.value = img.id; | bjImgActive.value = img.id; | ||||
| materialList.BGI.material = img.material; | |||||
| materialList.BGI.id = img.id; | |||||
| } | } | ||||
| //#endregion ---------------------------- | //#endregion ---------------------------- | ||||
| @@ -812,6 +865,7 @@ async function reGetpersonSCIList() { | |||||
| const scImgActive = ref(null); | const scImgActive = ref(null); | ||||
| function selectScImg(img) { | function selectScImg(img) { | ||||
| scImgActive.value = img.id; | scImgActive.value = img.id; | ||||
| materialList.scList.push({ ...img, x: 0, y: 0, z: 0, w: 1, h: 1 }); | |||||
| } | } | ||||
| // 删除上传的背景或素材 | // 删除上传的背景或素材 | ||||
| function delImg(id) { | function delImg(id) { | ||||
| @@ -849,8 +903,10 @@ watch( | |||||
| (newValue, oldValue) => { | (newValue, oldValue) => { | ||||
| // 根据横竖屏来确定比例 1竖2横 | // 根据横竖屏来确定比例 1竖2横 | ||||
| if (videoType.value == 1) { | if (videoType.value == 1) { | ||||
| proportion.value = 1080 / elementWidth.value; | |||||
| // proportion.value = 1080 / elementWidth.value; | |||||
| proportion.value = 1080 / 432; | |||||
| } else if (videoType.value == 2) { | } else if (videoType.value == 2) { | ||||
| proportion.value = 1920 / 768; | |||||
| proportion.value = 1920 / elementWidth.value; | proportion.value = 1920 / elementWidth.value; | ||||
| } | } | ||||
| console.log(proportion.value); | console.log(proportion.value); | ||||
| @@ -891,6 +947,101 @@ watch( | |||||
| ); | ); | ||||
| //#endregion ---------------------------- | //#endregion ---------------------------- | ||||
| //#region 编辑区域控制台 | |||||
| const showImgInfo = ref({ | |||||
| id: null, | |||||
| data: null, | |||||
| }); //显示素材or数字人的id | |||||
| // const showImgInfoData = ref(null); | |||||
| watch( | |||||
| () => showImgInfo, | |||||
| (newValue, oldValue) => { | |||||
| if (materialList.virtual.id == showImgInfo.value.id) { | |||||
| showImgInfo.value.data = materialList.virtual; | |||||
| } else { | |||||
| showImgInfo.value.data = materialList.scList.find( | |||||
| (item) => item.id == showImgInfo.value.id | |||||
| ); | |||||
| } | |||||
| }, | |||||
| { deep: true } | |||||
| ); | |||||
| //#endregion ---------------------------- | |||||
| //#region 保存视频和生成草稿 | |||||
| const workId = ref(null); //保存作品完成后会有一个id,用于生成视频 | |||||
| async function saveOrUpdate() { | |||||
| try { | |||||
| if (!textareaContent.value) { | |||||
| ElMessage.error( | |||||
| lanChange.value == "zh-cn" | |||||
| ? `您还没有输入文案` | |||||
| : `You have not entered the copy yet` | |||||
| ); | |||||
| return; | |||||
| } | |||||
| if (!sound.value && !soundStyle.value) { | |||||
| ElMessage.error( | |||||
| lanChange.value == "zh-cn" | |||||
| ? `您还没有选择声音` | |||||
| : `You have not selected a sound` | |||||
| ); | |||||
| return; | |||||
| } | |||||
| // 处理数字人 | |||||
| const shuziren = { | |||||
| id: materialList.virtual.id, | |||||
| type: 1, | |||||
| material: materialList.virtual.material, | |||||
| x: materialList.virtual.x, | |||||
| y: materialList.virtual.y, | |||||
| z: materialList.virtual.z, | |||||
| w: materialList.virtual.w, | |||||
| h: materialList.virtual.h, | |||||
| }; | |||||
| // 处理素材 | |||||
| const scList = materialList.scList.map((item) => { | |||||
| return { | |||||
| id: item.id, | |||||
| type: 5, | |||||
| material: item.material, | |||||
| x: item.x, | |||||
| y: item.y, | |||||
| z: item.z, | |||||
| w: item.w, | |||||
| h: item.h, | |||||
| }; | |||||
| }); | |||||
| // 处理上传数据 | |||||
| const data = { | |||||
| id: workId.value, | |||||
| videoType: videoType.value, //横屏竖屏 | |||||
| personMouldId: materialList.virtual.id, //数字人id | |||||
| voiceMouldIds: [soundStyle.value ? soundStyle.value : sound.value], //声音id | |||||
| title: title.value, //标题 | |||||
| paperwork: textareaContent.value, //语音内容 | |||||
| backgroundId: materialList.BGI.id + "", //背景id | |||||
| personJson: JSON.stringify(shuziren), // 数字人 | |||||
| materialAllJson: JSON.stringify([...scList]), // 素材 | |||||
| }; | |||||
| const res = await saveOrUpdateApi(data); | |||||
| workId.value = res.data.id; | |||||
| } catch (error) { | |||||
| ElMessage.error(error); | |||||
| } | |||||
| } | |||||
| async function createVideo() { | |||||
| try { | |||||
| await saveOrUpdate(); | |||||
| const res2 = await createVideoApi(workId.value); | |||||
| } catch (error) { | |||||
| ElMessage.error(error); | |||||
| } | |||||
| } | |||||
| //#endregion ---------------------------- | |||||
| //#region | //#region | ||||
| //#endregion ---------------------------- | //#endregion ---------------------------- | ||||
| @@ -1080,13 +1231,54 @@ onMounted(async () => { | |||||
| max-width: 800px; | max-width: 800px; | ||||
| max-height: 800px; | max-height: 800px; | ||||
| } | } | ||||
| .EditPosition { | |||||
| .EditPositionBox1 { | |||||
| position: absolute; | position: absolute; | ||||
| top: 50%; | top: 50%; | ||||
| left: 50%; | left: 50%; | ||||
| transform: translate(-50%, -50%); | transform: translate(-50%, -50%); | ||||
| max-width: 800px; | |||||
| max-height: 800px; | |||||
| height: 768px; | |||||
| width: 432px; | |||||
| } | |||||
| .EditPositionBox2 { | |||||
| position: absolute; | |||||
| top: 50%; | |||||
| left: 50%; | |||||
| transform: translate(-50%, -50%); | |||||
| height: 432px; | |||||
| width: 768px; | |||||
| } | |||||
| .showImgInfoBox { | |||||
| position: absolute; | |||||
| top: 200px; | |||||
| right: 0px; | |||||
| width: 120px; | |||||
| background-color: #e9ecf1; | |||||
| border-radius: 20px; | |||||
| padding: 10px; | |||||
| box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 15px; | |||||
| .ItemName { | |||||
| width: 100%; | |||||
| height: 40px; | |||||
| text-align: center; | |||||
| line-height: 40px; | |||||
| background-color: #fff; | |||||
| border-radius: 10px; | |||||
| } | |||||
| .ItemValue { | |||||
| margin-bottom: 10px; | |||||
| width: 100%; | |||||
| height: 40px; | |||||
| text-align: center; | |||||
| line-height: 40px; | |||||
| background-color: #f5f7fa; | |||||
| border-radius: 10px; | |||||
| .el-input-number--large { | |||||
| width: 100px; | |||||
| } | |||||
| .el-input-number__increase { | |||||
| width: none; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| .btnBox { | .btnBox { | ||||
| position: absolute; | position: absolute; | ||||