2024-12-11 16:26:36 +08:00
import {
exportSele ,
JSRectUpdata ,
JSchangeType ,
JScanvasMouseDown ,
JScanvasMouseMove ,
JScreateCheck ,
JSSetTexture ,
JSSetRemoveImage ,
2025-01-14 10:21:17 +08:00
} from "@/tool/canvasDrawingCopy" ;
2024-12-11 16:26:36 +08:00
import { getMousePosition } from "@/tool/mdEvent" ;
import { file } from "jszip" ;
class MyCanvas {
canvas = null
constructor ( ) {
this . pencilList = {
textFontFamilyList : [
{ 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 : '请选择字体' } ,
] ,
brushList : [
{
value : 'PencilBrush' ,
url : '/image/brush/PencilBrush.jpg'
} , {
value : 'Marking' ,
url : '/image/brush/PencilBrush-2.jpg'
} , {
value : 'InkBrush' ,
url : '/image/brush/InkBrush.jpg'
} , {
value : 'CrayonBrush' ,
url : '/image/brush/CrayonBrush.jpg'
} , {
value : 'RibbonBrush' ,
url : '/image/brush/RibbonBrush.jpg'
} , {
value : 'MarkerBrush' ,
url : '/image/brush/MarkerBrush.jpg'
} , {
value : 'WritingBrush' ,
url : '/image/brush/WritingBrush.jpg'
} , {
value : 'LongfurBrush' ,
url : '/image/brush/LongfurBrush.jpg'
} , {
value : 'SpraypaintBrush' ,
url : '/image/brush/SpraypaintBrush.jpg'
} ,
]
}
this . canvasDomParent = null ;
this . canvas = MyCanvas . canvas ;
this . addPresent = { }
this . canvasWH = {
width : 0 ,
height : 0 ,
}
this . createPatterning = { //创建图形
state : false ,
content : null ,
current : null , //临时图形
polyLineBtn : null ,
textDataShow : false ,
}
this . mouse = {
point : null ,
upPoint : null ,
isMovePostion : false ,
isDown : false ,
lastPosX : 0 ,
lastPosY : 0 ,
}
this . keyboard = {
down : [ ]
}
this . pencilbtnStyle = { //笔触图形
background : '' ,
width : 0 + 'px' ,
height : 0 + 'px' ,
display : 'none' ,
left : 0 + 'px' ,
top : 0 + 'px' ,
}
this . layer = {
list : [ ] ,
selectLayer : {
group : null ,
id : - 1 ,
} ,
currentIndex : 0 ,
}
this . liquefaction = {
img : null ,
type : '' ,
dashed : null ,
}
this . clipPath = {
isImg : false ,
img : null ,
clipGroup : null
}
this . dashed = {
state : false , //用来判断鼠标是否移入dashed 如果移入就变为可拖拽
isDrawingMode : false , //用来获取移入前是否是绘画模式
}
this . fontFamily = this . pencilList . textFontFamilyList [ 0 ] . value
this . createText = null
this . pencilBtn = null ;
this . pencilType = null ;
this . canvasPencilColor = '#000000'
this . colorHistoryList = [ 'rgb(0, 0, 0)' ]
this . keyDown = [ ] ; //键盘按下
this . oldOperation = ''
//笔触
this . brushwork = {
value : 'PencilBrush' ,
width : { } ,
color : '#000000' ,
texture : 0 ,
}
this . texture = {
value : 0 ,
list : [ ] ,
}
for ( let index = 0 ; index < 20 ; index ++ ) {
this . texture . list . push ( { value : index , url : ` /image/texture/texture ${ index } .webp ` } )
}
this . _clipboard = null ; //剪切板
this . isLoadCanvas = false //撤回或者反撤回false为撤回
this . reverseCanvasState = [ ] ; //撤回
this . normalCanvasState = [ ] ; //反撤回
this . canvasState = { } //当前内容
this . operation = 'movePosition'
this . operationMode = 'fill'
this . setTimeOut = { //定时器
color : null ,
width : null ,
colorHistory : null ,
canvasWH : null ,
updataLayer : null ,
} //给切换颜色设置防抖
}
async canvasInit ( dom , val ) { //初始化
this . canvasClear ( )
this . canvasWH = val
this . canvasDomParent = dom ;
var canvasDom = document . createElement ( "canvas" ) ;
this . canvasDomParent . appendChild ( canvasDom ) ;
MyCanvas . canvas = new fabric . Canvas ( canvasDom , {
backgroundColor : "rgba(230, 230, 230)" ,
width : this . canvasWH . width ,
height : this . canvasWH . height ,
isDrawingMode : val . isDrawingMode , // 开启绘图模式
selectionFullyContained : true ,
selectionKey : 'ctrlKey' ,
includeDefaultValues : false , //尚未测试 精简导出JSON
// freeDrawingCursor: 'none',
preserveObjectStacking : true ,
} ) ;
// MyCanvas.canvas.freeDrawingCursor= 'none'
this . initCanvasWH ( 'init' )
fabric . Object . prototype . cornerSize = 10 //选中后的操作按钮大小
fabric . Object . prototype . transparentCorners = false //实心
if ( ! fabric . Object . prototype . controls . deleteControl ) { //设置元素删除
JSSetRemoveImage ( this . deleteObject . bind ( this ) )
} else {
fabric . Object . prototype . controls . deleteControl . mouseUpHandler = this . deleteObject . bind ( this )
}
MyCanvas . canvas . on ( "object:modified" , ( event ) => {
this . updateCanvasState ( '' )
this . updataLayer ( )
} ) ;
this . canvasKeyDown = this . canvasKeyDown . bind ( this ) ;
this . canvasKeyUp = this . canvasKeyUp . bind ( this ) ;
// let rect1 = new fabric.Rect({
// left: 0,
// top: 0,
// width: 500,
// height: 500,
// fill: "red",
// });
// MyCanvas.canvas.add(rect1)
// rect1.on('mouseover', function() {
// // rect1.set({ fill: 'green' }); // 鼠标移入时改变颜色为绿色
// // canvas.renderAll(); // 重新渲染画布
// });
// // 为矩形添加 mouseleave 事件
// rect1.on('mouseout', function() {
// // rect1.set({ fill: 'blue' }); // 鼠标移出时恢复颜色为蓝色
// // canvas.renderAll(); // 重新渲染画布
// });
// return
// rect1.filters.push(new fabric.Image.filters.Grayscale())
// MyCanvas.canvas.add(rect1)
// // MyCanvas.canvas.add(rect1)
// let rect = new fabric.Rect({
// left: 0,
// top: 0,
// width: MyCanvas.canvas.width,
// height: MyCanvas.canvas.height,
// inverted:true,
// fill: "red",
// });
// // let rect2 = new fabric.Rect({
// // width: MyCanvas.canvas.width,
// // height: MyCanvas.canvas.height,
// // fill:'#FFF'
// // });
// // // MyCanvas.canvas.add(rect2)
// fabric.Image.fromURL('https://www.minio.aida.com.hk:12024/aida-collection-element/83/Moodboard/7a5fec0f-5a8c-4f1e-80c0-c4cda335d7c5.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20241112%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20241112T060752Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=25c5fa23dc447d1d06b4efeeec23454c797219df9c45d2cec231d0c8372754ce',(img)=>{
// let scale = {
// X:MyCanvas.canvas.width/img.width,
// Y:MyCanvas.canvas.height/img.height
// }
// rect.set({
// fill: new fabric.Pattern({
// source: img.getElement(), // 传入图片元素
// repeat: 'no-repeat' // 设置图片不重复
// }),
// clipPath : rect1
// })
// img.set({
// scaleX:scale.X,
// scaleY:scale.Y,
// left:0,
// top:0,
// })
// MyCanvas.canvas.add(rect)
// },{ crossOrigin: "Anonymous" })
// // // MyCanvas.canvas.add(rect1)
// // // rect1.clipPath = group
// // // MyCanvas.canvas.forEachObject((item) =>{
// // // if(item.clipPath){
// // // item.clipPath.add(rect2)
// // // // item.clipPath = group
// // // }
// // // })
// return
MyCanvas . canvas . on ( "mouse:move" , this . setCanvasMove . bind ( this ) ) ;
MyCanvas . canvas . on ( "mouse:down" , this . setCanvasDown . bind ( this ) ) ;
MyCanvas . canvas . on ( "mouse:up" , this . setCanvasUp . bind ( this ) ) ;
MyCanvas . canvas . on ( "mouse:wheel" , this . setCanvasWheel . bind ( this ) ) ;
//双击
MyCanvas . canvas . on ( "mouse:dblclick" , event => {
if ( this . operation == 'fold' ) {
this . foldEnd ( 'Enter' )
}
} ) ;
document . addEventListener ( 'mousemove' , this . mouseMove . bind ( this ) ) ;
document . addEventListener ( 'touchmove' , this . touchmove . bind ( this ) ) ;
document . addEventListener ( "keydown" , this . canvasKeyDown ) ;
document . addEventListener ( "keyup" , this . canvasKeyUp ) ;
initAligningGuidelines ( MyCanvas . canvas , true ) ;
JSchangeType ( MyCanvas . canvas , 'init' )
// await this.createBg()
await this . createLayer ( { str : 'init' } ) //创建图层并且使用
MyCanvas . canvas . on ( "object:added" , ( event ) => {
this . addLayer ( event )
} ) ;
this . canvas = MyCanvas . canvas ;
return MyCanvas . canvas
}
initCanvasWH ( str ) {
let scale
if ( this . canvasWH . width > this . canvasWH . height ) scale = this . canvasDomParent . offsetWidth / this . canvasWH . width
if ( this . canvasWH . width < this . canvasWH . height ) scale = this . canvasDomParent . offsetHeight / this . canvasWH . height
if ( this . canvasWH . width == this . canvasWH . height ) scale = this . canvasDomParent . offsetHeight / this . canvasWH . height
let x = this . canvasWH . width / 2
let y = this . canvasWH . height / 2
if ( str == 'updata' ) {
x = 0
y = 0
const vpt = MyCanvas . canvas . viewportTransform ;
vpt [ 4 ] = 0 ; // 更新水平偏移
vpt [ 5 ] = 0 ; // 更新垂直偏移
}
MyCanvas . canvas . zoomToPoint (
{ // 关键点
x : x ,
y : y
} ,
scale
)
MyCanvas . canvas . setBackgroundColor ( {
source : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC' ,
repeat : 'repeat' ,
} , MyCanvas . canvas . renderAll . bind ( MyCanvas . canvas ) ,
)
}
mouseMove ( event ) {
let e = getMousePosition ( event , false )
this . setDomMove ( e )
}
touchmove ( event ) {
let e = getMousePosition ( event , true )
this . setDomMove ( e )
}
setDomMove ( event ) {
let canvasCenterBox = this . canvasDomParent ;
if ( ! canvasCenterBox ) return
let parentX = event . clientX - canvasCenterBox . getBoundingClientRect ( ) . left
let parentY = event . clientY - canvasCenterBox . getBoundingClientRect ( ) . top
this . pencilbtnStyle . left = parentX + "px"
this . pencilbtnStyle . top = parentY + 'px'
}
//设置操作
setOperation ( str ) {
this . operation = str
MyCanvas . canvas . discardActiveObject ( ) ; //取消所有选中边框
if ( this . createPatterning . state ) {
MyCanvas . canvas . remove ( this . createPatterning . current )
}
this . removeSetText ( )
initAligningGuidelines ( MyCanvas . canvas , false )
MyCanvas . canvas . remove ( this . createPatterning . polyLineBtn )
if ( str == 'pencil' ) {
this . setPencil ( )
this . pencilbtnStyle . display = ` block `
this . setCursor ( 'none' ) ;
MyCanvas . canvas . freeDrawingCursor = 'none'
} else if ( str == 'move' ) {
JSchangeType ( MyCanvas . canvas , '' )
MyCanvas . canvas . isDrawingMode = false
this . pencilbtnStyle . display = ` none `
this . setCursor ( 'grab' ) ;
} else if ( str == 'movePosition' ) {
JSchangeType ( MyCanvas . canvas , 'init' )
initAligningGuidelines ( MyCanvas . canvas , true )
this . setMove ( )
this . pencilbtnStyle . display = ` none `
this . setCursor ( 'all-scroll' ) ;
MyCanvas . canvas . isDrawingMode = false
} else if ( str == 'texture' ) {
this . setTexture ( )
this . pencilbtnStyle . display = ` block `
MyCanvas . canvas . freeDrawingCursor = 'none'
this . setCursor ( 'none' ) ;
} else if ( str == 'eraser' ) {
this . setEraser ( )
this . pencilbtnStyle . display = ` block `
MyCanvas . canvas . freeDrawingCursor = 'none'
this . setCursor ( 'none' ) ;
} else if ( str == 'text' ) {
this . setMove ( )
this . setText ( )
JSchangeType ( MyCanvas . canvas , 'init' )
this . setCursor ( 'text' )
this . pencilbtnStyle . display = ` none `
} else if ( [ 'zoomIn' , 'zoomOut' ] . includes ( str ) ) {
this . pencilbtnStyle . display = ` none `
if ( str == 'zoomIn' ) this . setCursor ( 'zoom-in' ) ;
if ( str == 'zoomOut' ) this . setCursor ( 'zoom-out' ) ;
MyCanvas . canvas . isDrawingMode = false
MyCanvas . canvas . forEachObject ( ( obj ) => {
if ( obj . type != 'group' && ! obj . isType ( 'path' ) ) {
obj . selectable = false
}
} ) ;
} else if ( [ 'dashedPencil' , 'dashed' ] . includes ( str ) ) {
this . setGroupGrid ( 'all' )
MyCanvas . canvas . isDrawingMode = false
this . pencilbtnStyle . display = ` none `
this . setCursor ( 'crosshair' )
MyCanvas . canvas . freeDrawingCursor = 'crosshair'
if ( str == 'dashedPencil' ) this . setDashedPencil ( )
MyCanvas . canvas . forEachObject ( ( obj ) => {
if ( obj . type != 'group' && ! obj . isType ( 'path' ) ) {
obj . selectable = false
}
} ) ;
} else if ( str ) {
this . pencilbtnStyle . display = ` none `
this . setCursor ( 'auto' ) ;
MyCanvas . canvas . isDrawingMode = false
MyCanvas . canvas . forEachObject ( ( obj ) => {
if ( obj . type != 'group' && ! obj . isType ( 'path' ) ) {
obj . selectable = false
}
} ) ;
}
2025-01-15 11:23:23 +08:00
if ( str == 'dashed' || str == 'dashedPencil' ) {
// if(str == 'dashed' || str == 'dashedPencil' || str != 'movePosition'){
2024-12-11 16:26:36 +08:00
if ( this . layer . selectLayer . group . custom . groupType == 'Grid' ) this . setGroupGrid ( 'all' )
this . clipPath = {
isImg : false ,
clipGroup : null ,
img : null ,
}
}
}
setCursor ( str ) {
MyCanvas . canvas . defaultCursor = str ;
MyCanvas . canvas . moveCursor = str ;
MyCanvas . canvas . hoverCursor = str ;
MyCanvas . canvas . upperCanvasEl . style . cursor = str ;
}
setCanvasMove = ( event ) => {
if ( this . mouse . isMovePostion && this . operation == 'move' ) return this . setCanvasPosition ( event )
if ( MyCanvas . canvas . isDrawingMode ) {
} else {
let getActiveObject = MyCanvas . canvas . getActiveObject ( )
if (
! this . clipPath . isImg &&
this . mouse . isDown &&
getActiveObject &&
getActiveObject . custom . dashed &&
this . layer . selectLayer . group . custom ? . groupType == 'Grid' &&
2025-01-16 09:47:28 +08:00
this . operation == 'movePosition'
2024-12-11 16:26:36 +08:00
) {
this . setclipPathImg ( )
}
if ( this . createPatterning . state ) {
let str = this . operation
if ( this . operation == 'dashed' ) str = 'rect'
JScanvasMouseMove ( str , event , this . createPatterning . current , this . mouse . point , this . keyboard . down )
MyCanvas . canvas . requestRenderAll ( )
}
}
}
setCanvasPosition ( event ) {
const e = event ;
const vpt = MyCanvas . canvas . viewportTransform ;
vpt [ 4 ] += e . pointer . x - this . mouse . lastPosX ; // 更新水平偏移
vpt [ 5 ] += e . pointer . y - this . mouse . lastPosY ; // 更新垂直偏移
MyCanvas . canvas . requestRenderAll ( ) ; // 请求重绘画布
this . mouse . lastPosX = e . pointer . x ;
this . mouse . lastPosY = e . pointer . y ;
}
// setRemoveDashed(){
// MyCanvas.canvas.forEachObject((obj) =>{
// if(obj.custom.dashed && obj._objects){
// let rect = obj._objects.filter(item => item.type == 'rect')[0]
// obj.remove(rect)
// MyCanvas.canvas.renderAll();
// }
// });
// }
//设置再画布上按下
setCanvasDown ( event ) {
if ( event . target && event . target . custom ? . dashed && [ 'dashedPencil' , 'dashed' ] . includes ( this . operation ) ) {
// if(MyCanvas.canvas.isDrawingMode){
// MyCanvas.canvas.isDrawingMode = false;
// }
this . dashed . state = true
} else if ( ! event . target ? . custom ? . dashed ) {
// if(['dashedPencil'].includes(this.operation)){
// MyCanvas.canvas.isDrawingMode = true;
// }
this . dashed . state = false
}
2025-01-15 11:23:23 +08:00
let dashedGroup = MyCanvas . canvas . getObjects ( ) . filter ( obj => obj ? . custom ? . dashed ) [ 0 ] ;
2024-12-11 16:26:36 +08:00
if ( this . dashed . state && ( this . operation == 'dashed' || this . operation == 'dashedPencil' ) && dashedGroup ) return
if ( ! this . dashed . state && ( this . operation == 'dashed' || this . operation == 'dashedPencil' ) && ! event . target ? . custom ? . dashed && dashedGroup ) {
MyCanvas . canvas . remove ( dashedGroup )
}
if ( this . operation == 'movePosition' && ! event ? . target ? . custom ? . dashed && this . layer . selectLayer . group . custom . groupType == 'Grid' ) this . setGroupGrid ( 'all' ) ;
//设置移动端按下添加元素
this . mouse . isDown = true
this . mouse . lastPosX = event . pointer . x ;
this . mouse . lastPosY = event . pointer . y ;
if ( this . operation == 'move' ) {
this . mouse . isMovePostion = true ;
this . setCursor ( 'grabbing' ) ;
return
}
if ( this . operation == 'zoomIn' || this . operation == 'zoomOut' ) {
this . setCanvasZoom ( event )
return
}
// this.setRemoveDashed()
if ( this . addPresent . upScaleChecked ) { //创建元素
this . present . upScaleChecked = false
this . present = { }
let pointerVpt = canvas . restorePointerVpt ( event . pointer )
switch ( currentType . value . type ) {
case 'colorBoards' :
let rect = setGroup ( currentType . value . data )
setCanvasColor ( pointerVpt . y , pointerVpt . x , rect )
break
default :
createImage ( pointerVpt . y , pointerVpt . x , currentType . value . type )
break
}
// 创建完元素,把当前操作的元素类型设置回 null
currentType . value . type = null
currentType . value . data = null
}
this . mouse . point = event . absolutePointer
let arr = [ 'rect' , 'line' , 'circle' , 'triangle' , 'ellipse' , 'fold' , 'dashed' ]
if ( arr . indexOf ( this . operation ) > - 1 ) {
JSchangeType ( MyCanvas . canvas , this . operation )
this . createPatterning . state = true
MyCanvas . canvas . forEachObject ( ( obj ) => {
obj . set ( 'selectable' , false ) ; // 禁用选中
} ) ;
if ( this . createPatterning . current && this . operation == 'fold' ) {
MyCanvas . canvas . skipTargetFind = false
this . createPatterning . current . points . push ( {
x : this . mouse . point . x ,
y : this . mouse . point . y
} )
} else {
let width = this . brushwork . width [ this . operation ] ? this . brushwork . width [ this . operation ] : 20
let data = {
str : this . operation ,
width ,
selectable : true ,
}
if ( this . operation == 'dashed' ) {
width = 1 / MyCanvas . canvas . getZoom ( )
data = {
fill : 'transparent' ,
strokeDashArray : [ width * 3 , width * 3 ] ,
width ,
radius : 0 ,
str : 'rect' ,
selectable : true ,
}
} else if ( this . operation == 'rect' ) {
data . width = 0
}
this . createPatterning . current = JScanvasMouseDown ( event , data )
if ( this . operation == 'dashed' ) this . createPatterning . current . set ( { custom : { dashed : true } } )
MyCanvas . canvas . add ( this . createPatterning . current )
if ( this . operation == 'fold' ) {
this . createPatterning . polyLineBtn = JScreateCheck ( event )
this . createPatterning . polyLineBtn . on ( 'mousedown' , this . foldEnd . bind ( this ) )
MyCanvas . canvas . add ( this . createPatterning . polyLineBtn )
}
}
} else {
// var clickedObject = event.target;
// if (clickedObject instanceof fabric.Textbox && this.operation != 'text') {
// this.createPatterning.textDataShow = true
// this.createText = clickedObject
// console.log(1);
// }else{
// console.log(2);
// this.createPatterning.textDataShow = false
// this.createText = {}
// }
// this.createPatterning.state = false
}
}
setTextData ( obj ) {
this . fontFamily = obj . fontFamily
this . brushwork . width [ 'text' ] = obj . fontSize
this . brushwork . color = obj . fill
}
async setCanvasUp ( event ) {
this . mouse . isDown = false
if ( this . mouse . isMovePostion ) {
this . mouse . isMovePostion = false
this . setCursor ( 'grab' ) ;
return
}
if ( this . operation == 'eraser' ) return this . updataLayer ( )
this . mouse . upPoint = event . absolutePointer
if ( MyCanvas . canvas . isDrawingMode ) {
setTimeout ( ( ) => {
// pencilbtnStyle.value.display = `none`
this . updateCanvasState ( )
} , 100 ) ;
} else {
// event.target && (event.target.bringToFront())//设置优先级
}
if ( this . createPatterning . state ) {
switch ( this . operation ) {
case 'line' :
this . createPatterning . current . set ( { stroke : this . brushwork . color } )
break
case 'fold' :
// this.createPatterning.current.set({stroke: this.brushwork.color})
break
default :
if ( JSON . stringify ( this . mouse . point ) == JSON . stringify ( this . mouse . upPoint ) ) {
MyCanvas . canvas . remove ( this . createPatterning . current )
return
}
if ( this . operation == 'dashed' ) {
this . createPatterning . current . set ( { fill : 'transparent' } )
} else if ( this . operationMode == 'fill' ) {
this . createPatterning . current . set ( { fill : this . brushwork . color } )
} else if ( this . operationMode == 'border' ) {
this . createPatterning . current . set ( { fill : 'transparent' , stroke : this . brushwork . color , strokeWidth : this . brushwork . width [ this . operation ] ? this . brushwork . width [ this . operation ] : 20 } )
}
break
}
if ( this . operation == 'fold' ) {
MyCanvas . canvas . forEachObject ( ( obj ) => {
if ( this . isSelectable ( obj ) ) {
obj . selectable = true
} else {
obj . selectable = false
}
} ) ;
MyCanvas . canvas . bringToFront ( this . createPatterning . polyLineBtn ) ; //设置优先级最高
} else if ( this . operation ) {
this . createPatterning . state = false
MyCanvas . canvas . renderAll ( ) ;
if ( this . operation == 'dashed' ) {
await this . setDashed ( this . createPatterning . current )
} else {
2025-01-15 11:23:23 +08:00
this . addLayer ( { target : this . createPatterning ? . current } )
2024-12-11 16:26:36 +08:00
this . setOperation ( 'movePosition' )
}
this . clearPatterning ( ) //临时图形置为空并且添加撤回对象里面
}
}
}
async setclipPathImg ( ) { //裁剪图片
if ( ! this . clipPath . clipGroup ) return
this . clipPath . isImg = true
2025-01-16 09:47:28 +08:00
let clipPathElement = this . clipPath . clipGroup . _objects . filter ( obj => obj . custom ) [ 0 ]
2024-12-11 16:26:36 +08:00
let imgBG = MyCanvas . canvas . getObjects ( ) . filter ( obj => obj . custom . isSelectable && obj . type == 'rect' ) [ 0 ] ;
let position = {
left : this . clipPath . clipGroup ? . left - ( imgBG . left ? imgBG . left : 0 ) ,
top : this . clipPath . clipGroup ? . top - ( imgBG . top ? imgBG . top : 0 ) ,
width : this . clipPath . clipGroup ? . width ,
height : this . clipPath . clipGroup ? . height ,
}
// await this.setGroupGrid()
//添加裁剪后的图片
let elements = MyCanvas . canvas . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) ) ;
let imgData = await this . groupToImg ( elements , position , 'clipPath' )
let img = await this . createImage ( { minioUrl : imgData } )
img . set ( {
scaleX : 1 ,
scaleY : 1 ,
left : 0 - position . width / 2 ,
top : 0 - position . height / 2 ,
} )
img . clipPath = clipPathElement
this . clipPath . clipGroup . insertAt ( img )
//裁剪
this . layer . selectLayer . group . custom . groupType = 'Grid'
clipPathElement . clone ( cloned => {
cloned . set ( { left : position . left , top : position . top , strokeWidth : 0 } )
if ( imgBG ? . custom ? . state != 'success' ) this . setClipPath ( imgBG , cloned )
} )
}
setDashedPencil ( ) {
MyCanvas . canvas . isDrawingMode = true
let pencil = new fabric . Test ( MyCanvas . canvas , { } ) ; //普通笔
MyCanvas . canvas . freeDrawingBrush = pencil
}
async setDashed ( obj ) {
MyCanvas . canvas . remove ( obj )
let position = {
left : obj . left ,
top : obj . top ,
width : obj . width ,
height : obj . height ,
}
await obj . clone ( ( cloned ) => {
let { width , height , left , top } = position
2025-01-17 17:16:01 +08:00
cloned . set ( {
custom : {
dashed : true
}
} )
2024-12-11 16:26:36 +08:00
// cloned.set({left:cloned.strokeWidth/2,top:cloned.strokeWidth/2})
let group = new fabric . Group ( [ cloned ] , {
left : left + cloned . strokeWidth / 2 ,
top : top + cloned . strokeWidth / 2 ,
width , height ,
custom : {
dashed : true
}
} )
2025-01-15 11:23:23 +08:00
console . log ( 223 ) ;
2024-12-11 16:26:36 +08:00
MyCanvas . canvas . add ( group )
} )
}
async setGridOrObject ( id , str ) {
this . layer . list . forEach ( ( item ) => {
if ( item . id == id ) item . groupType = str
} )
await this . lookingLayer ( id ) . then ( rv => {
rv . custom . groupType = str
} )
if ( str == 'Grid' ) {
await this . setGroupGrid ( )
} else {
await this . setGroupGrid ( 'all' )
}
this . setOperation ( 'movePosition' )
}
async copyLayer ( id ) {
let createId = new Date ( ) . getTime ( )
let elements = MyCanvas . canvas . getObjects ( ) . filter ( obj => obj . custom . layerId == id )
let copyElements = [ ]
for ( let i = 0 ; i < elements . length ; i ++ ) {
await new Promise ( ( resolve , reject ) => {
let item = elements [ i ]
item . clone ( ( clonedObj ) => {
this . setClone ( item , clonedObj )
clonedObj . custom . layerId = createId
copyElements . push ( clonedObj )
resolve ( '' )
} )
} )
}
await this . createLayer ( { id : createId } )
copyElements . forEach ( item => MyCanvas . canvas . add ( item ) )
}
async setGroupGrid ( str ) { //group变为图片
// MyCanvas.canvas.discardActiveObject();//取消所有选中边框
let elements = MyCanvas . canvas . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) && ! obj . custom . dashed && obj . type ) ;
if ( str == 'all' ) {
elements = MyCanvas . canvas . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) && obj . type ) ;
}
let layerBg = elements . filter ( obj => obj . custom . isSelectable ) [ 0 ]
let scaleXY = {
scaleX : layerBg ? . scaleX ? layerBg ? . scaleX : 1 ,
scaleY : layerBg ? . scaleY ? layerBg ? . scaleY : 1 ,
width : layerBg ? . width ? layerBg ? . width : MyCanvas . canvas . width ,
height : layerBg ? . height ? layerBg ? . height : MyCanvas . canvas . height ,
}
let imgData = await this . groupToImg ( elements , { } , 'setGrid' , scaleXY )
let img = await this . createImage ( { minioUrl : imgData } )
elements . forEach ( ( obj ) => {
if ( obj . custom . isSelectable ) {
} else {
MyCanvas . canvas . remove ( obj )
}
} ) ;
if ( layerBg ) {
layerBg . custom . state = ''
delete layerBg . eraser
layerBg . set ( {
scaleX : 1 ,
scaleY : 1 ,
width : scaleXY . width * scaleXY . scaleX ,
height : scaleXY . height * scaleXY . scaleY ,
clipPath : null ,
fill : new fabric . Pattern ( {
source : img . getElement ( ) , // 传入图片元素
repeat : 'no-repeat' // 设置图片不重复
} ) ,
hasBorders : true ,
hasControls : true
} )
this . setGroupStyle ( layerBg )
} else {
const rect = new fabric . Rect ( {
// left:0,
// top:0,
width : MyCanvas . canvas . width ,
height : MyCanvas . canvas . height ,
strokeWidth : 0 ,
fill : new fabric . Pattern ( {
source : img . getElement ( ) , // 传入图片元素
repeat : 'no-repeat' // 设置图片不重复
} ) ,
custom : {
isSelectable : true ,
} ,
hasBorders : true ,
hasControls : true
} ) ;
this . setGroupStyle ( rect )
MyCanvas . canvas . add ( rect )
}
MyCanvas . canvas . renderAll ( ) // 刷新画布, 改变group的visible属性, 必须通过刷新画布, 才能应用新属性值
}
//液化
getLiquefactionImgObj ( ) {
return new Promise ( async ( resolve , reject ) => {
let img , str = null
const activeObject = this . canvas . getActiveObject ( ) ; // 获取选中的对象
let dashedGroup = MyCanvas . canvas . getObjects ( ) . filter ( obj => obj . custom . dashed ) [ 0 ] ;
if ( activeObject && activeObject . type === 'image' &&
activeObject . custom . type == 'upImgFiles'
) {
img = activeObject
this . liquefaction . type = 'upImgFiles'
} else if ( dashedGroup ) { //判断选取是否存在
if (
dashedGroup . _objects . filter ( item => item . type == 'image' ) . length == 0 &&
this . layer . selectLayer . group . custom . groupType == 'Grid'
) {
await this . setclipPathImg ( )
} else if ( dashedGroup . _objects . filter ( item => item . type == 'image' ) . length == 0 ) {
resolve ( )
return
}
await new Promise ( ( resolve , reject ) => {
dashedGroup . clone ( async ( cloned ) => {
this . setClone ( dashedGroup , cloned )
this . liquefaction . dashed = dashedGroup
this . liquefaction . type = 'dashed'
cloned . _objects = cloned . _objects . filter ( item => item . type == 'image' )
img = await cloned . toDataURL ( )
resolve ( )
} )
} )
} else if ( this . layer . selectLayer . group . custom . groupType == 'Grid' ) { //判断当前图层是否可以做为液化图片
let bg = this . canvas . getObjects ( ) . filter ( item => item . custom ? . isSelectable ) [ 0 ]
img = bg . fill . source . src
this . liquefaction . type = 'layer'
}
this . liquefaction . img = img
resolve ( this . liquefaction )
} )
}
async setLiquefactionImgObj ( liquefaction , data ) {
if ( liquefaction . type == 'upImgFiles' ) {
await new Promise ( ( resolve , reject ) => {
liquefaction . img . setSrc ( data , ( value ) => {
delete liquefaction . img . minioUrl
resolve ( )
} )
} )
} else if ( liquefaction . type == 'dashed' ) {
if ( liquefaction . dashed ) {
await new Promise ( ( resolve , reject ) => {
liquefaction . dashed . _objects = liquefaction . dashed . _objects . filter ( item => item . type != 'image' )
fabric . Image . fromURL ( data , ( value ) => {
value . set ( {
left : - liquefaction . dashed . width / 2 ,
top : - liquefaction . dashed . height / 2 ,
} )
liquefaction . dashed . insertAt ( value )
resolve ( )
} )
} )
// canvasObj.addDashedImg(value)
}
} else if ( liquefaction . type == 'layer' ) {
let bg = this . canvas . getObjects ( ) . filter ( item => item . custom ? . isSelectable ) [ 0 ]
let img = await this . createImage ( { minioUrl : data } )
bg . set ( {
fill : new fabric . Pattern ( {
source : img . getElement ( ) , // 传入图片元素
repeat : 'no-repeat' // 设置图片不重复
} ) ,
} )
}
MyCanvas . canvas . renderAll ( ) ;
this . updateCanvasState ( )
}
//end液化
setGroupStyle ( obj ) {
obj . set ( {
borderColor : '#4584ff' ,
cornerStrokeColor : '#4584ff' ,
cornerStyle : 'circle'
} )
obj . setControlsVisibility ( {
mtr : false ,
deleteControl : false
} )
// obj.controls.deleteControl.mouseUpHandler = null
}
setClipPath ( img , clipPath ) {
let imgScale = {
pX : ( img ? . scaleX ? img . scaleX : 1 ) ,
pY : ( img ? . scaleY ? img . scaleY : 1 ) ,
}
clipPath . set ( {
left : clipPath . left - img . width * imgScale . pX / 2 ,
top : clipPath . top - img . height * imgScale . pY / 2 ,
inverted : true ,
} )
img . set ( { clipPath : clipPath } )
img . custom . state = 'success'
MyCanvas . canvas . renderAll ( ) // 刷新画布, 改变group的visible属性, 必须通过刷新画布, 才能应用新属性值
}
async groupToImg ( elements , imgData , type , scaleXY ) {
let temporar = this . temporarilyExport ( scaleXY )
let bg = elements . filter ( item => item . custom ? . isSelectable ) [ 0 ]
let xy = {
x : bg ? . left ? bg ? . left : 0 ,
y : bg ? . top ? bg ? . top : 0 ,
}
for ( let index = 0 ; index < elements . length ; index ++ ) {
const item = elements [ index ] ;
await new Promise ( ( resolve , reject ) => {
item . clone ( ( cloned ) => {
this . setClone ( item , cloned )
if ( item . custom ? . dashed && item . _objects ) {
cloned . _objects = cloned . _objects . filter ( item => item . type == 'image' )
}
// if(type == 'setGrid'){
cloned . set ( {
left : cloned . left - xy . x ,
top : cloned . top - xy . y ,
} )
// }
if ( cloned . custom ? . layerId != - 1 ) {
temporar . add ( cloned )
}
resolve ( )
} )
} )
}
let data = temporar . toDataURL ( imgData ) ;
this . closeTemporarilyExport ( temporar )
return data
}
setCanvasWheel ( opt ) {
const delta = opt . e . deltaY // 滚轮,向上滚一下是 -100, 向下滚一下是 100
let zoom = MyCanvas . canvas . getZoom ( ) // 获取画布当前缩放值
zoom *= 0.999 * * delta
if ( zoom > 20 ) zoom = 20
if ( zoom < 0.01 ) zoom = 0.01
MyCanvas . canvas . zoomToPoint (
{ // 关键点
x : opt . e . offsetX ,
y : opt . e . offsetY
} ,
zoom
)
opt . e . preventDefault ( )
opt . e . stopPropagation ( )
this . setPencilWidth ( )
}
foldEnd ( key ) {
MyCanvas . canvas . skipTargetFind = true
let points = this . createPatterning . current . points
if ( key == 'Enter' ) {
} else {
points . pop ( )
}
points . pop ( )
this . createPatterning . state = false
MyCanvas . canvas . remove ( this . createPatterning . current )
MyCanvas . canvas . remove ( this . createPatterning . polyLineBtn )
let polyline = new fabric . Polyline ( points , {
fill : this . operationMode == 'fill' ? this . brushwork . color : 'transparent' ,
stroke : this . brushwork . color ,
strokeWidth : this . brushwork . width [ this . operation ] ? this . brushwork . width [ this . operation ] : 20 ,
// selection:false,
} )
polyline . set ( {
left : polyline . left + polyline . strokeWidth / 2 ,
top : polyline . top + polyline . strokeWidth / 2 ,
} )
MyCanvas . canvas . add ( polyline )
this . clearPatterning ( ) //临时图形置为空并且添加撤回对象里面
// this.layerAddElement(polyline)
}
clearPatterning ( ) {
if ( this . createPatterning . state ) {
MyCanvas . canvas . remove ( this . createPatterning . current )
}
this . createPatterning . current = null
MyCanvas . canvas . remove ( this . createPatterning . polyLineBtn )
this . updateCanvasState ( )
}
textureValueChange = ( value ) => {
this . texture . value = value
this . setTexture ( )
}
setOperationMode ( str ) {
this . operationMode = str
}
brushworkChange = ( value ) => {
this . brushwork . value = value
this . setPencil ( )
}
setLayerIndex ( str ) { //设置优先级
var activeObject = MyCanvas . canvas . getActiveObject ( ) ;
switch ( str ) {
case 'Front' :
MyCanvas . canvas . bringToFront ( activeObject ) //顶层
// this.layer.selectLayer.group.bringToFront(activeObject)
break
case 'Back' :
MyCanvas . canvas . sendToBack ( activeObject ) //底层
// this.layer.selectLayer.group.sendToBack(activeObject)
break
case 'Forward' :
MyCanvas . canvas . bringForward ( activeObject )
// this.layer.selectLayer.group.bringForward(activeObject)
break
case 'Backwards' :
MyCanvas . canvas . sendBackwards ( activeObject )
// this.layer.selectLayer.group.sendBackwards(activeObject)
break
}
}
setPencil ( ) {
let pencil
MyCanvas . canvas . isDrawingMode = true //开启绘画模式
if ( this . brushwork . value == 'PencilBrush' ) {
pencil = new fabric . PencilBrush ( MyCanvas . canvas , { } ) ; //普通笔
} else if ( this . brushwork . value == 'Marking' ) {
pencil = new fabric . PencilBrush ( MyCanvas . canvas , ) ; //记号笔
} else if ( this . brushwork . value == 'InkBrush' ) {
pencil = new fabric . InkBrush ( MyCanvas . canvas , { } ) ; //油画笔
} else if ( this . brushwork . value == 'CrayonBrush' ) {
pencil = new fabric . CrayonBrush ( MyCanvas . canvas , { } ) ; //蜡笔
} else if ( this . brushwork . value == 'RibbonBrush' ) {
pencil = new fabric . RibbonBrush ( MyCanvas . canvas , { width : 1 , } ) ; //色带
} else if ( this . brushwork . value == 'MarkerBrush' ) {
pencil = new fabric . MarkerBrush ( MyCanvas . canvas , { } ) ; //书写笔
// pencil = new fabric.PenBrush(MyCanvas.canvas,{}); //书写笔
} else if ( this . brushwork . value == 'WritingBrush' ) {
pencil = new fabric . WritingBrush ( MyCanvas . canvas , { } ) ; //毛笔
} else if ( this . brushwork . value == 'LongfurBrush' ) {
pencil = new fabric . LongfurBrush ( MyCanvas . canvas , { width : 1 , } ) ; //色带
} else if ( this . brushwork . value == 'SpraypaintBrush' ) {
pencil = new fabric . SpraypaintBrush ( MyCanvas . canvas , { } ) ; //长毛刷
}
MyCanvas . canvas . freeDrawingBrush = pencil
if ( this . brushwork . value == 'RibbonBrush' || this . brushwork . value == 'LongfurBrush' ) {
MyCanvas . canvas . freeDrawingBrush . width = 1 ;
}
if ( this . brushwork . value == 'Marking' ) {
MyCanvas . canvas . freeDrawingBrush . color = this . hexToRgba ( this . brushwork . color , . 5 ) ;
// }else if(this.brushwork.value == 'InkBrush'){
// canvas.freeDrawingBrush.color = this.hexToRgba(this.brushwork.color,.2);
} else {
MyCanvas . canvas . freeDrawingBrush . color = this . hexToRgba ( this . brushwork . color , 1 ) ;
}
this . setPencilWidth ( )
this . pencilbtnStyle . background = this . brushwork . color
MyCanvas . canvas . freeDrawingBrush . isEraser = false
}
setCanvasZoom ( opt ) {
let zoom = MyCanvas . canvas . getZoom ( ) // 获取画布当前缩放值
let num = - 100
if ( this . operation == 'zoomOut' ) num = 100
zoom *= 0.999 * * num
if ( zoom > 20 ) zoom = 20
if ( zoom < 0.01 ) zoom = 0.01
// MyCanvas.canvas.setDimensions(MyCanvas.canvas.width *= zoom,MyCanvas.canvas.height *= zoom)
// MyCanvas.canvas.wrapperEl.style.zoom = zoom
MyCanvas . canvas . zoomToPoint (
{ // 关键点
x : opt . pointer . x ,
y : opt . pointer . y
} ,
zoom
)
opt . e . preventDefault ( )
opt . e . stopPropagation ( )
this . setPencilWidth ( )
}
async addImage ( imgData ) {
let img = await this . createImage ( imgData )
let position = {
// left: 0,
// top:MyCanvas.canvas.wrapperEl.parentNode.scrollTop,
left : MyCanvas . canvas . width / 2 ,
top : MyCanvas . canvas . height / 2 ,
}
img . set ( {
custom : {
type : 'upImgFiles'
}
} )
await this . createLayer ( { } )
this . setCanvasImage ( img , position , "upImgFiles" , imgData )
}
createImage ( imgData ) {
return new Promise ( ( resolve , reject ) => {
fabric . Image . fromURL ( imgData . minioUrl , ( img ) => {
resolve ( img )
} , { crossOrigin : "Anonymous" } )
} )
}
setImageWidth = ( key , img ) => {
const CW = MyCanvas . canvas . width
const CH = MyCanvas . canvas . height
let WH = CW > CH ? 'H' : 'W'
let imgWidth ; //这是设置画布等宽
if ( WH == 'W' ) {
imgWidth = CW / 2 ;
} else {
let heightScale = ( CH / 2 ) / img . height
imgWidth = img . width * heightScale
}
// let sketchGrouping = 6
// if(key == 'upImgFiles'){
// imgWidth = imgWidth / 8;
// }else if (key == "printboardFiles") {
// imgWidth = imgWidth / 14;
// }else if (key == "sketchboardFiles"||key == 'moodboardFiles'||key == 'FinalizeImage') {
// imgWidth =
// (imgWidth -
// (sketchGrouping - 1) * 20) /
// sketchGrouping;
// }else if (key == "likeDesignCollectionList") {
// if(img){
// let imgObj = JSON.parse(JSON.stringify(img))
// let height = imgObj.height
// imgObj.height = imgWidth / 8 * 1.8
// let heightScale = imgObj.height / height
// imgWidth = imgObj.width * heightScale
// }
// }else {
// if(img){
// let imgObj = JSON.parse(JSON.stringify(img))
// if(imgObj.height > imgObj.width){
// let heightScale = (MyCanvas.canvas.height/2) / imgObj.height
// imgWidth = imgObj.width * heightScale
// }else{
// imgWidth /= 2
// }
// }
// }
return imgWidth
}
async setCanvasImage ( img , position , key , data ) {
let minioUrl = '' //表示收藏或者generate
let imgUrl = data . imgUrl
if ( key == "likeDesignCollectionList" ) {
imgUrl = data . designOutfitUrl ;
}
let imgWidth = await this . setImageWidth ( key , img ) ;
if ( imgUrl ? . split ( '?' ) ) {
2025-05-09 16:07:47 +08:00
// let url = imgUrl.split('?')[0]
// var match = url.match(/^(?:https?:\/\/[^\/]+)\/(.*)/);
// minioUrl = match[1]
const { pathname } = new URL ( imgUrl ) ;
const result = pathname . slice ( 1 ) ;
minioUrl = result
2024-12-11 16:26:36 +08:00
}
let proportion = img . height / img . width ; //计算图形宽高比例
let scaleWH = imgWidth / img . width ; //计算放到画布上缩小倍率
let scale = {
X : imgWidth / img . width ,
Y : ( img . width * proportion * scaleWH ) / img . height ,
}
img . set ( {
left : position . left - img . width * scale . X / 2 ,
top : position . top - img . height * scale . Y / 2 ,
minioUrl ,
scaleX : scale . X ,
scaleY : scale . Y ,
} ) ;
MyCanvas . canvas . add ( img )
this . updateCanvasState ( '' )
}
setMove ( ) {
MyCanvas . canvas . isDrawingMode = false
MyCanvas . canvas . forEachObject ( ( obj ) => {
if ( this . isSelectable ( obj ) ) {
obj . selectable = true
} else {
obj . selectable = false
}
} ) ;
MyCanvas . canvas . renderAll ( ) // 刷新画布, 改变group的visible属性, 必须通过刷新画布, 才能应用新属性值
}
async setTexture ( ) {
MyCanvas . canvas . isDrawingMode = true //开启绘画模式
let img = await JSSetTexture ( this . texture . list [ this . texture . value ] . url )
let zoom = MyCanvas . canvas . getZoom ( ) // 获取画布当前缩放值
let patternBrush = new fabric . PatternBrush ( MyCanvas . canvas )
patternBrush . source = img
patternBrush . width = Number ( this . brushwork . width [ this . operation ] ) / zoom ; // 设置画笔大小
this . setPencilWidth ( )
MyCanvas . canvas . freeDrawingBrush = patternBrush
}
setEraser ( ) {
MyCanvas . canvas . isDrawingMode = true
let eraser = new fabric . EraserBrush ( MyCanvas . canvas )
MyCanvas . canvas . freeDrawingBrush = eraser
this . pencilbtnStyle . background = '#fff'
MyCanvas . canvas . freeDrawingBrush . isEraser = true
this . setPencilWidth ( )
MyCanvas . canvas . requestRenderAll ( ) ;
}
hexToRgba ( hex , alpha ) {
const r = parseInt ( hex . slice ( 1 , 3 ) , 16 ) ;
const g = parseInt ( hex . slice ( 3 , 5 ) , 16 ) ;
const b = parseInt ( hex . slice ( 5 , 7 ) , 16 ) ;
return ` rgba( ${ r } , ${ g } , ${ b } , ${ alpha } ) ` ;
}
pencilColor ( ) {
if ( this . createText ? . set ) {
this . setFontFamily ( )
return
}
if ( MyCanvas . canvas . freeDrawingBrush . isEraser ) {
} else {
this . pencilbtnStyle . background = this . brushwork . color
}
if ( this . brushwork . value == 'Marking' ) {
MyCanvas . canvas . freeDrawingBrush . color = this . hexToRgba ( this . brushwork . color , . 5 ) ;
} else if ( this . brushwork . value == 'InkBrush' ) {
MyCanvas . canvas . freeDrawingBrush . color = this . hexToRgba ( this . brushwork . color , . 2 ) ;
} else {
MyCanvas . canvas . freeDrawingBrush . color = this . hexToRgba ( this . brushwork . color , 1 ) ;
}
}
setFontFamily = ( ) => {
if ( this . createText . set ) {
this . createText . set ( {
fontFamily : this . fontFamily ,
fontSize : this . brushwork . width [ this . operation ] ? this . brushwork . width [ this . operation ] : 20 ,
fill : this . brushwork . color ,
} )
MyCanvas . canvas . renderAll ( ) ;
}
}
setPencilColor ( ) { //切换颜色给铅笔设置颜色
clearTimeout ( this . setTimeOut . color )
clearTimeout ( this . setTimeOut . colorHistory )
this . setTimeOut . color = setTimeout ( ( ) => {
this . pencilColor ( )
} , 200 )
this . setTimeOut . colorHistory = setTimeout ( ( ) => {
this . colorHistoryList . push ( this . brushwork . color )
} , 1000 )
}
setCanvasWH = ( str ) => {
clearTimeout ( this . setTimeOut . canvasWH )
this . setTimeOut . canvasWH = setTimeout ( ( ) => {
MyCanvas . canvas . setWidth ( this . canvasWH . width ) ;
MyCanvas . canvas . setHeight ( this . canvasWH . height ) ;
// MyCanvas.canvas.width = this.canvasWH.width
// MyCanvas.canvas.height = this.canvasWH.height
this . initCanvasWH ( 'updata' )
} , 1000 )
}
setColorHistory = ( value ) => {
this . brushwork . color = value
this . pencilColor ( )
}
setPencilWidth ( ) { //切换颜色给铅笔设置颜色
let zoom = MyCanvas . canvas . getZoom ( ) // 获取画布当前缩放值
clearTimeout ( this . setTimeOut . width )
this . setTimeOut . width = setTimeout ( ( ) => {
if ( ! this . brushwork . width [ this . operation ] ) this . brushwork . width [ this . operation ] = 20
// MyCanvas.canvas.freeDrawingBrush.width = Number(this.brushwork.width[this.operation]);
let arr = [ 'PencilBrush' , 'Marking' ]
this . pencilbtnStyle . height = this . brushwork . width [ this . operation ] + 'px'
this . pencilbtnStyle . width = this . brushwork . width [ this . operation ] + 'px'
if ( arr . indexOf ( this . brushwork . value ) > - 1 ) {
MyCanvas . canvas . freeDrawingBrush . width = Number ( this . brushwork . width [ this . operation ] ) / zoom ;
} else {
MyCanvas . canvas . freeDrawingBrush . width = Number ( this . brushwork . width [ this . operation ] ) ;
}
if ( ( this . brushwork . value == 'LongfurBrush' || this . brushwork . value == 'RibbonBrush' ) && this . operation == 'pencil' ) {
MyCanvas . canvas . freeDrawingBrush . width = 1 ;
this . pencilbtnStyle . height = 1 + 'px'
this . pencilbtnStyle . width = 1 + 'px'
}
} , 100 )
}
//关闭u或者创建文字
setTextFun ( e ) {
if ( this . operation != 'text' ) {
return
}
MyCanvas . canvas . forEachObject ( ( obj ) => {
if ( obj . type == 'textbox' && ! obj . text ) {
MyCanvas . canvas . remove ( obj ) ;
}
} ) ;
var clickedObject = e . target ;
if ( clickedObject instanceof fabric . Textbox ) {
this . createText = clickedObject
this . setTextData ( this . createText )
} else {
var pointer = MyCanvas . canvas . getPointer ( e . pointer ) ;
var x = pointer . x ;
var y = pointer . y ;
this . createText = new fabric . Textbox ( '' , {
left : x ,
top : y ,
width : 50 ,
fontSize : this . brushwork . width [ this . operation ] ? this . brushwork . width [ this . operation ] : 20 ,
fontFamily : this . fontFamily ,
fill : this . canvasPencilColor ,
} )
MyCanvas . canvas . add ( this . createText )
// this.layer.selectLayer.group.add(this.createText)
this . createText . enterEditing ( ) ;
MyCanvas . canvas . setActiveObject ( this . createText ) . renderAll ( ) ;
this . removeSetText ( )
}
}
setText ( ) {
MyCanvas . canvas . on ( 'mouse:down' , ( event ) => {
if ( this . operation == 'zoomIn' || this . operation == 'zoomOut' ) {
} else {
this . setTextFun ( event )
}
} )
}
removeSetText ( ) {
MyCanvas . canvas . off ( 'mouse:down' , this . setTextFun . bind ( this ) )
}
// async createBg(){//
// await new Promise((resolve, reject) => {
// let url = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC'
// fabric.Image.fromURL(url, (backgroundImage)=>{
// backgroundImage.set({
// })
// const rect = new fabric.Rect({
// left: 0,
// top: 0,
// width: MyCanvas.canvas.width,
// height: MyCanvas.canvas.height,
// fill:'#FFF',
// // fill: new fabric.Pattern({
// // source: backgroundImage.getElement(), // 使用图像元素作为填充
// // repeat: 'repeat', // 设置为重复
// // patternTransform: [this.canvasWH.width/this.canvasDomParent.offsetWidth, 0, 0, this.canvasWH.width/this.canvasDomParent.offsetWidth, 0, 0]
// // }),
// });
// const group = new fabric.Group([rect], {
// width: MyCanvas.canvas.width,
// height: MyCanvas.canvas.height,
// erasable:false,
// selectable:false,
// });
// group.custom.layerId = -1
// MyCanvas.canvas.add(group)
// MyCanvas.canvas.clipPath = rect
// resolve()
// });
// })
// }
createLayer ( data ) {
let { str , id } = data
let canvasData = MyCanvas . canvas . toJSON ( [ 'selectable' , 'minioUrl' , 'custom' ] ) ;
return new Promise ( async ( resolve , reject ) => {
MyCanvas . canvas . discardActiveObject ( ) ;
if ( ! id ) id = new Date ( ) . getTime ( )
let index = this . layer . currentIndex += 1
const rect = new fabric . Rect ( {
left : - MyCanvas . canvas . width / 2 ,
top : - MyCanvas . canvas . height / 2 ,
// left:0,
// top:0,
width : MyCanvas . canvas . width ,
height : MyCanvas . canvas . height ,
strokeWidth : 0 ,
fill : '#FFF' ,
custom : {
layerId : id ,
isSelectable : true ,
} ,
// erasable:false,
selectable : false ,
} ) ;
rect . clone ( ( cloned ) => {
rect . clipPath = cloned
} )
const group = new fabric . Group ( [ ] , {
width : MyCanvas . canvas . width ,
height : MyCanvas . canvas . height ,
left : 0 ,
top : 0 ,
selectable : false ,
erasable : false ,
subTargetCheck : true ,
evented : false ,
// originX:'left',
// originY:'top',
custom : {
layerId : id ,
type : 'layer' ,
groupType : 'Object' ,
layerIndex : index ,
selectLayerIndex : ( index ) * 10000 ,
}
} ) ;
if ( str == 'init' ) {
group . moveTo ( group . custom . selectLayerIndex )
group . add ( rect )
group . clone ( ( cloned ) => {
cloned . set ( { left : 0 , top : 0 } )
MyCanvas . canvas . clipPath = cloned
} )
}
MyCanvas . canvas . add ( group )
let img = group . toDataURL ( {
width : MyCanvas . canvas . width ,
height : MyCanvas . canvas . height ,
} )
this . layer . list . unshift ( {
name : ` Layer ${ index } ` ,
id , img , isShow : true ,
groupType : 'Object' ,
index , } )
await this . selectLayer ( id )
MyCanvas . canvas . renderAll ( ) ;
this . updateCanvasState ( )
resolve ( group )
} )
}
layerAddElement ( obj ) {
let group = this . layer . selectLayer . group
obj . left = obj . left - group . width / 2
obj . top = obj . top - group . height / 2
group . add ( obj )
MyCanvas . canvas . remove ( obj )
this . updataLayerImg ( this . layer . selectLayer . id , group . toDataURL ( {
width : MyCanvas . canvas . width ,
height : MyCanvas . canvas . height
} ) )
}
2025-01-16 09:47:28 +08:00
async addLayer ( options ) {
console . log ( options ) ;
2024-12-11 16:26:36 +08:00
if ( this . createPatterning . state ) return
this . clipPath . clipGroup = MyCanvas . canvas . getObjects ( ) . filter ( obj => obj . custom ? . dashed ) ? . [ 0 ] ;
if ( options . target . type === 'group' && options . target . custom ? . layerId ) return ;
if ( ! options . target ? . custom ? . layerId ) {
if ( options . target ? . custom ) {
options . target . custom . layerId = this . layer . selectLayer . id
} else {
options . target . set ( { custom : { layerId : this . layer . selectLayer . id } } )
}
}
//判断是否可以点击空白地方进行选中
if ( options . target ? . custom ? . dashed ) {
options . target . set ( { perPixelTargetFind : false , erasable : false , hasBorders : false , hasControls : false } )
// MyCanvas.canvas.setActiveObject(options.target);
MyCanvas . canvas . skipTargetFind = false
this . setOperation ( 'movePosition' )
} else if ( options . target . type == 'textbox' || options . target ? . custom . type == 'layer' ) {
options . target . set ( { perPixelTargetFind : false } )
} else {
options . target . set ( { perPixelTargetFind : true } )
}
//设置优先级
if ( options . target ? . custom ? . isSelectable && ( options . target ? . type == 'rect' ) ) {
options . target . custom . selectLayerIndex = this . layer . selectLayer . group . custom . layerIndex * 10000
} else {
options . target . custom . selectLayerIndex = this . layer . selectLayer . group . custom . selectLayerIndex += 1
if ( this . clipPath . clipGroup ) {
this . clipPath . clipGroup . custom . selectLayerIndex = this . layer . selectLayer . group . custom . selectLayerIndex + 1
}
}
if ( options . target . isType ( 'path' ) ) options . target . selectable = false
let arr = MyCanvas . canvas . getObjects ( ) . sort ( ( a , b ) => {
return a . custom . selectLayerIndex - b . custom . selectLayerIndex ;
} ) ;
arr . forEach ( ( item , index ) => {
item . moveTo ( index )
} )
2025-01-15 11:23:23 +08:00
if ( ! options ? . target ? . custom ? . dashed && this . layer . selectLayer . group . custom . groupType == 'Grid' ) {
2025-01-16 09:47:28 +08:00
await new Promise ( ( resolve , reject ) => {
2025-01-17 17:16:01 +08:00
console . log ( this . clipPath . clipGroup ) ;
let clipPathElement = this . clipPath . clipGroup . _objects . filter ( obj => obj . custom ? . dashed ) [ 0 ]
2025-01-16 09:47:28 +08:00
let clipPathLect = this . clipPath . clipGroup . left
let clipPathTop = this . clipPath . clipGroup . top
clipPathElement . clone ( ( clipPathElementCloned ) => {
clipPathElementCloned . set ( {
// left:this.clipPath.clipGroup.left,
// top:this.clipPath.clipGroup.top,
left : clipPathLect ,
top : clipPathTop ,
absolutePositioned : true ,
} )
let optionLect = ( options . target . left - this . clipPath . clipGroup . left ) - this . clipPath . clipGroup . width / 2
let optionTop = ( options . target . top - this . clipPath . clipGroup . top ) - this . clipPath . clipGroup . height / 2
options . target . clone ( ( cloned ) => {
cloned . set ( {
left : optionLect ,
top : optionTop ,
clipPath : clipPathElementCloned ,
} )
this . clipPath . clipGroup . add ( cloned )
console . log ( this . clipPath . clipGroup ) ;
MyCanvas . canvas . remove ( options . target )
resolve ( )
} )
} )
} )
2025-01-15 11:23:23 +08:00
// this.setGroupGrid('all')
}
2024-12-11 16:26:36 +08:00
MyCanvas . canvas . renderAll ( ) ;
this . updataLayer ( )
}
upLayerIndex ( list ) {
list . forEach ( ( item , index ) => {
let arr = MyCanvas . canvas . getObjects ( ) . filter ( obj => obj . custom . layerId == item . id )
arr . forEach ( ( obj ) => {
if ( obj . custom . type == 'layer' ) obj . custom . layerIndex = item . index
let selectLayerIndex = obj . custom . selectLayerIndex + ''
selectLayerIndex = selectLayerIndex . replace ( /^\d/ , item . index ) ;
obj . custom . selectLayerIndex = Number ( selectLayerIndex )
} )
// arrList.unshift(obj)
} )
// this.layer.list = arrList
let arr = MyCanvas . canvas . getObjects ( ) . sort ( ( a , b ) => {
return a . custom . selectLayerIndex - b . custom . selectLayerIndex ;
} ) ;
arr . forEach ( ( item , index ) => item . moveTo ( index ) )
}
updataLayer ( ) {
clearTimeout ( this . setTimeOut . updataLayer )
this . setTimeOut . updataLayer = setTimeout ( async ( ) => {
let elements
elements = MyCanvas . canvas . getObjects ( ) . filter ( obj => {
return this . isAddToLayer ( obj )
} ) ;
const group = new fabric . Group ( [ ] , {
width : this . layer . selectLayer . group . width ,
height : this . layer . selectLayer . group . height ,
erasable : false ,
selectable : false ,
} ) ;
for ( let i = 0 ; i < elements . length ; i ++ ) {
await new Promise ( ( resolve , reject ) => {
let item = elements [ i ]
item . clone ( ( clonedObj ) => {
this . setClone ( item , clonedObj )
clonedObj . left = clonedObj . left - this . layer . selectLayer . group . width / 2
clonedObj . top = clonedObj . top - this . layer . selectLayer . group . height / 2
if ( clonedObj . custom ? . dashed ) {
let clipPath = clonedObj . _objects . filter ( item => item . type != 'image' ) [ 0 ]
clonedObj . remove ( clipPath )
}
group . add ( clonedObj )
resolve ( '' )
} )
} )
}
this . updataLayerImg ( this . layer . selectLayer . id , group . toDataURL ( {
width : this . layer . selectLayer . group . width ,
height : this . layer . selectLayer . group . height
} )
)
} , 500 )
}
updataLayerImg ( id , img ) {
this . layer . list . forEach ( v => {
if ( v . id === id ) {
v . img = img
}
} )
}
async layerDelete ( index , id ) {
if ( this . layer . list . length == 1 ) return
for ( let i = index ; i < this . layer . list . length ; i ++ ) {
this . layer . list [ this . layer . list . length - i - 1 ] . index --
}
this . layer . list . splice ( index , 1 )
if ( id == this . layer . selectLayer . id ) {
MyCanvas . canvas . remove ( this . layer . selectLayer . group )
MyCanvas . canvas . forEachObject ( ( obj ) => {
if ( obj . type != 'group' && obj . custom ? . layerId == id ) {
MyCanvas . canvas . remove ( obj )
}
} ) ;
this . layer . selectLayer . id = - 1
this . selectLayer ( this . layer . list [ this . layer . list . length - 1 ] . id )
} else {
let group = await this . lookingLayer ( id , 'setLayerIndex' )
MyCanvas . canvas . remove ( group )
}
this . updateCanvasState ( )
}
async selectLayer ( id ) {
await new Promise ( async ( resolve , reject ) => {
if ( this . layer . selectLayer . id != - 1 ) {
await this . mergeGroup ( )
}
let group = await this . lookingLayer ( id , 'setRubber' )
group . custom . selectLayerIndex = group . custom . layerIndex * 10000
this . layer . selectLayer . group = group
this . layer . selectLayer . id = id
await this . expandGroup ( )
MyCanvas . canvas . renderAll ( ) // 刷新画布, 改变group的visible属性, 必须通过刷新画布, 才能应用新属性值
this . setOperation ( 'movePosition' )
resolve ( '' )
} )
}
async mergeGroup ( ) {
const elements = MyCanvas . canvas . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) ) ;
let isClipPath = MyCanvas . canvas . getObjects ( ) . filter ( obj => obj . custom . dashed ) ;
if ( isClipPath . length > 0 ) await this . setGroupGrid ( 'all' )
let group = await this . lookingLayer ( this . layer . selectLayer . id , 'setlayerIndex' )
group . set ( { visible : true } )
for ( let index = 0 ; index < elements . length ; index ++ ) {
const item = elements [ index ] ;
await new Promise ( ( resolve , reject ) => {
item . clone ( ( v ) => {
this . setClone ( item , v )
v . left = v . left - group . width / 2
v . top = v . top - group . height / 2
if ( v . custom ? . dashed ) {
// MyCanvas.canvas.remove(item)
// let img = v._objects.filter(item => item.type == 'image')[0]
// if(img){
// img.set({
// left:v.left,
// top:v.top,
// custom:{
// layerId:v.custom.layerId
// }
// })
// group.add(img)
// }
} else {
group . add ( v )
}
resolve ( '' )
} )
} )
}
elements . forEach ( v => MyCanvas . canvas . remove ( v ) )
}
async expandGroup ( ) {
const elements = this . layer . selectLayer . group . _objects . filter ( obj => this . isAddToLayer ( obj ) ) ;
// fabric.util.enlivenObjects(elements, (clonedObjects) => {
this . layer . selectLayer . group . set ( { visible : false } )
for ( let index = 0 ; index < elements . length ; index ++ ) {
const item = elements [ index ] ;
await new Promise ( ( resolve , reject ) => {
item . clone ( ( v ) => {
this . setClone ( item , v )
v . left = v . left + this . layer . selectLayer . group . width / 2
v . top = v . top + this . layer . selectLayer . group . height / 2
if ( v . custom ? . dashed ) {
// this.layer.selectLayer.group._objects.remove(item)
// let img = v._objects.filter(item => item.type == 'image')[0]
// if(img){
// img.set({
// left:v.left,
// top:v.top,
// custom:{
// layerId:v.custom.layerId
// }
// })
// MyCanvas.canvas.add(img)
// }
} else {
MyCanvas . canvas . add ( v )
}
if ( index == elements . length - 1 ) {
elements . forEach ( v => this . layer . selectLayer . group . remove ( v ) )
}
resolve ( )
} )
} )
}
}
lookingLayer ( id , str ) {
return new Promise ( ( resolve , reject ) => {
const groups = MyCanvas . canvas . getObjects ( )
let group = null
groups . forEach ( v => {
if ( str && v ? . custom ? . type === 'layer' && ( str == 'setlayerIndex' || str == 'setRubber' ) ) {
let layerIndex = v ? . custom ? . layerIndex * 10000
v . moveTo ( layerIndex )
}
if ( v ? . custom ? . layerId == id ) {
if ( str && str == 'setRubber' ) {
v . set ( { erasable : 'deep' } )
}
} else if ( v ? . custom ? . type === 'layer' ) {
v . set ( { erasable : false } )
}
if ( v ? . custom ? . layerId === id && v ? . custom ? . type === 'layer' ) {
group = v
}
} )
resolve ( group )
} )
}
canvasKeyUp ( event ) {
this . keyDown = this . keyDown . filter ( ( item ) => {
if ( item . code !== 'AltLeft' ) {
if ( this . oldOperation ) this . setOperation ( this . oldOperation )
}
return event . code !== item ;
} )
}
async layerShowHide ( id , item ) {
// console.log(id);
item . isShow = ! item . isShow
MyCanvas . canvas . forEachObject ( ( obj ) => {
if ( obj . custom . layerId == id ) obj . visible = item . isShow
} )
MyCanvas . canvas . renderAll ( ) // 刷新画布, 改变group的visible属性, 必须通过刷新画布, 才能应用新属性值
}
canvasKeyDown ( event ) {
if ( this . keyDown . indexOf ( event . key ) > - 1 ) {
} else {
this . keyDown . push ( event . code )
if ( event . key === 'Enter' && this . operation == 'fold' ) {
this . foldEnd ( 'Enter' )
} else if ( event . key === 'Delete' ) {
this . deleteObject ( )
} else if ( this . keyDown . indexOf ( 'ControlLeft' ) > - 1 && this . keyDown . indexOf ( 'KeyZ' ) > - 1 && this . keyDown . indexOf ( 'ShiftLeft' ) > - 1 ) {
this . historyState ( 'reverse' )
} else if ( this . keyDown . indexOf ( 'ControlLeft' ) > - 1 && this . keyDown . indexOf ( 'KeyZ' ) > - 1 ) {
this . historyState ( '' )
} else if ( this . keyDown . indexOf ( 'ControlLeft' ) > - 1 && this . keyDown . indexOf ( 'KeyC' ) > - 1 ) {
this . copy ( )
} else if ( this . keyDown . indexOf ( 'ControlLeft' ) > - 1 && this . keyDown . indexOf ( 'KeyV' ) > - 1 ) {
this . paste ( )
} else if ( this . keyDown . indexOf ( 'AltLeft' ) > - 1 && this . keyDown . length == 1 && this . operation != 'move' ) {
this . oldOperation = this . operation
this . setOperation ( 'move' )
}
}
}
canvasClear ( ) {
if ( MyCanvas . canvas ? . dispose ) MyCanvas . canvas . dispose ( )
let oldCanvasDom = this . canvasDomParent ? . querySelector ( '.canvas-container' )
let oldCanvasDom1 = this . canvasDomParent ? . querySelector ( 'canvas' )
if ( oldCanvasDom ) oldCanvasDom . remove ( )
if ( oldCanvasDom1 ) oldCanvasDom1 . remove ( )
this . reverseCanvasState = [ ] ; //撤回
this . normalCanvasState = [ ] ; //反撤回
MyCanvas . canvas = null
this . canvas = null
this . layer = {
list : [ ] ,
selectLayer : {
group : null ,
id : - 1 ,
} ,
currentIndex : 0 ,
}
this . mouse = {
point : null ,
upPoint : null ,
isMovePostion : false ,
lastPosX : 0 ,
lastPosY : 0 ,
}
this . brushwork = {
value : 'PencilBrush' ,
width : { } ,
color : '#000000' ,
texture : 0 ,
}
this . operation = 'movePosition'
document . removeEventListener ( "keydown" , this . canvasKeyDown ) ;
document . removeEventListener ( "keyup" , this . canvasKeyUp ) ;
document . removeEventListener ( 'mousemove' , this . mouseMove ) ;
document . removeEventListener ( 'touchmove' , this . touchmove ) ;
}
//删除选中元素
deleteObject ( ) {
if ( ! MyCanvas . canvas . getActiveObjects ( ) ) {
return
}
let target = MyCanvas . canvas . getActiveObjects ( )
target . forEach ( ( item ) => {
MyCanvas . canvas . fxRemove ( item , {
onComplete : ( ) => {
MyCanvas . canvas . discardActiveObject ( ) ; // 丢弃当前选中的对象
MyCanvas . canvas . renderAll ( ) ; // 重新渲染 Canvas
}
} )
MyCanvas . canvas . FX _DURATION = 200
// MyCanvas.canvas.remove(item)
} )
this . updataLayer ( )
this . updateCanvasState ( 'remove' )
}
async getDashedImg ( cloned ) {
let position = {
left : cloned ? . left ,
top : cloned ? . top ,
width : cloned ? . width + cloned ? . strokeWidth * 2 ,
height : cloned ? . height + cloned ? . strokeWidth * 2 ,
}
let elements = MyCanvas . canvas . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) ) ;
let imgData = await this . groupToImg ( elements , position , 'clipPath' ) //矩形裁剪图片
let img = await this . createImage ( { minioUrl : imgData } )
// cloned._objects = cloned._objects.filter(item => item.type == 'image')
let clipPathElement = cloned . _objects . filter ( obj => obj . type != 'image' ) [ 0 ]
cloned . set ( {
left : 0 ,
top : 0 ,
visible : true
} )
img . set ( {
left : position . left ,
top : position . top ,
clipPath : clipPathElement ,
} )
return img
}
//复制粘贴
async copy ( canvas ) {
var activeObject = null ;
if ( MyCanvas . canvas . getActiveObject ( ) ) {
activeObject = MyCanvas . canvas . getActiveObject ( )
} else {
activeObject = MyCanvas . canvas . getObjects ( ) . filter ( obj => obj . custom . dashed ) [ 0 ] ;
}
if ( ! activeObject ) {
return
}
let copyObj = null
await new Promise ( ( resolve , reject ) => {
activeObject . clone ( async ( cloned ) => {
this . setClone ( activeObject , cloned )
if ( cloned . custom . dashed ) {
copyObj = await this . getDashedImg ( cloned )
} else {
copyObj = cloned
}
resolve ( )
} )
} )
this . _clipboard = copyObj ;
}
async paste ( ) { //粘贴
if ( ! this . _clipboard ) {
return
}
await this . createLayer ( { } )
this . _clipboard . clone ( clonedObj => {
// this.setClone(this._clipboard,clonedObj)
MyCanvas . canvas . discardActiveObject ( ) // 取消选择
clonedObj . set ( {
left : clonedObj . left ,
top : clonedObj . top ,
selectable : true
} )
if ( clonedObj . type === 'activeSelection' ) {
// 活动选择需要一个对画布的引用
clonedObj . forEachObject ( ( obj ) => {
MyCanvas . canvas . add ( obj )
} )
clonedObj . setCoords ( )
} else {
MyCanvas . canvas . add ( clonedObj )
// this.layer.selectLayer.group.add(clonedObj)
}
MyCanvas . canvas . setActiveObject ( clonedObj )
MyCanvas . canvas . requestRenderAll ( )
} )
this . _clipboard = null
this . updateCanvasState ( )
}
isSelectable ( obj ) { //判断元素是否允许选中
return ( obj . custom ? . type != 'layer' && ( ! obj . custom ? . isSelectable || this . layer . selectLayer . group . custom . groupType == 'Grid' ) && ! obj . isType ( 'path' ) )
//isSelectable已废弃, 现在isSelectable作为判断是否是背景来使用
return ( obj . custom ? . type != 'layer' && ! obj . isType ( 'path' ) )
}
isAddToLayer ( obj ) { //判断元素是否允许添加
return ( obj . custom ? . type != 'layer' && obj . custom ? . layerId == this . layer . selectLayer . id )
}
//撤回反撤回
//设置画布监听修改添加事件,用来做撤回功能
updateCanvasState ( str ) {
let canvasData = MyCanvas . canvas . toJSON ( [ 'custom' , 'selectable' , 'minioUrl' , 'perPixelTargetFind' , 'subTargetCheck' , 'evented' ] ) ;
if ( canvasData . clipPath ) {
canvasData . clipPath . left = 0
canvasData . clipPath . top = 0
}
let canvasAsJson = JSON . stringify ( canvasData )
let layerList = JSON . stringify ( this . layer . list )
let layerId = this . layer . selectLayer . id
if ( str == 'loadingCompleted' ) {
// this.reverseCanvasState.push(canvasAsJson);
}
this . normalCanvasState . push ( { canvasAsJson , layerList , layerId } ) ;
if ( this . isLoadCanvas ) {
this . reverseCanvasState = [ ]
this . isLoadCanvas = false ;
this . canvasState = canvasAsJson
}
}
//撤回
async historyState ( str ) {
if ( str == 'reverse' && this . reverseCanvasState . length > 0 ) { //反撤回
let obj = this . reverseCanvasState . pop ( )
let layerList = JSON . parse ( obj . layerList )
this . layer . list = layerList
this . layer . selectLayer . id = obj . layerId
this . canvasState = obj . canvasAsJson
this . normalCanvasState . push ( obj ) ;
} else if ( str == '' && this . normalCanvasState . length > 1 ) {
let obj = this . normalCanvasState . pop ( )
let select = this . normalCanvasState [ this . normalCanvasState . length - 1 ]
this . canvasState = select . canvasAsJson
this . layer . list = JSON . parse ( select . layerList )
this . layer . selectLayer . id = select . layerId
this . reverseCanvasState . push ( obj ) ;
this . isLoadCanvas = true ;
} else {
return
}
MyCanvas . canvas . loadFromJSON ( this . canvasState , ( ) => { } ) ;
MyCanvas . canvas . setBackgroundColor ( {
source : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC' ,
repeat : 'repeat' ,
} , MyCanvas . canvas . renderAll . bind ( MyCanvas . canvas ) ,
)
}
temporarilyExport ( data ) {
let scaleXY = {
scaleX : data ? . scaleX ? data ? . scaleX : 1 ,
scaleY : data ? . scaleY ? data ? . scaleY : 1 ,
}
let width = data ? . width || MyCanvas . canvas . width
let height = data ? . height || MyCanvas . canvas . height
var canvasDom = document . createElement ( "canvas" ) ;
let exportCanvas = new fabric . Canvas ( canvasDom , {
width : width * scaleXY . scaleX ,
height : height * scaleXY . scaleY ,
scaleX : scaleXY . scaleX ,
scaleY : scaleXY . scaleY ,
isDrawingMode : false , // 开启绘图模式
} ) ;
return exportCanvas
}
closeTemporarilyExport ( temporar ) {
if ( temporar ) {
temporar . wrapperEl . remove ( )
temporar . dispose ( )
}
}
setClone ( obj , goal ) {
if ( obj . custom ) {
goal . set ( { custom : JSON . parse ( JSON . stringify ( obj . custom ) ) } )
}
goal . perPixelTargetFind = obj . perPixelTargetFind
goal . hasBorders = obj . hasBorders
goal . hasControls = obj . hasControls
goal . selectable = obj . selectable
goal . erasable = obj . erasable
if ( obj . minioUrl ) goal . minioUrl = obj . minioUrl
}
//导出
selectExport ( ) {
let layer = this . layer . list . filter ( item => item . id == this . layer . selectLayer . id ) [ 0 ]
return layer . img
}
allExport ( ) {
let exportCanvas = this . temporarilyExport ( )
MyCanvas . canvas . forEachObject ( ( obj ) => {
if ( obj . custom ? . layerId != - 1 ) {
obj . clone ( ( cloned ) => {
this . setClone ( obj , cloned )
exportCanvas . add ( cloned )
} )
}
} ) ;
let data = exportCanvas . toDataURL ( "image/png" ) ;
this . closeTemporarilyExport ( exportCanvas )
return data
}
}
export default new MyCanvas ( )