2015-06-11 08:27:22
5. 事件响应
5.1. 图形的事件响应
图形对象对事件的响应处理可以使用on()
方法绑定事件类型和相应方法. on()
方法需要一个事件类型参数和相应方法, 其中所支持的事件类型包括: mouseover
, mouseout
, mousemove
, mousedown
, mouseup
, click
, dblclick
, dragstart
以及dragend
事件. 默认情况下, 图形对象事件响应使用的是路径检测方法, 下一节还会介绍像素检测方法.
绑定代码如下:
# Language: js
<script>
shape.on("click", function(evt) {
// 事件响应代码
});
</script>
如下代码绘制一个矩形, 并响应鼠标在此矩形上的点击操作, 弹出消息框:
# Language: js
<script>
window.onload = function() {
var stage = new Kinetic.Stage({
container: "container",
width: 600,
height: 400
});
var layer = new Kinetic.Layer();
//创建config参数
var config = {
x: 200,
y: 150,
width: 200,
height: 100,
fill: "blue",
stroke: "black",
strokeWidth: 4
};
//创建矩形对象
var rect = new Kinetic.Rect(config);
//绑定事件响应方法
rect.on("click", function() {
alert("clicked");
});
//把矩形对象添加到层里
layer.add(rect);
//将层添加到舞台中
stage.add(layer);
};
</script>
运行效果如下:
5.2. 像素检测
对于图像, 线条和文本之类的对象, 路径检测就不太合适, 这时就需要使用像素检测方法来响应事件. 为了使用像素检测, 就需要为图形图像对象的检测类型detectionType
设置为像素检测pixel
. 这个值默认是路径检测path
.
# Language: js
<script>
// 在构造方法的config中指定检测类型
var image = new Kinetic.Image({
detectionType: "pixel"
});
// 或者是用对象方法设定检测类型
image.setDetectionType("pixel");
</script>
然后, Kinetic
还需要用对象的saveData()
来保存数据才可以使用像素检测功能. 另外还可以用clearData()
来清除保存的数据. 但要注意的是, saveData()
需要在对象所在的层被添加到舞台上以后才能使用, 否则会出错.
# Language: js
<script>
// 保存图像数据
image.saveData();
// 清除图像数据
image.clearData();
</script>
示例代码如下:
# Language: js
<script>
var stage;
function loadImage() {
var image = new Image();
image.onload = function() {
var kimage = new Kinetic.Image({
x: 100,
y: 100,
image: image,
detectionType: "pixel"
});
//绑定事件响应方法
kimage.on("click", function() {
alert("image clicked");
});
var layer = new Kinetic.Layer();
layer.add(kimage);
stage.add(layer);
//保存数据以响应事件
kimage.saveData();
};
//图像需要与此页面在同一个服务器上, 否则会Javascript会抛出安全异常
image.src = "FSM.png";
}
window.onload = function() {
stage = new Kinetic.Stage({
container: "container",
width: 600,
height: 400
});
var rect = new Kinetic.Rect({
x: 400,
y: 100,
width: 100,
height: 100,
fill: "red",
detectionType: "pixel"
});
//绑定事件响应方法
rect.on("click", function() {
alert("rect clicked");
});
var layer = new Kinetic.Layer();
layer.add(rect);
stage.add(layer);
//保存数据以响应事件
rect.saveData();
loadImage();
};
</script>
运行效果如下:
5.3. 事件命名
对于同一个事件, 可以通过对事件进行命名绑定多个事件处理方法. 事件的命名格式遵循事件类型.自定义名称
. 比如, 针对鼠标点击事件click
, 可以命名两个事件处理方法click.a
和click.b
分别绑定各自的事件处理方法:
# Language: js
//创建矩形对象
var rect = new Kinetic.Rect(config);
//绑定消息响应方法
rect.on("click.a", function() {
alert("clicked a");
});
rect.on("click.b", function() {
alert("clicked b");
});
//把矩形对象添加到层里
layer.add(rect);
//将层添加到舞台中
stage.add(layer);
点击这个矩形的时候会依次调用这两个绑定的方法, 弹出两个消息框.
5.4. 鼠标位置的获取
在响应鼠标事件的时候常常需要获取鼠标位置信息, 这时可以在事件响应方法中使用舞台对象的getMousePosition
方法获取鼠标位置:
# Language: js
//绑定事件响应方法
rect.on("click", function() {
var mousePos = stage.getMousePosition();
var msg = "x:"+mousePos.x+" | "+"y:"+mousePos.y;
alert(msg);
});
当然, 要注意的是, 这个坐标是相对于舞台左上角的, 而不是绑定的图像左上角.
5.5. 多事件绑定
如果希望同时响应多个不同的事件, 可以在on
方法绑定事件处理方法的时候, 在事件参数中以空格分隔不同的事件, 如下代码在鼠标按下和移过的时候都调用此处理方法:
# Language: js
<script>
shape.on("mousedown mouseover", function(evt) {
// 事件响应代码
});
</script>
5.6. 取消事件绑定
要取消对某个事件响应的绑定, 只需要用图形对象的off
方法, 参数为要取消的事件名称, 如下代码取消了鼠标点击事件的响应:
# Language: js
<script>
shape.off("click");
</script>
对于有多个自定义命名的事件, 比如上文中的click.a
和click.b
, 使用shape.off("click")
会将两个事件处理的绑定都取消掉, 如果只是单独取消其中某个, 可以如下操作:
shape.off("click.a");
或
shape.off("click.b");
5.7. 事件监听开关
Kinetic
中还可以通过设定listening
属性的方法来确定是否要监听事件. 如果设为false
, 则绑定的事件响应方法会被忽略不执行.
# Language: js
<script>
// 在构造方法的config参数中设置
var shape = new Kinetic.Circle({
listening: false
});
// 使用对象方法设置
shape.listen(true);
</script>
5.8. 禁止事件向上级对象传递
如果某个图形对象属于某个组, 则某个发生在图形上的事件会被依次传递到图形对象, 组, 层, 那么如果这三者都绑定了此事件的相应方法, 那么这些方法也会被依次执行.
那么如果希望在本对象处理事件后事件不再继续向上级传递, 则可以在绑定事件处理方法时如下用方法的evt
参数处理:
# Language: js
<script>
shape.on("click", function(evt) {
evt.cancelBubble = true;
});
</script>
5.9. 在事件处理方法中获取图形对象
同样也是用在绑定事件处理方法时方法的evt
参数获取当前事件绑定的图形对象:
# Language: js
<script>
shape.on("click", function(evt) {
var shape = evt.shape;
});
</script>
然后就可以在事件处理方法中对图形对象进行操作了.
5.10. 触发事件响应方法
除了由用户交互操作出发事件而执行响应方法外, 还可以在代码里用simulate
方法触发事件.
比如:
# Language: js
<script>
// 图形对象绑定了鼠标点击事件
shape.on("click", function(evt){
// 事件处理
});
// 触发事件鼠标点击事件
shape.simulate("click");
</script>
5.11. 移动设备的触摸屏事件响应
触摸屏的事件响应与普通电脑的响应处理方法类似, 只是事件类型的名称略有不同. Kinetic
支持的触摸屏事件包括touchstart
, touchmove
, touchend
, tap
, dbltap
, dragstart
, dragmove
以及dragend
.
而触摸点坐标的获取就不是用getMousePosition(evt)
, 而是触摸屏专用方法getTouchPosition(evt)
或者桌面与触摸屏通用方法getUserPosition(evt)
.
6. 拖拽
6.1. 拖拽功能
要实现Kinetic
对象的拖拽功能很简单, 只需要将图形对象的draggable
属性设为true
就可以了.
# Language: js
<script>
// 在构造方法中的config参数设置
var shape = new Kinetic.Circle({
draggable: true;
});
// 用图形对象的方法设置
shape.draggable(true);
</script>
这种拖拽功能还可以应用到组(Group
), 层(Layer
)和舞台(Stage
), 设置方法类似. 不过要注意的是, 应用到组或层上时, 拖拽组或层上的任一对象, 整个组或层都会移动, 而对于舞台, 拖拽舞台上任何位置都能移动整个舞台, 而无需拖拽舞台上的图形对象.
6.2. 拖拽线条
线条(Line
)拖拽功能的设定与其他类型图形类似, 只是线条需要用像素检测功能, 因此需要线条所在层添加到舞台后执行一次saveData
方法, 在拖拽动作结束事件处理方法中也要执行一次saveData
方法.
# Language: js
<script>
// 在构造方法中的config中设定
var line= new Kinetic.Line({
draggable: true;
});
// 使用对象的方法设定
line.draggable(true);
// 保存像素数据
line.saveData();
//必须在每次拖拽完毕后执行一次saveData
line.on("dragend", function() {
blueLine.saveData();
});
</script>
完整代码:
# Language: js
<script>
window.onload = function() {
var stage = new Kinetic.Stage({
container: "container",
width: 600,
height: 400
});
var layer = new Kinetic.Layer();
var line = new Kinetic.Line({
points: [ 100, 150, 340, 230 ],
stroke: "blue",
strokeWidth: 10,
draggable: true
});
layer.add(line);
stage.add(layer);
//保存像素数据
line.saveData();
//必须在每次拖拽完毕后执行一次saveData
line.on("dragend", function() {
blueLine.saveData();
});
};
</script>
6.3. 拖拽事件
有关拖拽的事件包括拖拽开始dragstart
, 拖拽中dragmove
, 拖拽结束dragend
, 我们可以根据自己的需要绑定这几个事件响应方法.
# Language: js
<script>
shape.on("dragstart", function(evt) {
// 响应代码
};
shape.on("dragmove", function(evt) {
// 响应代码
};
shape.on("dragend", function(evt) {
// 响应代码
};
</script>
6.4. 拖拽方向限制
Kinetic
支持对拖拽运动限制在水平或者垂直方向上, 这个功能通过对象的dragConstraint
属性进行设置来实现. dragConstraint
属性可以有三个选项, 包括none
, horizontal
和vertical
, 默认情况下这个属性的值是none
.
# Language: js
<script>
// 在构造方法中的config参数中设置, 拖动被限制在水平方向上
var shape = new Kinetic.Rect({
dragConstraint: "horizontal"
});
// 用对象的方法设置, 拖动被限制在水平方向上
shape.setDragConstraint("horizontal");
</script>
6.5. 拖拽范围限制
Kinetic
通过dragBounds
属性的设置可以将拖拽限制在一个矩形范围之内. dragBounds
属性包括top
, right
, bottom
和left
四个参数, 这四个参数可以只设置其中的几个, 不需要全部设置.
# Language: js
<script>
// 在构造方法的config参数中设置
var shape = new Kinetic.Circle({
dragBounds: {
top: 50
}
});
// 在对象的方法中设置
shape.setDragBounds({
top: 0,
left: 0,
right: 200,
bottom: 200
});
</script>