Files
aida_front/src/component/HomePage/createSlogan.vue
2024-10-02 11:33:14 +08:00

504 lines
14 KiB
Vue

<template>
<a-modal
class="clearSlogan_modal generalModel"
v-model:visible="showPayOrder"
:footer="null"
width="50%"
:maskClosable="false"
:centered="true"
:closable="false"
wrapClassName="#app"
:keyboard="false"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<i class="fi fi-rr-cross-small"></i>
</div>
</div>
<div class="clearSlogan_center">
<div class="modal_title_text">
<div>{{ $t('createSlogan.title') }}</div>
<div class="modal_title_text_intro"></div>
</div>
<div class="exportCanvasBox_center">
<div v-show="textBtnShow" class="clearSlogan_center_item clearSlogan_center_btn_move">
<div class="clearSlogan_center_btn_item">
<div>{{ $t('createSlogan.Color') }}</div>
<input type="color" v-model="fill">
</div>
<!-- <div class="clearSlogan_center_btn_item">
<div>font Size</div>
<input type="Number" v-model="fontSize">
</div> -->
<div class="clearSlogan_center_btn_item">
<div>{{ $t('createSlogan.FontAlign') }}</div>
<ul>
<i class="fi fi-br-align-left" @click="setTextData('textAlign','left')" :class="{active:textAlign === 'left'}"></i>
<i class="fi fi-br-align-center" @click="setTextData('textAlign','center')" :class="{active:textAlign === 'center'}"></i>
<i class="fi fi-br-symbol" @click="setTextData('textAlign','right')" :class="{active:textAlign === 'right'}"></i>
</ul>
</div>
<div class="clearSlogan_center_btn_item">
<div>{{ $t('createSlogan.FontStyle') }}</div>
<ul>
<i class="fi fi-br-border-top" @click="setTextData('overline','')" :class="{active:overline}"></i>
<i class="fi fi-br-border-center-h" @click="setTextData('linethrough','')" :class="{active:linethrough}"></i>
<i class="fi fi-br-border-bottom" @click="setTextData('underline','')" :class="{active:underline}"></i>
</ul>
</div>
<div class="clearSlogan_center_btn_item">
<div>{{ $t('createSlogan.FontFamily') }}</div>
<select v-model="fontFamily" :style="{'font-family':fontFamily}">
<option v-for="item in textFontFamilyList" :style="{'font-family':item.value}" :value="item.value">{{item.name}}</option>
</select>
</div>
</div>
<div class="clearSlogan_center_btn clearSlogan_center_item">
<div @click="setTextFun('')" class="clearSlogan_center_btn_item">
<div>{{ $t('createSlogan.add') }}</div>
</div>
<div @click="removeTextFun()" class="clearSlogan_center_btn_item">
<div>{{ $t('createSlogan.delete') }}</div>
</div>
</div>
</div>
<div class="exportCanvasBox_submit" @click="setSubmit">
<div class="started_btn">
{{ $t('createSlogan.submit') }}
</div>
</div>
</div>
<div></div>
</a-modal>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</template>
<script>
import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs } from "vue";
import { Https } from "@/tool/https";
import { formatTime } from "@/tool/util";
import { setCookie, getCookie } from "@/tool/cookie";
import { Modal, message } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import allOrder from "@/component/Pay/allOrder.vue";
import creditsDetail from "@/component/Pay/creditsDetail.vue";
import { JSSetRemoveImage } from "@/tool/canvasDrawing";
import { useI18n } from "vue-i18n";
export default defineComponent({
components: {
creditsDetail,
allOrder,
},
emits: ['setSloganData'],
setup(props,{emit}) {
let presentState = ref('paypal');
let showPayOrder = ref(false);
let loadingShow = ref(false);
let textBtnShow = ref(false)
let { t } = useI18n();
let canvas = reactive({});
let scale = 2;
let exportWH = 512
let canvasWH = ref(0);
let isDeleteSlogan = ref(false)
let textData = reactive({
fill:'#000000',
fontSize:'51',
fontFamily:'Arial',
textAlign:'left',
overline: false,
linethrough: false,
underline: false,
})
onMounted(()=>{
let arr = [
{ value: 'Arial', name: 'select font' },
{ value: 'EN_slogan_art1', name: 'select font' },
{ value: 'EN_slogan_art2', name: 'select font' },
{ value: 'EN_slogan_art3', name: 'select font' },
{ value: 'EN_slogan_art4', name: 'select font' },
{ value: 'EN_slogan_art5', name: 'select font' },
{ value: 'EN_slogan_art6', name: 'select font' },
{ value: 'EN_slogan_art7', name: 'select font' },
{ value: '微软雅黑', name: '请选择字体' },
{ value: 'CN_slogan_art1', name: '请选择字体' },
{ value: 'CN_slogan_art2', name: '请选择字体' },
{ value: 'CN_slogan_art3', name: '请选择字体' },
{ value: 'CN_slogan_art4', name: '请选择字体' },
{ value: '华文行楷', name: '请选择字体' },
{ value: '隶书', name: '请选择字体' },
]
textDataList.textFontFamilyList = arr
textData.fontFamily = arr[0].value
})
let textDataList = reactive({
textFontFamilyList: [],
})
let init = ()=>{
showPayOrder.value = true;
nextTick(()=>{
let canvasBox = document.querySelector(".clearSlogan_modal .exportCanvasBox_center");
let height = canvasBox.offsetHeight;
textData.fontSize = (height/10*1.9).toFixed(0)
canvasBox.style.width = height+'px'
canvasWH.value = height
scale = exportWH/canvasWH.value
let oldCanvasDom = canvasBox.querySelector('.canvas-container')
let oldCanvasDom1 = canvasBox.querySelector('canvas')
if(isDeleteSlogan.value && oldCanvasDom){
oldCanvasDom.remove()
canvas.remove(textbox);
canvas.dispose();
oldCanvasDom = null
isDeleteSlogan.value = false
}
if(oldCanvasDom1){
oldCanvasDom1.remove()
}
// if(oldCanvasDom)oldCanvasDom.remove()
if(!oldCanvasDom){
var canvasDom = document.createElement("canvas");
canvasBox.appendChild(canvasDom);
canvas = new fabric.Canvas(canvasDom, {
backgroundColor: "#e6e6e6",
width: canvasWH.value,
height: canvasWH.value,
isDrawingMode: false, // 开启绘图模式
});
canvas.on('object:moving',canvasMoving)
setTextFun('请输入\n一段话吧~')
}
if(!fabric.Object.prototype.controls.deleteControl){
JSSetRemoveImage(deleteObj)
}else{
fabric.Object.prototype.controls.deleteControl.mouseUpHandler = deleteObj
}
// setRemoveImage()
fabric.Object.prototype.cornerSize = 10
fabric.Object.prototype.transparentCorners = false
canvas.on('mouse:down',setTextBtn)
})
}
let selectTextbox = ref(null)
let oldClickedObject = null
let clickObjChanged = (options)=>{
// var changedObject = options.target;
setBtnPosition(oldClickedObject)
}
let clickedObject
let setTextBtn = (e) =>{//点击判断是否点击到文字
clickedObject = e.target;
if (clickedObject instanceof fabric.IText){
if(oldClickedObject)oldClickedObject.off('changed',clickObjChanged);
selectTextbox.value = clickedObject
textData.fill = clickedObject.fill
textData.fontSize = clickedObject.fontSize
textData.fontFamily = clickedObject.fontFamily
textData.textAlign = clickedObject.textAlign
textData.overline = clickedObject.overline
textData.linethrough = clickedObject.linethrough
textData.underline = clickedObject.underline
setBtnPosition(clickedObject)
clickedObject.on('changed',clickObjChanged);
oldClickedObject = clickedObject
}else{
selectTextbox.value = null
textBtnShow.value = false
}
}
let deleteObj = ()=> {
if(!canvas.getActiveObjects()){
return
}
let target = canvas.getActiveObjects()
target.forEach((item)=>{
canvas.fxRemove(item, {
onComplete(){
canvas.discardActiveObject(); // 丢弃当前选中的对象
canvas.renderAll(); // 重新渲染 Canvas
}
})
canvas.FX_DURATION = 300
})
}
let messageShow = false
let canvasMoving = (options)=>{
let obj = options.target
let left,top
let canvasWidth = canvas.getWidth()
let canvasHeight = canvas.getHeight()
if(obj.left < 0){
left = obj.left<0?0:obj.left
}else{
left = obj.left + obj.width*obj.scaleX>canvasWidth?canvasWidth - obj.width*obj.scaleX:obj.left
}
if(obj.top < 0){
top = obj.top<0?0:obj.top
}else{
top = obj.top + obj.height*obj.scaleY>canvasHeight?canvasHeight - obj.height*obj.scaleY:obj.top
}
obj.set({
left,
top
})
isCanvasMoving(obj)
}
let isCanvasMoving = (obj)=>{
canvas.forEachObject(function(options) {
setBtnPosition(obj)
if(messageShow) return
if (options === obj) return
// 检查对象是否与另一个对象相交
if (obj.intersectsWithObject(options)) {
messageShow = true
message.info(t('Generate.jsContent11'),()=>{
messageShow = false
});
}
})
}
let setBtnPosition = (obj)=>{//传入文字对象,设置工具位置
let domXY = {x:0,y:0}
textBtnShow.value = true
let scaleY = obj.scaleY?obj.scaleY:1
domXY = {
y:obj.top+obj.height * scaleY,
x:obj.left,
}
let dom = document.querySelector('.clearSlogan_modal .clearSlogan_center_btn_move')
domXY.x = domXY.x<0?0:domXY.x
dom.style.left = domXY.x+'px'
dom.style.top = (domXY.y + 5)+'px'
}
let textbox
let setTextFun = (str)=>{
textbox = new fabric.IText(str, {
fontSize: 20,
textAlign:'center'
// fill:canvasPencilColor.value,
})
textbox.set(textData)
textbox.set({
left:canvasWH.value/2 - textbox.width / 2,
top:canvasWH.value/2 - textbox.height / 2,
})
setBtnPosition(textbox)
canvas.add(textbox)
isCanvasMoving(textbox)
textbox.enterEditing();
canvas.setActiveObject(textbox).renderAll();
selectTextbox.value = textbox
}
let removeTextFun = ()=>{
let selectObj = canvas.getActiveObjects();
if(selectObj){
selectObj.forEach(function(object) {
canvas.remove(object);
textBtnShow.value = false
});
}
}
let watchTime
watch(textData,(newValue,oldValue)=>{
clearTimeout(watchTime)
watchTime = setTimeout(()=>{
if(selectTextbox.value){
selectTextbox.value.set(newValue)
canvas.renderAll();
}
},500)
})
let setTextData = (name,value)=>{
textData[name] = value?value:!textData[name]
}
let setSubmit = ()=>{
var allObjects = canvas.getObjects();
if(allObjects.length == 0){
message.info(t('Generate.jsContent12'))
return
}
var canvasDom = document.createElement("canvas");
let exportCanvas = new fabric.Canvas(canvasDom, {
backgroundColor: "rgba(255, 255, 255,0)",
width: canvasWH.value*scale,
height: canvasWH.value*scale,
isDrawingMode: false, // 开启绘图模式
});
let canvasArr = canvas.getObjects()
canvasArr.forEach(item=>{
// let obj = fabric.util.object.clone(item);
let obj
item.clone((cloned)=>{
obj = cloned
})
obj.set(
{
scaleX:(item.scaleX?item.scaleX:1)*scale,
scaleY:(item.scaleY?item.scaleY:1)*scale,
left:item.left*scale,
top:item.top*scale,
}
)
exportCanvas.add(obj)
})
// textbox.set({
// left:canvasWH.value.width/2 - textbox.width / 2,
// top:canvasWH.value.height/2 - textbox.height / 2,
// })
let data = [{
imgUrl : exportCanvas.toDataURL('png'),
base64:true
}]
emit('setSloganData',data)
showPayOrder.value = false;
// console.log(exportCanvas.toDataURL('png') );
}
let cancelDsign = ()=>{
canvas.off('object:moving',canvasMoving)
if(oldClickedObject)oldClickedObject.off('changed',clickObjChanged);
if(clickedObject)clickedObject.off('changed',clickObjChanged);
canvas.off('mouse:down',setTextBtn)
canvas.dispose();
showPayOrder.value = false
}
return {
presentState,
showPayOrder,
loadingShow,
...toRefs(textData),
...toRefs(textDataList),
textBtnShow,
isDeleteSlogan,
t,
init,
setTextFun,
removeTextFun,
setTextData,
setSubmit,
cancelDsign,
};
},
data() {
return {
};
},
mounted() {},
methods: {
},
});
</script>
<style lang="less">
.clearSlogan_modal {
.closeIcon {
z-index: 2;
}
.clearSlogan_center{
position: relative;
// width: calc(512px / 2);
// width: 256px;
height: 100%;
display: flex;
flex-direction: column;
// height: calc(512px / 2);
margin: 0 auto;
.modal_title_text{
padding-bottom: calc(2rem* 1.2);
background: #fff;
z-index: 4;
margin-bottom: 0;
}
.clearSlogan_center_item{
// position: relative;
background: #fff;
position: absolute;
display: flex;
border: 0.2rem solid #c4c4c4;
width: 25rem;
border-radius: 4px; /* 设置圆角半径 */
flex-wrap: wrap;
.clearSlogan_center_btn_item{
display: flex;
align-items: center;
padding: 1rem 0;
>*{
cursor: pointer;
}
>input{
width: 4rem;
height: 2.5rem;
border-radius: 4px; /* 设置圆角半径 */
}
input::-webkit-inner-spin-button,
input::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
div{
padding: 0 1rem;
font-weight: 600;
}
ul{
display: flex;
margin: 0;
i{
display: flex;
align-items: center;
justify-content: center;
font-size: 2.5rem;
cursor: pointer;
width: 4rem;
height: 4rem;
&.active{
border: 1px solid;
border-radius: 0.4rem;
}
}
}
}
}
.clearSlogan_center_btn{
top: 0px;
left: 50%;
width: auto;
transition: all 0.3s;
transform: translate(-50%,-100%);
}
.exportCanvasBox_center:hover .clearSlogan_center_btn{
transform: translate(-50%,0%);
z-index: 4;
}
.clearSlogan_center_btn_move{
position: absolute;
z-index: 2;
}
.exportCanvasBox_center{
height: 100%;
flex: 1;
position: relative;
margin: 0 auto;
// overflow: hidden;
// overflow: scroll;
.canvas-container{
margin: 0 auto;
}
}
}
.exportCanvasBox_submit{
margin-top: 2.4rem;
text-align: center;
}
}
</style>