mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
fix docs, Better implementation of mouseover
event for stage
This commit is contained in:
parent
31785f6323
commit
b02ac65e68
@ -16,7 +16,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
* Full rewrite to Typescript with tons of refactoring and small optimizations. The public API should be 100% the same
|
* Full rewrite to Typescript with tons of refactoring and small optimizations. The public API should be 100% the same
|
||||||
* Fixed `patternImage` and `radialGradient` for `Konva.Text`
|
* Fixed `patternImage` and `radialGradient` for `Konva.Text`
|
||||||
* `Konva.Util._isObject` is renamed to `Konva.Util._isPlainObject`.
|
* `Konva.Util._isObject` is renamed to `Konva.Util._isPlainObject`.
|
||||||
* A bit changed behavior of `removeId` (private method), not it doesn't clear node ref, of id is changed.
|
* A bit changed behavior of `removeId` (private method), now it doesn't clear node ref, if object is changed.
|
||||||
* simplified `batchDraw` method (it doesn't use `Konva.Animation`) now.
|
* simplified `batchDraw` method (it doesn't use `Konva.Animation`) now.
|
||||||
* `id` and `name` properties defaults are empty strings, not `undefined`
|
* `id` and `name` properties defaults are empty strings, not `undefined`
|
||||||
|
|
||||||
@ -30,6 +30,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
* Better mouse support on mobile devices (yes, that is possible to connect mouse to mobile)
|
* Better mouse support on mobile devices (yes, that is possible to connect mouse to mobile)
|
||||||
|
* Better implementation of `mouseover` event for stage
|
||||||
|
|
||||||
## [2.6.0][2018-12-14]
|
## [2.6.0][2018-12-14]
|
||||||
|
|
||||||
|
46
konva.js
46
konva.js
@ -3433,6 +3433,8 @@
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
// TODO: validate z index
|
||||||
|
// it should be >= 0 and < length
|
||||||
Node.prototype.setZIndex = function (zIndex) {
|
Node.prototype.setZIndex = function (zIndex) {
|
||||||
if (!this.parent) {
|
if (!this.parent) {
|
||||||
Util.warn('Node has no parent. zIndex parameter is ignored.');
|
Util.warn('Node has no parent. zIndex parameter is ignored.');
|
||||||
@ -3845,7 +3847,10 @@
|
|||||||
* @param {Number} [config.y] y position of canvas section
|
* @param {Number} [config.y] y position of canvas section
|
||||||
* @param {Number} [config.width] width of canvas section
|
* @param {Number} [config.width] width of canvas section
|
||||||
* @param {Number} [config.height] height of canvas section
|
* @param {Number} [config.height] height of canvas section
|
||||||
* @paremt {Number} [config.pixelRatio] pixelRatio of ouput image. Default is 1.
|
* @param {Number} [config.pixelRatio] pixelRatio of output canvas. Default is 1.
|
||||||
|
* You can use that property to increase quality of the image, for example for super hight quality exports
|
||||||
|
* or usage on retina (or similar) displays. pixelRatio will be used to multiply the size of exported image.
|
||||||
|
* If you export to 500x500 size with pixelRatio = 2, then produced image will have size 1000x1000.
|
||||||
* @example
|
* @example
|
||||||
* var canvas = node.toCanvas();
|
* var canvas = node.toCanvas();
|
||||||
*/
|
*/
|
||||||
@ -3868,7 +3873,10 @@
|
|||||||
* @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType,
|
* @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType,
|
||||||
* you can specify the quality from 0 to 1, where 0 is very poor quality and 1
|
* you can specify the quality from 0 to 1, where 0 is very poor quality and 1
|
||||||
* is very high quality
|
* is very high quality
|
||||||
* @param {Number} [config.pixelRatio] pixelRatio of output image url. Default is 1
|
* @param {Number} [config.pixelRatio] pixelRatio of output image url. Default is 1.
|
||||||
|
* You can use that property to increase quality of the image, for example for super hight quality exports
|
||||||
|
* or usage on retina (or similar) displays. pixelRatio will be used to multiply the size of exported image.
|
||||||
|
* If you export to 500x500 size with pixelRatio = 2, then produced image will have size 1000x1000.
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
Node.prototype.toDataURL = function (config) {
|
Node.prototype.toDataURL = function (config) {
|
||||||
@ -3897,7 +3905,10 @@
|
|||||||
* @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType,
|
* @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType,
|
||||||
* you can specify the quality from 0 to 1, where 0 is very poor quality and 1
|
* you can specify the quality from 0 to 1, where 0 is very poor quality and 1
|
||||||
* is very high quality
|
* is very high quality
|
||||||
* @paremt {Number} [config.pixelRatio] pixelRatio of ouput image. Default is 1.
|
* @param {Number} [config.pixelRatio] pixelRatio of output image. Default is 1.
|
||||||
|
* You can use that property to increase quality of the image, for example for super hight quality exports
|
||||||
|
* or usage on retina (or similar) displays. pixelRatio will be used to multiply the size of exported image.
|
||||||
|
* If you export to 500x500 size with pixelRatio = 2, then produced image will have size 1000x1000.
|
||||||
* @example
|
* @example
|
||||||
* var image = node.toImage({
|
* var image = node.toImage({
|
||||||
* callback(img) {
|
* callback(img) {
|
||||||
@ -5716,7 +5727,12 @@
|
|||||||
};
|
};
|
||||||
Stage.prototype._mouseover = function (evt) {
|
Stage.prototype._mouseover = function (evt) {
|
||||||
this._setPointerPosition(evt);
|
this._setPointerPosition(evt);
|
||||||
|
// TODO: add test on mouseover
|
||||||
|
// I guess it should fire on:
|
||||||
|
// 1. mouseenter
|
||||||
|
// 2. leave or enter any shape
|
||||||
this._fire(CONTENT_MOUSEOVER, { evt: evt });
|
this._fire(CONTENT_MOUSEOVER, { evt: evt });
|
||||||
|
this._fire(MOUSEOVER, { evt: evt, target: this, currentTarget: this });
|
||||||
};
|
};
|
||||||
Stage.prototype._mouseout = function (evt) {
|
Stage.prototype._mouseout = function (evt) {
|
||||||
this._setPointerPosition(evt);
|
this._setPointerPosition(evt);
|
||||||
@ -5739,8 +5755,8 @@
|
|||||||
if (!getGlobalKonva().isDragging()) {
|
if (!getGlobalKonva().isDragging()) {
|
||||||
shape = this.getIntersection(this.getPointerPosition());
|
shape = this.getIntersection(this.getPointerPosition());
|
||||||
if (shape && shape.isListening()) {
|
if (shape && shape.isListening()) {
|
||||||
if (!getGlobalKonva().isDragging() &&
|
var differentTarget = !this.targetShape || this.targetShape !== shape;
|
||||||
(!this.targetShape || this.targetShape._id !== shape._id)) {
|
if (!getGlobalKonva().isDragging() && differentTarget) {
|
||||||
if (this.targetShape) {
|
if (this.targetShape) {
|
||||||
this.targetShape._fireAndBubble(MOUSEOUT, { evt: evt }, shape);
|
this.targetShape._fireAndBubble(MOUSEOUT, { evt: evt }, shape);
|
||||||
this.targetShape._fireAndBubble(MOUSELEAVE$1, { evt: evt }, shape);
|
this.targetShape._fireAndBubble(MOUSELEAVE$1, { evt: evt }, shape);
|
||||||
@ -5761,6 +5777,11 @@
|
|||||||
if (this.targetShape && !getGlobalKonva().isDragging()) {
|
if (this.targetShape && !getGlobalKonva().isDragging()) {
|
||||||
this.targetShape._fireAndBubble(MOUSEOUT, { evt: evt });
|
this.targetShape._fireAndBubble(MOUSEOUT, { evt: evt });
|
||||||
this.targetShape._fireAndBubble(MOUSELEAVE$1, { evt: evt });
|
this.targetShape._fireAndBubble(MOUSELEAVE$1, { evt: evt });
|
||||||
|
this._fire(MOUSEOVER, {
|
||||||
|
evt: evt,
|
||||||
|
target: this,
|
||||||
|
currentTarget: this
|
||||||
|
});
|
||||||
this.targetShape = null;
|
this.targetShape = null;
|
||||||
}
|
}
|
||||||
this._fire(MOUSEMOVE, {
|
this._fire(MOUSEMOVE, {
|
||||||
@ -6670,6 +6691,13 @@
|
|||||||
var HAS_SHADOW = 'hasShadow';
|
var HAS_SHADOW = 'hasShadow';
|
||||||
var SHADOW_RGBA = 'shadowRGBA';
|
var SHADOW_RGBA = 'shadowRGBA';
|
||||||
// TODO: cache gradient from context
|
// TODO: cache gradient from context
|
||||||
|
// TODO: write a test for adding destroyed shape into the layer
|
||||||
|
// will it draw?
|
||||||
|
// will it pass hit test?
|
||||||
|
// show warning on adding destroyed shape?
|
||||||
|
// TODO: idea - use only "remove" (or destroy method)
|
||||||
|
// how? on add, check that every inner shape has reference in konva store with color
|
||||||
|
// on remove - clear that reference
|
||||||
function _fillFunc(context) {
|
function _fillFunc(context) {
|
||||||
context.fill();
|
context.fill();
|
||||||
}
|
}
|
||||||
@ -8489,8 +8517,11 @@
|
|||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
* circle.to({
|
* circle.to({
|
||||||
* x : 50,
|
* x : 50,
|
||||||
* duration : 0.5
|
* duration : 0.5,
|
||||||
|
* onFinish: () => {
|
||||||
|
* console.log('finished');
|
||||||
|
* }
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
Node.prototype.to = function (params) {
|
Node.prototype.to = function (params) {
|
||||||
@ -12584,6 +12615,7 @@
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
// TODO: add docs, use overloaded setter/getter
|
||||||
Transformer.prototype.getNode = function () {
|
Transformer.prototype.getNode = function () {
|
||||||
return this._node;
|
return this._node;
|
||||||
};
|
};
|
||||||
|
17
src/Node.ts
17
src/Node.ts
@ -1242,6 +1242,8 @@ export abstract class Node {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// TODO: validate z index
|
||||||
|
// it should be >= 0 and < length
|
||||||
setZIndex(zIndex) {
|
setZIndex(zIndex) {
|
||||||
if (!this.parent) {
|
if (!this.parent) {
|
||||||
Util.warn('Node has no parent. zIndex parameter is ignored.');
|
Util.warn('Node has no parent. zIndex parameter is ignored.');
|
||||||
@ -1701,7 +1703,10 @@ export abstract class Node {
|
|||||||
* @param {Number} [config.y] y position of canvas section
|
* @param {Number} [config.y] y position of canvas section
|
||||||
* @param {Number} [config.width] width of canvas section
|
* @param {Number} [config.width] width of canvas section
|
||||||
* @param {Number} [config.height] height of canvas section
|
* @param {Number} [config.height] height of canvas section
|
||||||
* @paremt {Number} [config.pixelRatio] pixelRatio of ouput image. Default is 1.
|
* @param {Number} [config.pixelRatio] pixelRatio of output canvas. Default is 1.
|
||||||
|
* You can use that property to increase quality of the image, for example for super hight quality exports
|
||||||
|
* or usage on retina (or similar) displays. pixelRatio will be used to multiply the size of exported image.
|
||||||
|
* If you export to 500x500 size with pixelRatio = 2, then produced image will have size 1000x1000.
|
||||||
* @example
|
* @example
|
||||||
* var canvas = node.toCanvas();
|
* var canvas = node.toCanvas();
|
||||||
*/
|
*/
|
||||||
@ -1724,7 +1729,10 @@ export abstract class Node {
|
|||||||
* @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType,
|
* @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType,
|
||||||
* you can specify the quality from 0 to 1, where 0 is very poor quality and 1
|
* you can specify the quality from 0 to 1, where 0 is very poor quality and 1
|
||||||
* is very high quality
|
* is very high quality
|
||||||
* @param {Number} [config.pixelRatio] pixelRatio of output image url. Default is 1
|
* @param {Number} [config.pixelRatio] pixelRatio of output image url. Default is 1.
|
||||||
|
* You can use that property to increase quality of the image, for example for super hight quality exports
|
||||||
|
* or usage on retina (or similar) displays. pixelRatio will be used to multiply the size of exported image.
|
||||||
|
* If you export to 500x500 size with pixelRatio = 2, then produced image will have size 1000x1000.
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
toDataURL(config) {
|
toDataURL(config) {
|
||||||
@ -1754,7 +1762,10 @@ export abstract class Node {
|
|||||||
* @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType,
|
* @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType,
|
||||||
* you can specify the quality from 0 to 1, where 0 is very poor quality and 1
|
* you can specify the quality from 0 to 1, where 0 is very poor quality and 1
|
||||||
* is very high quality
|
* is very high quality
|
||||||
* @paremt {Number} [config.pixelRatio] pixelRatio of ouput image. Default is 1.
|
* @param {Number} [config.pixelRatio] pixelRatio of output image. Default is 1.
|
||||||
|
* You can use that property to increase quality of the image, for example for super hight quality exports
|
||||||
|
* or usage on retina (or similar) displays. pixelRatio will be used to multiply the size of exported image.
|
||||||
|
* If you export to 500x500 size with pixelRatio = 2, then produced image will have size 1000x1000.
|
||||||
* @example
|
* @example
|
||||||
* var image = node.toImage({
|
* var image = node.toImage({
|
||||||
* callback(img) {
|
* callback(img) {
|
||||||
|
@ -10,6 +10,14 @@ var HAS_SHADOW = 'hasShadow';
|
|||||||
var SHADOW_RGBA = 'shadowRGBA';
|
var SHADOW_RGBA = 'shadowRGBA';
|
||||||
|
|
||||||
// TODO: cache gradient from context
|
// TODO: cache gradient from context
|
||||||
|
// TODO: write a test for adding destroyed shape into the layer
|
||||||
|
// will it draw?
|
||||||
|
// will it pass hit test?
|
||||||
|
// show warning on adding destroyed shape?
|
||||||
|
|
||||||
|
// TODO: idea - use only "remove" (or destroy method)
|
||||||
|
// how? on add, check that every inner shape has reference in konva store with color
|
||||||
|
// on remove - clear that reference
|
||||||
|
|
||||||
function _fillFunc(context) {
|
function _fillFunc(context) {
|
||||||
context.fill();
|
context.fill();
|
||||||
|
16
src/Stage.ts
16
src/Stage.ts
@ -345,7 +345,12 @@ export class Stage extends Container {
|
|||||||
}
|
}
|
||||||
_mouseover(evt) {
|
_mouseover(evt) {
|
||||||
this._setPointerPosition(evt);
|
this._setPointerPosition(evt);
|
||||||
|
// TODO: add test on mouseover
|
||||||
|
// I guess it should fire on:
|
||||||
|
// 1. mouseenter
|
||||||
|
// 2. leave or enter any shape
|
||||||
this._fire(CONTENT_MOUSEOVER, { evt: evt });
|
this._fire(CONTENT_MOUSEOVER, { evt: evt });
|
||||||
|
this._fire(MOUSEOVER, { evt: evt, target: this, currentTarget: this });
|
||||||
}
|
}
|
||||||
_mouseout(evt) {
|
_mouseout(evt) {
|
||||||
this._setPointerPosition(evt);
|
this._setPointerPosition(evt);
|
||||||
@ -371,10 +376,8 @@ export class Stage extends Container {
|
|||||||
if (!getGlobalKonva().isDragging()) {
|
if (!getGlobalKonva().isDragging()) {
|
||||||
shape = this.getIntersection(this.getPointerPosition());
|
shape = this.getIntersection(this.getPointerPosition());
|
||||||
if (shape && shape.isListening()) {
|
if (shape && shape.isListening()) {
|
||||||
if (
|
var differentTarget = !this.targetShape || this.targetShape !== shape;
|
||||||
!getGlobalKonva().isDragging() &&
|
if (!getGlobalKonva().isDragging() && differentTarget) {
|
||||||
(!this.targetShape || this.targetShape._id !== shape._id)
|
|
||||||
) {
|
|
||||||
if (this.targetShape) {
|
if (this.targetShape) {
|
||||||
this.targetShape._fireAndBubble(MOUSEOUT, { evt: evt }, shape);
|
this.targetShape._fireAndBubble(MOUSEOUT, { evt: evt }, shape);
|
||||||
this.targetShape._fireAndBubble(MOUSELEAVE, { evt: evt }, shape);
|
this.targetShape._fireAndBubble(MOUSELEAVE, { evt: evt }, shape);
|
||||||
@ -393,6 +396,11 @@ export class Stage extends Container {
|
|||||||
if (this.targetShape && !getGlobalKonva().isDragging()) {
|
if (this.targetShape && !getGlobalKonva().isDragging()) {
|
||||||
this.targetShape._fireAndBubble(MOUSEOUT, { evt: evt });
|
this.targetShape._fireAndBubble(MOUSEOUT, { evt: evt });
|
||||||
this.targetShape._fireAndBubble(MOUSELEAVE, { evt: evt });
|
this.targetShape._fireAndBubble(MOUSELEAVE, { evt: evt });
|
||||||
|
this._fire(MOUSEOVER, {
|
||||||
|
evt: evt,
|
||||||
|
target: this,
|
||||||
|
currentTarget: this
|
||||||
|
});
|
||||||
this.targetShape = null;
|
this.targetShape = null;
|
||||||
}
|
}
|
||||||
this._fire(MOUSEMOVE, {
|
this._fire(MOUSEMOVE, {
|
||||||
|
@ -525,8 +525,11 @@ export class Tween {
|
|||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
* circle.to({
|
* circle.to({
|
||||||
* x : 50,
|
* x : 50,
|
||||||
* duration : 0.5
|
* duration : 0.5,
|
||||||
|
* onFinish: () => {
|
||||||
|
* console.log('finished');
|
||||||
|
* }
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
Node.prototype.to = function(params) {
|
Node.prototype.to = function(params) {
|
||||||
|
@ -223,6 +223,7 @@ export class Transformer extends Group {
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
// TODO: add docs, use overloaded setter/getter
|
||||||
getNode() {
|
getNode() {
|
||||||
return this._node;
|
return this._node;
|
||||||
}
|
}
|
||||||
|
@ -1092,6 +1092,67 @@ suite('Stage', function() {
|
|||||||
assert.equal(dblicks, 1, 'first dbclick registered');
|
assert.equal(dblicks, 1, 'first dbclick registered');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.only('test mouseover event on stage', function() {
|
||||||
|
var stage = addStage();
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
stage.add(layer);
|
||||||
|
var rect = new Konva.Rect({
|
||||||
|
x: 50,
|
||||||
|
y: 50,
|
||||||
|
width: stage.width(),
|
||||||
|
height: stage.height(),
|
||||||
|
fill: 'red'
|
||||||
|
});
|
||||||
|
layer.add(rect);
|
||||||
|
layer.draw();
|
||||||
|
|
||||||
|
var mouseover = 0;
|
||||||
|
|
||||||
|
stage.on('mouseover', function(e) {
|
||||||
|
mouseover += 1;
|
||||||
|
|
||||||
|
if (mouseover === 1) {
|
||||||
|
assert.equal(e.target, stage);
|
||||||
|
assert.equal(e.currentTarget, stage);
|
||||||
|
}
|
||||||
|
if (mouseover === 2) {
|
||||||
|
assert.equal(e.target, rect);
|
||||||
|
assert.equal(e.currentTarget, stage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
stage._mouseover({
|
||||||
|
clientX: 0,
|
||||||
|
clientY: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(mouseover, 1, 'initial over');
|
||||||
|
stage.simulateMouseMove({
|
||||||
|
x: 10,
|
||||||
|
y: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(mouseover, 1, 'moved inside stage - no new over events');
|
||||||
|
|
||||||
|
stage.simulateMouseMove({
|
||||||
|
x: 60,
|
||||||
|
y: 60
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(mouseover, 2, 'moved into inner shape, trigger new mouseover');
|
||||||
|
|
||||||
|
stage.simulateMouseMove({
|
||||||
|
x: 10,
|
||||||
|
y: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
mouseover,
|
||||||
|
3,
|
||||||
|
'moved out of inner shape, trigger new mouseover'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('toCanvas in sync way', function() {
|
test('toCanvas in sync way', function() {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
var layer = new Konva.Layer();
|
var layer = new Konva.Layer();
|
||||||
|
Loading…
Reference in New Issue
Block a user