From 55c812425d428e37abba36df2bc76656def7f071 Mon Sep 17 00:00:00 2001 From: Anton Lavrenov Date: Mon, 6 Apr 2020 21:51:03 -0500 Subject: [PATCH] some transformer fixes --- konva.js | 1543 +++----------------------- src/BaseLayer.ts | 4 +- src/shapes/Transformer.ts | 257 ++++- test/unit/shapes/Transformer-test.js | 668 +++++++++-- 4 files changed, 932 insertions(+), 1540 deletions(-) diff --git a/konva.js b/konva.js index d902e034..4ce7ffd2 100644 --- a/konva.js +++ b/konva.js @@ -5,10 +5,10 @@ }(this, (function () { 'use strict'; /* - * Konva JavaScript Framework v4.2.2 + * Konva JavaScript Framework v@@version * http://konvajs.org/ * Licensed under the MIT - * Date: Thu Apr 02 2020 + * Date: @@date * * Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS) * Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva) @@ -76,7 +76,7 @@ : {}; var Konva = { _global: glob, - version: '4.2.2', + version: '@@version', isBrowser: detectBrowser(), isUnminified: /param/.test(function (param) { }.toString()), dblClickWindow: 400, @@ -2597,26 +2597,7 @@ * @constructor * @memberof Konva * @param {Object} config - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@nodeParams */ var Node = /** @class */ (function () { function Node(config) { @@ -5159,33 +5140,8 @@ * @augments Konva.Node * @abstract * @param {Object} config - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] - * * @param {Object} [config.clip] set clip - * @param {Number} [config.clipX] set clip x - * @param {Number} [config.clipY] set clip y - * @param {Number} [config.clipWidth] set clip width - * @param {Number} [config.clipHeight] set clip height - * @param {Function} [config.clipFunc] set clip func - + * @@nodeParams + * @@containerParams */ var Container = /** @class */ (function (_super) { __extends(Container, _super); @@ -5826,26 +5782,7 @@ * @augments Konva.Container * @param {Object} config * @param {String|Element} config.container Container selector or DOM element - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@nodeParams * @example * var stage = new Konva.Stage({ * width: 500, @@ -6687,33 +6624,8 @@ * @param {Object} config * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want * to clear the canvas before each layer draw. The default value is true. - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] - * * @param {Object} [config.clip] set clip - * @param {Number} [config.clipX] set clip x - * @param {Number} [config.clipY] set clip y - * @param {Number} [config.clipWidth] set clip width - * @param {Number} [config.clipHeight] set clip height - * @param {Function} [config.clipFunc] set clip func - + * @@nodeParams + * @@containerParams */ var BaseLayer = /** @class */ (function (_super) { __extends(BaseLayer, _super); @@ -6890,7 +6802,7 @@ this.getContext()._context.imageSmoothingEnabled = this.imageSmoothingEnabled(); }; /** - * get/set width of layer.getter return width of stage. setter doing nothing. + * get/set width of layer. getter return width of stage. setter doing nothing. * if you want change width use `stage.width(value);` * @name Konva.BaseLayer#width * @method @@ -6965,10 +6877,8 @@ * // get imageSmoothingEnabled flag * var imageSmoothingEnabled = layer.imageSmoothingEnabled(); * - * // disable clear before draw * layer.imageSmoothingEnabled(false); * - * // enable clear before draw * layer.imageSmoothingEnabled(true); */ Factory.addGetterSetter(BaseLayer, 'imageSmoothingEnabled', true); @@ -7045,78 +6955,8 @@ * @memberof Konva * @augments Konva.Node * @param {Object} config - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var customShape = new Konva.Shape({ * x: 5, @@ -8619,33 +8459,8 @@ * @param {Object} config * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want * to clear the canvas before each layer draw. The default value is true. - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] - * * @param {Object} [config.clip] set clip - * @param {Number} [config.clipX] set clip x - * @param {Number} [config.clipY] set clip y - * @param {Number} [config.clipWidth] set clip width - * @param {Number} [config.clipHeight] set clip height - * @param {Function} [config.clipFunc] set clip func - + * @@nodeParams + * @@containerParams * @example * var layer = new Konva.Layer(); * stage.add(layer); @@ -8868,13 +8683,7 @@ * @param {String} [config.id] unique id * @param {String} [config.name] non-unique name * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * * @param {Object} [config.clip] set clip - * @param {Number} [config.clipX] set clip x - * @param {Number} [config.clipY] set clip y - * @param {Number} [config.clipWidth] set clip width - * @param {Number} [config.clipHeight] set clip height - * @param {Function} [config.clipFunc] set clip func - + * @@containerParams * @example * var layer = new Konva.FastLayer(); */ @@ -8920,33 +8729,8 @@ * @memberof Konva * @augments Konva.Container * @param {Object} config - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] - * * @param {Object} [config.clip] set clip - * @param {Number} [config.clipX] set clip x - * @param {Number} [config.clipY] set clip y - * @param {Number} [config.clipWidth] set clip width - * @param {Number} [config.clipHeight] set clip height - * @param {Function} [config.clipFunc] set clip func - + * @@nodeParams + * @@containerParams * @example * var group = new Konva.Group(); */ @@ -9913,78 +9697,8 @@ * @param {Number} config.innerRadius * @param {Number} config.outerRadius * @param {Boolean} [config.clockwise] - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * // draw a Arc that's pointing downwards * var arc = new Konva.Arc({ @@ -10102,78 +9816,8 @@ * The default is 0 * @param {Boolean} [config.closed] defines whether or not the line shape is closed, creating a polygon or blob * @param {Boolean} [config.bezier] if no tension is provided but bezier=true, we draw the line as a bezier using the passed points - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var line = new Konva.Line({ * x: 100, @@ -10396,78 +10040,8 @@ * @param {Number} config.pointerLength Arrow pointer length. Default value is 10. * @param {Number} config.pointerWidth Arrow pointer width. Default value is 10. * @param {Boolean} config.pointerAtBeginning Do we need to draw pointer on both sides?. Default false. - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var line = new Konva.Line({ * points: [73, 70, 340, 23, 450, 60, 500, 20], @@ -10613,78 +10187,8 @@ * @augments Konva.Shape * @param {Object} config * @param {Number} config.radius - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * // create circle * var circle = new Konva.Circle({ @@ -10750,78 +10254,8 @@ * @augments Konva.Shape * @param {Object} config * @param {Object} config.radius defines x and y radius - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var ellipse = new Konva.Ellipse({ * radius : { @@ -10924,78 +10358,8 @@ * @param {Object} config * @param {Image} config.image * @param {Object} [config.crop] - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var imageObj = new Image(); * imageObj.onload = function() { @@ -11208,26 +10572,7 @@ * @constructor * @memberof Konva * @param {Object} config - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@nodeParams * @example * // create label * var label = new Konva.Label({ @@ -11503,78 +10848,8 @@ * @augments Konva.Shape * @param {Object} config * @param {String} config.data SVG data string - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var path = new Konva.Path({ * x: 240, @@ -12320,78 +11595,8 @@ * @augments Konva.Shape * @param {Object} config * @param {Number} [config.cornerRadius] - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var rect = new Konva.Rect({ * width: 100, @@ -12472,78 +11677,8 @@ * @param {Object} config * @param {Number} config.sides * @param {Number} config.radius - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var hexagon = new Konva.RegularPolygon({ * x: 100, @@ -12630,78 +11765,8 @@ * @param {Number} config.innerRadius * @param {Number} config.outerRadius * @param {Boolean} [config.clockwise] - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var ring = new Konva.Ring({ * innerRadius: 40, @@ -12783,78 +11848,8 @@ * @param {Integer} [config.frameIndex] animation frame index * @param {Image} config.image image object * @param {Integer} [config.frameRate] animation frame rate - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var imageObj = new Image(); * imageObj.onload = function() { @@ -13150,78 +12145,8 @@ * @param {Integer} config.numPoints * @param {Number} config.innerRadius * @param {Number} config.outerRadius - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var star = new Konva.Star({ * x: 100, @@ -13377,78 +12302,8 @@ * @param {Number} [config.lineHeight] default is 1 * @param {String} [config.wrap] can be "word", "char", or "none". Default is word * @param {Boolean} [config.ellipsis] can be true or false. Default is false. if Konva.Text config is set to wrap="none" and ellipsis=true, then it will add "..." to the end - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var text = new Konva.Text({ * x: 10, @@ -14038,78 +12893,8 @@ * @param {String} config.data SVG data string * @param {Function} config.getKerning a getter for kerning values for the specified characters * @param {Function} config.kerningFunc a getter for kerning values for the specified characters - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * var kerningPairs = { * 'A': { @@ -14847,7 +13632,10 @@ } function transformShape(shape, oldSelection, newSelection, keepOffset) { if (keepOffset === void 0) { keepOffset = 1; } - var offset = rotateAroundPoint(shape, -oldSelection.rotation, oldSelection); + var offset = rotateAroundPoint(shape, -oldSelection.rotation, { + x: oldSelection.x, + y: oldSelection.y + }); var offsetX = offset.x - oldSelection.x; var offsetY = offset.y - oldSelection.y; var angle = oldSelection.rotation; @@ -14861,12 +13649,13 @@ offsetX * scaleX * Math.sin(angle) + offsetY * scaleY * Math.cos(angle), width: shape.width * scaleX, - height: shape.height * scaleY + height: shape.height * scaleY, + rotation: shape.rotation }; } function transformAndRotateShape(shape, oldSelection, newSelection) { var updated = transformShape(shape, oldSelection, newSelection); - return rotateAroundPoint(__assign(__assign({}, updated), { rotation: shape.rotation }), newSelection.rotation - oldSelection.rotation, newSelection); + return rotateAroundPoint(updated, newSelection.rotation - oldSelection.rotation, newSelection); } /** * Transformer constructor. Transformer is a special type of group that allow you transform Konva @@ -15133,22 +13922,22 @@ strokeWidth: 1, name: name + ' _anchor', dragDistance: 0, - draggable: true, + draggable: false, hitStrokeWidth: TOUCH_DEVICE ? 10 : 'auto' }); var self = this; anchor.on('mousedown touchstart', function (e) { self._handleMouseDown(e); }); - anchor.on('dragstart', function (e) { - e.cancelBubble = true; - }); - anchor.on('dragmove', function (e) { - e.cancelBubble = true; - }); - anchor.on('dragend', function (e) { - e.cancelBubble = true; - }); + // anchor.on('dragstart', function(e) { + // e.cancelBubble = true; + // }); + // anchor.on('dragmove', function(e) { + // e.cancelBubble = true; + // }); + // anchor.on('dragend', function(e) { + // e.cancelBubble = true; + // }); // add hover styling anchor.on('mouseenter', function () { var rad = Konva.getAngle(_this.rotation()); @@ -15233,10 +14022,38 @@ x: pp.x - this._anchorDragOffset.x, y: pp.y - this._anchorDragOffset.y }; + var oldAbs = anchorNode.getAbsolutePosition(); anchorNode.setAbsolutePosition(newNodePos); + var newAbs = anchorNode.getAbsolutePosition(); + if (oldAbs.x === newAbs.x && oldAbs.y === newAbs.y) { + return; + } + var centeredScaling = this.centeredScaling() || e.altKey; + // if (centeredScaling && this._movingAnchorName.indexOf('left') >= 0) { + // var topLeft = this.findOne('.top-left'); + // var bottomRight = this.findOne('.bottom-right'); + // var topOffsetX = topLeft.x() + padding; + // var topOffsetY = topLeft.y() + padding; + // var bottomOffsetX = this.getWidth() - bottomRight.x() + padding; + // var bottomOffsetY = this.getHeight() - bottomRight.y() + padding; + // bottomRight.move({ + // x: -anchorNode.x(), + // y: -anchorNode.y() + // }); + // topLeft.move({ + // x: bottomOffsetX, + // y: bottomOffsetY + // }); + // } var keepProportion = this.keepRatio() || e.shiftKey; var padding = 0; if (this._movingAnchorName === 'top-left') { + // if (centeredScaling) { + // this.findOne('.bottom-right').move({ + // x: -anchorNode.x(), + // y: -anchorNode.y() + // }); + // } if (keepProportion) { newHypotenuse = Math.sqrt(Math.pow(this.findOne('.bottom-right').x() - anchorNode.x() - padding * 2, 2) + Math.pow(this.findOne('.bottom-right').y() - anchorNode.y() - padding * 2, 2)); @@ -15253,9 +14070,18 @@ } } else if (this._movingAnchorName === 'top-center') { + // if (centeredScaling) { + // this.findOne('.bottom-right').move({ + // x: 0, + // y: -anchorNode.y() + // }); + // } this.findOne('.top-left').y(anchorNode.y()); } else if (this._movingAnchorName === 'top-right') { + // var center = getCenter({ + // x + // }) if (keepProportion) { newHypotenuse = Math.sqrt(Math.pow(anchorNode.x() - this.findOne('.bottom-left').x() - padding * 2, 2) + Math.pow(this.findOne('.bottom-left').y() - anchorNode.y() - padding * 2, 2)); @@ -15275,12 +14101,30 @@ this.findOne('.bottom-right').x(pos.x); } else if (this._movingAnchorName === 'middle-left') { + // if (centeredScaling) { + // this.findOne('.bottom-right').move({ + // x: -anchorNode.x(), + // y: 0 + // }); + // } this.findOne('.top-left').x(anchorNode.x()); } else if (this._movingAnchorName === 'middle-right') { + // if (centeredScaling) { + // this.findOne('.top-left').move({ + // x: -(anchorNode.x() - this.width()), + // y: 0 + // }); + // } this.findOne('.bottom-right').x(anchorNode.x()); } else if (this._movingAnchorName === 'bottom-left') { + // if (centeredScaling) { + // this.findOne('.bottom-right').move({ + // x: -anchorNode.x(), + // y: -(anchorNode.y() - this.height()) + // }); + // } if (keepProportion) { newHypotenuse = Math.sqrt(Math.pow(this.findOne('.top-right').x() - anchorNode.x() - padding * 2, 2) + Math.pow(anchorNode.y() - this.findOne('.top-right').y() - padding * 2, 2)); @@ -15300,9 +14144,21 @@ this.findOne('.bottom-right').y(pos.y); } else if (this._movingAnchorName === 'bottom-center') { + // if (centeredScaling) { + // this.findOne('.top-left').move({ + // x: 0, + // y: -(anchorNode.y() - this.height()) + // }); + // } this.findOne('.bottom-right').y(anchorNode.y()); } else if (this._movingAnchorName === 'bottom-right') { + // if (centeredScaling) { + // this.findOne('.top-left').move({ + // x: -(anchorNode.x() - this.width()), + // y: -(anchorNode.y() - this.height()) + // }); + // } if (keepProportion) { newHypotenuse = Math.sqrt(Math.pow(this.findOne('.bottom-right').x() - padding, 2) + Math.pow(this.findOne('.bottom-right').y() - padding, 2)); @@ -15368,14 +14224,14 @@ y: bottomOffsetY }); } - var absPos = this.findOne('.top-left').getAbsolutePosition(this.getParent()); + var absPos = this.findOne('.top-left').getAbsolutePosition(); x = absPos.x; y = absPos.y; var width = this.findOne('.bottom-right').x() - this.findOne('.top-left').x(); var height = this.findOne('.bottom-right').y() - this.findOne('.top-left').y(); this._fitNodesInto({ - x: x + this.offsetX(), - y: y + this.offsetY(), + x: x, + y: y, width: width, height: height, rotation: Konva.getAngle(this.rotation()) @@ -15404,46 +14260,69 @@ }; Transformer.prototype._fitNodesInto = function (newAttrs, evt) { var _this = this; - // console.log(newAttrs, oldAttrs); - // waring! in this attrs padding is included var oldAttrs = this._getNodeRect(); var boundBoxFunc = this.boundBoxFunc(); if (boundBoxFunc) { newAttrs = boundBoxFunc.call(this, oldAttrs, newAttrs); } - console.log(newAttrs.width, newAttrs.height); - if (newAttrs.width < 1 && newAttrs.width > -this.padding() * 2) { + var minSize = 1; + if (Util._inRange(newAttrs.width, -this.padding() * 2 - minSize, minSize)) { this.update(); return; } - if (Math.abs(newAttrs.height) < 1) { + if (Util._inRange(newAttrs.height, -this.padding() * 2 - minSize, minSize)) { this.update(); return; } + // if (newAttrs.width < 0) { + // debugger; + // } var an = this._movingAnchorName; + var t = new Transform(); + t.rotate(Konva.getAngle(this.rotation())); if (an && newAttrs.width < 0 && an.indexOf('left') >= 0) { + var offset = t.point({ + x: -this.padding() * 2, + y: 0 + }); + newAttrs.x += offset.x; + newAttrs.y += offset.y; + newAttrs.width += this.padding() * 2; this._movingAnchorName = an.replace('left', 'right'); - this._anchorDragOffset.x += this.padding() * 2; - this.update(); - return; + this._anchorDragOffset.x -= offset.x; + this._anchorDragOffset.y -= offset.y; } else if (an && newAttrs.width < 0 && an.indexOf('right') >= 0) { + var offset = t.point({ + x: this.padding() * 2, + y: 0 + }); this._movingAnchorName = an.replace('right', 'left'); - this._anchorDragOffset.x -= this.padding() * 2; - this.update(); - return; + this._anchorDragOffset.x -= offset.x; + this._anchorDragOffset.y -= offset.y; + newAttrs.width += this.padding() * 2; } - else if (an && newAttrs.height < 0 && an.indexOf('top') >= 0) { + if (an && newAttrs.height < 0 && an.indexOf('top') >= 0) { + var offset = t.point({ + x: 0, + y: -this.padding() * 2 + }); + newAttrs.x += offset.x; + newAttrs.y += offset.y; this._movingAnchorName = an.replace('top', 'bottom'); - this._anchorDragOffset.y += this.padding() * 2; - this.update(); - return; + this._anchorDragOffset.x -= offset.x; + this._anchorDragOffset.y -= offset.y; + newAttrs.height += this.padding() * 2; } else if (an && newAttrs.height < 0 && an.indexOf('bottom') >= 0) { + var offset = t.point({ + x: 0, + y: this.padding() * 2 + }); this._movingAnchorName = an.replace('bottom', 'top'); - this._anchorDragOffset.y -= this.padding() * 2; - this.update(); - return; + this._anchorDragOffset.x -= offset.x; + this._anchorDragOffset.y -= offset.y; + newAttrs.height += this.padding() * 2; } this._nodes.forEach(function (node) { var oldRect = _this.__getNodeShape(node, 0); @@ -16002,78 +14881,8 @@ * @param {Number} config.angle in degrees * @param {Number} config.radius * @param {Boolean} [config.clockwise] - * @param {String} [config.fill] fill color - * @param {Image} [config.fillPatternImage] fill pattern image - * @param {Number} [config.fillPatternX] - * @param {Number} [config.fillPatternY] - * @param {Object} [config.fillPatternOffset] object with x and y component - * @param {Number} [config.fillPatternOffsetX] - * @param {Number} [config.fillPatternOffsetY] - * @param {Object} [config.fillPatternScale] object with x and y component - * @param {Number} [config.fillPatternScaleX] - * @param {Number} [config.fillPatternScaleY] - * @param {Number} [config.fillPatternRotation] - * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" - * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component - * @param {Number} [config.fillLinearGradientStartPointX] - * @param {Number} [config.fillLinearGradientStartPointY] - * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component - * @param {Number} [config.fillLinearGradientEndPointX] - * @param {Number} [config.fillLinearGradientEndPointY] - * @param {Array} [config.fillLinearGradientColorStops] array of color stops - * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component - * @param {Number} [config.fillRadialGradientStartPointX] - * @param {Number} [config.fillRadialGradientStartPointY] - * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component - * @param {Number} [config.fillRadialGradientEndPointX] - * @param {Number} [config.fillRadialGradientEndPointY] - * @param {Number} [config.fillRadialGradientStartRadius] - * @param {Number} [config.fillRadialGradientEndRadius] - * @param {Array} [config.fillRadialGradientColorStops] array of color stops - * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true - * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration - * @param {String} [config.stroke] stroke color - * @param {Number} [config.strokeWidth] stroke width - * @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth - * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true - * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true - * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true - * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true - * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true - * @param {String} [config.lineJoin] can be miter, round, or bevel. The default - * is miter - * @param {String} [config.lineCap] can be butt, round, or sqare. The default - * is butt - * @param {String} [config.shadowColor] - * @param {Number} [config.shadowBlur] - * @param {Object} [config.shadowOffset] object with x and y component - * @param {Number} [config.shadowOffsetX] - * @param {Number} [config.shadowOffsetY] - * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number - * between 0 and 1 - * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true - * @param {Array} [config.dash] - * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Boolean} [config.visible] - * @param {Boolean} [config.listening] whether or not the node is listening for events - * @param {String} [config.id] unique id - * @param {String} [config.name] non-unique name - * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 - * @param {Object} [config.scale] set scale - * @param {Number} [config.scaleX] set scale x - * @param {Number} [config.scaleY] set scale y - * @param {Number} [config.rotation] rotation in degrees - * @param {Object} [config.offset] offset from center point and rotation point - * @param {Number} [config.offsetX] set offset x - * @param {Number} [config.offsetY] set offset y - * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop - * the entire stage by dragging any portion of the stage - * @param {Number} [config.dragDistance] - * @param {Function} [config.dragBoundFunc] + * @@shapeParams + * @@nodeParams * @example * // draw a wedge that's pointing downwards * var wedge = new Konva.Wedge({ diff --git a/src/BaseLayer.ts b/src/BaseLayer.ts index 7299558a..2da57cec 100644 --- a/src/BaseLayer.ts +++ b/src/BaseLayer.ts @@ -218,7 +218,7 @@ export abstract class BaseLayer extends Container { this.getContext()._context.imageSmoothingEnabled = this.imageSmoothingEnabled(); } /** - * get/set width of layer.getter return width of stage. setter doing nothing. + * get/set width of layer. getter return width of stage. setter doing nothing. * if you want change width use `stage.width(value);` * @name Konva.BaseLayer#width * @method @@ -302,10 +302,8 @@ BaseLayer.prototype.nodeType = 'BaseLayer'; * // get imageSmoothingEnabled flag * var imageSmoothingEnabled = layer.imageSmoothingEnabled(); * - * // disable clear before draw * layer.imageSmoothingEnabled(false); * - * // enable clear before draw * layer.imageSmoothingEnabled(true); */ Factory.addGetterSetter(BaseLayer, 'imageSmoothingEnabled', true); diff --git a/src/shapes/Transformer.ts b/src/shapes/Transformer.ts index 4ce261da..08a5de78 100644 --- a/src/shapes/Transformer.ts +++ b/src/shapes/Transformer.ts @@ -145,7 +145,15 @@ var ANCHORS_NAMES = [ var MAX_SAFE_INTEGER = 100000000; -function getCenter(shape) { +type SHAPE = { + x: number; + y: number; + width: number; + height: number; + rotation: number; +}; + +function getCenter(shape: SHAPE) { return { x: shape.x + @@ -158,7 +166,7 @@ function getCenter(shape) { }; } -function rotateAroundPoint(shape, angleRad, point) { +function rotateAroundPoint(shape: SHAPE, angleRad: number, point: Point) { const x = point.x + (shape.x - point.x) * Math.cos(angleRad) - @@ -175,12 +183,12 @@ function rotateAroundPoint(shape, angleRad, point) { }; } -function rotateAroundCenter(shape, deltaRad) { +function rotateAroundCenter(shape: SHAPE, deltaRad: number) { const center = getCenter(shape); return rotateAroundPoint(shape, deltaRad, center); } -function getShapeRect(shape) { +function getShapeRect(shape: SHAPE) { const angleRad = shape.rotation; const x1 = shape.x; const y1 = shape.y; @@ -209,7 +217,7 @@ function getShapeRect(shape) { }; } -function getShapesRect(shapes) { +function getShapesRect(shapes: Array) { // if (shapes.length === 1) { // const shape = shapes[0]; @@ -242,25 +250,16 @@ function getShapesRect(shapes) { }; } -function isOverlap(rect1, rect2) { - const offset = 0; - if (rect1.x - offset > rect2.x + rect2.width) { - return false; - } - if (rect1.x + rect1.width + offset < rect2.x) { - return false; - } - if (rect1.y - offset > rect2.y + rect2.height) { - return false; - } - if (rect1.y + rect1.height + offset < rect2.y) { - return false; - } - return true; -} - -function transformShape(shape, oldSelection, newSelection, keepOffset = 1) { - const offset = rotateAroundPoint(shape, -oldSelection.rotation, oldSelection); +function transformShape( + shape: SHAPE, + oldSelection: SHAPE, + newSelection: SHAPE, + keepOffset = 1 +) { + const offset = rotateAroundPoint(shape, -oldSelection.rotation, { + x: oldSelection.x, + y: oldSelection.y + }); const offsetX = offset.x - oldSelection.x; const offsetY = offset.y - oldSelection.y; @@ -279,14 +278,19 @@ function transformShape(shape, oldSelection, newSelection, keepOffset = 1) { offsetX * scaleX * Math.sin(angle) + offsetY * scaleY * Math.cos(angle), width: shape.width * scaleX, - height: shape.height * scaleY + height: shape.height * scaleY, + rotation: shape.rotation }; } -function transformAndRotateShape(shape, oldSelection, newSelection) { +function transformAndRotateShape( + shape: SHAPE, + oldSelection: SHAPE, + newSelection: SHAPE +) { const updated = transformShape(shape, oldSelection, newSelection); return rotateAroundPoint( - { ...updated, rotation: shape.rotation }, + updated, newSelection.rotation - oldSelection.rotation, newSelection ); @@ -580,22 +584,22 @@ export class Transformer extends Group { strokeWidth: 1, name: name + ' _anchor', dragDistance: 0, - draggable: true, + draggable: false, hitStrokeWidth: TOUCH_DEVICE ? 10 : 'auto' }); var self = this; anchor.on('mousedown touchstart', function(e) { self._handleMouseDown(e); }); - anchor.on('dragstart', function(e) { - e.cancelBubble = true; - }); - anchor.on('dragmove', function(e) { - e.cancelBubble = true; - }); - anchor.on('dragend', function(e) { - e.cancelBubble = true; - }); + // anchor.on('dragstart', function(e) { + // e.cancelBubble = true; + // }); + // anchor.on('dragmove', function(e) { + // e.cancelBubble = true; + // }); + // anchor.on('dragend', function(e) { + // e.cancelBubble = true; + // }); // add hover styling anchor.on('mouseenter', () => { @@ -697,13 +701,47 @@ export class Transformer extends Group { x: pp.x - this._anchorDragOffset.x, y: pp.y - this._anchorDragOffset.y }; + const oldAbs = anchorNode.getAbsolutePosition(); anchorNode.setAbsolutePosition(newNodePos); + const newAbs = anchorNode.getAbsolutePosition(); + + if (oldAbs.x === newAbs.x && oldAbs.y === newAbs.y) { + return; + } + + var centeredScaling = this.centeredScaling() || e.altKey; + // if (centeredScaling && this._movingAnchorName.indexOf('left') >= 0) { + // var topLeft = this.findOne('.top-left'); + // var bottomRight = this.findOne('.bottom-right'); + // var topOffsetX = topLeft.x() + padding; + // var topOffsetY = topLeft.y() + padding; + + // var bottomOffsetX = this.getWidth() - bottomRight.x() + padding; + // var bottomOffsetY = this.getHeight() - bottomRight.y() + padding; + + // bottomRight.move({ + // x: -anchorNode.x(), + // y: -anchorNode.y() + // }); + + // topLeft.move({ + // x: bottomOffsetX, + // y: bottomOffsetY + // }); + // } var keepProportion = this.keepRatio() || e.shiftKey; var padding = 0; if (this._movingAnchorName === 'top-left') { + // if (centeredScaling) { + // this.findOne('.bottom-right').move({ + // x: -anchorNode.x(), + // y: -anchorNode.y() + // }); + // } + if (keepProportion) { newHypotenuse = Math.sqrt( Math.pow( @@ -737,8 +775,32 @@ export class Transformer extends Group { ); } } else if (this._movingAnchorName === 'top-center') { + // if (centeredScaling) { + // this.findOne('.bottom-right').move({ + // x: 0, + // y: -anchorNode.y() + // }); + // } this.findOne('.top-left').y(anchorNode.y()); } else if (this._movingAnchorName === 'top-right') { + if (centeredScaling) { + // this.findOne('.bottom-left').move({ + // x: -(anchorNode.x() - this.width()), + // y: -anchorNode.y() + // }); + // this.findOne('.top-left').move({ + // x: -(anchorNode.x() - this.width()), + // y: anchorNode.y() + // }); + // this.findOne('.bottom-right').move({ + // x: -(anchorNode.x() - this.width()), + // y: anchorNode.y() + // }); + } + + // var center = getCenter({ + // x + // }) if (keepProportion) { newHypotenuse = Math.sqrt( Math.pow( @@ -770,14 +832,31 @@ export class Transformer extends Group { ); } var pos = anchorNode.position(); - this.findOne('.top-left').y(pos.y); this.findOne('.bottom-right').x(pos.x); } else if (this._movingAnchorName === 'middle-left') { + // if (centeredScaling) { + // this.findOne('.bottom-right').move({ + // x: -anchorNode.x(), + // y: 0 + // }); + // } this.findOne('.top-left').x(anchorNode.x()); } else if (this._movingAnchorName === 'middle-right') { + // if (centeredScaling) { + // this.findOne('.top-left').move({ + // x: -(anchorNode.x() - this.width()), + // y: 0 + // }); + // } this.findOne('.bottom-right').x(anchorNode.x()); } else if (this._movingAnchorName === 'bottom-left') { + // if (centeredScaling) { + // this.findOne('.bottom-right').move({ + // x: -anchorNode.x(), + // y: -(anchorNode.y() - this.height()) + // }); + // } if (keepProportion) { newHypotenuse = Math.sqrt( Math.pow( @@ -814,8 +893,21 @@ export class Transformer extends Group { this.findOne('.top-left').x(pos.x); this.findOne('.bottom-right').y(pos.y); } else if (this._movingAnchorName === 'bottom-center') { + // if (centeredScaling) { + // this.findOne('.top-left').move({ + // x: 0, + // y: -(anchorNode.y() - this.height()) + // }); + // } this.findOne('.bottom-right').y(anchorNode.y()); } else if (this._movingAnchorName === 'bottom-right') { + // if (centeredScaling) { + // this.findOne('.top-left').move({ + // x: -(anchorNode.x() - this.width()), + // y: -(anchorNode.y() - this.height()) + // }); + // } + if (keepProportion) { newHypotenuse = Math.sqrt( Math.pow(this.findOne('.bottom-right').x() - padding, 2) + @@ -910,9 +1002,7 @@ export class Transformer extends Group { }); } - var absPos = this.findOne('.top-left').getAbsolutePosition( - this.getParent() - ); + var absPos = this.findOne('.top-left').getAbsolutePosition(); x = absPos.x; y = absPos.y; @@ -924,8 +1014,8 @@ export class Transformer extends Group { this._fitNodesInto( { - x: x + this.offsetX(), - y: y + this.offsetY(), + x: x, + y: y, width: width, height: height, rotation: Konva.getAngle(this.rotation()) @@ -956,43 +1046,88 @@ export class Transformer extends Group { } } _fitNodesInto(newAttrs, evt) { - // console.log(newAttrs, oldAttrs); - // waring! in this attrs padding is included var oldAttrs = this._getNodeRect(); var boundBoxFunc = this.boundBoxFunc(); if (boundBoxFunc) { newAttrs = boundBoxFunc.call(this, oldAttrs, newAttrs); } - console.log(newAttrs.width, newAttrs.height); - if (newAttrs.width < 1 && newAttrs.width > - this.padding() * 2) { + + const minSize = 1; + + if (Util._inRange(newAttrs.width, -this.padding() * 2 - minSize, minSize)) { this.update(); return; } - if (Math.abs(newAttrs.height) < 1) { + if ( + Util._inRange(newAttrs.height, -this.padding() * 2 - minSize, minSize) + ) { this.update(); return; } + // if (newAttrs.width < 0) { + // debugger; + // } const an = this._movingAnchorName; + const allowNegativeScale = true; + var t = new Transform(); + t.rotate(Konva.getAngle(this.rotation())); if (an && newAttrs.width < 0 && an.indexOf('left') >= 0) { + const offset = t.point({ + x: -this.padding() * 2, + y: 0 + }); + newAttrs.x += offset.x; + newAttrs.y += offset.y; + newAttrs.width += this.padding() * 2; this._movingAnchorName = an.replace('left', 'right'); - this._anchorDragOffset.x += this.padding() * 2; - this.update(); - return; + this._anchorDragOffset.x -= offset.x; + this._anchorDragOffset.y -= offset.y; + if (!allowNegativeScale) { + this.update(); + return; + } } else if (an && newAttrs.width < 0 && an.indexOf('right') >= 0) { + const offset = t.point({ + x: this.padding() * 2, + y: 0 + }); this._movingAnchorName = an.replace('right', 'left'); - this._anchorDragOffset.x -= this.padding() * 2; - this.update(); - return; - } else if (an && newAttrs.height < 0 && an.indexOf('top') >= 0) { + this._anchorDragOffset.x -= offset.x; + this._anchorDragOffset.y -= offset.y; + newAttrs.width += this.padding() * 2; + if (!allowNegativeScale) { + this.update(); + return; + } + } + if (an && newAttrs.height < 0 && an.indexOf('top') >= 0) { + const offset = t.point({ + x: 0, + y: -this.padding() * 2 + }); + newAttrs.x += offset.x; + newAttrs.y += offset.y; this._movingAnchorName = an.replace('top', 'bottom'); - this._anchorDragOffset.y += this.padding() * 2; - this.update(); - return; + this._anchorDragOffset.x -= offset.x; + this._anchorDragOffset.y -= offset.y; + newAttrs.height += this.padding() * 2; + if (!allowNegativeScale) { + this.update(); + return; + } } else if (an && newAttrs.height < 0 && an.indexOf('bottom') >= 0) { + const offset = t.point({ + x: 0, + y: this.padding() * 2 + }); this._movingAnchorName = an.replace('bottom', 'top'); - this._anchorDragOffset.y -= this.padding() * 2; - this.update(); - return; + this._anchorDragOffset.x -= offset.x; + this._anchorDragOffset.y -= offset.y; + newAttrs.height += this.padding() * 2; + if (!allowNegativeScale) { + this.update(); + return; + } } this._nodes.forEach(node => { var oldRect = this.__getNodeShape(node, 0); diff --git a/test/unit/shapes/Transformer-test.js b/test/unit/shapes/Transformer-test.js index 14914b9f..2daf473e 100644 --- a/test/unit/shapes/Transformer-test.js +++ b/test/unit/shapes/Transformer-test.js @@ -1,4 +1,26 @@ suite.only('Transformer', function() { + function isClose(a, b) { + return Math.abs(a - b) < 0.000001; + } + + Konva.Transformer.prototype.simulateMouseDown = function(pos) { + this.getStage().simulateMouseDown(pos); + }; + + Konva.Transformer.prototype.simulateMouseMove = function(pos) { + var top = this.getStage().content.getBoundingClientRect().top; + this._handleMouseMove({ + clientX: pos.x, + clientY: pos.y + top + }); + this.getStage().simulateMouseMove(pos); + }; + + Konva.Transformer.prototype.simulateMouseUp = function(pos) { + this._handleMouseUp(pos); + this.getStage().simulateMouseUp(pos || { x: 1, y: 1 }); + }; + // ====================================================== test('init transformer on simple rectangle', function() { var stage = addStage(); @@ -196,7 +218,7 @@ suite.only('Transformer', function() { assert.equal(tr.rotation(), rect.rotation()); }); - test.skip('try to fit simple rectangle into negative scale', function() { + test('try to fit simple rectangle into negative scale', function() { var stage = addStage(); var layer = new Konva.Layer(); stage.add(layer); @@ -227,8 +249,6 @@ suite.only('Transformer', function() { tr._fitNodesInto(box); - assert.deepEqual(box, tr.__getNodeRect()); - assert.equal(rect.x(), 100); assert.equal(rect.y(), 0); assert.equal(rect.width(), 100); @@ -939,14 +959,14 @@ suite.only('Transformer', function() { }); }); - test.only('can add padding', function() { + 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, + x: 30, + y: 30, draggable: true, width: 100, height: 100, @@ -956,77 +976,36 @@ suite.only('Transformer', function() { var tr = new Konva.Transformer({ node: rect, - padding: 50 - }); - layer.add(tr); - - tr._fitNodesInto({ - x: 20, - y: 20, - width: 100, - height: 100, - rotation: 0 - }); - - layer.draw(); - - assert.equal(rect.x(), 20); - assert.equal(rect.y(), 20); - assert.equal(rect.width(), 120); - assert.equal(rect.height(), 120); - }); - - test.skip('test padding + keep ratio', function() { - var stage = addStage(); - var layer = new Konva.Layer(); - stage.add(layer); - - var rect = new Konva.Rect({ - x: 50, - y: 50, - width: 180, - height: 50, - fill: 'red', - draggable: true - }); - layer.add(rect); - - var tr = new Konva.Transformer({ - node: rect, - padding: 40, - keepRatio: true + padding: 20 }); layer.add(tr); layer.draw(); stage.simulateMouseDown({ - x: 250, - y: 150 - }); - var top = stage.content.getBoundingClientRect().top; - tr._handleMouseMove({ - target: tr.findOne('.bottom-right'), - clientX: 200, - clientY: 150 + top + x: 10, + y: 80 + }); + + var top = stage.content.getBoundingClientRect().top; + tr._handleMouseMove({ + clientX: 60, + clientY: 80 + top }); - // here is duplicate, because transformer is listening window events tr._handleMouseUp({ clientX: 200, - clientY: 150 + top + clientY: 150 }); stage.simulateMouseUp({ x: 200, y: 150 }); - layer.draw(); - - assert.equal(rect.x(), 50); - assert.equal(rect.y(), 50); + assert.equal(rect.x(), 80); + assert.equal(rect.y(), 30); assert.equal(rect.width(), 100); - assert.equal(rect.height(), 50); - assert.equal(rect.scaleX(), 1); + assert.equal(rect.scaleX(), 0.5); + assert.equal(rect.height(), 100); assert.equal(rect.scaleY(), 1); }); @@ -1051,6 +1030,11 @@ suite.only('Transformer', function() { layer.add(tr); layer.draw(); + // rect.on('transform', () => { + // console.log(tr.getActiveAnchor(), tr._anchorDragOffset); + // }); + // throw 1; + var anchor = tr.findOne('.top-right'); var pos = anchor.getAbsolutePosition(); @@ -1059,9 +1043,7 @@ suite.only('Transformer', function() { y: pos.y }); var box = stage.content.getBoundingClientRect(); - // debugger; tr._handleMouseMove({ - target: anchor, clientX: box.left + pos.x - 100, clientY: box.top + pos.y + 100 }); @@ -1080,14 +1062,36 @@ suite.only('Transformer', function() { assert.equal(rect.scaleY(), -1); }); - test('can add padding with rotation', function() { + test.skip('visual test', function(done) { + var stage = addStage(); + var layer = new Konva.Layer(); + stage.add(layer); + var src = 'assets/darth-vader.jpg'; + Konva.Image.fromURL(src, function(image) { + image.setAttrs({ + draggable: true, + scaleX: 0.5, + scaleY: 0.5 + }); + layer.add(image); + var tr = new Konva.Transformer({ + node: image, + keepRatio: false + }); + layer.add(tr); + layer.draw(); + done(); + }); + }); + + test('switch scaling with padding - x', function() { var stage = addStage(); var layer = new Konva.Layer(); stage.add(layer); var rect = new Konva.Rect({ - x: 100, - y: 60, + x: 10, + y: 10, draggable: true, width: 100, height: 100, @@ -1101,21 +1105,411 @@ suite.only('Transformer', function() { }); layer.add(tr); - tr._fitNodesInto({ - x: 120, - y: 0, - width: 120, - height: 120, - rotation: Konva.getAngle(90) + layer.draw(); + + tr.simulateMouseDown({ + x: 0, + y: 60 }); + tr.simulateMouseMove({ + x: 125, + y: 60 + }); + + assert.equal(rect.x(), 115); + assert.equal(rect.y(), 10); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), -0.05); + assert.equal(rect.height(), 100); + assert.equal(rect.rotation(), 0); + + tr.simulateMouseMove({ + x: 125, + y: 60 + }); + + assert.equal(rect.x(), 115); + assert.equal(rect.y(), 10); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), 0.05); + assert.equal(rect.height(), 100); + assert.equal(rect.scaleY(), -1); + + // switch again + tr.simulateMouseMove({ + x: 90, + y: 60 + }); + + assert.equal(rect.x(), 100); + assert.equal(rect.y(), 10); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleY(), -1); + assert.equal(rect.scaleX() + 0.1 < 0.0001, true); + assert.equal(rect.height(), 100); + + tr.simulateMouseUp(); + }); + + test('switch scaling with padding - y', function() { + var stage = addStage(); + var layer = new Konva.Layer(); + stage.add(layer); + + var rect = new Konva.Rect({ + x: 10, + y: 10, + draggable: true, + width: 100, + height: 100, + fill: 'yellow' + }); + layer.add(rect); + + var tr = new Konva.Transformer({ + node: rect, + padding: 10 + }); + layer.add(tr); + layer.draw(); + tr.simulateMouseDown({ + x: 60, + y: 0 + }); + + tr.simulateMouseMove({ + x: 60, + y: 125 + }); + + assert.equal(rect.x(), 10); + assert.equal(rect.y(), 115); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleY(), -0.05); + assert.equal(rect.height(), 100); + assert.equal(rect.rotation(), 0); + + tr.simulateMouseMove({ + x: 60, + y: 125 + }); + + assert.equal(rect.x(), 10); + assert.equal(rect.y(), 115); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleY(), -0.05); + assert.equal(rect.height(), 100); + assert.equal(rect.rotation(), 0); + + // switch again + tr.simulateMouseMove({ + x: 60, + y: 90 + }); + + assert.equal(rect.x(), 10); + assert.equal(rect.y(), 100); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), 1); + assert.equal(rect.scaleY(), 0.1); + assert.equal(rect.height(), 100); + assert.equal(rect.rotation(), 0); + + tr.simulateMouseUp(); + }); + + test('switch horizontal scaling with (top-left anchor)', function() { + var stage = addStage(); + var layer = new Konva.Layer(); + stage.add(layer); + + var rect = new Konva.Rect({ + x: 0, + y: 0, + draggable: true, + width: 100, + height: 100, + fill: 'yellow' + }); + layer.add(rect); + + var tr = new Konva.Transformer({ + node: rect + }); + layer.add(tr); + + layer.draw(); + + tr.simulateMouseDown({ + x: 0, + y: 0 + }); + + tr.simulateMouseMove({ + x: 150, + y: 50 + }); + layer.draw(); + + assert.equal(rect.x(), 150); + assert.equal(rect.y(), 50); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), -0.5); + assert.equal(rect.height(), 100); + assert.equal(rect.rotation(), 0); + + tr.simulateMouseMove({ + x: 98, + y: 2.859375 + }); + tr.simulateMouseMove({ + x: 98, + y: 2.859375 + }); + tr.simulateMouseMove({ + x: 98, + y: 2.859375 + }); + tr.simulateMouseMove({ + x: 100, + y: 2.859375 + }); + layer.draw(); + tr.simulateMouseMove({ + x: 101, + y: 2.859375 + }); + layer.draw(); + tr.simulateMouseMove({ + x: 101, + y: 2.859375 + }); + layer.draw(); + tr.simulateMouseMove({ + x: 101, + y: 2.859375 + }); + layer.draw(); + tr.simulateMouseMove({ + x: 102, + y: 2.859375 + }); + layer.draw(); + // switch again + tr.simulateMouseMove({ + x: 0, + y: 0 + }); + + assert.equal(isClose(rect.x(), 0), true); + assert.equal(Math.round(rect.y()), 0); + assert.equal(rect.width(), 100); + assert.equal(Math.round(rect.scaleY()), -1); + assert.equal(Math.round(rect.scaleX()), -1); + assert.equal(rect.height(), 100); + + tr.simulateMouseUp(); + }); + + // TODO: doesn't work!!! + test.skip('switch vertical scaling with (top-left anchor)', function() { + var stage = addStage(); + var layer = new Konva.Layer(); + stage.add(layer); + + var rect = new Konva.Rect({ + x: 0, + y: 0, + draggable: true, + width: 100, + height: 100, + fill: 'yellow' + }); + layer.add(rect); + + var tr = new Konva.Transformer({ + node: rect + }); + layer.add(tr); + + layer.draw(); + + tr.simulateMouseDown({ + x: 0, + y: 0 + }); + + tr.simulateMouseMove({ + x: 0, + y: 200 + }); + layer.draw(); + + assert.equal(rect.x(), 0); + assert.equal(rect.y(), 200); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), 1); + assert.equal(rect.height(), 100); + assert.equal(rect.rotation(), 0); + + tr.simulateMouseMove({ + x: 0, + y: 0 + }); + layer.draw(); + tr.simulateMouseUp(); + + assert.equal(rect.x(), 0); + assert.equal(rect.y(), 100); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), 1); + assert.equal(rect.height(), 100); + assert.equal(rect.rotation(), 0); + assert.equal(rect.scaleY(), -1); + }); + + test('switch scaling with padding for rotated - x', function() { + var stage = addStage(); + var layer = new Konva.Layer(); + stage.add(layer); + + var rect = new Konva.Rect({ + x: 110, + y: 10, + draggable: true, + width: 100, + height: 100, + fill: 'yellow', + rotation: 90 + }); + layer.add(rect); + + var tr = new Konva.Transformer({ + node: rect, + padding: 10 + }); + layer.add(tr); + + layer.draw(); + + tr.simulateMouseDown({ + x: 60, + y: 0 + }); + + tr.simulateMouseMove({ + x: 60, + y: 125 + }); + + assert.equal(rect.x(), 110); + assert.equal(rect.y(), 115); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), -0.05); + assert.equal(rect.height(), 100); + assert.equal(rect.rotation(), 90); + + tr.simulateMouseMove({ + x: 60, + y: 125 + }); + + assert.equal(rect.x(), 110); + assert.equal(rect.y(), 115); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), 0.05); + assert.equal(rect.height(), 100); + assert.equal(rect.scaleY(), -1); + + // switch again + tr.simulateMouseMove({ + x: 60, + y: 90 + }); + + assert.equal(rect.x(), 110); + assert.equal(rect.y() - 120 < 0.001, true); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX() + 0.1 < 0.0001, true); + assert.equal(rect.scaleY(), -1); + + assert.equal(rect.height(), 100); + + tr.simulateMouseUp(); + }); + + test('switch scaling with padding for rotated - y', function() { + var stage = addStage(); + var layer = new Konva.Layer(); + stage.add(layer); + + var rect = new Konva.Rect({ + x: 110, + y: 10, + draggable: true, + width: 100, + height: 100, + fill: 'yellow', + rotation: 90 + }); + layer.add(rect); + + var tr = new Konva.Transformer({ + node: rect, + padding: 10 + }); + layer.add(tr); + + layer.draw(); + + tr.simulateMouseDown({ + x: 0, + y: 60 + }); + + tr.simulateMouseMove({ + x: 125, + y: 60 + }); + assert.equal(rect.x(), 110); assert.equal(rect.y(), 10); assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), 1); + assert.equal(rect.scaleY(), -0.05); assert.equal(rect.height(), 100); assert.equal(rect.rotation(), 90); + + tr.simulateMouseMove({ + x: 125, + y: 60 + }); + + assert.equal(rect.x(), 110); + assert.equal(rect.y(), 10); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), 1); + assert.equal(rect.scaleY(), -0.05); + assert.equal(rect.height(), 100); + assert.equal(rect.rotation(), 90); + + // switch again + tr.simulateMouseMove({ + x: 90, + y: 60 + }); + + assert.equal(rect.x(), 110); + assert.equal(rect.y() - 120 < 0.001, true); + assert.equal(rect.width(), 100); + assert.equal(rect.scaleX(), 1); + assert.equal(rect.scaleY(), 0.1); + assert.equal(rect.height(), 100); + + tr.simulateMouseUp(); }); test('transformer should automatically track attr changes of a node', function() { @@ -1368,7 +1762,6 @@ suite.only('Transformer', function() { }); var top = stage.content.getBoundingClientRect().top; tr._handleMouseMove({ - target: rotater, clientX: pos.x + 100, clientY: pos.y - 100 + top }); @@ -1453,7 +1846,6 @@ suite.only('Transformer', function() { }); var top = stage.content.getBoundingClientRect().top; tr._handleMouseMove({ - target: target, clientX: 120, clientY: 100 + top }); @@ -1581,7 +1973,6 @@ suite.only('Transformer', function() { var top = stage.content.getBoundingClientRect().top; tr._handleMouseMove({ - target: tr.findOne('.top-left'), clientX: 60, clientY: 60 + top }); @@ -1670,7 +2061,6 @@ suite.only('Transformer', function() { var top = stage.content.getBoundingClientRect().top; tr._handleMouseMove({ - target: tr.findOne('.top-left'), clientX: 60, clientY: 60 + top }); @@ -1984,6 +2374,71 @@ suite.only('Transformer', function() { }); }); + test('centered scaling - no keep ratio', function() { + var stage = addStage(); + var layer = new Konva.Layer(); + stage.add(layer); + + var rect = new Konva.Rect({ + draggable: true, + fill: 'yellow' + }); + layer.add(rect); + + var tr = new Konva.Transformer({ + node: rect, + centeredScaling: true, + keepRatio: false + }); + layer.add(tr); + + tests.forEach(function(test) { + rect.setAttrs({ + x: 0, + y: 0, + width: 100, + height: 100, + scaleX: 1, + scaleY: 1 + }); + tr.update(); + + layer.draw(); + + stage.simulateMouseDown(test.startPos); + + var target = stage.getIntersection(test.startPos); + var top = stage.content.getBoundingClientRect().top; + tr._handleMouseMove({ + target: target, + clientX: test.endPos.x, + clientY: test.endPos.y + top + }); + + // here is duplicate, because transformer is listening window events + tr._handleMouseUp({ + clientX: test.endPos.x, + clientY: test.endPos.y + top + }); + stage.simulateMouseUp({ + x: test.endPos.x, + y: test.endPos.y + }); + layer.draw(); + + assert.equal( + rect.width() * rect.scaleX(), + test.expectedWidth, + test.name + ' width check' + ); + assert.equal( + rect.height() * rect.scaleY(), + test.expectedHeight, + test.name + ' height check' + ); + }); + }); + test('centered scaling', function() { var stage = addStage(); var layer = new Konva.Layer(); @@ -2048,7 +2503,7 @@ suite.only('Transformer', function() { }); }); - test.skip('centered scaling on flip', function() { + test.only('centered scaling on flip + keep ratio', function() { var stage = addStage(); var layer = new Konva.Layer(); stage.add(layer); @@ -2062,14 +2517,14 @@ suite.only('Transformer', function() { var tr = new Konva.Transformer({ node: rect, centeredScaling: true, - keepRatio: false + keepRatio: true }); layer.add(tr); rect.setAttrs({ x: 0, y: 0, - width: 100, + width: 200, height: 100, scaleX: 1, scaleY: 1 @@ -2078,39 +2533,36 @@ suite.only('Transformer', function() { layer.draw(); - // stage.simulateMouseDown({x: 0, y: 0}); + tr.simulateMouseDown({ + x: 0, + y: 0 + }); + tr.simulateMouseMove({ + x: 200, + y: 0 + }); + assert.equal(isClose(rect.x(), 200), true); + assert.equal(isClose(rect.y(), 0), true); + assert.equal(rect.width(), 200); + assert.equal(Math.round(rect.scaleY()), 1); + assert.equal(Math.round(rect.scaleX()), -1); + assert.equal(rect.height(), 100); - var target = stage.getIntersection({ x: 0, y: 0 }); - var top = stage.content.getBoundingClientRect().top; - throw 11; - debugger; - tr._handleMouseMove({ - target: target, - clientX: 100, - clientY: 0 + top + tr.simulateMouseMove({ + x: 200, + y: 0 }); - console.log(rect.width() * rect.scaleX()); - tr._handleMouseMove({ - target: target, - clientX: 100, - clientY: 0 + top - }); - console.log(rect.width() * rect.scaleX()); - // here is duplicate, because transformer is listening window events - tr._handleMouseUp({ - clientX: 100, - clientY: 0 + top - }); - stage.simulateMouseUp({ - x: 100, + tr.simulateMouseUp({ + x: 0, y: 0 }); layer.draw(); - - assert.equal(rect.width() * rect.scaleX(), -100); - assert.equal(rect.height() * rect.scaleY(), -100); - - throw 1; + assert.equal(isClose(rect.x(), 200), true); + assert.equal(isClose(rect.y(), 0), true); + assert.equal(rect.width(), 200); + assert.equal(Math.round(rect.scaleY()), -1); + assert.equal(Math.round(rect.scaleX()), 1); + assert.equal(rect.height(), 100); }); test('transform scaled (in one direction) node', function() { @@ -2149,7 +2601,6 @@ suite.only('Transformer', function() { }); var top = Math.round(stage.content.getBoundingClientRect().top); tr._handleMouseMove({ - target: target, clientX: 100, clientY: 100 + top }); @@ -2800,7 +3251,6 @@ suite.only('Transformer', function() { }); var top = stage.content.getBoundingClientRect().top; tr._handleMouseMove({ - target: target, clientX: 100, clientY: 50 + top });