Browse Source

1

dev_YWQ
congzc 1 year ago
parent
commit
ae5cb82e8d
3 changed files with 189 additions and 145 deletions
  1. +1
    -1
      index.html
  2. +129
    -121
      src/components/EditPosition.vue
  3. +59
    -23
      src/views/createVideo/index.vue

+ 1
- 1
index.html View File

@@ -5,7 +5,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Metavatar-PC-Admin</title>
<title>Metavatar-PC</title>
</head>

<body>


+ 129
- 121
src/components/EditPosition.vue View File

@@ -1,5 +1,14 @@
<template>
<div class="myPage">
<!-- 获取点图片原始大小 -->
<img
draggable="false"
v-if="realImgUrl"
ref="realImg"
:src="realImgUrl"
alt=""
class="realImg"
/>
<!-- 主要显示 -->
<div
:class="props.videoType == 1 ? 'content1' : 'content2'"
@@ -11,10 +20,15 @@
<div
class="virtual"
:class="showBorderActive == materialList.virtual.id ? 'border' : ''"
@mousedown="handleDrag(materialList.virtual.id, $event)"
@mousedown.stop="handleDrag(materialList.virtual, $event)"
:style="virtualStyle"
>
<img id="virtualImg" :src="materialList.virtual.material" alt="" />
<img
id="virtualImg"
draggable="false"
:src="materialList.virtual.material"
alt=""
/>
<div ref="box1" class="stretchBox box1"></div>
<div class="stretchBox box2"></div>
<div class="stretchBox box3"></div>
@@ -25,6 +39,7 @@
class="stretchBox box4"
>
<img
draggable="false"
style="width: 100px; height: 100px"
src="../assets/img/Scale.png"
alt=""
@@ -37,7 +52,7 @@
:key="item.id"
class="scListItem"
:class="showBorderActive == item.id ? 'border' : ''"
@mousedown="handleDragSc(item.id, index, $event)"
@mousedown.stop="handleDragSc(item, index, $event)"
:style="{
top: item.y / props.proportion + 'px',
left: item.x / props.proportion + 'px',
@@ -46,7 +61,7 @@
zIndex: item.z,
}"
>
<img id="scListItemImg" :src="item.material" alt="" />
<img id="scListItemImg" draggable="false" :src="item.material" alt="" />
<div ref="box1" class="stretchBox box1"></div>
<div
v-show="showBorderActive == item.id"
@@ -54,6 +69,7 @@
@click="delScListItem(index)"
>
<img
draggable="false"
style="width: 100px; height: 100px"
src="../assets/img/delete2.png"
alt=""
@@ -67,6 +83,7 @@
class="stretchBox box4"
>
<img
draggable="false"
style="width: 100px; height: 100px"
src="../assets/img/Scale.png"
alt=""
@@ -76,6 +93,7 @@
</div>
</div>
</template>
<script setup>
//#region 导入
import { useI18n } from "vue-i18n";
@@ -129,10 +147,12 @@ const virtualStyle = computed(() => {
};
});
// 拖动盒子
const showBorderActive = ref(null); //判断显示边框
const showBorderActive = ref(-1); //判断显示边框
const fatherBox = ref(null);
const handleDrag = (id, event) => {
showBorderActive.value = id;
const handleDrag = (item, event) => {
realImgUrl.value = item.material;
console.log(realImgUrl.value);
showBorderActive.value = item.id;
event.preventDefault();
const imageElement = fatherBox.value;
const startX = event.clientX; //保存初始值,避免闪烁
@@ -167,31 +187,24 @@ const touchOver = ref({
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;
// 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,
// // pageY: MoveY,
// // };
// touchStart.pageX = MoveX;
// touchStart.pageY = MoveY;
// } else {
@@ -199,10 +212,6 @@ const scaleNum = ref(0.004);
// 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;
// }
@@ -218,37 +227,47 @@ const scaleNum = ref(0.004);
// document.addEventListener("mouseup", onMouseUp);
// }
// 改动
// 距离
function changeScale(event) {
event.preventDefault();
const x = event.clientX;
const y = event.clientY;
touchStart.pageX = x;
touchStart.pageY = y;
// 鼠标移动
event.stopPropagation();
const baseLine = Diagonal.value / props.proportion; //原图基线
const baseLineScale = baseLine * props.materialList.virtual.w; //缩放后的基线
touchStart.pageX = event.clientX;
touchStart.pageY = event.clientY;
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;
let x = event.clientX;
let y = event.clientY;
let deltaX = touchStart.pageX - x;
let deltaY = touchStart.pageY - y;
let boxDistance2 = Number(Math.sqrt(deltaX ** 2 + deltaY ** 2).toFixed(0));
if (deltaX < 0) {
if (props.materialList.virtual.w < 0.4) {
props.materialList.virtual.w = 0.4;
return;
}
props.materialList.virtual.w = Number(
(baseLineScale + boxDistance2) / baseLine
);
props.materialList.virtual.w = Number(
Number(props.materialList.virtual.w).toFixed(2)
);
} else {
// 限制最小缩放系数
if (props.materialList.virtual.w < 0.4) return;
props.materialList.virtual.w -= scaleNum.value;
// 更新坐标位置
touchStart.pageX = MoveX;
touchStart.pageY = MoveY;
if (props.materialList.virtual.w > 1.3) {
props.materialList.virtual.w = 1.3;
return;
}
props.materialList.virtual.w = Number(
(baseLineScale - boxDistance2) / baseLine
);
props.materialList.virtual.w = Number(
Number(props.materialList.virtual.w).toFixed(2)
);
}
};
// 鼠标抬起
const onMouseUp = () => {
// touchStart.pageX = touchOver.pageX;
// touchStart.pageY = touchOver.pageY;
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
@@ -256,63 +275,14 @@ function changeScale(event) {
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;
const handleDragSc = (item, index, event) => {
realImgUrl.value = item.material;
showBorderActive.value = item.id;
event.preventDefault();
const imageElement = fatherBox.value;
const startX = event.clientX; //保存初始值,避免闪烁
@@ -337,36 +307,47 @@ const handleDragSc = (id, index, event) => {
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;
// 鼠标移动
event.stopPropagation();
const baseLine = Diagonal.value / props.proportion; //原图基线
const baseLineScale = baseLine * props.materialList.scList[index].w; //缩放后的基线
touchStart.pageX = event.clientX;
touchStart.pageY = event.clientY;
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;
let x = event.clientX;
let y = event.clientY;
let deltaX = touchStart.pageX - x;
let deltaY = touchStart.pageY - y;
let boxDistance2 = Number(Math.sqrt(deltaX ** 2 + deltaY ** 2).toFixed(0));
if (deltaX < 0) {
if (props.materialList.scList[index].w < 0.4) {
props.materialList.scList[index].w = 0.4;
return;
}
props.materialList.scList[index].w = Number(
(baseLineScale + boxDistance2) / baseLine
);
props.materialList.scList[index].w = Number(
Number(props.materialList.scList[index].w).toFixed(2)
);
} else {
// 限制最小缩放系数
if (props.materialList.scList[index].w < 0.4) return;
props.materialList.scList[index].w -= scaleNum.value;
// 更新坐标位置
touchStart.pageX = MoveX;
touchStart.pageY = MoveY;
if (props.materialList.scList[index].w > 1.3) {
props.materialList.scList[index].w = 1.3;
return;
}
props.materialList.scList[index].w = Number(
(baseLineScale - boxDistance2) / baseLine
);
props.materialList.scList[index].w = Number(
Number(props.materialList.scList[index].w).toFixed(2)
);
}
};
// 鼠标抬起
const onMouseUp = () => {
// touchStart.pageX = touchOver.pageX;
// touchStart.pageY = touchOver.pageY;
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
@@ -401,16 +382,43 @@ watch(
);
//#endregion --------------------------
//#region 获取图片原始大小及其对角线长度
const realImg = ref(null); //dom
const realImgUrl = ref(null); //
const Diagonal = ref(null); //对角线长度
watch(
() => realImgUrl,
async (newValue, oldValue) => {
await nextTick();
console.log();
console.log();
Diagonal.value = Math.sqrt(
realImg.value.width ** 2 + realImg.value.height ** 2
).toFixed(0);
},
{ deep: true }
);
//#endregion --------------------------
//#region
//#endregion --------------------------
</script>
<style lang="scss" scoped>
.myPage {
// height: 768px;
// width: 432px;
position: relative;
width: 100%;
height: 100%;
.realImg {
position: absolute;
top: 0;
left: 0;
z-index: -2;
opacity: 0;
}
}
.content1 {
position: relative;


+ 59
- 23
src/views/createVideo/index.vue View File

@@ -1024,24 +1024,6 @@ async function saveOrUpdate(isCreate) {
}
try {
saveLoading.value = true;
if (!textareaContent.value) {
ElMessage.error(
lanChange.value == "zh-cn"
? `您还没有输入文案`
: `You have not entered the copy yet`
);
saveLoading.value = false;
return;
}
if (!sound.value && !soundStyle.value) {
ElMessage.error(
lanChange.value == "zh-cn"
? `您还没有选择声音`
: `You have not selected a sound`
);
saveLoading.value = false;
return;
}
// 处理数字人
const shuziren = {
id: materialList.virtual.id,
@@ -1071,7 +1053,9 @@ async function saveOrUpdate(isCreate) {
id: workId.value,
videoType: videoType.value, //横屏竖屏
personMouldId: materialList.virtual.id, //数字人id
voiceMouldIds: [soundStyle.value ? soundStyle.value : sound.value], //声音id
speakTypeStr: soundStyle.value, //声音风格
voiceMouldId: sound.value, //声音id
// voiceMouldIds: [soundStyle.value ? soundStyle.value : sound.value], //声音id
title: title.value, //标题
paperwork: textareaContent.value, //语音内容
backgroundId: materialList.BGI.id + "", //背景id
@@ -1086,6 +1070,7 @@ async function saveOrUpdate(isCreate) {
? `保存草稿成功!`
: `Save draft successfully!`
);
router.push("/myCreating");
} catch (error) {
ElMessage.error(error);
saveLoading.value = false;
@@ -1142,7 +1127,8 @@ async function saveOrUpdate(isCreate) {
id: workId.value,
videoType: videoType.value, //横屏竖屏
personMouldId: materialList.virtual.id, //数字人id
voiceMouldIds: [soundStyle.value ? soundStyle.value : sound.value], //声音id
speakTypeStr: soundStyle.value, //声音风格
voiceMouldId: sound.value, //声音id
title: title.value, //标题
paperwork: textareaContent.value, //语音内容
backgroundId: materialList.BGI.id + "", //背景id
@@ -1188,6 +1174,43 @@ async function createVideo() {
createLoading.value = false;
return;
}
// 获取预估时长
const res4 = await previewAudioApi(
textareaContent.value,
sound.value,
soundStyle.value
);
if (res4.data.code != 200) {
ElMessage.error(
lanChange.value == "zh-cn"
? `视频时长预估失败,无法生成视频,您可以换个声音试试`
: `Video duration estimation failed, can not generate video, you can try to change the sound`
);
createLoading.value = false;
saveLoading.value = false;
return;
}
if (res4.data.data > 60) {
ElMessage.error(
lanChange.value == "zh-cn"
? `预计生成的视频时长约为${formatTime(
res4.data.data
)},免费用户生成视频时长为60秒,无法生成视频`
: `The video generated is expected to be about ${formatTime(
res4.data.data
)} long, and the free user-generated video is 60 seconds long and cannot be generated`
);
createLoading.value = false;
saveLoading.value = false;
return;
}
ElMessage.success(
lanChange.value == "zh-cn"
? `预计生成的视频时长约为${formatTime(res4.data.data)}`
: `The video generated is expected to be approximately${formatTime(
res4.data.data
)} in length`
);
await saveOrUpdate("isCreate");
const res2 = await createVideoApi(workId.value);
ElMessage.success(
@@ -1202,27 +1225,40 @@ async function createVideo() {
createLoading.value = false;
}
}
// 预估时长时把秒转为分
function formatTime(seconds) {
const minutes = Math.floor(Math.floor(seconds) / 60);
const remainingSeconds = Math.floor(seconds) % 60;
const formattedMinutes = String(minutes).padStart(2, "0");
const formattedSeconds = String(remainingSeconds).padStart(2, "0");
return `${formattedMinutes}:${formattedSeconds}`;
}
//#endregion ----------------------------

//#region 草稿回显
async function getModelDetailById() {
const res = await getModelDetailByIdApi(route.query.id);
language.value = res.data.voiceInfo ? res.data.voiceInfo.languageId : null;
if (language.value) {
await chooseType(language.value);
}
workId.value = res.data.id;
videoType.value = res.data.videoType;
title.value = res.data.title; //标题
textareaContent.value = res.data.paperwork; //语音内容
materialList.BGI.id = res.data.backgroundId + ""; //背景id
// language.value = res.data.voiceMouldId;
// sound.value = res.data.voiceMouldId;
// soundStyle.value = JSON.parse(res.data.voiceMouldSm).speakTypeStr;
sound.value = res.data.voiceMouldId; //声音id
chooseStyle();
soundStyle.value = res.data.speakTypeStr; //选择风格
materialList.BGI.material = JSON.parse(res.data.backgroundSm).material;
materialList.virtual = JSON.parse(res.data.personJson);
materialList.virtual.id = res.data.personMouldId; //数字人id
materialList.scList = res.data.materialAllJson
? JSON.parse(res.data.materialAllJson)
: [];
console.log(sound.value);
console.log();
showChooseModel.value = false;
}
//#endregion ----------------------------



Loading…
Cancel
Save