Browse Source

调色板及宽度调节

dev
congzc 1 year ago
parent
commit
bffacd2ce5
5 changed files with 319 additions and 52 deletions
  1. BIN
      src/assets/img/bgc.png
  2. BIN
      src/assets/img/font.png
  3. +7
    -0
      src/lang/package/en.ts
  4. +7
    -0
      src/lang/package/zh-cn.ts
  5. +305
    -52
      src/views/createVideo/index.vue

BIN
src/assets/img/bgc.png View File

Before After
Width: 36  |  Height: 36  |  Size: 656 B

BIN
src/assets/img/font.png View File

Before After
Width: 200  |  Height: 200  |  Size: 6.7 KiB

+ 7
- 0
src/lang/package/en.ts View File

@@ -86,6 +86,13 @@ export default {
uploadImgTip2:'please upload a clear frontal photo', uploadImgTip2:'please upload a clear frontal photo',
entered:'entered', entered:'entered',
subtitles:"subtitles", 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",
}, },


// 我的视频 // 我的视频


+ 7
- 0
src/lang/package/zh-cn.ts View File

@@ -84,6 +84,13 @@ export default {
uploadImgTip2:'请确保上传图片为无遮挡的正脸图片', uploadImgTip2:'请确保上传图片为无遮挡的正脸图片',
entered:'已输入', entered:'已输入',
subtitles:"字幕", subtitles:"字幕",
XAxis:"X轴",
YAxis:"Y轴",
fontSize:"字体大小",
width:"宽度",
FontColor:"字体颜色",
backgroundColor:"背景颜色",
SubtitlesTip:"请在文案区编辑您的正文",
}, },


// 我的视频 // 我的视频


+ 305
- 52
src/views/createVideo/index.vue View File

@@ -4,7 +4,7 @@
<div class="left "> <div class="left ">
<!-- 顶部 --> <!-- 顶部 -->
<!-- 选中AiFace --> <!-- 选中AiFace -->
<div class="left-top" v-show="showUploadBtn == 1">
<div class="left-top" v-show="showUploadBtn == 1" >
<el-row class="justify-between"> <el-row class="justify-between">
<!-- title框 v-show="!submitImgBtn"--> <!-- title框 v-show="!submitImgBtn"-->
<div <div
@@ -21,31 +21,76 @@
<!-- 编辑字幕框 --> <!-- 编辑字幕框 -->
</div> </div>
<div v-if="imgUrl&&SubtitlesSwitch" class="editSubtitlesBox "> <div v-if="imgUrl&&SubtitlesSwitch" class="editSubtitlesBox ">
<div class="item">X:&nbsp;<el-input
<!-- Y轴 -->
<div class="item">{{$t('createVideo.YAxis')}}:&nbsp;<el-input
v-model="SubtitlesTop" v-model="SubtitlesTop"
width="30" width="30"
/></div> /></div>
<div class="item">Y:&nbsp;<el-input
<!-- X轴 -->
<div class="item">{{$t('createVideo.XAxis')}}:&nbsp;<el-input
v-model="SubtitlesLeft" v-model="SubtitlesLeft"
width="30" width="30"
/></div> /></div>
<div class="item">Size:&nbsp;<el-input
<!-- 字号大小 -->
<div class="item">{{$t('createVideo.fontSize')}}:&nbsp;<el-input
v-model="SubtitlesSize" v-model="SubtitlesSize"
width="30" width="30"
/></div> /></div>
<div class="item">Color:&nbsp;<el-color-picker v-model="SubtitlesColor" show-alpha /></div>
<div class="item">BGC:&nbsp;<el-color-picker v-model="SubtitlesBgc" show-alpha /></div>
<!-- 字幕盒子宽度 -->
<div class="item">{{$t('createVideo.width')}}:&nbsp;<el-input
v-model="SubtitlesWidth"
width="30"
/></div>
<!-- 字色 -->
<div class="item">
<el-tooltip
class="box-item"
effect="dark"
:content="$t('createVideo.FontColor')"
placement="bottom"
>
<img style=" max-width: 15px;
max-height: 15px;" src="../../assets/img/font.png" alt="">
</el-tooltip>

:&nbsp;
<div @click="handleSubtitlesColorShow" class="myColorBox" :style="{backgroundColor: SubtitlesColor}">
<div v-show="SubtitlesColorShow" class="selectColor">
<div v-for="item in colorList" :style="{backgroundColor: item}" class="selectColor-item" @click="SubtitlesColor=item"></div>
</div>
</div>
</div>
<!-- 背景色 -->
<div class="item"> <el-tooltip
class="box-item"
effect="dark"
:content="$t('createVideo.backgroundColor')"
placement="bottom"
>
<img style=" max-width: 25px;
max-height: 25px;" src="../../assets/img/bgc.png" alt="">
</el-tooltip>:&nbsp;
<div @click="handleSubtitlesBgcShow" class="myColorBox" :style="{backgroundColor: SubtitlesBgc}">
<div v-show="SubtitlesBgcShow" class="selectColor">
<div v-for="item in colorList" :style="{backgroundColor: item}" class="selectColor-item" @click="SubtitlesBgc=item"></div>
</div>
</div>
</div>
</div> </div>
</el-row> </el-row>
<!-- 中间展示大图 --> <!-- 中间展示大图 -->
<div ref="canvasImgBox" class="bigImg inmiddle"> <div ref="canvasImgBox" class="bigImg inmiddle">
<img id="canvasImg" :src="imgUrl" alt="" class="" /> <img id="canvasImg" :src="imgUrl" alt="" class="" />
<div ref="SubtitlesBox" @mousedown="handleDrag" :style="SubtitlesStyle" v-if="SubtitlesSwitch" class="SubtitlesBox">请在文案区编辑您的正文
<div id="SubtitlesBox" ref="SubtitlesBox" @mousedown="handleDrag" :style="SubtitlesStyle" v-if="SubtitlesSwitch" class="SubtitlesBox">
<div class="SubtitlesTip">{{$t('createVideo.SubtitlesTip')}}</div>
<div class="stretchBox box1"></div> <div 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 class="stretchBox box5"></div>
<div class="stretchBox box4" @mousedown="startResize2"
></div>
<div class="stretchBox box5" @mousedown="startResize"
></div>
<div class="stretchBox box6"></div> <div class="stretchBox box6"></div>
<div class="stretchBox box7"></div> <div class="stretchBox box7"></div>
<div class="stretchBox box8"></div> <div class="stretchBox box8"></div>
@@ -55,7 +100,7 @@
<!-- 字幕开关 --> <!-- 字幕开关 -->
<div v-if="imgUrl" class="SubtitlesSwitch"> <div v-if="imgUrl" class="SubtitlesSwitch">
<p>{{ $t('createVideo.subtitles') }}</p> <p>{{ $t('createVideo.subtitles') }}</p>
<el-switch v-model="SubtitlesSwitch" />
<el-switch v-model="SubtitlesSwitch" style="--el-switch-on-color: #000"/>
</div> </div>
</div> </div>
<!-- 选中需要上传的图片前 --> <!-- 选中需要上传的图片前 -->
@@ -1936,47 +1981,192 @@ function copyAnswerContent() {
textareaContent.value = answerContent.value; textareaContent.value = answerContent.value;
document.getElementById("tab-0").click(); document.getElementById("tab-0").click();
} }

//#endregion ---------------------------- //#endregion ----------------------------


//#region 字幕部分 //#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( watch(
() => SubtitlesSwitch, () => SubtitlesSwitch,
@@ -2095,10 +2285,12 @@ onUnmounted(() => {
height: 67%; height: 67%;
// height: calc(70vh - 80px ); // height: calc(70vh - 80px );
margin-bottom: 20px; margin-bottom: 20px;
overflow: hidden;
.editSubtitlesBox{ .editSubtitlesBox{
display: flex; display: flex;
justify-content: flex-start;
padding-right: 80px;
justify-content: space-evenly;
// padding-right: 80px;
padding:0 10px;
margin-left: 10px; margin-left: 10px;
margin-right: 80px; margin-right: 80px;
border-radius: 20px; border-radius: 20px;
@@ -2110,6 +2302,48 @@ onUnmounted(() => {
display: flex; display: flex;
align-items: center; align-items: center;
margin-left: 10px; 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 { .el-input {
width: 60px; width: 60px;
height: 25px; height: 25px;
@@ -2142,16 +2376,30 @@ onUnmounted(() => {
width: 50%; width: 50%;
height: 88%; height: 88%;
margin-top: 20px; margin-top: 20px;

.SubtitlesBox { .SubtitlesBox {
position: absolute; position: absolute;
user-select: none; user-select: none;
width: 300px;
// width: 200px;
padding: 5px 5px; padding: 5px 5px;
border: 2px solid #00ff00;
text-align: center; text-align: center;
border: 2px solid rgba(0, 0, 0, 0);
background-color: #fff; background-color: #fff;
cursor: move; cursor: move;
&:hover {
border: 2px solid #00ff00;
.stretchBox {
opacity: 1;
}
}
.SubtitlesTip {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.stretchBox { .stretchBox {
opacity: 0;
position: absolute; position: absolute;
width: 10px; width: 10px;
height: 10px; height: 10px;
@@ -2161,15 +2409,17 @@ onUnmounted(() => {
top: -5px; top: -5px;
left: -5px; left: -5px;
cursor: nwse-resize; cursor: nwse-resize;
display: none;
} }
.box2 { .box2 {
display: none;
top: -5px; top: -5px;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
cursor: ns-resize; cursor: ns-resize;
} }
.box3 { .box3 {
display: none;
top: -5px; top: -5px;
left:100%; left:100%;
transform: translateX(-5px); transform: translateX(-5px);
@@ -2188,18 +2438,21 @@ onUnmounted(() => {
cursor: ew-resize; cursor: ew-resize;
} }
.box6 { .box6 {
display: none;
top: 100%; top: 100%;
left: -5px; left: -5px;
transform: translateY(-5px); transform: translateY(-5px);
cursor: nesw-resize; cursor: nesw-resize;
} }
.box7 { .box7 {
display: none;
top: 100%; top: 100%;
left: 50%; left: 50%;
transform: translate(-5px,-5px); transform: translate(-5px,-5px);
cursor: ns-resize; cursor: ns-resize;
} }
.box8 { .box8 {
display: none;
top: 100%; top: 100%;
left: 100%; left: 100%;
transform: translate(-5px,-5px); transform: translate(-5px,-5px);


Loading…
Cancel
Save