| @@ -6,4 +6,4 @@ NODE_ENV='development' | |||
| VITE_APP_TITLE = 'Metavatar-PC' | |||
| VITE_APP_PORT = 3000 | |||
| ## VITE_APP_BASE_API = 'https://photo.metavatar.cc/C' | |||
| VITE_APP_BASE_API = 'https://mtest.metavatar.cc/C' | |||
| VITE_APP_BASE_API = 'https://test.metavatar.cc/C' | |||
| @@ -6,4 +6,4 @@ NODE_ENV='test' | |||
| VITE_APP_TITLE = 'Metavatar-PC' | |||
| VITE_APP_PORT = 3000 | |||
| # VITE_APP_BASE_API = 'https://photo.metavatar.cc/C' | |||
| VITE_APP_BASE_API = 'https://mtest.metavatar.cc/C' | |||
| VITE_APP_BASE_API = 'https://test.metavatar.cc/C' | |||
| @@ -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</title> | |||
| <title>Metavatar-慧影</title> | |||
| </head> | |||
| <body> | |||
| @@ -90,6 +90,16 @@ | |||
| /> | |||
| </div> | |||
| </div> | |||
| <!-- 字幕 --> | |||
| <div | |||
| v-show="props.Subtitles.SubtitlesSwitch" | |||
| class="subtitles" | |||
| :class="showBorderActive == 'subtitles' ? 'border' : ''" | |||
| :style="SubtitlesStyle" | |||
| @mousedown.stop="handleDragSubtitles" | |||
| > | |||
| {{ $t("createVideo.SubtitlesTip") }} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| @@ -118,6 +128,9 @@ const props = defineProps({ | |||
| showImgInfo: { | |||
| required: true, | |||
| }, | |||
| Subtitles: { | |||
| required: true, | |||
| }, | |||
| }); | |||
| //#endregion -------------------------- | |||
| @@ -148,6 +161,14 @@ const virtualStyle = computed(() => { | |||
| }); | |||
| // 拖动盒子 | |||
| const showBorderActive = ref(-1); //判断显示边框 | |||
| watch( | |||
| () => props.materialList.virtual.id, | |||
| (newValue, oldValue) => { | |||
| showBorderActive.value = props.materialList.virtual.id; | |||
| }, | |||
| { deep: true } | |||
| ); | |||
| const fatherBox = ref(null); | |||
| const handleDrag = (item, event) => { | |||
| realImgUrl.value = item.material; | |||
| @@ -188,45 +209,6 @@ const touchOver = ref({ | |||
| }); | |||
| const scaleNum = ref(0.004); | |||
| // 改动版 | |||
| // 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); | |||
| // } | |||
| // 距离版 | |||
| function changeScale(event) { | |||
| event.stopPropagation(); | |||
| @@ -400,6 +382,72 @@ watch( | |||
| ); | |||
| //#endregion -------------------------- | |||
| //#region 字幕 | |||
| const SubtitlesStyle = computed(() => { | |||
| let leftX = null; | |||
| if (props.videoType == 1) { | |||
| leftX = | |||
| (1080 / 2 - props.Subtitles.SubtitlesWidth / 2) / props.proportion + "px"; | |||
| } else if (props.videoType == 2) { | |||
| leftX = | |||
| (1920 / 2 - props.Subtitles.SubtitlesWidth / 2) / props.proportion + "px"; | |||
| } | |||
| 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", | |||
| fontFamily: props.Subtitles.SubtitlesFontFamily, | |||
| color: props.Subtitles.SubtitlesColor, | |||
| zIndex: 99, | |||
| }; | |||
| }); | |||
| const handleDragSubtitles = (event) => { | |||
| showBorderActive.value = "subtitles"; | |||
| event.preventDefault(); | |||
| // const startX = event.clientX; //保存初始值,避免闪烁 | |||
| const startY = event.clientY; | |||
| const startTop = props.Subtitles.SubtitlesTop; | |||
| // 鼠标移动 | |||
| const onMouseMove = (event) => { | |||
| const deltaY = event.clientY - startY; | |||
| props.Subtitles.SubtitlesTop = startTop + deltaY * props.proportion; | |||
| }; | |||
| // 鼠标抬起 | |||
| const onMouseUp = () => { | |||
| document.removeEventListener("mousemove", onMouseMove); | |||
| document.removeEventListener("mouseup", onMouseUp); | |||
| }; | |||
| document.addEventListener("mousemove", onMouseMove); | |||
| document.addEventListener("mouseup", onMouseUp); | |||
| }; | |||
| 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 | |||
| //#endregion -------------------------- | |||
| @@ -446,6 +494,16 @@ watch( | |||
| user-select: none; | |||
| border: rgba(0, 0, 0, 0) 5px solid; | |||
| } | |||
| .subtitles { | |||
| position: absolute; | |||
| user-select: none; | |||
| border: rgba(0, 0, 0, 0) 5px solid; | |||
| padding: 20px; | |||
| text-align: center; | |||
| white-space: nowrap; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| } | |||
| .border { | |||
| border: 5px solid #00ff00; | |||
| .stretchBox { | |||
| @@ -13,7 +13,8 @@ export default { | |||
| }, | |||
| // 登录页面国际化 | |||
| login: { | |||
| title: "Metavatar-PC", | |||
| // title: "Metavatar-MetaTalker", | |||
| title: "MetaTalker", | |||
| username: "Username", | |||
| email: "Phone", | |||
| password: "Password", | |||
| @@ -98,6 +99,7 @@ export default { | |||
| ratio:'ratio', | |||
| entered:'entered', | |||
| tooltip2:'Add Pause', | |||
| SubtitlesTip:"Subtitles will be shown here", | |||
| }, | |||
| // 我的视频 | |||
| @@ -13,7 +13,7 @@ export default { | |||
| }, | |||
| // 登录页面国际化 | |||
| login: { | |||
| title: "Metavatar-PC", | |||
| title: "慧影", | |||
| username: "用户名", | |||
| email: "手机号", | |||
| password: "密码", | |||
| @@ -100,6 +100,7 @@ export default { | |||
| ratio:'缩放倍率', | |||
| entered:'已输入', | |||
| tooltip2:'添加停顿', | |||
| SubtitlesTip:"字幕将在此处展示", | |||
| }, | |||
| // 我的视频 | |||
| @@ -42,7 +42,7 @@ interface DefaultSettings { | |||
| } | |||
| const defaultSettings: DefaultSettings = { | |||
| title: "Metavatar-PC", | |||
| title: "Metavatar-慧影", | |||
| showSettings: false, | |||
| tagsView: false, | |||
| fixedHeader: false, | |||
| @@ -97,11 +97,13 @@ | |||
| class="" | |||
| > | |||
| <EditPosition | |||
| ref="EditPositionDom" | |||
| id="editPosition" | |||
| :materialList="materialList" | |||
| :videoType="videoType" | |||
| :proportion="proportion" | |||
| :showImgInfo="showImgInfo" | |||
| :Subtitles="Subtitles" | |||
| > | |||
| </EditPosition> | |||
| </div> | |||
| @@ -463,15 +465,55 @@ | |||
| </div> | |||
| <!-- 字幕 --> | |||
| <div v-if="tabItemActive == 4" class="tabContent tab4"> | |||
| <!-- <div class="tab4Item"> | |||
| <div v-if="imgUrl" class="SubtitlesSwitch"> | |||
| <!-- 开关 --> | |||
| <div class="tab4Item"> | |||
| <div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
| <p>{{ $t("createVideo.subtitles") }}</p> | |||
| <el-switch | |||
| v-model="SubtitlesSwitch" | |||
| v-model="Subtitles.SubtitlesSwitch" | |||
| style="--el-switch-on-color: #000" | |||
| /> | |||
| </div> | |||
| </div> --> | |||
| </div> | |||
| <!-- 字体系列 --> | |||
| <div class="tab4Item"> | |||
| <div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
| <p> | |||
| {{ lanChange == "zh-cn" ? `字体` : `Font Family` }} | |||
| </p> | |||
| <el-select | |||
| v-model="Subtitles.SubtitlesFontFamily" | |||
| style="width: 80px" | |||
| placeholder=" " | |||
| size="default" | |||
| > | |||
| <el-option | |||
| v-for="item in fontFamilyList" | |||
| :key="item.value" | |||
| :label="item.label" | |||
| :value="item.value" | |||
| /> | |||
| </el-select> | |||
| </div> | |||
| </div> | |||
| <!-- y轴 --> | |||
| <div class="tab4Item"> | |||
| <div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
| <p> | |||
| {{ lanChange == "zh-cn" ? `Y轴` : `Y-axis` }} | |||
| </p> | |||
| <el-input v-model="Subtitles.SubtitlesTop" width="30" /> | |||
| </div> | |||
| </div> | |||
| <!-- 字号大小 --> | |||
| <div class="tab4Item"> | |||
| <div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
| <p> | |||
| {{ lanChange == "zh-cn" ? `字号大小` : `Font Size` }} | |||
| </p> | |||
| <el-input v-model="Subtitles.SubtitlesTop" width="30" /> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <!-- 试听的mp3 --> | |||
| @@ -952,6 +994,44 @@ function delImg(id) { | |||
| //#endregion ---------------------------- | |||
| //#region 字幕 | |||
| const Subtitles = reactive({ | |||
| SubtitlesSwitch: false, //开关 | |||
| SubtitlesFontFamily: "仿宋", //字体系列 | |||
| SubtitlesTop: 400, //Y轴 | |||
| SubtitlesSize: 70, //字号大小 | |||
| SubtitlesColor: "#FFFFFF", //字色 | |||
| SubtitlesWidth: 500, //宽度 | |||
| colorList: [ | |||
| "#FFFFFF", | |||
| "#FF8080", | |||
| "#000000", | |||
| "#FF80FF", | |||
| "#FF0000", | |||
| "#00FF80", | |||
| "#FF00FF", | |||
| "#0080FF", | |||
| "#00FF00", | |||
| "#0000FF", | |||
| "#000080", | |||
| "#FFFF00", | |||
| "#FF0080", | |||
| "#FF8000", | |||
| "#80FF00", | |||
| "#00FFFF", | |||
| ], | |||
| fontFamilyList: [ | |||
| { label: "仿宋", value: "仿宋" }, | |||
| { label: "微软雅黑", value: "微软雅黑" }, | |||
| { label: "新宋体", value: "新宋体" }, | |||
| { label: "黑体", value: "黑体" }, | |||
| { label: "楷体", value: "楷体" }, | |||
| { label: "等线", value: "等线" }, | |||
| { label: "Corbel", value: "Corbel" }, | |||
| { label: "Terminal", value: "Terminal" }, | |||
| { label: "Times New Roman", value: "Times New Roman" }, | |||
| { label: "Verdana", value: "Verdana" }, | |||
| ], | |||
| }); | |||
| //#endregion ---------------------------- | |||
| @@ -961,18 +1041,24 @@ const elementWidth = ref(null); | |||
| onMounted(() => { | |||
| elementWidth.value = document.getElementById("editPosition").clientWidth; | |||
| }); | |||
| const EditPositionDom = ref(null); | |||
| watch( | |||
| () => videoType.value, | |||
| (newValue, oldValue) => { | |||
| async (newValue, oldValue) => { | |||
| // 根据横竖屏来确定比例 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 = 1080 / elementWidth.value; | |||
| // proportion.value = 1080 / 432; | |||
| } else if (videoType.value == 2) { | |||
| proportion.value = 1920 / 768; | |||
| // proportion.value = 1920 / 768; | |||
| proportion.value = 1920 / elementWidth.value; | |||
| } | |||
| console.log(proportion.value); | |||
| Subtitles.SubtitlesWidth = elementWidth.value * 0.7 * proportion.value; | |||
| // console.log(EditPositionDom.value); | |||
| console.log(proportion.value, "比例"); | |||
| }, | |||
| { deep: true } | |||
| ); | |||
| @@ -993,9 +1079,9 @@ async function getPersonPatch() { | |||
| materialList.virtual = { | |||
| ...materialList.virtual, | |||
| x: 50, | |||
| y: 50, | |||
| y: 10, | |||
| z: 0, | |||
| w: 1, | |||
| w: 0.55, | |||
| h: 1, | |||
| }; | |||
| // } | |||
| @@ -1689,8 +1775,23 @@ onMounted(async () => { | |||
| .tab4 { | |||
| display: flex; | |||
| justify-content: flex-start; | |||
| align-content: flex-start; | |||
| flex-wrap: wrap; | |||
| .tab4Item { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| width: 30%; | |||
| background-color: #f1e5e5; | |||
| text-align: center; | |||
| padding: 10px; | |||
| height: 80px; | |||
| border-radius: 10px; | |||
| margin: auto; | |||
| margin-bottom: 10px; | |||
| display: none; | |||
| } | |||
| .SubtitlesSwitch { | |||
| width: 100%; | |||
| } | |||
| } | |||
| } | |||