Fabric.js在vue3上实现裁剪图片功能
概要
Fabic.js利用clipPath实现图片裁剪
整体架构流程
利用画布点击和松开位置生成一个矩形,然后设置一个mask背景矩形,利用生成的矩形裁剪这个全覆盖的背景矩形
var canvas = null//设置全局的canvas
const startPoint = reactive({
top:0,
left:0
})
const endPoint = reactive({
top:0,
left:0
})
const activeRect = ref(null)//记录当前裁剪区域的矩形
const canvasForm = reactive({
width:720,//画布宽
height:720,//画布高
})
function createCanvas(id){//新建一个fabric画布
canvas = new fabric.Canvas(id,{
width:1024,//设置默认大小,可根据你的图片缩放比例
height:1024
})
canvas.on('mouse:down',(e)=>{
if(activeRect.value == null){
startPoint.left = e.absolutePointer.x
startPoint.top = e.absolutePointer.y
}else{
//如果存在要判断是否起点在矩形内
if(e.absolutePointer.x<activeRect.value.left + 10 || e.absolutePointer.x > activeRect.value.left + activeRect.value.width + 10 && e.absolutePointer.y<activeRect.value.top + 10 || e.absolutePointer.y > activeRect.value.top + activeRect.value.width + 10){
//这个10是调整的时候的范围差
//不在范围内,继续执行
startPoint.left = e.absolutePointer.x
startPoint.top = e.absolutePointer.y
//清除矩形
clearRect()
}else{
activeRect.value = canvas.getActiveObject()
createRect(activeRect.value.width,activeRect.value.height,activeRect.value.left,active.value.top,activeRect.value.scaleX,activeRect.value.scaleY)
}
}
})
canvas.on('mouse:up',(e)=>{
endPoint.left = e.absolutePointer.x
endPoint.top = e.absolutePointer.y
//还要判断是否两个为同一个点
if(endPoint.left !== startPoint.left && endPoint.top !== startPoint.top ){
let width = Math.abs(endPoint.left - startPoint.left)
let height = Math.abs(endPoint.top - startPoint.top)
let top = endPoint.top < startPoint.top ? endPoint.top : startPoint.top
let left = endPoint.left < startPoint.left ? endPoint.left : startPoint.left
createRect(width,height,left,top)
}
})
}
//添加图片(可以作为一个组件从父组件触发拿到图片链接/blob临时链接)可能出现跨域问题的话建议先转换成base64
function addImage(url){
const image = new Image()
image.src = url
image.onload(()=>{
canvasForm.width = image.width
canvasForm.height = image.height
canvas.setWidth(image.width)
canvas.setHeight(image.height)
const newFabricImg = new fabric.Image(image,{
width:image.width,
height:image.height,
top:0,
left:0,
seletable:false//设置无法选中,作为背景图
})
canvas.add(newFabricImg)
})
}
//创建一个矩形
function createRect(w,h,l,t,scaleX = 1,scaleY = 1){
const rect = new fabric.Rect({
left:l,
top:t,
width:w,
height:h,
scaleX:scaleX,
scaleY:scaleY,
fill:'rgba(255,255,255,0.1)',//透明显示区
type:'rect',//添加类型,方便清除
})
//监听平移缩放操作后的行为
rect.on('mouseup',(e)={
//例如超过边界...
})
rect.setActiveObject(rect)//设置选中
activeRect.value = rect
canvas.add(rect)
const maskRect = new fabric.Rect({
top:0,
left:0,
width:canvasForm.width,
height:canvasForm.height,
type:'mask',//添加类型,方便清除
})
maskRect.clipPath = new fabric.Rect({
//因为裁切是以当前矩形中心为基准,如果不改变中心的话
left:-l,
top:-t,
width:w,
height:h,
scaleX:scaleX,
scaleY:scaleY,
})
canvas.add(maskRect)
canvas.renderAll()
}
//清除矩形
function clearRect(){
canvas.getObjects().forEach(item=>{
if(item.type == 'rect' || item.type == 'mask'){
canvas.remove(item)
}
})
canvas.renderAll()
}
小结
提供一下思路吗看,其中还有很多细节要填写
832

被折叠的 条评论
为什么被折叠?



