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 {
2025-02-25 15:32:55 +08:00
constructor ( id ) {
this . id = id || Date . now ( ) ;
2024-12-11 16:26:36 +08:00
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 ;
2025-02-25 15:32:55 +08:00
this . canvas = MyCanvas ? . [ this . id ] ;
2024-12-11 16:26:36 +08:00
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 , //用来获取移入前是否是绘画模式
2025-02-25 15:32:55 +08:00
isDetail : false , //判断裁剪或者局部添加内容, 为true是添加内容
2025-03-03 14:52:05 +08:00
isDashedShow : false , //判断选区是否存在
2024-12-11 16:26:36 +08:00
}
2025-02-25 15:32:55 +08:00
this . currentOperation = true //表示是否可以使用快捷键
2024-12-11 16:26:36 +08:00
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 ,
} //给切换颜色设置防抖
}
2025-03-03 14:52:05 +08:00
async canvasInit ( dom , val , img , editGroupImg , data ) { //初始化
// let {erasable} = data
2025-02-25 15:32:55 +08:00
// this.canvasClear()
2024-12-11 16:26:36 +08:00
this . canvasWH = val
this . canvasDomParent = dom ;
var canvasDom = document . createElement ( "canvas" ) ;
this . canvasDomParent . appendChild ( canvasDom ) ;
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] = await new fabric . Canvas ( canvasDom , {
2024-12-11 16:26:36 +08:00
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 ,
2025-02-25 15:32:55 +08:00
hoverCursor : 'pointer' ,
2024-12-11 16:26:36 +08:00
} ) ;
2025-02-25 15:32:55 +08:00
// await new Promise((resolve, reject) => {
// canvas.clone(cloned=>{
// cloned.set({
// })
// this.canvas = cloned
// resolve()
// })
// })
// MyCanvas?.[this.id].freeDrawingCursor= 'none'
2024-12-11 16:26:36 +08:00
2025-02-25 15:32:55 +08:00
// let imgage = await this.createImage({minioUrl:img})
// let rect1 = new fabric.Rect({
// left: 0,
// top: 0,
// width: 500,
// height: 500,
// fill: "red",
// });
// canvas.add(rect1)
2024-12-11 16:26:36 +08:00
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 )
}
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . on ( "object:modified" , ( event ) => {
2024-12-11 16:26:36 +08:00
this . updateCanvasState ( '' )
this . updataLayer ( )
} ) ;
this . canvasKeyDown = this . canvasKeyDown . bind ( this ) ;
this . canvasKeyUp = this . canvasKeyUp . bind ( this ) ;
2025-02-25 15:32:55 +08:00
2024-12-11 16:26:36 +08:00
// let rect1 = new fabric.Rect({
// left: 0,
// top: 0,
// width: 500,
// height: 500,
// fill: "red",
// });
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].add(rect1)
2024-12-11 16:26:36 +08:00
// 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())
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].add(rect1)
// // MyCanvas?.[this.id].add(rect1)
2024-12-11 16:26:36 +08:00
// let rect = new fabric.Rect({
// left: 0,
// top: 0,
2025-02-25 15:32:55 +08:00
// width: MyCanvas?.[this.id].width,
// height: MyCanvas?.[this.id].height,
2024-12-11 16:26:36 +08:00
// inverted:true,
// fill: "red",
// });
// // let rect2 = new fabric.Rect({
2025-02-25 15:32:55 +08:00
// // width: MyCanvas?.[this.id].width,
// // height: MyCanvas?.[this.id].height,
2024-12-11 16:26:36 +08:00
// // fill:'#FFF'
// // });
2025-02-25 15:32:55 +08:00
// // // MyCanvas?.[this.id].add(rect2)
2024-12-11 16:26:36 +08:00
// 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 = {
2025-02-25 15:32:55 +08:00
// X:MyCanvas?.[this.id].width/img.width,
// Y:MyCanvas?.[this.id].height/img.height
2024-12-11 16:26:36 +08:00
// }
// 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,
// })
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].add(rect)
2024-12-11 16:26:36 +08:00
// },{ crossOrigin: "Anonymous" })
2025-02-25 15:32:55 +08:00
// // // MyCanvas?.[this.id].add(rect1)
2024-12-11 16:26:36 +08:00
// // // rect1.clipPath = group
2025-02-25 15:32:55 +08:00
// // // MyCanvas?.[this.id].forEachObject((item) =>{
2024-12-11 16:26:36 +08:00
// // // if(item.clipPath){
// // // item.clipPath.add(rect2)
// // // // item.clipPath = group
// // // }
// // // })
// return
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . on ( "mouse:move" , this . setCanvasMove . bind ( this ) ) ;
MyCanvas ? . [ this . id ] . on ( "mouse:down" , this . setCanvasDown . bind ( this ) ) ;
MyCanvas ? . [ this . id ] . on ( "mouse:up" , this . setCanvasUp . bind ( this ) ) ;
MyCanvas ? . [ this . id ] . on ( "mouse:wheel" , this . setCanvasWheel . bind ( this ) ) ;
2024-12-11 16:26:36 +08:00
//双击
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . on ( "mouse:dblclick" , event => {
2024-12-11 16:26:36 +08:00
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 ) ;
2025-02-25 15:32:55 +08:00
initAligningGuidelines ( MyCanvas ? . [ this . id ] , true ) ;
JSchangeType ( MyCanvas ? . [ this . id ] , 'init' )
2024-12-11 16:26:36 +08:00
// await this.createBg()
2025-03-03 14:52:05 +08:00
await this . createLayer ( { str : 'init' , img : img , noErasable : data ? . noErasable || false } ) //创建图层并且使用
2025-02-25 15:32:55 +08:00
if ( img ) {
this . dashed . isDetail = true
2025-03-03 14:52:05 +08:00
await this . createLayer ( { editImg : editGroupImg , noErasable : data ? . noErasable || false } ) //创建图层并且使用
2025-02-25 15:32:55 +08:00
}
MyCanvas ? . [ this . id ] . on ( "object:added" , this . addLayer . bind ( this ) ) ;
// MyCanvas?.[this.id].on("object:added", this.addLayer.bind(this));
this . canvas = MyCanvas ? . [ this . id ] ;
return MyCanvas ? . [ this . id ]
2024-12-11 16:26:36 +08:00
}
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
2025-02-25 15:32:55 +08:00
const vpt = MyCanvas ? . [ this . id ] . viewportTransform ;
2024-12-11 16:26:36 +08:00
vpt [ 4 ] = 0 ; // 更新水平偏移
vpt [ 5 ] = 0 ; // 更新垂直偏移
}
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . zoomToPoint (
2024-12-11 16:26:36 +08:00
{ // 关键点
x : x ,
y : y
} ,
scale
)
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . setBackgroundColor ( {
2024-12-11 16:26:36 +08:00
source : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC' ,
repeat : 'repeat' ,
2025-02-25 15:32:55 +08:00
} , MyCanvas ? . [ this . id ] . renderAll . bind ( MyCanvas ? . [ this . id ] ) ,
2024-12-11 16:26:36 +08:00
)
}
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
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . discardActiveObject ( ) ; //取消所有选中边框
2024-12-11 16:26:36 +08:00
if ( this . createPatterning . state ) {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( this . createPatterning . current )
2024-12-11 16:26:36 +08:00
}
this . removeSetText ( )
2025-02-25 15:32:55 +08:00
initAligningGuidelines ( MyCanvas ? . [ this . id ] , false )
MyCanvas ? . [ this . id ] . remove ( this . createPatterning . polyLineBtn )
2024-12-11 16:26:36 +08:00
if ( str == 'pencil' ) {
this . setPencil ( )
this . pencilbtnStyle . display = ` block `
this . setCursor ( 'none' ) ;
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingCursor = 'none'
2024-12-11 16:26:36 +08:00
} else if ( str == 'move' ) {
2025-02-25 15:32:55 +08:00
JSchangeType ( MyCanvas ? . [ this . id ] , '' )
MyCanvas [ this . id ] . isDrawingMode = false
2024-12-11 16:26:36 +08:00
this . pencilbtnStyle . display = ` none `
this . setCursor ( 'grab' ) ;
} else if ( str == 'movePosition' ) {
2025-02-25 15:32:55 +08:00
JSchangeType ( MyCanvas ? . [ this . id ] , 'init' )
initAligningGuidelines ( MyCanvas ? . [ this . id ] , true )
2024-12-11 16:26:36 +08:00
this . setMove ( )
this . pencilbtnStyle . display = ` none `
this . setCursor ( 'all-scroll' ) ;
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . isDrawingMode = false
2024-12-11 16:26:36 +08:00
} else if ( str == 'texture' ) {
this . setTexture ( )
this . pencilbtnStyle . display = ` block `
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingCursor = 'none'
2024-12-11 16:26:36 +08:00
this . setCursor ( 'none' ) ;
} else if ( str == 'eraser' ) {
this . setEraser ( )
this . pencilbtnStyle . display = ` block `
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingCursor = 'none'
2024-12-11 16:26:36 +08:00
this . setCursor ( 'none' ) ;
} else if ( str == 'text' ) {
this . setMove ( )
this . setText ( )
2025-02-25 15:32:55 +08:00
JSchangeType ( MyCanvas ? . [ this . id ] , 'init' )
2024-12-11 16:26:36 +08:00
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' ) ;
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . isDrawingMode = false
MyCanvas ? . [ this . id ] . forEachObject ( ( obj ) => {
2024-12-11 16:26:36 +08:00
if ( obj . type != 'group' && ! obj . isType ( 'path' ) ) {
obj . selectable = false
}
} ) ;
} else if ( [ 'dashedPencil' , 'dashed' ] . includes ( str ) ) {
2025-03-03 14:52:05 +08:00
this . dashed . isDashedShow = false
2024-12-11 16:26:36 +08:00
this . setGroupGrid ( 'all' )
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . isDrawingMode = false
2024-12-11 16:26:36 +08:00
this . pencilbtnStyle . display = ` none `
this . setCursor ( 'crosshair' )
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingCursor = 'crosshair'
2024-12-11 16:26:36 +08:00
if ( str == 'dashedPencil' ) this . setDashedPencil ( )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . forEachObject ( ( obj ) => {
2024-12-11 16:26:36 +08:00
if ( obj . type != 'group' && ! obj . isType ( 'path' ) ) {
obj . selectable = false
}
} ) ;
} else if ( str ) {
this . pencilbtnStyle . display = ` none `
this . setCursor ( 'auto' ) ;
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . isDrawingMode = false
MyCanvas ? . [ this . id ] . forEachObject ( ( obj ) => {
2024-12-11 16:26:36 +08:00
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 ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . defaultCursor = str ;
MyCanvas [ this . id ] . moveCursor = str ;
MyCanvas [ this . id ] . hoverCursor = str ;
MyCanvas [ this . id ] . upperCanvasEl . style . cursor = str ;
2024-12-11 16:26:36 +08:00
}
setCanvasMove = ( event ) => {
if ( this . mouse . isMovePostion && this . operation == 'move' ) return this . setCanvasPosition ( event )
2025-02-25 15:32:55 +08:00
if ( MyCanvas ? . [ this . id ] . isDrawingMode ) {
2024-12-11 16:26:36 +08:00
} else {
2025-02-25 15:32:55 +08:00
let getActiveObject = MyCanvas ? . [ this . id ] . getActiveObject ( )
2024-12-11 16:26:36 +08:00
if (
! this . clipPath . isImg &&
this . mouse . isDown &&
getActiveObject &&
2025-02-25 15:32:55 +08:00
getActiveObject . custom ? . dashed &&
2024-12-11 16:26:36 +08:00
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 )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . requestRenderAll ( )
2024-12-11 16:26:36 +08:00
}
}
}
setCanvasPosition ( event ) {
const e = event ;
2025-02-25 15:32:55 +08:00
const vpt = MyCanvas ? . [ this . id ] . viewportTransform ;
2024-12-11 16:26:36 +08:00
vpt [ 4 ] += e . pointer . x - this . mouse . lastPosX ; // 更新水平偏移
vpt [ 5 ] += e . pointer . y - this . mouse . lastPosY ; // 更新垂直偏移
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . requestRenderAll ( ) ; // 请求重绘画布
2024-12-11 16:26:36 +08:00
this . mouse . lastPosX = e . pointer . x ;
this . mouse . lastPosY = e . pointer . y ;
}
// setRemoveDashed(){
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].forEachObject((obj) =>{
2024-12-11 16:26:36 +08:00
// if(obj.custom.dashed && obj._objects){
// let rect = obj._objects.filter(item => item.type == 'rect')[0]
// obj.remove(rect)
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].renderAll();
2024-12-11 16:26:36 +08:00
// }
// });
// }
//设置再画布上按下
setCanvasDown ( event ) {
2025-02-25 15:32:55 +08:00
if ( event . target && event . target . custom ? . dashed && [ 'dashedPencil' , 'dashed' ] . includes ( this . operation ) && ! this . dashed . isDetail ) {
// if(MyCanvas?.[this.id].isDrawingMode){
// MyCanvas[this.id].isDrawingMode = false;
2024-12-11 16:26:36 +08:00
// }
this . dashed . state = true
} else if ( ! event . target ? . custom ? . dashed ) {
// if(['dashedPencil'].includes(this.operation)){
2025-02-25 15:32:55 +08:00
// MyCanvas[this.id].isDrawingMode = true;
2024-12-11 16:26:36 +08:00
// }
this . dashed . state = false
}
2025-02-25 15:32:55 +08:00
let dashedGroup = MyCanvas ? . [ this . id ] . 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
2025-02-25 15:32:55 +08:00
if ( ! this . dashed . state && ( ! event . target ? . custom ? . dashed || this . dashed . isDetail ) && ( this . operation == 'dashed' || this . operation == 'dashedPencil' ) && dashedGroup ) {
MyCanvas ? . [ this . id ] . remove ( dashedGroup )
2024-12-11 16:26:36 +08:00
}
2025-02-25 15:32:55 +08:00
if ( this . operation == 'movePosition' && ! event ? . target ? . custom ? . dashed && this . layer . selectLayer . group ? . custom ? . groupType == 'Grid' ) this . setGroupGrid ( 'all' ) ;
2024-12-11 16:26:36 +08:00
//设置移动端按下添加元素
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 ) {
2025-02-25 15:32:55 +08:00
JSchangeType ( MyCanvas ? . [ this . id ] , this . operation )
2024-12-11 16:26:36 +08:00
this . createPatterning . state = true
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . forEachObject ( ( obj ) => {
2024-12-11 16:26:36 +08:00
obj . set ( 'selectable' , false ) ; // 禁用选中
} ) ;
if ( this . createPatterning . current && this . operation == 'fold' ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . skipTargetFind = false
2024-12-11 16:26:36 +08:00
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' ) {
2025-02-25 15:32:55 +08:00
width = 1 / MyCanvas ? . [ this . id ] . getZoom ( )
2024-12-11 16:26:36 +08:00
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 } } )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( this . createPatterning . current )
2024-12-11 16:26:36 +08:00
if ( this . operation == 'fold' ) {
this . createPatterning . polyLineBtn = JScreateCheck ( event )
this . createPatterning . polyLineBtn . on ( 'mousedown' , this . foldEnd . bind ( this ) )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( this . createPatterning . polyLineBtn )
2024-12-11 16:26:36 +08:00
}
}
} 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
2025-02-25 15:32:55 +08:00
if ( MyCanvas ? . [ this . id ] . isDrawingMode ) {
2024-12-11 16:26:36 +08:00
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 ) ) {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( this . createPatterning . current )
2024-12-11 16:26:36 +08:00
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' ) {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . forEachObject ( ( obj ) => {
if ( this . isSelectable ( obj . target ) ) {
2024-12-11 16:26:36 +08:00
obj . selectable = true
} else {
obj . selectable = false
}
} ) ;
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . bringToFront ( this . createPatterning . polyLineBtn ) ; //设置优先级最高
2024-12-11 16:26:36 +08:00
} else if ( this . operation ) {
this . createPatterning . state = false
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . renderAll ( ) ;
2024-12-11 16:26:36 +08:00
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 ]
2025-02-25 15:32:55 +08:00
let imgBG = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => obj . custom . isSelectable && obj . type == 'rect' ) [ 0 ] ;
2024-12-11 16:26:36 +08:00
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()
//添加裁剪后的图片
2025-02-25 15:32:55 +08:00
let elements = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) ) ;
2024-12-11 16:26:36 +08:00
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 ( ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . isDrawingMode = true
let pencil = new fabric . Test ( MyCanvas ? . [ this . id ] , { } ) ; //普通笔
MyCanvas [ this . id ] . freeDrawingBrush = pencil
2024-12-11 16:26:36 +08:00
}
async setDashed ( obj ) {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( obj )
2024-12-11 16:26:36 +08:00
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-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( group )
2024-12-11 16:26:36 +08:00
} )
}
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' )
}
2025-02-25 15:32:55 +08:00
// 复制图层
2024-12-11 16:26:36 +08:00
async copyLayer ( id ) {
let createId = new Date ( ) . getTime ( )
2025-02-25 15:32:55 +08:00
let elements = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => obj . custom . layerId == id )
2024-12-11 16:26:36 +08:00
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 } )
2025-02-25 15:32:55 +08:00
copyElements . forEach ( item => MyCanvas ? . [ this . id ] . add ( item ) )
2024-12-11 16:26:36 +08:00
}
async setGroupGrid ( str ) { //group变为图片
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].discardActiveObject();//取消所有选中边框
let elements = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) && ! obj . custom . dashed && obj . type ) ;
2024-12-11 16:26:36 +08:00
if ( str == 'all' ) {
2025-02-25 15:32:55 +08:00
elements = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) && obj . type ) ;
2024-12-11 16:26:36 +08:00
}
let layerBg = elements . filter ( obj => obj . custom . isSelectable ) [ 0 ]
let scaleXY = {
scaleX : layerBg ? . scaleX ? layerBg ? . scaleX : 1 ,
scaleY : layerBg ? . scaleY ? layerBg ? . scaleY : 1 ,
2025-02-25 15:32:55 +08:00
width : layerBg ? . width ? layerBg ? . width : MyCanvas ? . [ this . id ] . width ,
height : layerBg ? . height ? layerBg ? . height : MyCanvas ? . [ this . id ] . height ,
2024-12-11 16:26:36 +08:00
}
let imgData = await this . groupToImg ( elements , { } , 'setGrid' , scaleXY )
let img = await this . createImage ( { minioUrl : imgData } )
elements . forEach ( ( obj ) => {
if ( obj . custom . isSelectable ) {
} else {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( obj )
2024-12-11 16:26:36 +08:00
}
} ) ;
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,
2025-02-25 15:32:55 +08:00
width : MyCanvas ? . [ this . id ] . width ,
height : MyCanvas ? . [ this . id ] . height ,
2024-12-11 16:26:36 +08:00
strokeWidth : 0 ,
fill : new fabric . Pattern ( {
source : img . getElement ( ) , // 传入图片元素
repeat : 'no-repeat' // 设置图片不重复
} ) ,
custom : {
isSelectable : true ,
} ,
hasBorders : true ,
hasControls : true
} ) ;
this . setGroupStyle ( rect )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( rect )
2024-12-11 16:26:36 +08:00
}
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . renderAll ( ) // 刷新画布, 改变group的visible属性, 必须通过刷新画布, 才能应用新属性值
2024-12-11 16:26:36 +08:00
}
//液化
getLiquefactionImgObj ( ) {
return new Promise ( async ( resolve , reject ) => {
let img , str = null
2025-02-25 15:32:55 +08:00
const activeObject = MyCanvas ? . [ this . id ] . getActiveObject ( ) ; // 获取选中的对象
let dashedGroup = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => obj . custom . dashed ) [ 0 ] ;
2024-12-11 16:26:36 +08:00
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' ) { //判断当前图层是否可以做为液化图片
2025-02-25 15:32:55 +08:00
let bg = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( item => item . custom ? . isSelectable ) [ 0 ]
2024-12-11 16:26:36 +08:00
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' ) {
2025-02-25 15:32:55 +08:00
let bg = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( item => item . custom ? . isSelectable ) [ 0 ]
2024-12-11 16:26:36 +08:00
let img = await this . createImage ( { minioUrl : data } )
bg . set ( {
fill : new fabric . Pattern ( {
source : img . getElement ( ) , // 传入图片元素
repeat : 'no-repeat' // 设置图片不重复
} ) ,
} )
}
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . renderAll ( ) ;
2024-12-11 16:26:36 +08:00
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'
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . renderAll ( ) // 刷新画布, 改变group的visible属性, 必须通过刷新画布, 才能应用新属性值
2024-12-11 16:26:36 +08:00
}
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 ( )
} )
} )
}
2025-02-25 15:32:55 +08:00
let data = await temporar . toDataURL ( imgData ) ;
2024-12-11 16:26:36 +08:00
this . closeTemporarilyExport ( temporar )
return data
}
setCanvasWheel ( opt ) {
const delta = opt . e . deltaY // 滚轮,向上滚一下是 -100, 向下滚一下是 100
2025-02-25 15:32:55 +08:00
let zoom = MyCanvas ? . [ this . id ] . getZoom ( ) // 获取画布当前缩放值
2024-12-11 16:26:36 +08:00
zoom *= 0.999 * * delta
if ( zoom > 20 ) zoom = 20
if ( zoom < 0.01 ) zoom = 0.01
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . zoomToPoint (
2024-12-11 16:26:36 +08:00
{ // 关键点
x : opt . e . offsetX ,
y : opt . e . offsetY
} ,
zoom
)
opt . e . preventDefault ( )
opt . e . stopPropagation ( )
this . setPencilWidth ( )
}
foldEnd ( key ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . skipTargetFind = true
2024-12-11 16:26:36 +08:00
let points = this . createPatterning . current . points
if ( key == 'Enter' ) {
} else {
points . pop ( )
}
points . pop ( )
this . createPatterning . state = false
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( this . createPatterning . current )
MyCanvas ? . [ this . id ] . remove ( this . createPatterning . polyLineBtn )
2024-12-11 16:26:36 +08:00
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 ,
} )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( polyline )
2024-12-11 16:26:36 +08:00
this . clearPatterning ( ) //临时图形置为空并且添加撤回对象里面
// this.layerAddElement(polyline)
}
clearPatterning ( ) {
if ( this . createPatterning . state ) {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( this . createPatterning . current )
2024-12-11 16:26:36 +08:00
}
this . createPatterning . current = null
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( this . createPatterning . polyLineBtn )
2024-12-11 16:26:36 +08:00
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 ) { //设置优先级
2025-02-25 15:32:55 +08:00
var activeObject = MyCanvas ? . [ this . id ] . getActiveObject ( ) ;
2024-12-11 16:26:36 +08:00
switch ( str ) {
case 'Front' :
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . bringToFront ( activeObject ) //顶层
2024-12-11 16:26:36 +08:00
// this.layer.selectLayer.group.bringToFront(activeObject)
break
case 'Back' :
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . sendToBack ( activeObject ) //底层
2024-12-11 16:26:36 +08:00
// this.layer.selectLayer.group.sendToBack(activeObject)
break
case 'Forward' :
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . bringForward ( activeObject )
2024-12-11 16:26:36 +08:00
// this.layer.selectLayer.group.bringForward(activeObject)
break
case 'Backwards' :
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . sendBackwards ( activeObject )
2024-12-11 16:26:36 +08:00
// this.layer.selectLayer.group.sendBackwards(activeObject)
break
}
}
setPencil ( ) {
let pencil
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . isDrawingMode = true //开启绘画模式
2024-12-11 16:26:36 +08:00
if ( this . brushwork . value == 'PencilBrush' ) {
2025-02-25 15:32:55 +08:00
pencil = new fabric . PencilBrush ( MyCanvas ? . [ this . id ] , { } ) ; //普通笔
2024-12-11 16:26:36 +08:00
} else if ( this . brushwork . value == 'Marking' ) {
2025-02-25 15:32:55 +08:00
pencil = new fabric . PencilBrush ( MyCanvas ? . [ this . id ] , ) ; //记号笔
2024-12-11 16:26:36 +08:00
} else if ( this . brushwork . value == 'InkBrush' ) {
2025-02-25 15:32:55 +08:00
pencil = new fabric . InkBrush ( MyCanvas ? . [ this . id ] , { } ) ; //油画笔
2024-12-11 16:26:36 +08:00
} else if ( this . brushwork . value == 'CrayonBrush' ) {
2025-02-25 15:32:55 +08:00
pencil = new fabric . CrayonBrush ( MyCanvas ? . [ this . id ] , { } ) ; //蜡笔
2024-12-11 16:26:36 +08:00
} else if ( this . brushwork . value == 'RibbonBrush' ) {
2025-02-25 15:32:55 +08:00
pencil = new fabric . RibbonBrush ( MyCanvas ? . [ this . id ] , { width : 1 , } ) ; //色带
2024-12-11 16:26:36 +08:00
} else if ( this . brushwork . value == 'MarkerBrush' ) {
2025-02-25 15:32:55 +08:00
pencil = new fabric . MarkerBrush ( MyCanvas ? . [ this . id ] , { } ) ; //书写笔
// pencil = new fabric.PenBrush(MyCanvas?.[this.id],{}); //书写笔
2024-12-11 16:26:36 +08:00
} else if ( this . brushwork . value == 'WritingBrush' ) {
2025-02-25 15:32:55 +08:00
pencil = new fabric . WritingBrush ( MyCanvas ? . [ this . id ] , { } ) ; //毛笔
2024-12-11 16:26:36 +08:00
} else if ( this . brushwork . value == 'LongfurBrush' ) {
2025-02-25 15:32:55 +08:00
pencil = new fabric . LongfurBrush ( MyCanvas ? . [ this . id ] , { width : 1 , } ) ; //色带
2024-12-11 16:26:36 +08:00
} else if ( this . brushwork . value == 'SpraypaintBrush' ) {
2025-02-25 15:32:55 +08:00
pencil = new fabric . SpraypaintBrush ( MyCanvas ? . [ this . id ] , { } ) ; //长毛刷
2024-12-11 16:26:36 +08:00
}
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush = pencil
2024-12-11 16:26:36 +08:00
if ( this . brushwork . value == 'RibbonBrush' || this . brushwork . value == 'LongfurBrush' ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . width = 1 ;
2024-12-11 16:26:36 +08:00
}
if ( this . brushwork . value == 'Marking' ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . color = this . hexToRgba ( this . brushwork . color , . 5 ) ;
2024-12-11 16:26:36 +08:00
// }else if(this.brushwork.value == 'InkBrush'){
// canvas.freeDrawingBrush.color = this.hexToRgba(this.brushwork.color,.2);
} else {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . color = this . hexToRgba ( this . brushwork . color , 1 ) ;
2024-12-11 16:26:36 +08:00
}
this . setPencilWidth ( )
this . pencilbtnStyle . background = this . brushwork . color
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . isEraser = false
2024-12-11 16:26:36 +08:00
}
setCanvasZoom ( opt ) {
2025-02-25 15:32:55 +08:00
let zoom = MyCanvas ? . [ this . id ] . getZoom ( ) // 获取画布当前缩放值
2024-12-11 16:26:36 +08:00
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
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].setDimensions(MyCanvas?.[this.id].width *= zoom,MyCanvas?.[this.id].height *= zoom)
// MyCanvas?.[this.id].wrapperEl.style.zoom = zoom
MyCanvas ? . [ this . id ] . zoomToPoint (
2024-12-11 16:26:36 +08:00
{ // 关键点
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,
2025-02-25 15:32:55 +08:00
// top:MyCanvas?.[this.id].wrapperEl.parentNode.scrollTop,
left : MyCanvas ? . [ this . id ] . width / 2 ,
top : MyCanvas ? . [ this . id ] . height / 2 ,
2024-12-11 16:26:36 +08:00
}
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 ) => {
2025-02-25 15:32:55 +08:00
img . set ( {
hasControls : true
} )
2024-12-11 16:26:36 +08:00
resolve ( img )
} , { crossOrigin : "Anonymous" } )
} )
}
setImageWidth = ( key , img ) => {
2025-02-25 15:32:55 +08:00
const CW = MyCanvas ? . [ this . id ] . width
const CH = MyCanvas ? . [ this . id ] . height
2024-12-11 16:26:36 +08:00
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){
2025-02-25 15:32:55 +08:00
// let heightScale = (MyCanvas?.[this.id].height/2) / imgObj.height
2024-12-11 16:26:36 +08:00
// 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 ( '?' ) ) {
let url = imgUrl . split ( '?' ) [ 0 ]
var match = url . match ( /:(\d+)\/(.*)/ ) ;
minioUrl = match [ 2 ]
}
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 ,
} ) ;
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( img )
2024-12-11 16:26:36 +08:00
this . updateCanvasState ( '' )
}
setMove ( ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . isDrawingMode = false
MyCanvas ? . [ this . id ] . forEachObject ( ( obj ) => {
2024-12-11 16:26:36 +08:00
if ( this . isSelectable ( obj ) ) {
obj . selectable = true
} else {
obj . selectable = false
}
} ) ;
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . renderAll ( ) // 刷新画布, 改变group的visible属性, 必须通过刷新画布, 才能应用新属性值
2024-12-11 16:26:36 +08:00
}
async setTexture ( ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . isDrawingMode = true //开启绘画模式
2024-12-11 16:26:36 +08:00
let img = await JSSetTexture ( this . texture . list [ this . texture . value ] . url )
2025-02-25 15:32:55 +08:00
let zoom = MyCanvas ? . [ this . id ] . getZoom ( ) // 获取画布当前缩放值
let patternBrush = new fabric . PatternBrush ( MyCanvas ? . [ this . id ] )
2024-12-11 16:26:36 +08:00
patternBrush . source = img
patternBrush . width = Number ( this . brushwork . width [ this . operation ] ) / zoom ; // 设置画笔大小
this . setPencilWidth ( )
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush = patternBrush
2024-12-11 16:26:36 +08:00
}
setEraser ( ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . isDrawingMode = true
let eraser = new fabric . EraserBrush ( MyCanvas ? . [ this . id ] )
MyCanvas [ this . id ] . freeDrawingBrush = eraser
2024-12-11 16:26:36 +08:00
this . pencilbtnStyle . background = '#fff'
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . isEraser = true
2024-12-11 16:26:36 +08:00
this . setPencilWidth ( )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . requestRenderAll ( ) ;
2024-12-11 16:26:36 +08:00
}
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
}
2025-02-25 15:32:55 +08:00
if ( MyCanvas [ this . id ] . freeDrawingBrush . isEraser ) {
2024-12-11 16:26:36 +08:00
} else {
this . pencilbtnStyle . background = this . brushwork . color
}
if ( this . brushwork . value == 'Marking' ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . color = this . hexToRgba ( this . brushwork . color , . 5 ) ;
2024-12-11 16:26:36 +08:00
} else if ( this . brushwork . value == 'InkBrush' ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . color = this . hexToRgba ( this . brushwork . color , . 2 ) ;
2024-12-11 16:26:36 +08:00
} else {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . color = this . hexToRgba ( this . brushwork . color , 1 ) ;
2024-12-11 16:26:36 +08:00
}
}
setFontFamily = ( ) => {
2025-02-25 15:32:55 +08:00
if ( this . createText ? . set ) {
2024-12-11 16:26:36 +08:00
this . createText . set ( {
fontFamily : this . fontFamily ,
fontSize : this . brushwork . width [ this . operation ] ? this . brushwork . width [ this . operation ] : 20 ,
fill : this . brushwork . color ,
} )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . renderAll ( ) ;
2024-12-11 16:26:36 +08:00
}
}
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 ( ( ) => {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . setWidth ( this . canvasWH . width ) ;
MyCanvas ? . [ this . id ] . setHeight ( this . canvasWH . height ) ;
// MyCanvas?.[this.id].width = this.canvasWH.width
// MyCanvas?.[this.id].height = this.canvasWH.height
2024-12-11 16:26:36 +08:00
this . initCanvasWH ( 'updata' )
} , 1000 )
}
setColorHistory = ( value ) => {
this . brushwork . color = value
this . pencilColor ( )
}
setPencilWidth ( ) { //切换颜色给铅笔设置颜色
2025-02-25 15:32:55 +08:00
let zoom = MyCanvas ? . [ this . id ] . getZoom ( ) // 获取画布当前缩放值
2024-12-11 16:26:36 +08:00
clearTimeout ( this . setTimeOut . width )
this . setTimeOut . width = setTimeout ( ( ) => {
if ( ! this . brushwork . width [ this . operation ] ) this . brushwork . width [ this . operation ] = 20
2025-02-25 15:32:55 +08:00
// MyCanvas[this.id].freeDrawingBrush.width = Number(this.brushwork.width[this.operation]);
2024-12-11 16:26:36 +08:00
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 ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . width = Number ( this . brushwork . width [ this . operation ] ) / zoom ;
2024-12-11 16:26:36 +08:00
} else {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . width = Number ( this . brushwork . width [ this . operation ] ) ;
2024-12-11 16:26:36 +08:00
}
if ( ( this . brushwork . value == 'LongfurBrush' || this . brushwork . value == 'RibbonBrush' ) && this . operation == 'pencil' ) {
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . freeDrawingBrush . width = 1 ;
2024-12-11 16:26:36 +08:00
this . pencilbtnStyle . height = 1 + 'px'
this . pencilbtnStyle . width = 1 + 'px'
}
} , 100 )
}
2025-02-25 15:32:55 +08:00
uploadImg ( ) {
const input = document . createElement ( 'input' ) ;
input . type = 'file' ;
input . accept = 'image/*' ;
// 将文件输入框和图片预览元素添加到页面中
document . body . appendChild ( input ) ;
// 监听文件输入框的变化事件
input . addEventListener ( 'change' , ( event ) => {
event . preventDefault ( )
const file = event . target . files [ 0 ] ; // 获取用户选择的文件
if ( file ) {
const reader = new FileReader ( ) ; // 创建 FileReader 对象读取文件
reader . onload = ( e ) => {
const base64Image = e . target . result ;
this . addPartImg ( { minioUrl : base64Image } , 'print' )
input . remove ( )
} ;
reader . readAsDataURL ( file ) ;
}
} ) ;
input . click ( )
}
2024-12-11 16:26:36 +08:00
//关闭u或者创建文字
setTextFun ( e ) {
if ( this . operation != 'text' ) {
return
}
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . forEachObject ( ( obj ) => {
2024-12-11 16:26:36 +08:00
if ( obj . type == 'textbox' && ! obj . text ) {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( obj ) ;
2024-12-11 16:26:36 +08:00
}
} ) ;
var clickedObject = e . target ;
if ( clickedObject instanceof fabric . Textbox ) {
this . createText = clickedObject
this . setTextData ( this . createText )
} else {
2025-02-25 15:32:55 +08:00
var pointer = MyCanvas ? . [ this . id ] . getPointer ( e . pointer ) ;
2024-12-11 16:26:36 +08:00
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 ,
} )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( this . createText )
2024-12-11 16:26:36 +08:00
// this.layer.selectLayer.group.add(this.createText)
this . createText . enterEditing ( ) ;
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . setActiveObject ( this . createText ) . renderAll ( ) ;
2024-12-11 16:26:36 +08:00
this . removeSetText ( )
}
}
setText ( ) {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . on ( 'mouse:down' , ( event ) => {
2024-12-11 16:26:36 +08:00
if ( this . operation == 'zoomIn' || this . operation == 'zoomOut' ) {
} else {
this . setTextFun ( event )
}
} )
}
removeSetText ( ) {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . off ( 'mouse:down' , this . setTextFun . bind ( this ) )
2024-12-11 16:26:36 +08:00
}
// 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,
2025-02-25 15:32:55 +08:00
// width: MyCanvas?.[this.id].width,
// height: MyCanvas?.[this.id].height,
2024-12-11 16:26:36 +08:00
// 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], {
2025-02-25 15:32:55 +08:00
// width: MyCanvas?.[this.id].width,
// height: MyCanvas?.[this.id].height,
2024-12-11 16:26:36 +08:00
// erasable:false,
// selectable:false,
// });
// group.custom.layerId = -1
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].add(group)
// MyCanvas?.[this.id].clipPath = rect
2024-12-11 16:26:36 +08:00
// resolve()
// });
// })
// }
createLayer ( data ) {
2025-03-03 14:52:05 +08:00
let { str , id , editImg , noErasable } = data
2025-02-25 15:32:55 +08:00
let image = data . img
let canvasData = MyCanvas ? . [ this . id ] . toJSON ( [ 'selectable' , 'minioUrl' , 'custom' ] ) ;
2024-12-11 16:26:36 +08:00
return new Promise ( async ( resolve , reject ) => {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . discardActiveObject ( ) ;
2024-12-11 16:26:36 +08:00
if ( ! id ) id = new Date ( ) . getTime ( )
let index = this . layer . currentIndex += 1
const rect = new fabric . Rect ( {
2025-02-25 15:32:55 +08:00
left : - MyCanvas ? . [ this . id ] . width / 2 ,
top : - MyCanvas ? . [ this . id ] . height / 2 ,
2024-12-11 16:26:36 +08:00
// left:0,
// top:0,
2025-02-25 15:32:55 +08:00
width : MyCanvas ? . [ this . id ] . width ,
height : MyCanvas ? . [ this . id ] . height ,
2024-12-11 16:26:36 +08:00
strokeWidth : 0 ,
fill : '#FFF' ,
custom : {
layerId : id ,
isSelectable : true ,
} ,
// erasable:false,
selectable : false ,
} ) ;
rect . clone ( ( cloned ) => {
rect . clipPath = cloned
} )
const group = new fabric . Group ( [ ] , {
2025-02-25 15:32:55 +08:00
width : MyCanvas ? . [ this . id ] . width ,
height : MyCanvas ? . [ this . id ] . height ,
2024-12-11 16:26:36 +08:00
left : 0 ,
top : 0 ,
erasable : false ,
subTargetCheck : true ,
evented : false ,
// originX:'left',
// originY:'top',
custom : {
2025-03-03 14:52:05 +08:00
noErasable : noErasable ,
2024-12-11 16:26:36 +08:00
layerId : id ,
type : 'layer' ,
groupType : 'Object' ,
layerIndex : index ,
selectLayerIndex : ( index ) * 10000 ,
}
} ) ;
if ( str == 'init' ) {
group . moveTo ( group . custom . selectLayerIndex )
2025-02-25 15:32:55 +08:00
if ( image ) {
let img = await this . createImage ( { minioUrl : image } )
rect . set ( {
fill : new fabric . Pattern ( {
source : img . getElement ( ) , // 传入图片元素
repeat : 'no-repeat' , // 设置图片不重复
patternTransform : [ group . width / img . width , 0 , 0 , group . height / img . height , 0 , 0 ]
} ) ,
} )
}
2024-12-11 16:26:36 +08:00
group . add ( rect )
group . clone ( ( cloned ) => {
cloned . set ( { left : 0 , top : 0 } )
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].clipPath = cloned
} )
} else if ( editImg ) {
group . moveTo ( group . custom . selectLayerIndex )
let img = await this . createImage ( { minioUrl : editImg } )
rect . set ( {
fill : new fabric . Pattern ( {
source : img . getElement ( ) , // 传入图片元素
repeat : 'no-repeat' , // 设置图片不重复
patternTransform : [ group . width / img . width , 0 , 0 , group . height / img . height , 0 , 0 ]
} ) ,
} )
group . add ( rect )
group . clone ( ( cloned ) => {
cloned . set ( { left : 0 , top : 0 } )
// MyCanvas?.[this.id].clipPath = cloned
2024-12-11 16:26:36 +08:00
} )
}
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( group )
2024-12-11 16:26:36 +08:00
let img = group . toDataURL ( {
2025-02-25 15:32:55 +08:00
width : MyCanvas ? . [ this . id ] . width ,
height : MyCanvas ? . [ this . id ] . height ,
2024-12-11 16:26:36 +08:00
} )
2025-02-25 15:32:55 +08:00
2024-12-11 16:26:36 +08:00
this . layer . list . unshift ( {
name : ` Layer ${ index } ` ,
id , img , isShow : true ,
groupType : 'Object' ,
index , } )
await this . selectLayer ( id )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . renderAll ( ) ;
2024-12-11 16:26:36 +08:00
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 )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( obj )
2024-12-11 16:26:36 +08:00
this . updataLayerImg ( this . layer . selectLayer . id , group . toDataURL ( {
2025-02-25 15:32:55 +08:00
width : MyCanvas ? . [ this . id ] . width ,
height : MyCanvas ? . [ this . id ] . height
2024-12-11 16:26:36 +08:00
} ) )
}
2025-03-03 14:52:05 +08:00
async addPartImg ( file , str , data ) {
// let {erasable} = data
2025-02-25 15:32:55 +08:00
let img = await this . createImage ( file )
2025-03-03 14:52:05 +08:00
2025-02-25 15:32:55 +08:00
if ( str ) {
img . set ( {
custom : {
type : str
}
} )
}
// let dashedGroup = MyCanvas?.[this.id].getObjects().filter(obj => obj?.custom?.dashed)[0];
// dashedGroup.clone(cloned=>{
// this.setClone(img,cloned)
// img.set({
// left:0,
// top:0
// })
// })
MyCanvas ? . [ this . id ] . add ( img )
img . bringToFront ( ) ;
MyCanvas ? . [ this . id ] . renderAll ( ) ;
}
2025-01-16 09:47:28 +08:00
async addLayer ( options ) {
2024-12-11 16:26:36 +08:00
if ( this . createPatterning . state ) return
2025-02-25 15:32:55 +08:00
this . clipPath . clipGroup = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => obj . custom ? . dashed ) ? . [ 0 ] ;
2024-12-11 16:26:36 +08:00
if ( options . target . type === 'group' && options . target . custom ? . layerId ) return ;
2025-03-03 14:52:05 +08:00
if ( ! options . target ? . custom ? . layerId , this . layer . selectLayer . id ) {
2024-12-11 16:26:36 +08:00
if ( options . target ? . custom ) {
options . target . custom . layerId = this . layer . selectLayer . id
} else {
options . target . set ( { custom : { layerId : this . layer . selectLayer . id } } )
}
}
2025-02-25 15:32:55 +08:00
if ( this . clipPath . clipGroup && this . dashed . isDetail && ! options . target ? . custom ? . dashed ) {
let clipPathElement = this . clipPath . clipGroup . _objects . filter ( obj => obj . custom ) [ 0 ]
clipPathElement . clone ( cloned => {
cloned . set ( {
left : this . clipPath . clipGroup . left ,
top : this . clipPath . clipGroup . top ,
absolutePositioned : true ,
inverted : false ,
} )
if ( options . target . type == 'image' && options . target . custom ? . type != 'pencil' ) {
options . target . set ( {
scaleX : this . clipPath . clipGroup . width / options . target . width ,
scaleY : this . clipPath . clipGroup . height / options . target . height ,
left : this . clipPath . clipGroup . left ,
top : this . clipPath . clipGroup . top ,
// width:cloned.width,
// height:options.cloned.width / target.width * options.target.height,
} )
}
options . target . clipPath = cloned
} )
} else if ( options . target . type == 'image' && options . target . custom ? . type != 'pencil' ) {
let scale = 1
if ( options . target ? . custom ? . type == 'print' ) scale = 2
options . target . set ( {
scaleX : MyCanvas ? . [ this . id ] . width / scale / options . target . width ,
scaleY : MyCanvas ? . [ this . id ] . height / scale / options . target . height ,
left : MyCanvas ? . [ this . id ] . width / scale - ( options . target . width / scale * MyCanvas ? . [ this . id ] . width / scale / options . target . width ) ,
top : MyCanvas ? . [ this . id ] . height / scale - ( options . target . height / scale * MyCanvas ? . [ this . id ] . height / scale / options . target . height ) ,
// width:cloned.width,
// height:options.cloned.width / target.width * options.target.height,
} )
}
2024-12-11 16:26:36 +08:00
//判断是否可以点击空白地方进行选中
if ( options . target ? . custom ? . dashed ) {
2025-03-03 14:52:05 +08:00
this . dashed . isDashedShow = true
2024-12-11 16:26:36 +08:00
options . target . set ( { perPixelTargetFind : false , erasable : false , hasBorders : false , hasControls : false } )
2025-02-25 15:32:55 +08:00
if ( this . dashed . isDetail ) { //判断是裁剪还是局部添加
options . target . set ( { selectable : false , perPixelTargetFind : true } )
} else {
// MyCanvas?.[this.id].setActiveObject(options.target);
MyCanvas [ this . id ] . skipTargetFind = false
}
2024-12-11 16:26:36 +08:00
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
2025-02-25 15:32:55 +08:00
2024-12-11 16:26:36 +08:00
} 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
2025-02-25 15:32:55 +08:00
let arr = MyCanvas ? . [ this . id ] . getObjects ( ) . sort ( ( a , b ) => {
2024-12-11 16:26:36 +08:00
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
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 )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( options . target )
2025-01-16 09:47:28 +08:00
resolve ( )
} )
} )
} )
2025-01-15 11:23:23 +08:00
// this.setGroupGrid('all')
}
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . renderAll ( ) ;
2024-12-11 16:26:36 +08:00
this . updataLayer ( )
}
upLayerIndex ( list ) {
list . forEach ( ( item , index ) => {
2025-02-25 15:32:55 +08:00
let arr = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => obj . custom . layerId == item . id )
2024-12-11 16:26:36 +08:00
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
2025-02-25 15:32:55 +08:00
let arr = MyCanvas ? . [ this . id ] . getObjects ( ) . sort ( ( a , b ) => {
2024-12-11 16:26:36 +08:00
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
2025-02-25 15:32:55 +08:00
elements = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => {
2024-12-11 16:26:36 +08:00
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 ) {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( this . layer . selectLayer . group )
MyCanvas ? . [ this . id ] . forEachObject ( ( obj ) => {
2024-12-11 16:26:36 +08:00
if ( obj . type != 'group' && obj . custom ? . layerId == id ) {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( obj )
2024-12-11 16:26:36 +08:00
}
} ) ;
this . layer . selectLayer . id = - 1
this . selectLayer ( this . layer . list [ this . layer . list . length - 1 ] . id )
} else {
let group = await this . lookingLayer ( id , 'setLayerIndex' )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . remove ( group )
2024-12-11 16:26:36 +08:00
}
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 ( )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . renderAll ( ) // 刷新画布, 改变group的visible属性, 必须通过刷新画布, 才能应用新属性值
2024-12-11 16:26:36 +08:00
this . setOperation ( 'movePosition' )
resolve ( '' )
} )
}
async mergeGroup ( ) {
2025-02-25 15:32:55 +08:00
const elements = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) ) ;
let isClipPath = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => obj . custom ? . dashed ) ;
2024-12-11 16:26:36 +08:00
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 ) {
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].remove(item)
2024-12-11 16:26:36 +08:00
// 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 ( '' )
} )
} )
}
2025-02-25 15:32:55 +08:00
elements . forEach ( v => MyCanvas ? . [ this . id ] . remove ( v ) )
2024-12-11 16:26:36 +08:00
}
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
2025-03-03 14:52:05 +08:00
if ( v . custom ? . isSelectable && this . layer . selectLayer . group . custom . noErasable ) {
v . set ( {
erasable : false
} )
}
2024-12-11 16:26:36 +08:00
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
// }
// })
2025-02-25 15:32:55 +08:00
// MyCanvas?.[this.id].add(img)
2024-12-11 16:26:36 +08:00
// }
} else {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( v )
2024-12-11 16:26:36 +08:00
}
if ( index == elements . length - 1 ) {
elements . forEach ( v => this . layer . selectLayer . group . remove ( v ) )
}
resolve ( )
} )
} )
}
}
lookingLayer ( id , str ) {
return new Promise ( ( resolve , reject ) => {
2025-02-25 15:32:55 +08:00
const groups = MyCanvas ? . [ this . id ] . getObjects ( )
2024-12-11 16:26:36 +08:00
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 )
}
2025-03-03 14:52:05 +08:00
if ( v ? . custom ? . layerId == id && ! v ? . custom ? . noErasable ) {
2024-12-11 16:26:36 +08:00
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 ) {
item . isShow = ! item . isShow
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . forEachObject ( ( obj ) => {
2024-12-11 16:26:36 +08:00
if ( obj . custom . layerId == id ) obj . visible = item . isShow
} )
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . renderAll ( ) // 刷新画布, 改变group的visible属性, 必须通过刷新画布, 才能应用新属性值
2024-12-11 16:26:36 +08:00
}
canvasKeyDown ( event ) {
2025-02-25 15:32:55 +08:00
if ( ! this . currentOperation ) return
let keys = [ 'Enter' , 'Delete' , 'ControlLeft' , 'ShiftLeft' , 'BracketLeft' , 'BracketRight' , 'MetaLeft' ]
var activeObject = MyCanvas ? . [ this . id ] . getActiveObject ( ) ;
let state = ( activeObject && activeObject . type == 'textbox' && activeObject . isEditing )
if ( keys . indexOf ( event . code ) > - 1 ) {
event . preventDefault ( ) ;
}
if ( this . keyDown . indexOf ( event . code ) > - 1 || state ) {
} else {
this . keyDown . push ( event . code )
// console.log(this.keyDown.indexOf('ControlLeft') > -1 , this.keyDown.indexOf('MetaLeft') > -1, event.code == 'KeyC')
if ( event . code === 'Enter' && operation . value == 'fold' ) {
this . foldEnd ( 'Enter' )
} else if ( event . key === 'Delete' ) {
this . deleteObject ( )
} else if ( ( this . keyDown . indexOf ( 'ControlLeft' ) > - 1 || this . keyDown . indexOf ( 'MetaLeft' ) > - 1 ) && event . code == 'KeyZ' && this . keyDown . indexOf ( 'ShiftLeft' ) > - 1 ) {
this . historyState ( 'reverse' )
} else if ( ( this . keyDown . indexOf ( 'ControlLeft' ) > - 1 || this . keyDown . indexOf ( 'MetaLeft' ) > - 1 ) && event . code == 'KeyZ' ) {
this . historyState ( '' )
} else if ( ( this . keyDown . indexOf ( 'ControlLeft' ) > - 1 || this . keyDown . indexOf ( 'MetaLeft' ) > - 1 ) && event . code == 'KeyC' ) {
this . copy ( )
} else if ( ( this . keyDown . indexOf ( 'ControlLeft' ) > - 1 || this . keyDown . indexOf ( 'MetaLeft' ) > - 1 ) && event . code == 'KeyV' ) {
this . paste ( )
} else if ( this . keyDown . indexOf ( 'BracketLeft' ) > - 1 ) {
let width = this . brushwork . width [ this . operation ]
this . brushwork . width [ this . operation ] = ( width - 5 ) < 3 ? 3 : ( width - 5 )
this . setPencilWidth ( )
} else if ( this . keyDown . indexOf ( 'BracketRight' ) > - 1 ) {
let width = this . brushwork . width [ this . operation ]
this . brushwork . width [ this . operation ] = ( width + 5 ) > 50 ? 50 : ( width + 5 )
this . setPencilWidth ( )
} else if ( this . keyDown . indexOf ( 'KeyI' ) > - 1 ) {
this . getColor ( ) //吸色
} else if ( this . keyDown . indexOf ( 'KeyM' ) > - 1 ) {
setOperation ( 'move' )
} else if ( ( this . keyDown . indexOf ( 'ControlLeft' ) > - 1 || this . keyDown . indexOf ( 'MetaLeft' ) > - 1 ) && event . code == 'KeyD' ) {
MyCanvas ? . [ this . id ] . discardActiveObject ( ) . renderAll ( ) ;
} else if ( ( this . keyDown . indexOf ( 'ControlLeft' ) > - 1 || this . keyDown . indexOf ( 'MetaLeft' ) > - 1 ) && event . code == 'KeyO' ) {
event . preventDefault ( ) ;
this . uploadImg ( )
} else if ( this . keyDown . indexOf ( 'KeyB' ) > - 1 ) {
// if(operation.value == 'pencil' || operation.value == 'texture'){
this . setOperation ( 'pencil' )
// }
} else if ( this . keyDown . indexOf ( 'KeyE' ) > - 1 ) {
// if(operation.value == 'pencil' || operation.value == 'texture'){
this . setOperation ( 'eraser' )
// }
}
2024-12-11 16:26:36 +08:00
}
2025-02-25 15:32:55 +08:00
// 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')
// }
// }
}
getColor = async ( ) => {
try {
const dropper = new EyeDropper ( ) ;
const result = await dropper . open ( ) ;
let hex = result . sRGBHex . replace ( "#" , "" ) ;
// 将十六进制颜色码拆分成红、绿、蓝三个部分
// const r = parseInt(hex.substring(0, 2), 16);
// const g = parseInt(hex.substring(2, 4), 16);
// const b = parseInt(hex.substring(4, 6), 16);
this . brushwork . color = result . sRGBHex ;
// canvasPencilColor.value =
setPencilColor ( )
} catch ( e ) {
// message.info(this.t('ColorboardUpload.jsContent1'))
2024-12-11 16:26:36 +08:00
}
}
canvasClear ( ) {
2025-02-25 15:32:55 +08:00
// if(this.canvas?.dispose)MyCanvas?.[this.id].dispose()
2024-12-11 16:26:36 +08:00
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 = [ ] ; //反撤回
2025-02-25 15:32:55 +08:00
this . canvas = null
2024-12-11 16:26:36 +08:00
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 ) ;
2025-02-25 15:32:55 +08:00
delete MyCanvas [ this . id ]
// MyCanvas[this.id] = null
2024-12-11 16:26:36 +08:00
}
//删除选中元素
deleteObject ( ) {
2025-02-25 15:32:55 +08:00
if ( ! MyCanvas ? . [ this . id ] . getActiveObjects ( ) ) {
2024-12-11 16:26:36 +08:00
return
}
2025-02-25 15:32:55 +08:00
let target = MyCanvas ? . [ this . id ] . getActiveObjects ( )
2024-12-11 16:26:36 +08:00
target . forEach ( ( item ) => {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . fxRemove ( item , {
2024-12-11 16:26:36 +08:00
onComplete : ( ) => {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . discardActiveObject ( ) ; // 丢弃当前选中的对象
MyCanvas ? . [ this . id ] . renderAll ( ) ; // 重新渲染 Canvas
2024-12-11 16:26:36 +08:00
}
} )
2025-02-25 15:32:55 +08:00
MyCanvas [ this . id ] . FX _DURATION = 200
// MyCanvas[this.id].remove(item)
2024-12-11 16:26:36 +08:00
} )
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 ,
}
2025-02-25 15:32:55 +08:00
let elements = MyCanvas [ this . id ] . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) ) ;
2024-12-11 16:26:36 +08:00
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 ;
2025-02-25 15:32:55 +08:00
if ( MyCanvas ? . [ this . id ] . getActiveObject ( ) ) {
activeObject = MyCanvas ? . [ this . id ] . getActiveObject ( )
2024-12-11 16:26:36 +08:00
} else {
2025-02-25 15:32:55 +08:00
activeObject = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => obj . custom . dashed ) [ 0 ] ;
2024-12-11 16:26:36 +08:00
}
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)
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . discardActiveObject ( ) // 取消选择
2024-12-11 16:26:36 +08:00
clonedObj . set ( {
left : clonedObj . left ,
top : clonedObj . top ,
selectable : true
} )
if ( clonedObj . type === 'activeSelection' ) {
// 活动选择需要一个对画布的引用
clonedObj . forEachObject ( ( obj ) => {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( obj )
2024-12-11 16:26:36 +08:00
} )
clonedObj . setCoords ( )
} else {
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . add ( clonedObj )
2024-12-11 16:26:36 +08:00
// this.layer.selectLayer.group.add(clonedObj)
}
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . setActiveObject ( clonedObj )
MyCanvas ? . [ this . id ] . requestRenderAll ( )
2024-12-11 16:26:36 +08:00
} )
this . _clipboard = null
this . updateCanvasState ( )
}
isSelectable ( obj ) { //判断元素是否允许选中
2025-02-25 15:32:55 +08:00
if ( this . dashed . isDetail ) {
return ( obj . custom ? . type != 'layer' && ( ! obj . custom ? . isSelectable || this . layer . selectLayer . group . custom . groupType == 'Grid' ) && ! obj . isType ( 'path' ) && ! obj . custom ? . dashed )
} else {
return ( obj . custom ? . type != 'layer' && ( ! obj . custom ? . isSelectable || this . layer . selectLayer . group . custom . groupType == 'Grid' ) && ! obj . isType ( 'path' ) && ( this . dashed . isDetail || ! obj . custom ? . dashed ) )
}
2024-12-11 16:26:36 +08:00
}
isAddToLayer ( obj ) { //判断元素是否允许添加
return ( obj . custom ? . type != 'layer' && obj . custom ? . layerId == this . layer . selectLayer . id )
}
//撤回反撤回
//设置画布监听修改添加事件,用来做撤回功能
updateCanvasState ( str ) {
2025-02-25 15:32:55 +08:00
let canvasData = MyCanvas ? . [ this . id ] . toJSON ( [ 'custom' , 'selectable' , 'minioUrl' , 'perPixelTargetFind' , 'subTargetCheck' , 'evented' ] ) ;
2024-12-11 16:26:36 +08:00
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
}
2025-02-25 15:32:55 +08:00
MyCanvas ? . [ this . id ] . loadFromJSON ( this . canvasState , ( ) => { } ) ;
MyCanvas ? . [ this . id ] . setBackgroundColor ( {
2024-12-11 16:26:36 +08:00
source : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC' ,
repeat : 'repeat' ,
2025-02-25 15:32:55 +08:00
} , MyCanvas ? . [ this . id ] . renderAll . bind ( MyCanvas ? . [ this . id ] ) ,
2024-12-11 16:26:36 +08:00
)
}
temporarilyExport ( data ) {
let scaleXY = {
scaleX : data ? . scaleX ? data ? . scaleX : 1 ,
scaleY : data ? . scaleY ? data ? . scaleY : 1 ,
}
2025-02-25 15:32:55 +08:00
let width = data ? . width || MyCanvas ? . [ this . id ] . width
let height = data ? . height || MyCanvas ? . [ this . id ] . height
2024-12-11 16:26:36 +08:00
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
}
2025-02-25 15:32:55 +08:00
//导出除了底图
async detailSubmit ( ) {
return await new Promise ( async ( resolve , reject ) => {
let list = MyCanvas ? . [ this . id ] . getObjects ( ) . filter ( obj => this . isAddToLayer ( obj ) && ! obj . custom . dashed && obj . type ) ;
let layerBg = list . 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 ? . [ this . id ] . width ,
height : layerBg ? . height ? layerBg ? . height : MyCanvas ? . [ this . id ] . height ,
}
let imgData = await this . groupToImg ( list , { } , 'setGrid' , scaleXY )
resolve ( imgData )
} )
// return imgData
}
2024-12-11 16:26:36 +08:00
//导出
selectExport ( ) {
let layer = this . layer . list . filter ( item => item . id == this . layer . selectLayer . id ) [ 0 ]
return layer . img
}
2025-02-25 15:32:55 +08:00
async allExport ( ) {
let list = MyCanvas ? . [ this . id ] . getObjects ( )
let layerBg = list . 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 ? . [ this . id ] . width ,
height : layerBg ? . height ? layerBg ? . height : MyCanvas ? . [ this . id ] . height ,
}
let imgData = await this . groupToImg ( list , { } , 'setGrid' , scaleXY )
// let exportCanvas = this.temporarilyExport()
// let list = MyCanvas?.[this.id].getObjects()
// for (let index = 0; index < list.length; index++) {
// let item = list[index]
// new Promise((resolve, reject) => {
// item.clone((cloned)=>{
// this.setClone(item,cloned)
// exportCanvas.add(cloned)
// resolve()
// })
// })
// }
// let data = exportCanvas.toDataURL("image/png");
// this.closeTemporarilyExport(exportCanvas)
return imgData
2024-12-11 16:26:36 +08:00
}
}
2025-02-25 15:32:55 +08:00
export default MyCanvas