const canvas = this.canvas = new fabric.Canvas('c')
canvas.selection = false
// 设置元素对象默认值 selectable (可被选择)
fabric.Object.prototype.selectable = false
// hasControls (元素对象拥有控制框架)
fabric.Object.prototype.hasControls = false
// hasBorders (元素对象拥有控制框线)
fabric.Object.prototype.hasBorders = false
fabric.Object.prototype.hoverCursor = 'default'
fabric.Object.prototype.originX = 'center'
fabric.Object.prototype.originY = 'center'
fabric.Object.prototype.removeSelf = function () {
canvas.remove(this)
}
canvas.add(circle)
}
const circle = this.mouseCircle = new fabric.Circle({
perPixelTargetFind: true,
hoverCursor: 'default',
originX: 'center',
originY: 'center',
objectCaching: false,
radius: 8,
fill: '#fff',
stroke: '#666',
strokeWidth: 1,
selectable: false
})
canvas.add(circle)
this.canvas.on({
// 鼠标移动事件
'mouse:move': mouseMove.bind(this),
// 鼠标按下事件
'mouse:down': mouseDown.bind(this),
// 鼠标抬起事件
'mouse:up': mouseUp.bind(this),
// 鼠标双击事件
'mouse:dblclick': mouseDblclick.bind(this),
// 元素移动后事件
'object:moved': objectMoved.bind(this),
// 元素移动中事件
'object:moving': objectMoving.bind(this),
// 下列控制鼠标下圆形图标的 鼠标出入元素事件
'mouse:over': mouseOver.bind(this),
'mouse:out': mouseOut.bind(this)
})
const upperCanvas = document.getElementsByClassName('upper-canvas')
// 鼠标右键事件,并添加终止画笔工具事件
upperCanvas[0].addEventListener('contextmenu', (e) => {
console.log('终止画笔工具')
this.cutNewLine()
e.preventDefault()
return false
})
1,判断是否处于Line工具下
2,判断是否线段的终点
2 =》 否,
将起始点挂载到data中
将this.createLine.isClick 改为true
2 =》 是,
清空this.createLine
判断直线斜率是否过大或过小,为了方便后期选择,将该直线元素的padding改为10(即将它的控制范围加大)
将鼠标事件的x和y 赋予newLine的x2 y2 实现预览的效果
1, 判断是否处于BezierCurve工具下
2, 将正在点击的flag改为true 当鼠标抬起的时候改回false
this.createLine.isClicking = true
3, 判断是否为起始点,
3 =》 是,
将起始点挂载到data中
将this.createLine.isClick 改为true
3=》否
将鼠标坐标 赋予 newLine 的最后两个坐标
1, 判断是否处于BezierCurve工具下
2, 判断已经按下尚未抬起鼠标 this.createLine.isClicking
3, 将鼠标的坐标赋予newLine的倒数第二个坐标(第二个控制点)实现预览的效果
将正在点击的flag改为false
将预览的newLine的path去掉最后一组预览坐标
赋给新建的一个Path对象
获取被点击元素的name 如果是直线的话还将获取其长度
取消之前抓取的元素上的浮标
创建控制浮标
直线的浮标 每个浮标的坐标为 直线的(x1, y2) (x2, y2)
曲线的浮标在path数组中,遍历获取每个坐标,生成浮标以及控制线
将浮标与被控制元素互相绑定
取消之前抓取的元素上的浮标
如果是直线移动,则更新直线的坐标 x1 y1 x2 y2
如果是曲线移动,则新建一根曲线代替之前的曲线
如果是浮标移动,则移动中更新被抓元素的坐标和path
移动后生成新的曲线代替(直线就不代替了)
将抓取到的元素remove
首先遍历画布中每一个元素,
获取其节点,
计算鼠标坐标与其距离 缓存之
对比上一个对象的距离 如果比它小 取代之(获得最小距离的元素和节点坐标)
如果这个最小距离小于10 则将鼠标下的圆圈坐标改为它
如果上一步以及获取到距离小于10的节点元素,则不进行下一步
再遍历画布每个元素,过滤出与鼠标相交的元素
如果是直线 计算点到线的距离 缓存之
对比上一个对象的距离 如果比它小 取代之(获得最小距离的元素和节点坐标)
如果这个最小距离小于10 则将鼠标下的圆圈坐标改为它
如果是曲线(尚未想好思路)
想法一:
根据曲线公式 B(t)=(1−t)3P0+3t(1−t)2P1+3t2(1−t)P2+t3P3
已知鼠标的坐标为 (x,y)
将B(t) = y代入 求出与鼠标竖线的相交点 再计算距离
同理将B(t) = x 和B(tx) = B(ty) 和 B(tx) = -B(ty) 的所有交点,计算其中每个相交点的距离
想法二:
根据公式可以列出 曲线每个点到鼠标坐标xy的距离 len = F(t) 再反向列出t=F(len) 当len趋于最小值的时候t为
想法三:
根据曲线公式 将曲线分为若干段,计算每个分割点的坐标,计算每个坐标到鼠标的距离