diff --git a/src/assets/img/bgc.png b/src/assets/img/bgc.png new file mode 100644 index 0000000..a380230 Binary files /dev/null and b/src/assets/img/bgc.png differ diff --git a/src/assets/img/font.png b/src/assets/img/font.png new file mode 100644 index 0000000..c59b26a Binary files /dev/null and b/src/assets/img/font.png differ diff --git a/src/lang/package/en.ts b/src/lang/package/en.ts index a64cf76..2e0de37 100644 --- a/src/lang/package/en.ts +++ b/src/lang/package/en.ts @@ -86,6 +86,13 @@ export default { uploadImgTip2:'please upload a clear frontal photo', entered:'entered', subtitles:"subtitles", + XAxis:"X-axis", + YAxis:"Y-axis", + fontSize:"Font Size", + width:"Width", + FontColor:"Font Color", + backgroundColor:"Background color", + SubtitlesTip:"Please edit text in copy area", }, // 我的视频 diff --git a/src/lang/package/zh-cn.ts b/src/lang/package/zh-cn.ts index 38c1df3..79872f4 100644 --- a/src/lang/package/zh-cn.ts +++ b/src/lang/package/zh-cn.ts @@ -84,6 +84,13 @@ export default { uploadImgTip2:'请确保上传图片为无遮挡的正脸图片', entered:'已输入', subtitles:"字幕", + XAxis:"X轴", + YAxis:"Y轴", + fontSize:"字体大小", + width:"宽度", + FontColor:"字体颜色", + backgroundColor:"背景颜色", + SubtitlesTip:"请在文案区编辑您的正文", }, // 我的视频 diff --git a/src/views/createVideo/index.vue b/src/views/createVideo/index.vue index 5155cb9..1b01954 100644 --- a/src/views/createVideo/index.vue +++ b/src/views/createVideo/index.vue @@ -4,7 +4,7 @@
-
+
-
X:  +
{{$t('createVideo.YAxis')}}: 
-
Y:  +
{{$t('createVideo.XAxis')}}: 
-
Size:  +
{{$t('createVideo.fontSize')}}: 
-
Color: 
-
BGC: 
+ +
{{$t('createVideo.width')}}: 
+ +
+ + + + + + :  +
+
+
+
+
+
+ +
+ + :  +
+
+
+
+
+
-
请在文案区编辑您的正文 +
+
{{$t('createVideo.SubtitlesTip')}}
-
-
+
+
@@ -55,7 +100,7 @@

{{ $t('createVideo.subtitles') }}

- +
@@ -1936,47 +1981,192 @@ function copyAnswerContent() { textareaContent.value = answerContent.value; document.getElementById("tab-0").click(); } + //#endregion ---------------------------- //#region 字幕部分 -const canvasImgBox=ref(null) //图片外盒子dom -const SubtitlesBox=ref(null) //字幕盒子dom -const SubtitlesSwitch=ref(false) //字幕开关 -const SubtitlesTop=ref(0) //字幕Y轴 -const SubtitlesLeft=ref(0) //字幕X轴 -const SubtitlesSize=ref(18) //字幕字号 -const SubtitlesColor=ref('rgba(0, 0, 0, 1)') //字幕字色 -const SubtitlesBgc=ref('rgba(255, 255, 255,1 )') //字幕背景色 -// 计算属性来计算盒子位置 -const SubtitlesStyle = computed(() => { - return { - top: SubtitlesTop.value + 'px', - left: SubtitlesLeft.value + 'px', - fontSize: SubtitlesSize.value+ 'px', - color:SubtitlesColor.value, - backgroundColor: SubtitlesBgc.value, - }; -}); -// 拖动盒子 -const handleDrag = (event) => { - event.preventDefault(); - const boxElement = canvasImgBox.value; - const imageElement = SubtitlesBox.value; - const offsetX = event.clientX - imageElement.offsetLeft; - const offsetY = event.clientY - imageElement.offsetTop; - const onMouseMove = (event) => { - const newX = event.clientX - offsetX; - const newY = event.clientY - offsetY; - SubtitlesLeft.value= newX; - SubtitlesTop.value = newY; - }; - const onMouseUp = () => { - document.removeEventListener('mousemove', onMouseMove); - document.removeEventListener('mouseup', onMouseUp); - }; - document.addEventListener('mousemove', onMouseMove); - document.addEventListener('mouseup', onMouseUp); +const canvasImgBox = ref(null); // 图片外盒子dom + const SubtitlesBox = ref(null); // 字幕盒子dom + const SubtitlesSwitch = ref(false); // 字幕开关 + const SubtitlesWidth = ref(250); // 字幕宽度 + const SubtitlesFontStyle = ref("微软雅黑"); //字幕字体系列 + const SubtitlesTop = ref(400); // 字幕Y轴 + const SubtitlesLeft = ref(100); // 字幕X轴 + const SubtitlesSize = ref(18); // 字幕字号 + const SubtitlesColor = ref('rgba(255, 255, 255, 1)'); // 字幕字色 + const SubtitlesColorBGRA = ref(rgbaToBgra(SubtitlesColor.value)); // 字幕字色 + const SubtitlesBgc = ref('rgba(0, 0, 0, 1)'); // 字幕背景色 + const SubtitlesBgcBGRA = ref(rgbaToBgra(SubtitlesBgc.value)); // 字幕背景色 +// 调色板 + const colorList = [ + 'rgba(255, 0, 0, 1)', // 红色 + 'rgba(0, 255, 0, 1)', // 绿色 + 'rgba(0, 0, 255, 1)', // 蓝色 + 'rgba(255, 255, 0, 1)', // 黄色 + 'rgba(0, 0, 0, 1)', // 黑色 + 'rgba(0, 255, 255, 1)', // 青色 + 'rgba(128, 0, 0, 1)', // 深红色 + 'rgba(0, 128, 0, 1)', // 深绿色 + 'rgba(0, 0, 128, 1)', // 深蓝色 + 'rgba(255, 255, 255, 1)', // 白色 + 'rgba(128, 0, 128, 1)', // 深品红色 + 'rgba(0, 128, 128, 1)', // 深青色 + 'rgba(255, 128, 0, 1)', // 橙色 + 'rgba(255, 0, 128, 1)', // 粉红色 + 'rgba(0, 255, 128, 1)', // 中绿色 + 'rgba(128, 255, 0, 1)' // 中黄色 +]; +const SubtitlesColorShow = ref(false); // 字色调色板开关 +const SubtitlesBgcShow = ref(false); // 背景调色板开关 +const handleSubtitlesColorShow = (e) => { + e.stopPropagation(); // 阻止事件冒泡 + SubtitlesColorShow.value = true; + SubtitlesBgcShow.value = false; +}; +const handleSubtitlesBgcShow = (e) => { + e.stopPropagation(); // 阻止事件冒泡 + SubtitlesBgcShow.value = true; + SubtitlesColorShow.value = false; +}; +const handleClickOutside = () => { + if(SubtitlesColorShow.value==true) { + } + SubtitlesColorShow.value = false; + if(SubtitlesBgcShow.value==true) { + } + SubtitlesBgcShow.value = false; }; +onMounted(() => { + document.addEventListener('click',handleClickOutside); +}); +function rgbaToBgra(rgba) { + const regex = /rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(\.\d+)?)\)/; + const match = regex.exec(rgba); + if (match) { + const red = parseInt(match[1]); + const green = parseInt(match[2]); + const blue = parseInt(match[3]); + const alpha = parseFloat(match[4]); + const b = blue; + const g = green; + const r = red; + const a = Math.round(alpha * 255); + const bgra = `bgra(${b}, ${g}, ${r}, ${a})`; + return bgra; + } + + // Return the original value if no match is found + return rgba; +} +watch( + () => SubtitlesColor, + (newValue, oldValue) => { + SubtitlesColorBGRA.value = ref(rgbaToBgra(SubtitlesColor.value)); // 字幕字色 + + }, + { deep: true } +); +watch( + () => SubtitlesBgc, + (newValue, oldValue) => { + SubtitlesBgcBGRA.value = ref(rgbaToBgra(SubtitlesBgc.value)); // 字幕背景色 + }, + { deep: true } +); + // 计算属性来计算盒子位置 + const SubtitlesStyle = computed(() => { + return { + width: SubtitlesWidth.value + 'px', + top: SubtitlesTop.value + 'px', + left: SubtitlesLeft.value + 'px', + fontSize: SubtitlesSize.value + 'px', + fontStyle: SubtitlesFontStyle.value, + color: SubtitlesColor.value, + backgroundColor: SubtitlesBgc.value, + }; + }); + + // 拖动盒子 + const handleDrag = (event) => { + if (isResizing.value) { + return; + } + event.preventDefault(); + const boxElement = canvasImgBox.value; + const imageElement = SubtitlesBox.value; + const offsetX = event.clientX - imageElement.offsetLeft; + const offsetY = event.clientY - imageElement.offsetTop; + + const onMouseMove = (event) => { + const newX = event.clientX - offsetX; + const newY = event.clientY - offsetY; + SubtitlesLeft.value = newX; + SubtitlesTop.value = newY; + }; + + const onMouseUp = () => { + document.removeEventListener('mousemove', onMouseMove); + document.removeEventListener('mouseup', onMouseUp); + }; + + document.addEventListener('mousemove', onMouseMove); + document.addEventListener('mouseup', onMouseUp); + }; + + // 改变盒子宽度 + const isResizing = ref(false); + const startX = ref(0); + + const startResize = (event) => { + isResizing.value = true; + startX.value = event.clientX; + document.addEventListener('mousemove', resizeBox); + document.addEventListener('mouseup', stopResize); + }; + + const stopResize = () => { + isResizing.value = false; + document.removeEventListener('mousemove', resizeBox); + document.removeEventListener('mouseup', stopResize); + }; + + const resizeBox = (event) => { + if (isResizing.value) { + const deltaX = event.clientX - startX.value; + SubtitlesWidth.value += deltaX; + startX.value = event.clientX; + } + }; + + const startResize2 = (event) => { + isResizing.value = true; + startX.value = event.clientX; + document.addEventListener('mousemove', resizeBox2); + document.addEventListener('mouseup', stopResize2); + }; + + const stopResize2 = () => { + isResizing.value = false; + document.removeEventListener('mousemove', resizeBox2); + document.removeEventListener('mouseup', stopResize2); + }; + + const resizeBox2 = (event) => { + if (isResizing.value) { + const deltaX = startX.value - event.clientX; + const newLeft = SubtitlesLeft.value - deltaX; + SubtitlesWidth.value += deltaX; + SubtitlesLeft.value = newLeft; + startX.value = event.clientX; + } + }; + + onBeforeUnmount(() => { + document.removeEventListener('mousemove', resizeBox); + document.removeEventListener('mouseup', stopResize); + document.removeEventListener('mousemove', resizeBox2); + document.removeEventListener('mouseup', stopResize2); + }); // 监听字幕显示 watch( () => SubtitlesSwitch, @@ -2095,10 +2285,12 @@ onUnmounted(() => { height: 67%; // height: calc(70vh - 80px ); margin-bottom: 20px; + overflow: hidden; .editSubtitlesBox{ display: flex; - justify-content: flex-start; - padding-right: 80px; + justify-content: space-evenly; + // padding-right: 80px; + padding:0 10px; margin-left: 10px; margin-right: 80px; border-radius: 20px; @@ -2110,6 +2302,48 @@ onUnmounted(() => { display: flex; align-items: center; margin-left: 10px; + img { + + cursor: pointer; + } + .myColorBox { + position: relative; + width: 25px; + height: 25px; + 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; + cursor: pointer; + } + } + } .el-input { width: 60px; height: 25px; @@ -2142,16 +2376,30 @@ onUnmounted(() => { width: 50%; height: 88%; margin-top: 20px; + .SubtitlesBox { position: absolute; user-select: none; - width: 300px; + // width: 200px; padding: 5px 5px; - border: 2px solid #00ff00; text-align: center; + border: 2px solid rgba(0, 0, 0, 0); background-color: #fff; cursor: move; + &:hover { + border: 2px solid #00ff00; + .stretchBox { + opacity: 1; + } + } + .SubtitlesTip { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + .stretchBox { + opacity: 0; position: absolute; width: 10px; height: 10px; @@ -2161,15 +2409,17 @@ onUnmounted(() => { top: -5px; left: -5px; cursor: nwse-resize; - + display: none; } .box2 { + display: none; top: -5px; left: 50%; transform: translateX(-50%); cursor: ns-resize; } .box3 { + display: none; top: -5px; left:100%; transform: translateX(-5px); @@ -2188,18 +2438,21 @@ onUnmounted(() => { cursor: ew-resize; } .box6 { + display: none; top: 100%; left: -5px; transform: translateY(-5px); cursor: nesw-resize; } .box7 { + display: none; top: 100%; left: 50%; transform: translate(-5px,-5px); cursor: ns-resize; } .box8 { + display: none; top: 100%; left: 100%; transform: translate(-5px,-5px);