From 63cba52999b7abd4fa2a9a420fd44db33778f8db Mon Sep 17 00:00:00 2001 From: congzc Date: Tue, 1 Aug 2023 17:52:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AD=97=E5=B9=95=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/EditPosition.vue | 49 +++---- src/lang/package/en.ts | 4 +- src/lang/package/zh-cn.ts | 4 +- src/layout/index.vue | 10 +- src/views/createVideo/index.vue | 231 +++++++++++++++++++++++++++++--- 5 files changed, 246 insertions(+), 52 deletions(-) diff --git a/src/components/EditPosition.vue b/src/components/EditPosition.vue index 82d308e..8c39478 100644 --- a/src/components/EditPosition.vue +++ b/src/components/EditPosition.vue @@ -221,29 +221,19 @@ function changeScale(event) { 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)); + let boxDistance2 = Math.sqrt(deltaX ** 2 + deltaY ** 2); 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) - ); + props.materialList.virtual.w = (baseLineScale + boxDistance2) / baseLine; } else { 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) - ); + props.materialList.virtual.w = (baseLineScale - boxDistance2) / baseLine; } }; // 鼠标抬起 @@ -301,29 +291,21 @@ function changeScaleSc(index, event) { 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)); + let boxDistance2 = Math.sqrt(deltaX ** 2 + deltaY ** 2); 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) - ); + props.materialList.scList[index].w = + (baseLineScale + boxDistance2) / baseLine; } else { 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) - ); + props.materialList.scList[index].w = + (baseLineScale - boxDistance2) / baseLine; } }; // 鼠标抬起 @@ -376,7 +358,7 @@ watch( console.log(); Diagonal.value = Math.sqrt( realImg.value.width ** 2 + realImg.value.height ** 2 - ).toFixed(0); + ); }, { deep: true } ); @@ -392,12 +374,13 @@ const SubtitlesStyle = computed(() => { leftX = (1920 / 2 - props.Subtitles.SubtitlesWidth / 2) / props.proportion + "px"; } - console.log(props.Subtitles.SubtitlesWidth); + // console.log(props.Subtitles.SubtitlesWidth); return { width: props.Subtitles.SubtitlesWidth / props.proportion + "px", top: props.Subtitles.SubtitlesTop / props.proportion + "px", left: leftX, - fontSize: props.Subtitles.SubtitlesSize / props.proportion + "px", + fontSize: props.Subtitles.SubtitlesSize + "px", + // fontWeight: props.Subtitles.SubtitlesWeight, fontFamily: props.Subtitles.SubtitlesFontFamily, color: props.Subtitles.SubtitlesColor, zIndex: 99, @@ -448,6 +431,12 @@ function BgraToRgba(hexColor) { } //#endregion -------------------------- +//#region 公共方法 +function NumToFixed(num1, num2) { + return Number(num1).toFixed(num2); +} +//#endregion ---------------------------- + //#region //#endregion -------------------------- @@ -498,7 +487,7 @@ function BgraToRgba(hexColor) { position: absolute; user-select: none; border: rgba(0, 0, 0, 0) 5px solid; - padding: 20px; + padding: 5px; text-align: center; white-space: nowrap; overflow: hidden; diff --git a/src/lang/package/en.ts b/src/lang/package/en.ts index 39b13ef..2d9dcd7 100644 --- a/src/lang/package/en.ts +++ b/src/lang/package/en.ts @@ -48,7 +48,8 @@ export default { navbar: { account: "Account", logout: "Logout", - goLogin:'Go and log in' + goLogin:'Go and log in', + LanguageChange:'Language switching' }, // 创作视频 @@ -100,6 +101,7 @@ export default { entered:'entered', tooltip2:'Add Pause', SubtitlesTip:"Subtitles will be shown here", + subtitlesSwitch:'Subtitles Switch', }, // 我的视频 diff --git a/src/lang/package/zh-cn.ts b/src/lang/package/zh-cn.ts index a896040..3acae3b 100644 --- a/src/lang/package/zh-cn.ts +++ b/src/lang/package/zh-cn.ts @@ -49,7 +49,8 @@ export default { navbar: { account: "账户", logout: "注销", - goLogin:'登录' + goLogin:'登录', + LanguageChange:'语言切换', }, // 创作视频 @@ -101,6 +102,7 @@ export default { entered:'已输入', tooltip2:'添加停顿', SubtitlesTip:"字幕将在此处展示", + subtitlesSwitch:'字幕开关', }, // 我的视频 diff --git a/src/layout/index.vue b/src/layout/index.vue index f15c893..0e74222 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -30,7 +30,15 @@ @@ -699,9 +771,10 @@ async function chooseType() { const soundStyleOptions = ref(null); async function chooseStyle() { const item = soundOptions.value.find((element) => element.id == sound.value); - soundStyle.value = null; - soundStyleOptions.value = item.style; + if (item) { + soundStyleOptions.value = item.style; + } } // 试听 @@ -994,11 +1067,13 @@ function delImg(id) { //#endregion ---------------------------- //#region 字幕 +const SubtitlesColorShow = ref(false); // 字色调色板开关 const Subtitles = reactive({ SubtitlesSwitch: false, //开关 SubtitlesFontFamily: "仿宋", //字体系列 SubtitlesTop: 400, //Y轴 - SubtitlesSize: 70, //字号大小 + SubtitlesSize: 30, //字号大小 + SubtitlesWeight: 500, //字粗 SubtitlesColor: "#FFFFFF", //字色 SubtitlesWidth: 500, //宽度 colorList: [ @@ -1031,8 +1106,44 @@ const Subtitles = reactive({ { label: "Times New Roman", value: "Times New Roman" }, { label: "Verdana", value: "Verdana" }, ], + fontSizeList: [12, 16, 20, 30, 44, 60, 80, 100], + fontWeightList: [100, 500, 900], }); - +const handleSubtitlesColorShow = (e) => { + e.stopPropagation(); // 阻止事件冒泡 + SubtitlesColorShow.value = true; + // SubtitlesBgcShow.value = false; +}; +const handleClickOutside = () => { + if (SubtitlesColorShow.value == true) { + } + SubtitlesColorShow.value = false; +}; +onMounted(() => { + document.addEventListener("click", handleClickOutside); +}); +function rgbaToBgra(hexColor) { + // 去除颜色前缀 + hexColor = hexColor.replace("#", ""); + // 分割颜色分量 + const red = hexColor.substring(0, 2); + const green = hexColor.substring(2, 4); + const blue = hexColor.substring(4, 6); + // 组合为新的颜色字符串 + const convertedColor = `&H${blue}${green}${red}`; + return convertedColor; +} +function BgraToRgba(hexColor) { + // 去除颜色前缀 + hexColor = hexColor.replace("&H", ""); + // 分割颜色分量 + const blue = hexColor.substring(0, 2); + const green = hexColor.substring(2, 4); + const red = hexColor.substring(4, 6); + // 组合为新的颜色字符串 + const convertedColor = `#${red}${green}${blue}`; + return convertedColor; +} //#endregion ---------------------------- //#region 编辑区域 @@ -1048,16 +1159,14 @@ watch( // 根据横竖屏来确定比例 1竖2横 await nextTick(); elementWidth.value = document.getElementById("editPosition").clientWidth; - console.log(elementWidth.value); + if (videoType.value == 1) { - proportion.value = 1080 / elementWidth.value; - // proportion.value = 1080 / 432; + proportion.value = Number(1080 / elementWidth.value).toFixed(2); } else if (videoType.value == 2) { - // proportion.value = 1920 / 768; - proportion.value = 1920 / elementWidth.value; + proportion.value = Number(1920 / elementWidth.value).toFixed(2); } + console.log("设置比例"); Subtitles.SubtitlesWidth = elementWidth.value * 0.7 * proportion.value; - // console.log(EditPositionDom.value); console.log(proportion.value, "比例"); }, { deep: true } @@ -1173,6 +1282,14 @@ async function saveOrUpdate(isCreate) { backgroundId: materialList.BGI.id + "", //背景id personJson: JSON.stringify(shuziren), // 数字人 materialAllJson: JSON.stringify([...scList]), // 素材 + subtitleEnabled: Subtitles.SubtitlesSwitch ? 1 : 0, //字幕开关 + subtitleParams: JSON.stringify({ + Fontname: Subtitles.SubtitlesFontFamily, //字体名字 + Fontsize: Subtitles.SubtitlesSize * proportion.value, //字体大小 + Marginv: Subtitles.SubtitlesTop, //上边距 + PrimaryColour: rgbaToBgra(Subtitles.SubtitlesColor), //字色 + Alignment: 6, + }), }; const res = await saveOrUpdateApi(data); workId.value = res.data.id; @@ -1246,6 +1363,13 @@ async function saveOrUpdate(isCreate) { backgroundId: materialList.BGI.id + "", //背景id personJson: JSON.stringify(shuziren), // 数字人 materialAllJson: JSON.stringify([...scList]), // 素材 + subtitleParams: JSON.stringify({ + Fontname: Subtitles.SubtitlesFontFamily, //字体名字 + Fontsize: Subtitles.SubtitlesSize * proportion.value, //字体大小 + Marginv: Subtitles.SubtitlesTop, //上边距 + PrimaryColour: rgbaToBgra(Subtitles.SubtitlesColor), //字色 + Alignment: 6, + }), }; const res = await saveOrUpdateApi(data); @@ -1348,14 +1472,15 @@ function formatTime(seconds) { //#endregion ---------------------------- //#region 草稿回显 +const subtitleParamsToObj = ref(null); async function getModelDetailById() { const res = await getModelDetailByIdApi(route.query.id); + videoType.value = res.data.videoType; 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 @@ -1371,6 +1496,24 @@ async function getModelDetailById() { ? JSON.parse(res.data.materialAllJson) : []; showChooseModel.value = false; + // 字幕回显 需要延时,不然proportion缩放比例不准确 + setTimeout(() => { + Subtitles.SubtitlesSwitch = res.data.subtitleEnabled == 1 ? true : false; + subtitleParamsToObj.value = JSON.parse(res.data.subtitleParams); + Subtitles.SubtitlesFontFamily = subtitleParamsToObj.value.Fontname; + Subtitles.SubtitlesSize = + subtitleParamsToObj.value.Fontsize / proportion.value; + Subtitles.SubtitlesTop = subtitleParamsToObj.value.Marginv; + Subtitles.SubtitlesColor = BgraToRgba( + subtitleParamsToObj.value.PrimaryColour + ); + }, 100); +} +//#endregion ---------------------------- + +//#region 公共方法 +function NumToFixed(num1, num2) { + return Number(num1).toFixed(num2); } //#endregion ---------------------------- @@ -1781,17 +1924,67 @@ onMounted(async () => { display: flex; justify-content: space-between; width: 30%; - background-color: #f1e5e5; + background-color: rgba(71, 105, 218, 0.1); text-align: center; padding: 10px; height: 80px; border-radius: 10px; margin: auto; margin-bottom: 10px; - display: none; + p { + padding-bottom: 5px; + } } .SubtitlesSwitch { width: 100%; + .el-input-number--large { + width: 100px; + } + .el-input-number__increase { + width: none; + } + } + .myColorBox { + position: relative; + width: 25px; + height: 25px; + margin: auto; + border: #000 solid 2px; + cursor: pointer; + .selectColor { + position: absolute; + top: 150%; + left: 50%; + transform: translateX(-50%); + display: flex; + justify-content: flex-start; + flex-wrap: wrap; + width: 142px; + background-color: #ffffff; + z-index: 99; + box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 5px 5px; + &::before { + content: ""; + display: block; + position: absolute; + top: -10%; + left: 50%; + transform: translateX(-50%); + width: 0; + height: 0; + border-left: 15px solid transparent; + border-right: 15px solid transparent; + border-bottom: 15px solid white; + } + &-item { + width: 25px; + height: 25px; + margin: 5px 5px; + border: #000 solid 2px; + border-radius: 5px; + cursor: pointer; + } + } } } }