mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
parent
bc9bd291fc
commit
aa78d632db
68
src/Layer.js
68
src/Layer.js
@ -2,7 +2,28 @@
|
|||||||
// constants
|
// constants
|
||||||
var HASH = '#',
|
var HASH = '#',
|
||||||
BEFORE_DRAW ='beforeDraw',
|
BEFORE_DRAW ='beforeDraw',
|
||||||
DRAW = 'draw';
|
DRAW = 'draw',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2 - 3 - 4
|
||||||
|
* | |
|
||||||
|
* 1 - 0 5
|
||||||
|
* |
|
||||||
|
* 8 - 7 - 6
|
||||||
|
*/
|
||||||
|
INTERSECTION_OFFSETS = [
|
||||||
|
{x: 0, y: 0}, // 0
|
||||||
|
{x: -1, y: 0}, // 1
|
||||||
|
{x: -1, y: -1}, // 2
|
||||||
|
{x: 0, y: -1}, // 3
|
||||||
|
{x: 1, y: -1}, // 4
|
||||||
|
{x: 1, y: 0}, // 5
|
||||||
|
{x: 1, y: 1}, // 6
|
||||||
|
{x: 0, y: 1}, // 7
|
||||||
|
{x: -1, y: 1} // 8
|
||||||
|
],
|
||||||
|
INTERSECTION_OFFSETS_LEN = INTERSECTION_OFFSETS.length;
|
||||||
|
|
||||||
|
|
||||||
Kinetic.Util.addMethods(Kinetic.Layer, {
|
Kinetic.Util.addMethods(Kinetic.Layer, {
|
||||||
___init: function(config) {
|
___init: function(config) {
|
||||||
@ -19,39 +40,46 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* get visible intersection object that contains shape and pixel data. This is the preferred
|
* get visible intersection shape. This is the preferred
|
||||||
* method for determining if a point intersects a shape or not
|
* method for determining if a point intersects a shape or not
|
||||||
* @method
|
* @method
|
||||||
* @memberof Kinetic.Layer.prototype
|
* @memberof Kinetic.Layer.prototype
|
||||||
* @param {Object} pos point object
|
* @param {Kinetic.Shape} shape
|
||||||
*/
|
*/
|
||||||
getIntersection: function() {
|
getIntersection: function() {
|
||||||
var pos = Kinetic.Util._getXY(Array.prototype.slice.call(arguments)),
|
var pos = Kinetic.Util._getXY(Array.prototype.slice.call(arguments)),
|
||||||
p, colorKey, shape;
|
shape, i, intersectionOffset;
|
||||||
|
|
||||||
if(this.isVisible()) {
|
if(this.isVisible()) {
|
||||||
p = this.hitCanvas.context._context.getImageData(pos.x | 0, pos.y | 0, 1, 1).data;
|
for (i=0; i<INTERSECTION_OFFSETS_LEN; i++) {
|
||||||
|
intersectionOffset = INTERSECTION_OFFSETS[i];
|
||||||
// this indicates that a hit pixel may have been found
|
shape = this._getIntersection({
|
||||||
if(p[3] === 255) {
|
x: pos.x + intersectionOffset.x,
|
||||||
colorKey = Kinetic.Util._rgbToHex(p[0], p[1], p[2]);
|
y: pos.y + intersectionOffset.y
|
||||||
shape = Kinetic.shapes[HASH + colorKey];
|
});
|
||||||
return {
|
if (shape) {
|
||||||
shape: shape,
|
return shape;
|
||||||
pixel: p
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// if no shape mapped to that pixel, just return the pixel array
|
|
||||||
return {
|
|
||||||
pixel: p
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
_getIntersection: function(pos) {
|
||||||
|
var p = this.hitCanvas.context._context.getImageData(pos.x, pos.y, 1, 1).data,
|
||||||
|
colorKey, shape;
|
||||||
|
|
||||||
|
// this indicates that a hit pixel may have been found
|
||||||
|
if(p[3] === 255) {
|
||||||
|
colorKey = Kinetic.Util._rgbToHex(p[0], p[1], p[2]);
|
||||||
|
shape = Kinetic.shapes[HASH + colorKey];
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
},
|
||||||
drawScene: function(canvas) {
|
drawScene: function(canvas) {
|
||||||
canvas = canvas || this.getCanvas();
|
canvas = canvas || this.getCanvas();
|
||||||
|
|
||||||
|
36
src/Stage.js
36
src/Stage.js
@ -42,7 +42,7 @@
|
|||||||
UNDERSCORE = '_',
|
UNDERSCORE = '_',
|
||||||
CONTAINER = 'container',
|
CONTAINER = 'container',
|
||||||
EMPTY_STRING = '',
|
EMPTY_STRING = '',
|
||||||
EVENTS = [MOUSEDOWN, MOUSEMOVE, MOUSEUP, MOUSEOUT, TOUCHSTART, TOUCHMOVE, TOUCHEND, MOUSEOVER],
|
EVENTS = [MOUSEDOWN, MOUSEMOVE, MOUSEUP, MOUSEOUT, TOUCHSTART, TOUCHMOVE, TOUCHEND, MOUSEOVER];
|
||||||
|
|
||||||
// cached variables
|
// cached variables
|
||||||
eventsLength = EVENTS.length;
|
eventsLength = EVENTS.length;
|
||||||
@ -250,24 +250,24 @@
|
|||||||
this.toDataURL(config);
|
this.toDataURL(config);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* get visible intersection object that contains shape and pixel data. This is the preferred
|
* get visible intersection shape. This is the preferred
|
||||||
* method for determining if a point intersects a shape or not
|
* method for determining if a point intersects a shape or not
|
||||||
* @method
|
* @method
|
||||||
* @memberof Kinetic.Stage.prototype
|
* @memberof Kinetic.Stage.prototype
|
||||||
* @param {Object} pos point object
|
* @param {Kinetic.Shape} shape
|
||||||
*/
|
*/
|
||||||
getIntersection: function() {
|
getIntersection: function() {
|
||||||
var pos = Kinetic.Util._getXY(Array.prototype.slice.call(arguments)),
|
var pos = Kinetic.Util._getXY(Array.prototype.slice.call(arguments)),
|
||||||
layers = this.getChildren(),
|
layers = this.getChildren(),
|
||||||
len = layers.length,
|
len = layers.length,
|
||||||
end = len - 1,
|
end = len - 1,
|
||||||
n, obj;
|
n, shape;
|
||||||
|
|
||||||
for(n = end; n >= 0; n--) {
|
for(n = end; n >= 0; n--) {
|
||||||
obj = layers[n].getIntersection(pos);
|
shape = layers[n].getIntersection(pos);
|
||||||
if (obj) {
|
if (shape) {
|
||||||
return obj;
|
return shape;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -355,11 +355,10 @@
|
|||||||
_mousemove: function(evt) {
|
_mousemove: function(evt) {
|
||||||
this._setPointerPosition(evt);
|
this._setPointerPosition(evt);
|
||||||
var dd = Kinetic.DD,
|
var dd = Kinetic.DD,
|
||||||
obj = this.getIntersection(this.getPointerPosition()),
|
shape = this.getIntersection(this.getPointerPosition());
|
||||||
shape = obj && obj.shape ? obj.shape : undefined;
|
|
||||||
|
|
||||||
if(shape && shape.isListening()) {
|
if(shape && shape.isListening()) {
|
||||||
if(!Kinetic.isDragging() && obj.pixel[3] === 255 && (!this.targetShape || this.targetShape._id !== shape._id)) {
|
if(!Kinetic.isDragging() && (!this.targetShape || this.targetShape._id !== shape._id)) {
|
||||||
if(this.targetShape) {
|
if(this.targetShape) {
|
||||||
this.targetShape._fireAndBubble(MOUSEOUT, evt, shape);
|
this.targetShape._fireAndBubble(MOUSEOUT, evt, shape);
|
||||||
this.targetShape._fireAndBubble(MOUSELEAVE, evt, shape);
|
this.targetShape._fireAndBubble(MOUSELEAVE, evt, shape);
|
||||||
@ -400,8 +399,7 @@
|
|||||||
},
|
},
|
||||||
_mousedown: function(evt) {
|
_mousedown: function(evt) {
|
||||||
this._setPointerPosition(evt);
|
this._setPointerPosition(evt);
|
||||||
var obj = this.getIntersection(this.getPointerPosition()),
|
var shape = this.getIntersection(this.getPointerPosition());
|
||||||
shape = obj && obj.shape ? obj.shape : undefined;
|
|
||||||
|
|
||||||
Kinetic.listenClickTap = true;
|
Kinetic.listenClickTap = true;
|
||||||
|
|
||||||
@ -422,8 +420,7 @@
|
|||||||
_mouseup: function(evt) {
|
_mouseup: function(evt) {
|
||||||
this._setPointerPosition(evt);
|
this._setPointerPosition(evt);
|
||||||
var that = this,
|
var that = this,
|
||||||
obj = this.getIntersection(this.getPointerPosition()),
|
shape = this.getIntersection(this.getPointerPosition()),
|
||||||
shape = obj && obj.shape ? obj.shape : undefined,
|
|
||||||
fireDblClick = false;
|
fireDblClick = false;
|
||||||
|
|
||||||
if(Kinetic.inDblClickWindow) {
|
if(Kinetic.inDblClickWindow) {
|
||||||
@ -469,8 +466,7 @@
|
|||||||
},
|
},
|
||||||
_touchstart: function(evt) {
|
_touchstart: function(evt) {
|
||||||
this._setPointerPosition(evt);
|
this._setPointerPosition(evt);
|
||||||
var obj = this.getIntersection(this.getPointerPosition()),
|
var shape = this.getIntersection(this.getPointerPosition());
|
||||||
shape = obj && obj.shape ? obj.shape : undefined;
|
|
||||||
|
|
||||||
Kinetic.listenClickTap = true;
|
Kinetic.listenClickTap = true;
|
||||||
|
|
||||||
@ -489,8 +485,7 @@
|
|||||||
_touchend: function(evt) {
|
_touchend: function(evt) {
|
||||||
this._setPointerPosition(evt);
|
this._setPointerPosition(evt);
|
||||||
var that = this,
|
var that = this,
|
||||||
obj = this.getIntersection(this.getPointerPosition()),
|
shape = this.getIntersection(this.getPointerPosition());
|
||||||
shape = obj && obj.shape ? obj.shape : undefined,
|
|
||||||
fireDblClick = false;
|
fireDblClick = false;
|
||||||
|
|
||||||
if(Kinetic.inDblClickWindow) {
|
if(Kinetic.inDblClickWindow) {
|
||||||
@ -534,8 +529,7 @@
|
|||||||
_touchmove: function(evt) {
|
_touchmove: function(evt) {
|
||||||
this._setPointerPosition(evt);
|
this._setPointerPosition(evt);
|
||||||
var dd = Kinetic.DD,
|
var dd = Kinetic.DD,
|
||||||
obj = this.getIntersection(this.getPointerPosition()),
|
shape = this.getIntersection(this.getPointerPosition());
|
||||||
shape = obj && obj.shape ? obj.shape : undefined;
|
|
||||||
|
|
||||||
if (shape && shape.isListening()) {
|
if (shape && shape.isListening()) {
|
||||||
shape._fireAndBubble(TOUCHMOVE, evt);
|
shape._fireAndBubble(TOUCHMOVE, evt);
|
||||||
|
@ -130,9 +130,9 @@ suite('Layer', function() {
|
|||||||
layer.add(greenCircle);
|
layer.add(greenCircle);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
assert.equal(layer.getIntersection(300, 100).shape.getId(), 'greenCircle', 'shape should be greenCircle');
|
assert.equal(layer.getIntersection(300, 100).getId(), 'greenCircle', 'shape should be greenCircle');
|
||||||
assert.equal(layer.getIntersection(380, 100).shape.getId(), 'redCircle', 'shape should be redCircle');
|
assert.equal(layer.getIntersection(380, 100).getId(), 'redCircle', 'shape should be redCircle');
|
||||||
assert.equal(layer.getIntersection(100, 100).shape, null, 'shape should be null');
|
assert.equal(layer.getIntersection(100, 100), null, 'shape should be null');
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -141,7 +141,7 @@ suite('Stage', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
test('stage getAllIntersections()', function() {
|
test('stage getIntersection()', function() {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
var layer = new Kinetic.Layer();
|
var layer = new Kinetic.Layer();
|
||||||
|
|
||||||
@ -169,9 +169,53 @@ suite('Stage', function() {
|
|||||||
layer.add(greenCircle);
|
layer.add(greenCircle);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
assert.equal(stage.getIntersection(300, 100).shape.getId(), 'greenCircle', 'shape should be greenCircle');
|
assert.equal(stage.getIntersection(300, 100).getId(), 'greenCircle', 'shape should be greenCircle');
|
||||||
assert.equal(stage.getIntersection(380, 100).shape.getId(), 'redCircle', 'shape should be redCircle');
|
assert.equal(stage.getIntersection(380, 100).getId(), 'redCircle', 'shape should be redCircle');
|
||||||
assert.equal(stage.getIntersection(100, 100).shape, null, 'shape should be null');
|
assert.equal(stage.getIntersection(100, 100), null, 'shape should be null');
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// ======================================================
|
||||||
|
test('stage getIntersection() edge detection', function() {
|
||||||
|
var stage = addStage();
|
||||||
|
var layer = new Kinetic.Layer();
|
||||||
|
|
||||||
|
var redCircle = new Kinetic.Circle({
|
||||||
|
x: 380,
|
||||||
|
y: stage.getHeight() / 2,
|
||||||
|
radius: 70,
|
||||||
|
strokeWidth: 4,
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black',
|
||||||
|
id: 'redCircle'
|
||||||
|
});
|
||||||
|
|
||||||
|
var greenCircle = new Kinetic.Circle({
|
||||||
|
x: 300,
|
||||||
|
y: stage.getHeight() / 2,
|
||||||
|
radius: 70,
|
||||||
|
strokeWidth: 4,
|
||||||
|
fill: 'green',
|
||||||
|
stroke: 'black',
|
||||||
|
id: 'greenCircle'
|
||||||
|
});
|
||||||
|
|
||||||
|
stage.on('contentMousemove', function() {
|
||||||
|
var pos = stage.getPointerPosition();
|
||||||
|
var shape = stage.getIntersection(pos);
|
||||||
|
if (!shape){
|
||||||
|
//console.log(pos);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
layer.add(redCircle);
|
||||||
|
layer.add(greenCircle);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
assert.equal(stage.getIntersection(370, 93).getId(), 'greenCircle', 'shape should be greenCircle');
|
||||||
|
assert.equal(stage.getIntersection(371, 93).getId(), 'greenCircle', 'shape should be greenCircle');
|
||||||
|
assert.equal(stage.getIntersection(372, 93).getId(), 'redCircle', 'shape should be greenCircle');
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user