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
|
||||
var HASH = '#',
|
||||
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, {
|
||||
___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
|
||||
* @memberof Kinetic.Layer.prototype
|
||||
* @param {Object} pos point object
|
||||
* @param {Kinetic.Shape} shape
|
||||
*/
|
||||
getIntersection: function() {
|
||||
var pos = Kinetic.Util._getXY(Array.prototype.slice.call(arguments)),
|
||||
p, colorKey, shape;
|
||||
shape, i, intersectionOffset;
|
||||
|
||||
if(this.isVisible()) {
|
||||
p = this.hitCanvas.context._context.getImageData(pos.x | 0, pos.y | 0, 1, 1).data;
|
||||
|
||||
// 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: shape,
|
||||
pixel: p
|
||||
};
|
||||
}
|
||||
else {
|
||||
// if no shape mapped to that pixel, just return the pixel array
|
||||
return {
|
||||
pixel: p
|
||||
};
|
||||
for (i=0; i<INTERSECTION_OFFSETS_LEN; i++) {
|
||||
intersectionOffset = INTERSECTION_OFFSETS[i];
|
||||
shape = this._getIntersection({
|
||||
x: pos.x + intersectionOffset.x,
|
||||
y: pos.y + intersectionOffset.y
|
||||
});
|
||||
if (shape) {
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
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) {
|
||||
canvas = canvas || this.getCanvas();
|
||||
|
||||
|
36
src/Stage.js
36
src/Stage.js
@ -42,7 +42,7 @@
|
||||
UNDERSCORE = '_',
|
||||
CONTAINER = 'container',
|
||||
EMPTY_STRING = '',
|
||||
EVENTS = [MOUSEDOWN, MOUSEMOVE, MOUSEUP, MOUSEOUT, TOUCHSTART, TOUCHMOVE, TOUCHEND, MOUSEOVER],
|
||||
EVENTS = [MOUSEDOWN, MOUSEMOVE, MOUSEUP, MOUSEOUT, TOUCHSTART, TOUCHMOVE, TOUCHEND, MOUSEOVER];
|
||||
|
||||
// cached variables
|
||||
eventsLength = EVENTS.length;
|
||||
@ -250,24 +250,24 @@
|
||||
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
|
||||
* @memberof Kinetic.Stage.prototype
|
||||
* @param {Object} pos point object
|
||||
* @param {Kinetic.Shape} shape
|
||||
*/
|
||||
getIntersection: function() {
|
||||
var pos = Kinetic.Util._getXY(Array.prototype.slice.call(arguments)),
|
||||
layers = this.getChildren(),
|
||||
len = layers.length,
|
||||
end = len - 1,
|
||||
n, obj;
|
||||
n, shape;
|
||||
|
||||
for(n = end; n >= 0; n--) {
|
||||
obj = layers[n].getIntersection(pos);
|
||||
if (obj) {
|
||||
return obj;
|
||||
}
|
||||
shape = layers[n].getIntersection(pos);
|
||||
if (shape) {
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -355,11 +355,10 @@
|
||||
_mousemove: function(evt) {
|
||||
this._setPointerPosition(evt);
|
||||
var dd = Kinetic.DD,
|
||||
obj = this.getIntersection(this.getPointerPosition()),
|
||||
shape = obj && obj.shape ? obj.shape : undefined;
|
||||
shape = this.getIntersection(this.getPointerPosition());
|
||||
|
||||
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) {
|
||||
this.targetShape._fireAndBubble(MOUSEOUT, evt, shape);
|
||||
this.targetShape._fireAndBubble(MOUSELEAVE, evt, shape);
|
||||
@ -400,8 +399,7 @@
|
||||
},
|
||||
_mousedown: function(evt) {
|
||||
this._setPointerPosition(evt);
|
||||
var obj = this.getIntersection(this.getPointerPosition()),
|
||||
shape = obj && obj.shape ? obj.shape : undefined;
|
||||
var shape = this.getIntersection(this.getPointerPosition());
|
||||
|
||||
Kinetic.listenClickTap = true;
|
||||
|
||||
@ -422,8 +420,7 @@
|
||||
_mouseup: function(evt) {
|
||||
this._setPointerPosition(evt);
|
||||
var that = this,
|
||||
obj = this.getIntersection(this.getPointerPosition()),
|
||||
shape = obj && obj.shape ? obj.shape : undefined,
|
||||
shape = this.getIntersection(this.getPointerPosition()),
|
||||
fireDblClick = false;
|
||||
|
||||
if(Kinetic.inDblClickWindow) {
|
||||
@ -469,8 +466,7 @@
|
||||
},
|
||||
_touchstart: function(evt) {
|
||||
this._setPointerPosition(evt);
|
||||
var obj = this.getIntersection(this.getPointerPosition()),
|
||||
shape = obj && obj.shape ? obj.shape : undefined;
|
||||
var shape = this.getIntersection(this.getPointerPosition());
|
||||
|
||||
Kinetic.listenClickTap = true;
|
||||
|
||||
@ -489,8 +485,7 @@
|
||||
_touchend: function(evt) {
|
||||
this._setPointerPosition(evt);
|
||||
var that = this,
|
||||
obj = this.getIntersection(this.getPointerPosition()),
|
||||
shape = obj && obj.shape ? obj.shape : undefined,
|
||||
shape = this.getIntersection(this.getPointerPosition());
|
||||
fireDblClick = false;
|
||||
|
||||
if(Kinetic.inDblClickWindow) {
|
||||
@ -534,8 +529,7 @@
|
||||
_touchmove: function(evt) {
|
||||
this._setPointerPosition(evt);
|
||||
var dd = Kinetic.DD,
|
||||
obj = this.getIntersection(this.getPointerPosition()),
|
||||
shape = obj && obj.shape ? obj.shape : undefined;
|
||||
shape = this.getIntersection(this.getPointerPosition());
|
||||
|
||||
if (shape && shape.isListening()) {
|
||||
shape._fireAndBubble(TOUCHMOVE, evt);
|
||||
|
@ -130,9 +130,9 @@ suite('Layer', function() {
|
||||
layer.add(greenCircle);
|
||||
stage.add(layer);
|
||||
|
||||
assert.equal(layer.getIntersection(300, 100).shape.getId(), 'greenCircle', 'shape should be greenCircle');
|
||||
assert.equal(layer.getIntersection(380, 100).shape.getId(), 'redCircle', 'shape should be redCircle');
|
||||
assert.equal(layer.getIntersection(100, 100).shape, null, 'shape should be null');
|
||||
assert.equal(layer.getIntersection(300, 100).getId(), 'greenCircle', 'shape should be greenCircle');
|
||||
assert.equal(layer.getIntersection(380, 100).getId(), 'redCircle', 'shape should be redCircle');
|
||||
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 layer = new Kinetic.Layer();
|
||||
|
||||
@ -169,9 +169,53 @@ suite('Stage', function() {
|
||||
layer.add(greenCircle);
|
||||
stage.add(layer);
|
||||
|
||||
assert.equal(stage.getIntersection(300, 100).shape.getId(), 'greenCircle', 'shape should be greenCircle');
|
||||
assert.equal(stage.getIntersection(380, 100).shape.getId(), 'redCircle', 'shape should be redCircle');
|
||||
assert.equal(stage.getIntersection(100, 100).shape, null, 'shape should be null');
|
||||
assert.equal(stage.getIntersection(300, 100).getId(), 'greenCircle', 'shape should be greenCircle');
|
||||
assert.equal(stage.getIntersection(380, 100).getId(), 'redCircle', 'shape should be redCircle');
|
||||
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