果然,靠人不如靠己,在我不懈的努力下最终将它完整的开发出来了,过程还算顺利。
先看一下效果
上面的效果看起来很难,实际上一点也不简单,我们需要考虑图片的位置,蒙层的位置,以及它们的放大、缩小、拉伸等行为
主要就是做以下几件事:
fabric.Object.prototype.controls是Fabric.js库中所有对象的父类属性,用于包含和管理对象的所有控制点信息。
我们可以通过自定义control,设置一个裁剪按钮,并将它应用在图片元素中
functiondrawImg(ctx,left,top,img,wSize,hSize,angle){if(angle===undefined)return;ctx.save();ctx.translate(left,top);ctx.rotate(fabric.util.degreesToRadians(angle));ctx.drawImage(img,-wSize/2,-hSize/2,wSize,hSize);ctx.restore();}constclipImageEl=document.createElement('img')clipImageEl.src="icon的路径"functionclipImage(eventData,transform){}fabric.Object.prototype.controls.centerButton=newfabric.Control({y:-0.5,mouseUpHandler:clipImage,//点击事件offsetY:-25,offsetX:0,cursorStyle:'pointer',//鼠标hover样式render:(ctx,left,top,styleOverride,fabricObject)=>{//这里判断了一下元素的类型,只在图片上生效if(fabricObject.type==='image'){drawImg(ctx,left,top,clipImageEl,30,30,fabricObject.angle);}}})这样我们就会得到一个只会在图片元素上生效的裁剪按钮
给按钮绑定点击事件,然后创建一个蒙层,将蒙层的大小和位置与图片保持一致
functionclipImage(eventData,transform){constimage=transform.target;constcanvas=image.canvas;if(image.type!=='image')returnconstrectLeft=image.left//矩形的位置XconstrectTop=image.top//矩形的位置YconstsourceWidth=image.getScaledWidth()//获取图片的宽constsourceHeight=image.getScaledHeight()//获取图片的高image.bringToFront()//将这个图片的层级移动到顶层constselectionRect=newfabric.Rect({left:rectLeft,top:rectTop,fill:'rgba(0,0,0,0.3)',originX:'left',originY:'top',stroke:'black',opacity:1,width:sourceWidth,height:sourceHeight,hasRotatingPoint:false,transparentCorners:false,cornerColor:'white',cornerStrokeColor:'black',borderColor:'black',cornerSize:12,padding:0,cornerStyle:'circle',borderDashArray:[5,5],borderScaleFactor:1.3,id:'currentClipRect',lockMovementX:true,lockMovementY:true,hoverCursor:'default'})canvas.add(selectionRect)canvas.setActiveObject(selectionRect)canvas.renderAll()}此外我们开始裁剪的时候还需要计算出原图和裁剪之后的图位置的差异
点击裁剪按钮的时候我们需要去监听图片和裁剪方块的拖拽事件,使其紧密相连,不能超出边界
image.on('scaling',(e)=>{constimage=e.transform.targetif(image.left>selectionRect.left){image.set({left:selectionRect.left})}if(image.top>selectionRect.top){image.set({top:selectionRect.top})}if(selectionRect.getScaledWidth()/image.getScaledWidth()>1){image.set({scaleX:selectionRect.getScaledWidth()*image.get('scaleX')/image.getScaledWidth()})}if(selectionRect.getScaledHeight()/image.getScaledHeight()>1){image.set({scaleY:selectionRect.getScaledHeight()*image.get('scaleY')/image.getScaledHeight()})}canvas.renderAll()})六、取消裁剪取消裁剪时需要把蒙层从画布中删除,然后恢复画布中元素的层级