Merge branch 'master' into fix-unscalable-strokes

This commit is contained in:
MaxGraey 2018-03-17 12:03:47 +02:00
commit d34865ff3a
12 changed files with 353 additions and 76 deletions

View File

@ -5,6 +5,20 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [new version][unreleased] ## [new version][unreleased]
### Added
* Typescript defs for `Konva.Transformer`
## Changes
* Fixed flow for `contextmenu` event. Not it will be triggered on shapes too
## [2.0.2][2018-03-15]
## Fixed
* Even more bugs fixes for `Konva.Transformer`
## [2.0.1][2018-03-15] ## [2.0.1][2018-03-15]
## Fixed ## Fixed

View File

@ -23,7 +23,7 @@ This repository began as a GitHub fork of [ericdrowell/KineticJS](https://github
# Quick Look # Quick Look
```html ```html
<script src="https://cdn.rawgit.com/konvajs/konva/2.0.1/konva.min.js"></script> <script src="https://cdn.rawgit.com/konvajs/konva/2.0.2/konva.min.js"></script>
<div id="container"></div> <div id="container"></div>
<script> <script>
var stage = new Konva.Stage({ var stage = new Konva.Stage({

25
konva.d.ts vendored
View File

@ -287,6 +287,10 @@ declare namespace Konva {
interface ContainerConfig extends NodeConfig { interface ContainerConfig extends NodeConfig {
clearBeforeDraw?: boolean; clearBeforeDraw?: boolean;
clipFunc?: (ctx: CanvasRenderingContext2D) => void; clipFunc?: (ctx: CanvasRenderingContext2D) => void;
clipX?: number;
clipY?: number;
clipWidth?: number;
clipHeight?: number;
} }
class Container extends Node { class Container extends Node {
@ -994,6 +998,27 @@ declare namespace Konva {
translate(x: number, y: Number): Transform; translate(x: number, y: Number): Transform;
} }
interface TransformerConfig extends ContainerConfig {
resizeEnabled?: boolean;
rotateEnabled?: boolean;
rotationSnaps?: Array<number>;
rotateHandlerOffset?: number;
lineEnabled?: number;
keepRatio?: boolean;
enabledHandlers?: Array<string>;
node?: Rect;
}
class Transformer extends Container {
constructor(config?: TransformerConfig);
attachTo(node: Node): void;
setNode(node: Node): void;
getNode(): Node;
detach(): void;
forceUpdate(): void;
update(): void;
}
interface Vector2d { interface Vector2d {
x: number; x: number;
y: number; y: number;

114
konva.js
View File

@ -1,8 +1,8 @@
/* /*
* Konva JavaScript Framework v2.0.1 * Konva JavaScript Framework v2.0.2
* http://konvajs.github.io/ * http://konvajs.github.io/
* Licensed under the MIT * Licensed under the MIT
* Date: Thu Mar 15 2018 * Date: Fri Mar 16 2018
* *
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS) * Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva) * Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
@ -21,7 +21,7 @@
var Konva = { var Konva = {
// public // public
version: '2.0.1', version: '2.0.2',
// private // private
stages: [], stages: [],
@ -2771,11 +2771,11 @@
}, },
/** /**
* bind events to the node. KonvaJS supports mouseover, mousemove, * bind events to the node. KonvaJS supports mouseover, mousemove,
* mouseout, mouseenter, mouseleave, mousedown, mouseup, wheel, click, dblclick, touchstart, touchmove, * mouseout, mouseenter, mouseleave, mousedown, mouseup, wheel, contextmenu, click, dblclick, touchstart, touchmove,
* touchend, tap, dbltap, dragstart, dragmove, and dragend events. The Konva Stage supports * touchend, tap, dbltap, dragstart, dragmove, and dragend events. The Konva Stage supports
* contentMouseover, contentMousemove, contentMouseout, contentMousedown, contentMouseup, contentWheel, contentContextmenu * contentMouseover, contentMousemove, contentMouseout, contentMousedown, contentMouseup, contentWheel, contentContextmenu
* contentClick, contentDblclick, contentTouchstart, contentTouchmove, contentTouchend, contentTap, * contentClick, contentDblclick, contentTouchstart, contentTouchmove, contentTouchend, contentTap,
* and contentDblTap. Pass in a string of events delimmited by a space to bind multiple events at once * and contentDblTap. Pass in a string of events delimited by a space to bind multiple events at once
* such as 'mousedown mouseup mousemove'. Include a namespace to bind an * such as 'mousedown mouseup mousemove'. Include a namespace to bind an
* event by name such as 'click.foobar'. * event by name such as 'click.foobar'.
* @method * @method
@ -10616,6 +10616,18 @@
} }
}, },
_contextmenu: function(evt) { _contextmenu: function(evt) {
this._setPointerPosition(evt);
var shape = this.getIntersection(this.getPointerPosition());
if (shape && shape.isListening()) {
shape._fireAndBubble(CONTEXTMENU, { evt: evt });
} else {
this._fire(CONTEXTMENU, {
evt: evt,
target: this,
currentTarget: this
});
}
this._fire(CONTENT_CONTEXTMENU, { evt: evt }); this._fire(CONTENT_CONTEXTMENU, { evt: evt });
}, },
_touchstart: function(evt) { _touchstart: function(evt) {
@ -18581,6 +18593,7 @@
* @param {Boolean} [config.rotateEnabled] Default is true * @param {Boolean} [config.rotateEnabled] Default is true
* @param {Array} [config.rotationSnaps] Array of angles for rotation snaps. Default is [] * @param {Array} [config.rotationSnaps] Array of angles for rotation snaps. Default is []
* @param {Number} [config.rotateHandlerOffset] Default is 50 * @param {Number} [config.rotateHandlerOffset] Default is 50
* @param {Number} [config.padding] Default is 0
* @param {Number} [config.lineEnabled] Should we draw border? Default is true * @param {Number} [config.lineEnabled] Should we draw border? Default is true
* @param {Boolean} [config.keepRatio] Should we keep ratio when we are moving edges? Default is true * @param {Boolean} [config.keepRatio] Should we keep ratio when we are moving edges? Default is true
* @param {Array} [config.enabledHandlers] Array of names of enabled handles * @param {Array} [config.enabledHandlers] Array of names of enabled handles
@ -18683,7 +18696,7 @@
}.bind(this) }.bind(this)
); );
node.on(TRANSFORM_CHANGE_STR, this.requestUpdate.bind(this)); node.on(TRANSFORM_CHANGE_STR, this.requestUpdate.bind(this));
node.on('dragmove.resizer', this.requestUpdate); node.on('dragmove.resizer', this.requestUpdate.bind(this));
var elementsCreated = !!this.findOne('.top-left'); var elementsCreated = !!this.findOne('.top-left');
if (elementsCreated) { if (elementsCreated) {
@ -18810,14 +18823,18 @@
height: 0, height: 0,
listening: false, listening: false,
sceneFunc: function(ctx) { sceneFunc: function(ctx) {
var tr = this.getParent();
var padding = tr.getPadding();
ctx.beginPath(); ctx.beginPath();
ctx.rect(0, 0, this.width(), this.height()); ctx.rect(
ctx.moveTo(this.width() / 2, 0); -padding,
if (this.getParent().rotateEnabled()) { -padding,
ctx.lineTo( this.width() + padding * 2,
this.width() / 2, this.height() + padding * 2
-this.getParent().rotateHandlerOffset()
); );
ctx.moveTo(this.width() / 2, -padding);
if (tr.rotateEnabled()) {
ctx.lineTo(this.width() / 2, -tr.rotateHandlerOffset());
} }
ctx.fillStrokeShape(this); ctx.fillStrokeShape(this);
@ -18941,6 +18958,7 @@
this.findOne('.bottom-right').y(y); this.findOne('.bottom-right').y(y);
} }
} else if (this.movingResizer === 'rotater') { } else if (this.movingResizer === 'rotater') {
var padding = this.getPadding();
var attrs = this._getNodeRect(); var attrs = this._getNodeRect();
x = resizerNode.x() - attrs.width / 2; x = resizerNode.x() - attrs.width / 2;
y = -resizerNode.y() + attrs.height / 2; y = -resizerNode.y() + attrs.height / 2;
@ -18970,6 +18988,9 @@
} }
} }
var dx = padding;
var dy = padding;
this._fitNodeInto( this._fitNodeInto(
Object.assign(attrs, { Object.assign(attrs, {
rotation: Konva.angleDeg rotation: Konva.angleDeg
@ -18977,14 +18998,20 @@
: Konva.Util._degToRad(newRotation), : Konva.Util._degToRad(newRotation),
x: x:
attrs.x + attrs.x +
attrs.width / 2 * (Math.cos(alpha) - Math.cos(newAlpha)) + (attrs.width / 2 + padding) *
attrs.height / 2 * (Math.sin(-alpha) - Math.sin(-newAlpha)), (Math.cos(alpha) - Math.cos(newAlpha)) +
(attrs.height / 2 + padding) *
(Math.sin(-alpha) - Math.sin(-newAlpha)) -
(dx * Math.cos(rot) + dy * Math.sin(-rot)),
y: y:
attrs.y + attrs.y +
attrs.height / 2 * (Math.cos(alpha) - Math.cos(newAlpha)) + (attrs.height / 2 + padding) *
attrs.width / 2 * (Math.sin(alpha) - Math.sin(newAlpha)), (Math.cos(alpha) - Math.cos(newAlpha)) +
width: attrs.width, (attrs.width / 2 + padding) *
height: attrs.height (Math.sin(alpha) - Math.sin(newAlpha)) -
(dy * Math.cos(rot) + dx * Math.sin(rot)),
width: attrs.width + padding * 2,
height: attrs.height + padding * 2
}) })
); );
} else { } else {
@ -19037,19 +19064,21 @@
}, },
_fitNodeInto: function(attrs) { _fitNodeInto: function(attrs) {
// waring! in this attrs padding may be included
this._settings = true; this._settings = true;
var node = this.getNode(); var node = this.getNode();
if (attrs.rotation !== undefined) { if (attrs.rotation !== undefined) {
this.getNode().rotation(attrs.rotation); this.getNode().rotation(attrs.rotation);
} }
var pure = node.getClientRect({ skipTransform: true }); var pure = node.getClientRect({ skipTransform: true });
var scaleX = attrs.width / pure.width; var padding = this.getPadding();
var scaleY = attrs.height / pure.height; var scaleX = (attrs.width - padding * 2) / pure.width;
var scaleY = (attrs.height - padding * 2) / pure.height;
var rotation = Konva.getAngle(node.getRotation()); var rotation = Konva.getAngle(node.getRotation());
// debugger; // debugger;
var dx = pure.x * scaleX; var dx = pure.x * scaleX - padding;
var dy = pure.y * scaleY; var dy = pure.y * scaleY - padding;
// var dxo = node.offsetX() * scaleX; // var dxo = node.offsetX() * scaleX;
// var dyo = node.offsetY() * scaleY; // var dyo = node.offsetY() * scaleY;
@ -19101,45 +19130,46 @@
var enabledHandlers = this.enabledHandlers(); var enabledHandlers = this.enabledHandlers();
var resizeEnabled = this.resizeEnabled(); var resizeEnabled = this.resizeEnabled();
var padding = this.getPadding();
this.findOne('.top-left').setAttrs({ this.findOne('.top-left').setAttrs({
x: 0, x: -padding,
y: 0, y: -padding,
visible: resizeEnabled && enabledHandlers.indexOf('top-left') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('top-left') >= 0
}); });
this.findOne('.top-center').setAttrs({ this.findOne('.top-center').setAttrs({
x: width / 2, x: width / 2,
y: 0, y: -padding,
visible: resizeEnabled && enabledHandlers.indexOf('top-center') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('top-center') >= 0
}); });
this.findOne('.top-right').setAttrs({ this.findOne('.top-right').setAttrs({
x: width, x: width + padding,
y: 0, y: -padding,
visible: resizeEnabled && enabledHandlers.indexOf('top-right') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('top-right') >= 0
}); });
this.findOne('.middle-left').setAttrs({ this.findOne('.middle-left').setAttrs({
x: 0, x: -padding,
y: height / 2, y: height / 2,
visible: resizeEnabled && enabledHandlers.indexOf('middle-left') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('middle-left') >= 0
}); });
this.findOne('.middle-right').setAttrs({ this.findOne('.middle-right').setAttrs({
x: width, x: width + padding,
y: height / 2, y: height / 2,
visible: resizeEnabled && enabledHandlers.indexOf('middle-right') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('middle-right') >= 0
}); });
this.findOne('.bottom-left').setAttrs({ this.findOne('.bottom-left').setAttrs({
x: 0, x: -padding,
y: height, y: height + padding,
visible: resizeEnabled && enabledHandlers.indexOf('bottom-left') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('bottom-left') >= 0
}); });
this.findOne('.bottom-center').setAttrs({ this.findOne('.bottom-center').setAttrs({
x: width / 2, x: width / 2,
y: height, y: height + padding,
visible: resizeEnabled && enabledHandlers.indexOf('bottom-center') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('bottom-center') >= 0
}); });
this.findOne('.bottom-right').setAttrs({ this.findOne('.bottom-right').setAttrs({
x: width, x: width + padding,
y: height, y: height + padding,
visible: resizeEnabled && enabledHandlers.indexOf('bottom-right') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('bottom-right') >= 0
}); });
@ -19304,6 +19334,22 @@
*/ */
Konva.Factory.addGetterSetter(Konva.Transformer, 'keepRatio', true); Konva.Factory.addGetterSetter(Konva.Transformer, 'keepRatio', true);
/**
* get/set padding
* @name padding
* @method
* @memberof Konva.Transformer.prototype
* @param {Array} array
* @returns {Array}
* @example
* // get
* var padding = shape.padding();
*
* // set
* shape.padding(10);
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'padding', 0);
Konva.Factory.addOverloadedGetterSetter(Konva.Transformer, 'node'); Konva.Factory.addOverloadedGetterSetter(Konva.Transformer, 'node');
Konva.Collection.mapMethods(Konva.Transformer); Konva.Collection.mapMethods(Konva.Transformer);

10
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{ {
"name": "konva", "name": "konva",
"version": "2.0.1", "version": "2.0.2",
"author": "Anton Lavrenov", "author": "Anton Lavrenov",
"files": [ "files": [
"README.md", "README.md",

View File

@ -412,11 +412,11 @@
}, },
/** /**
* bind events to the node. KonvaJS supports mouseover, mousemove, * bind events to the node. KonvaJS supports mouseover, mousemove,
* mouseout, mouseenter, mouseleave, mousedown, mouseup, wheel, click, dblclick, touchstart, touchmove, * mouseout, mouseenter, mouseleave, mousedown, mouseup, wheel, contextmenu, click, dblclick, touchstart, touchmove,
* touchend, tap, dbltap, dragstart, dragmove, and dragend events. The Konva Stage supports * touchend, tap, dbltap, dragstart, dragmove, and dragend events. The Konva Stage supports
* contentMouseover, contentMousemove, contentMouseout, contentMousedown, contentMouseup, contentWheel, contentContextmenu * contentMouseover, contentMousemove, contentMouseout, contentMousedown, contentMouseup, contentWheel, contentContextmenu
* contentClick, contentDblclick, contentTouchstart, contentTouchmove, contentTouchend, contentTap, * contentClick, contentDblclick, contentTouchstart, contentTouchmove, contentTouchend, contentTap,
* and contentDblTap. Pass in a string of events delimmited by a space to bind multiple events at once * and contentDblTap. Pass in a string of events delimited by a space to bind multiple events at once
* such as 'mousedown mouseup mousemove'. Include a namespace to bind an * such as 'mousedown mouseup mousemove'. Include a namespace to bind an
* event by name such as 'click.foobar'. * event by name such as 'click.foobar'.
* @method * @method

View File

@ -612,6 +612,18 @@
} }
}, },
_contextmenu: function(evt) { _contextmenu: function(evt) {
this._setPointerPosition(evt);
var shape = this.getIntersection(this.getPointerPosition());
if (shape && shape.isListening()) {
shape._fireAndBubble(CONTEXTMENU, { evt: evt });
} else {
this._fire(CONTEXTMENU, {
evt: evt,
target: this,
currentTarget: this
});
}
this._fire(CONTENT_CONTEXTMENU, { evt: evt }); this._fire(CONTENT_CONTEXTMENU, { evt: evt });
}, },
_touchstart: function(evt) { _touchstart: function(evt) {

View File

@ -88,6 +88,7 @@
* @param {Boolean} [config.rotateEnabled] Default is true * @param {Boolean} [config.rotateEnabled] Default is true
* @param {Array} [config.rotationSnaps] Array of angles for rotation snaps. Default is [] * @param {Array} [config.rotationSnaps] Array of angles for rotation snaps. Default is []
* @param {Number} [config.rotateHandlerOffset] Default is 50 * @param {Number} [config.rotateHandlerOffset] Default is 50
* @param {Number} [config.padding] Default is 0
* @param {Number} [config.lineEnabled] Should we draw border? Default is true * @param {Number} [config.lineEnabled] Should we draw border? Default is true
* @param {Boolean} [config.keepRatio] Should we keep ratio when we are moving edges? Default is true * @param {Boolean} [config.keepRatio] Should we keep ratio when we are moving edges? Default is true
* @param {Array} [config.enabledHandlers] Array of names of enabled handles * @param {Array} [config.enabledHandlers] Array of names of enabled handles
@ -165,7 +166,7 @@
}.bind(this) }.bind(this)
); );
node.on(TRANSFORM_CHANGE_STR, this.requestUpdate.bind(this)); node.on(TRANSFORM_CHANGE_STR, this.requestUpdate.bind(this));
node.on('dragmove.resizer', this.requestUpdate); node.on('dragmove.resizer', this.requestUpdate.bind(this));
var elementsCreated = !!this.findOne('.top-left'); var elementsCreated = !!this.findOne('.top-left');
if (elementsCreated) { if (elementsCreated) {
@ -292,14 +293,18 @@
height: 0, height: 0,
listening: false, listening: false,
sceneFunc: function(ctx) { sceneFunc: function(ctx) {
var tr = this.getParent();
var padding = tr.getPadding();
ctx.beginPath(); ctx.beginPath();
ctx.rect(0, 0, this.width(), this.height()); ctx.rect(
ctx.moveTo(this.width() / 2, 0); -padding,
if (this.getParent().rotateEnabled()) { -padding,
ctx.lineTo( this.width() + padding * 2,
this.width() / 2, this.height() + padding * 2
-this.getParent().rotateHandlerOffset()
); );
ctx.moveTo(this.width() / 2, -padding);
if (tr.rotateEnabled()) {
ctx.lineTo(this.width() / 2, -tr.rotateHandlerOffset());
} }
ctx.fillStrokeShape(this); ctx.fillStrokeShape(this);
@ -423,6 +428,7 @@
this.findOne('.bottom-right').y(y); this.findOne('.bottom-right').y(y);
} }
} else if (this.movingResizer === 'rotater') { } else if (this.movingResizer === 'rotater') {
var padding = this.getPadding();
var attrs = this._getNodeRect(); var attrs = this._getNodeRect();
x = resizerNode.x() - attrs.width / 2; x = resizerNode.x() - attrs.width / 2;
y = -resizerNode.y() + attrs.height / 2; y = -resizerNode.y() + attrs.height / 2;
@ -452,6 +458,9 @@
} }
} }
var dx = padding;
var dy = padding;
this._fitNodeInto( this._fitNodeInto(
Object.assign(attrs, { Object.assign(attrs, {
rotation: Konva.angleDeg rotation: Konva.angleDeg
@ -459,14 +468,20 @@
: Konva.Util._degToRad(newRotation), : Konva.Util._degToRad(newRotation),
x: x:
attrs.x + attrs.x +
attrs.width / 2 * (Math.cos(alpha) - Math.cos(newAlpha)) + (attrs.width / 2 + padding) *
attrs.height / 2 * (Math.sin(-alpha) - Math.sin(-newAlpha)), (Math.cos(alpha) - Math.cos(newAlpha)) +
(attrs.height / 2 + padding) *
(Math.sin(-alpha) - Math.sin(-newAlpha)) -
(dx * Math.cos(rot) + dy * Math.sin(-rot)),
y: y:
attrs.y + attrs.y +
attrs.height / 2 * (Math.cos(alpha) - Math.cos(newAlpha)) + (attrs.height / 2 + padding) *
attrs.width / 2 * (Math.sin(alpha) - Math.sin(newAlpha)), (Math.cos(alpha) - Math.cos(newAlpha)) +
width: attrs.width, (attrs.width / 2 + padding) *
height: attrs.height (Math.sin(alpha) - Math.sin(newAlpha)) -
(dy * Math.cos(rot) + dx * Math.sin(rot)),
width: attrs.width + padding * 2,
height: attrs.height + padding * 2
}) })
); );
} else { } else {
@ -519,19 +534,21 @@
}, },
_fitNodeInto: function(attrs) { _fitNodeInto: function(attrs) {
// waring! in this attrs padding may be included
this._settings = true; this._settings = true;
var node = this.getNode(); var node = this.getNode();
if (attrs.rotation !== undefined) { if (attrs.rotation !== undefined) {
this.getNode().rotation(attrs.rotation); this.getNode().rotation(attrs.rotation);
} }
var pure = node.getClientRect({ skipTransform: true }); var pure = node.getClientRect({ skipTransform: true });
var scaleX = attrs.width / pure.width; var padding = this.getPadding();
var scaleY = attrs.height / pure.height; var scaleX = (attrs.width - padding * 2) / pure.width;
var scaleY = (attrs.height - padding * 2) / pure.height;
var rotation = Konva.getAngle(node.getRotation()); var rotation = Konva.getAngle(node.getRotation());
// debugger; // debugger;
var dx = pure.x * scaleX; var dx = pure.x * scaleX - padding;
var dy = pure.y * scaleY; var dy = pure.y * scaleY - padding;
// var dxo = node.offsetX() * scaleX; // var dxo = node.offsetX() * scaleX;
// var dyo = node.offsetY() * scaleY; // var dyo = node.offsetY() * scaleY;
@ -583,45 +600,46 @@
var enabledHandlers = this.enabledHandlers(); var enabledHandlers = this.enabledHandlers();
var resizeEnabled = this.resizeEnabled(); var resizeEnabled = this.resizeEnabled();
var padding = this.getPadding();
this.findOne('.top-left').setAttrs({ this.findOne('.top-left').setAttrs({
x: 0, x: -padding,
y: 0, y: -padding,
visible: resizeEnabled && enabledHandlers.indexOf('top-left') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('top-left') >= 0
}); });
this.findOne('.top-center').setAttrs({ this.findOne('.top-center').setAttrs({
x: width / 2, x: width / 2,
y: 0, y: -padding,
visible: resizeEnabled && enabledHandlers.indexOf('top-center') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('top-center') >= 0
}); });
this.findOne('.top-right').setAttrs({ this.findOne('.top-right').setAttrs({
x: width, x: width + padding,
y: 0, y: -padding,
visible: resizeEnabled && enabledHandlers.indexOf('top-right') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('top-right') >= 0
}); });
this.findOne('.middle-left').setAttrs({ this.findOne('.middle-left').setAttrs({
x: 0, x: -padding,
y: height / 2, y: height / 2,
visible: resizeEnabled && enabledHandlers.indexOf('middle-left') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('middle-left') >= 0
}); });
this.findOne('.middle-right').setAttrs({ this.findOne('.middle-right').setAttrs({
x: width, x: width + padding,
y: height / 2, y: height / 2,
visible: resizeEnabled && enabledHandlers.indexOf('middle-right') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('middle-right') >= 0
}); });
this.findOne('.bottom-left').setAttrs({ this.findOne('.bottom-left').setAttrs({
x: 0, x: -padding,
y: height, y: height + padding,
visible: resizeEnabled && enabledHandlers.indexOf('bottom-left') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('bottom-left') >= 0
}); });
this.findOne('.bottom-center').setAttrs({ this.findOne('.bottom-center').setAttrs({
x: width / 2, x: width / 2,
y: height, y: height + padding,
visible: resizeEnabled && enabledHandlers.indexOf('bottom-center') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('bottom-center') >= 0
}); });
this.findOne('.bottom-right').setAttrs({ this.findOne('.bottom-right').setAttrs({
x: width, x: width + padding,
y: height, y: height + padding,
visible: resizeEnabled && enabledHandlers.indexOf('bottom-right') >= 0 visible: resizeEnabled && enabledHandlers.indexOf('bottom-right') >= 0
}); });
@ -786,6 +804,22 @@
*/ */
Konva.Factory.addGetterSetter(Konva.Transformer, 'keepRatio', true); Konva.Factory.addGetterSetter(Konva.Transformer, 'keepRatio', true);
/**
* get/set padding
* @name padding
* @method
* @memberof Konva.Transformer.prototype
* @param {Array} array
* @returns {Array}
* @example
* // get
* var padding = shape.padding();
*
* // set
* shape.padding(10);
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'padding', 0);
Konva.Factory.addOverloadedGetterSetter(Konva.Transformer, 'node'); Konva.Factory.addOverloadedGetterSetter(Konva.Transformer, 'node');
Konva.Collection.mapMethods(Konva.Transformer); Konva.Collection.mapMethods(Konva.Transformer);

View File

@ -999,7 +999,7 @@ suite('Shape', function() {
); );
}); });
test('class inherince', function() { test('class inherence', function() {
var rect = new Konva.Rect(); var rect = new Konva.Rect();
assert.equal(rect instanceof Konva.Rect, true); assert.equal(rect instanceof Konva.Rect, true);
assert.equal(rect instanceof Konva.Shape, true); assert.equal(rect instanceof Konva.Shape, true);

View File

@ -902,6 +902,78 @@ suite('Stage', function() {
assert.equal(dbltaps, 1, 'dbltap registered'); assert.equal(dbltaps, 1, 'dbltap registered');
}); });
test('pass context and wheel events to shape', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 50,
width: 100,
height: 100,
fill: 'red'
});
layer.add(rect);
layer.draw();
var contextmenus = 0;
var wheels = 0;
// test on empty
stage.on('contextmenu', function(e) {
contextmenus += 1;
assert.equal(e.target, stage);
assert.equal(e.currentTarget, stage);
});
stage.on('wheel', function(e) {
wheels += 1;
assert.equal(e.target, stage);
assert.equal(e.currentTarget, stage);
});
var top = stage.content.getBoundingClientRect().top;
stage._contextmenu({
clientX: 0,
clientY: top + 0
});
stage._wheel({
clientX: 0,
clientY: top + 0
});
assert.equal(contextmenus, 1, 'first contextment registered');
assert.equal(wheels, 1, 'first wheel registered');
stage.off('contextmenu');
stage.off('wheel');
// test on shape
stage.on('contextmenu', function(e) {
contextmenus += 1;
assert.equal(e.target, rect);
assert.equal(e.currentTarget, stage);
});
stage.on('wheel', function(e) {
wheels += 1;
assert.equal(e.target, rect);
assert.equal(e.currentTarget, stage);
});
stage._contextmenu({
clientX: 60,
clientY: top + 60
});
stage._wheel({
clientX: 60,
clientY: top + 60
});
assert.equal(contextmenus, 2, 'second contextment registered');
assert.equal(wheels, 2, 'second wheel registered');
});
test('make sure it does not trigger too many events', function() { test('make sure it does not trigger too many events', function() {
var stage = addStage(); var stage = addStage();
var layer = new Konva.Layer(); var layer = new Konva.Layer();
@ -1027,7 +1099,7 @@ suite('Stage', function() {
assert.equal(stage.toDataURL(), layer.toDataURL()); assert.equal(stage.toDataURL(), layer.toDataURL());
}); });
test('check hit graph with stage listeting property', function() { test('check hit graph with stage listening property', function() {
var stage = addStage(); var stage = addStage();
var layer = new Konva.Layer(); var layer = new Konva.Layer();
stage.add(layer); stage.add(layer);

View File

@ -672,4 +672,78 @@ suite('Transformer', function() {
var tr = new Konva.Transformer(); var tr = new Konva.Transformer();
tr.destroy(); tr.destroy();
}); });
test('can add padding', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect,
padding: 10
});
layer.add(tr);
tr._fitNodeInto({
x: 0,
y: 0,
width: 120,
height: 120
});
layer.draw();
assert.equal(rect.x(), 10);
assert.equal(rect.y(), 10);
assert.equal(rect.width(), 100);
assert.equal(rect.height(), 100);
});
test('can add padding with rotation', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect,
padding: 10
});
layer.add(tr);
tr._fitNodeInto({
x: 120,
y: 0,
width: 120,
height: 120,
rotation: 90
});
layer.draw();
assert.equal(rect.x(), 110);
assert.equal(rect.y(), 10);
assert.equal(rect.width(), 100);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 90);
});
}); });