Selaa lähdekoodia

调色板及宽度调节

dev
congzc 1 vuosi sitten
vanhempi
commit
bffacd2ce5
5 muutettua tiedostoa jossa 319 lisäystä ja 52 poistoa
  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 Näytä tiedosto

Before After
Leveys: 36  |  Korkeus: 36  |  Koko: 656 B

BIN
src/assets/img/font.png Näytä tiedosto

Before After
Leveys: 200  |  Korkeus: 200  |  Koko: 6.7 KiB

+ 7
- 0
src/lang/package/en.ts Näytä tiedosto

@@ -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",
},

// 我的视频


+ 7
- 0
src/lang/package/zh-cn.ts Näytä tiedosto

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

// 我的视频


+ 305
- 52
src/views/createVideo/index.vue Näytä tiedosto

@@ -4,7 +4,7 @@
<div class="left ">
<!-- 顶部 -->
<!-- 选中AiFace -->
<div class="left-top" v-show="showUploadBtn == 1">
<div class="left-top" v-show="showUploadBtn == 1" >
<el-row class="justify-between">
<!-- title框 v-show="!submitImgBtn"-->
<div
@@ -21,31 +21,76 @@
<!-- 编辑字幕框 -->
</div>
<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"
width="30"
/></div>
<div class="item">Y:&nbsp;<el-input
<!-- X轴 -->
<div class="item">{{$t('createVideo.XAxis')}}:&nbsp;<el-input
v-model="SubtitlesLeft"
width="30"
/></div>
<div class="item">Size:&nbsp;<el-input
<!-- 字号大小 -->
<div class="item">{{$t('createVideo.fontSize')}}:&nbsp;<el-input
v-model="SubtitlesSize"
width="30"
/></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>
</el-row>
<!-- 中间展示大图 -->
<div ref="canvasImgBox" class="bigImg inmiddle">
<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 box2"></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 box7"></div>
<div class="stretchBox box8"></div>
@@ -55,7 +100,7 @@
<!-- 字幕开关 -->
<div v-if="imgUrl" class="SubtitlesSwitch">
<p>{{ $t('createVideo.subtitles') }}</p>
<el-switch v-model="SubtitlesSwitch" />
<el-switch v-model="SubtitlesSwitch" style="--el-switch-on-color: #000"/>
</div>
</div>
<!-- 选中需要上传的图片前 -->
@@ -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);


Ladataan…
Peruuta
Tallenna