generate交互更新
This commit is contained in:
433
src/component/HomePage/createSlogan.vue
Normal file
433
src/component/HomePage/createSlogan.vue
Normal file
@@ -0,0 +1,433 @@
|
||||
<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>Create Slogan</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>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>Font Align</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>Font Style</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>Font Family</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>新增</div>
|
||||
</div>
|
||||
<div @click="removeTextFun()" class="clearSlogan_center_btn_item">
|
||||
<div>删除</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="exportCanvasBox_submit" @click="setSubmit">
|
||||
<div class="started_btn">
|
||||
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 { 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 canvasWH = ref(0);
|
||||
let textData = reactive({
|
||||
fill:'#000000',
|
||||
fontSize:'20',
|
||||
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;
|
||||
canvasBox.style.width = height+'px'
|
||||
canvasWH.value = height
|
||||
var canvasDom = document.createElement("canvas");
|
||||
let oldCanvasDom = canvasBox.querySelector('canvas')
|
||||
if(oldCanvasDom)canvasBox.removeChild(oldCanvasDom); // 清空原有内容
|
||||
canvasBox.appendChild(canvasDom);
|
||||
canvas = new fabric.Canvas(canvasDom, {
|
||||
backgroundColor: "#e6e6e6",
|
||||
width: canvasWH.value,
|
||||
height: canvasWH.value,
|
||||
isDrawingMode: false, // 开启绘图模式
|
||||
});
|
||||
canvas.on('object:moving',canvasMoving)
|
||||
setTextFun('请输入一段话吧~')
|
||||
// setRemoveImage()
|
||||
fabric.Object.prototype.cornerSize = 10
|
||||
fabric.Object.prototype.transparentCorners = false
|
||||
canvas.on('mouse:down',setTextBtn)
|
||||
})
|
||||
}
|
||||
let selectTextbox = ref(null)
|
||||
let setTextBtn = (e) =>{//点击判断是否点击到文字
|
||||
var clickedObject = e.target;
|
||||
if (clickedObject instanceof fabric.IText){
|
||||
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)
|
||||
}else{
|
||||
selectTextbox.value = null
|
||||
textBtnShow.value = false
|
||||
}
|
||||
}
|
||||
let messageShow = false
|
||||
let canvasMoving = (options)=>{
|
||||
let obj = options.target
|
||||
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('看到输入的内容可能存在重叠,重叠会影响最终效果哦~',()=>{
|
||||
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 setTextFun = (str)=>{
|
||||
let textbox
|
||||
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('最少需要创建一个文字')
|
||||
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') );
|
||||
}
|
||||
|
||||
return {
|
||||
presentState,
|
||||
showPayOrder,
|
||||
loadingShow,
|
||||
...toRefs(textData),
|
||||
...toRefs(textDataList),
|
||||
textBtnShow,
|
||||
t,
|
||||
init,
|
||||
setTextFun,
|
||||
removeTextFun,
|
||||
setTextData,
|
||||
setSubmit,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
|
||||
|
||||
cancelDsign(){
|
||||
this.showPayOrder = false
|
||||
}
|
||||
},
|
||||
});
|
||||
</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;
|
||||
.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;
|
||||
}
|
||||
>select{
|
||||
height: 2.5rem;
|
||||
border: 0.2rem solid #c4c4c4 !important;
|
||||
border-radius: 4px; /* 设置圆角半径 */
|
||||
}
|
||||
>select:focus-visible{
|
||||
border: 0.2rem solid #c4c4c4;
|
||||
}
|
||||
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>
|
||||
Reference in New Issue
Block a user