fabric不同版本的API也是不同,相同的API在不同的版本中,源码的实现方式有的也略微不同,所以请注意版本的区别
fabricjs
对于学习过fabric的人来说,对于canvas的操作,算是相当简化了,一些基础的操作我在这里就不多少了,网上有很多介绍,而且官网也是很详细的。
下面我说一下删除fabricjs中canvas的对象。
对于删除canvas 中的对象,fabricjs也提供了一个方法,remove(),可以移除指定对象。
但是,有一个小小的问题,我们在什么情境下或者什么条件下,执行移除操作呢。(虽然是小问题,我还是纠结了很久,想找一个不是很反人类的操作方式)
本来我是想为canvas的对象添加鼠标右键事件,以达到删除的目的,有了想法就去实现,不过我发现有一个坑,需要借助一些插件,
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset=
"utf-8"
>
<style>
canvas {
border: 1px dashed black;
}
</style>
<script src=
"fabric.js"
></script>
<script src=
"jquery-3.1.1.js"
></script>
<script src=
"contextMenu/jquery.ui.position.min.js"
type=
"text/javascript"
></script>
<script src=
"contextMenu/jquery.contextMenu.js"
type=
"text/javascript"
></script>
<link href=
"contextMenu/jquery.contextMenu.css"
rel=
"stylesheet"
type=
"text/css"
/>
<script>
var
canvas;
//菜单项
var
contextMenuItems;
window.onload =
function
() {
canvas =
new
fabric.Canvas(
'canvas'
);
var
rect1 =
new
fabric.Rect({top: 50, left: 50, width: 70, height: 70, fill:
'red'
});
canvas.add(rect1);
var
rect2 =
new
fabric.Rect({top: 50, left: 150, width: 70, height: 70, fill:
'red'
});
canvas.add(rect2);
var
rect3 =
new
fabric.Rect({top: 50, left: 250, width: 70, height: 70, fill:
'red'
});
canvas.add(rect3);
//在canvas上层对象上添加右键事件监听
$(
".upper-canvas"
).contextmenu(onContextmenu);
//初始化右键菜单
$.contextMenu({
selector:
'#contextmenu-output'
,
trigger:
'none'
,
build:
function
($trigger, e) {
//构建菜单项build方法在每次右键点击会执行
return
{
callback: contextMenuClick,
items: contextMenuItems
};
},
});
}
//右键点击事件响应
function
onContextmenu(event) {
var
pointer = canvas.getPointer(event.originalEvent);
var
objects = canvas.getObjects();
for
(
var
i = objects.length - 1; i >= 0; i--) {
var
object = objects[i];
//判断该对象是否在鼠标点击处
if
(canvas.containsPoint(event, object)) {
//选中该对象
canvas.setActiveObject(object);
//显示菜单
showContextMenu(event, object);
continue
;
}
}
//阻止系统右键菜单
event.preventDefault();
return
false
;
}
//右键菜单项点击
function
showContextMenu(event, object) {
//定义右键菜单项
contextMenuItems = {
"delete"
: {name:
"删除"
, icon:
"delete"
, data: object},
};
//右键菜单显示位置
var
position = {
x: event.clientX,
y: event.clientY
}
$(
'#contextmenu-output'
).contextMenu(position);
}
//右键菜单项点击
function
contextMenuClick(key, options) {
if
(key ==
"delete"
) {
//得到对应的object并删除
var
object = contextMenuItems[key].data;
canvas.remove(object);
}
}
</script>
</head>
<body>
<canvas id=
"canvas"
width=
"450"
height=
"200"
></canvas>
<div id=
"contextmenu-output"
></div>
</body>
</html>
|
具体可以参考:http://www.hangge.com/blog/cache/detail_1856.html
麻烦归麻烦,但是封装一下还是可以使用的,但是还需要引入插件,对于我来说有点不可以接受,所以我只能换个思路。
第二个方法,我是不是可以结合键盘操作,当我选中一个对象时,点击键盘的backspace,执行删除操作,虽然操作不是很反人类(还是有点反人类的),思路有了那就实现吧。
首选,要做的是要选中对象,可以调用fabric的object:selected方法,然后调用键盘的监听事件
代码:
// 删除对象
removeObject: function (that) {
// 监控canvas的object:selected事件
that.fabricCanvas.on('object:selected', function (option) {
// 监控页面的键盘事件
document.onkeydown = function (e) {
// 是否点击delete
if (e.keyCode === 8) {
// 移除当前所选对象
that.fabricCanvas.remove(option.target)
}
}
})
}
发现了bug,怎么在多个对象之间切换选中,没有执行事件呢。
经过我的测试,发现不管你选中那个对象,他都执行的是对象选中事件,也就是说,这个事件只会执行一次,除非你每次执行完,都移开,取消选中,但这有点太反人类了。
那就换个事件实施,用mouse:down,鼠标点击就执行,这总可以了吧。
代码:
// 删除对象
removeObject: function (that) {
// 监控canvas的mouse:down事件
that.fabricCanvas.on('mouse:down', function (option) {
// 监控页面的键盘事件
document.onkeydown = function (e) {
// 是否点击delete
if (e.keyCode === 8) {
// 移除当前所选对象
that.fabricCanvas.remove(option.target)
}
}
})
}
试了一下,真的可以,确实删除了,不过操作的方式肯定没有鼠标右键删除的方式好,但也算一个方式吧。
最后希望fabricjs尽快支持鼠标右键吧。
以上代码版本比较老了,实现方式也比较粗糙