diff --git a/CHANGELOG.md b/CHANGELOG.md index a7a0e062..a22642da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added * new `Konva.Transformer` group that allow simple resize, and rotate of a shape. +* Add ability to remove event by callback `node.off('event', callback)` ## Changed diff --git a/konva.js b/konva.js index 6060f46e..71cd8020 100644 --- a/konva.js +++ b/konva.js @@ -2386,13 +2386,13 @@ SCALE_CHANGE_STR = ['scaleXChange.konva', 'scaleYChange.konva'].join(SPACE); /** - * Node constructor. Nodes are entities that can be transformed, layered, - * and have bound events. The stage, layers, groups, and shapes all extend Node. - * @constructor - * @memberof Konva - * @abstract - * @param {Object} config - * @param {Number} [config.x] + * Node constructor. Nodes are entities that can be transformed, layered, + * and have bound events. The stage, layers, groups, and shapes all extend Node. + * @constructor + * @memberof Konva + * @abstract + * @param {Object} config + * @param {Number} [config.x] * @param {Number} [config.y] * @param {Number} [config.width] * @param {Number} [config.height] @@ -2412,7 +2412,7 @@ * the entire stage by dragging any portion of the stage * @param {Number} [config.dragDistance] * @param {Function} [config.dragBoundFunc] - */ + */ Konva.Node = function(config) { this._init(config); }; @@ -2479,60 +2479,60 @@ } }, /** - * clear cached canvas - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Node} - * @example - * node.clearCache(); - */ + * clear cached canvas + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + * @example + * node.clearCache(); + */ clearCache: function() { delete this._cache.canvas; this._filterUpToDate = false; return this; }, /** - * cache node to improve drawing performance, apply filters, or create more accurate - * hit regions. For all basic shapes size of cache canvas will be automatically detected. - * If you need to cache your custom `Konva.Shape` instance you have to pass shape's bounding box - * properties. Look at [https://konvajs.github.io/docs/performance/Shape_Caching.html](link to demo page) for more information. - * @method - * @memberof Konva.Node.prototype - * @param {Object} [config] - * @param {Number} [config.x] - * @param {Number} [config.y] - * @param {Number} [config.width] - * @param {Number} [config.height] - * @param {Number} [config.offset] increase canvas size by `offset` pixel in all directions. - * @param {Boolean} [config.drawBorder] when set to true, a red border will be drawn around the cached - * region for debugging purposes - * @param {Number} [config.pixelRatio] change quality (or pixel ratio) of cached image. pixelRatio = 2 will produce 2x sized cache. - * @returns {Konva.Node} - * @example - * // cache a shape with the x,y position of the bounding box at the center and - * // the width and height of the bounding box equal to the width and height of - * // the shape obtained from shape.width() and shape.height() - * image.cache(); - * - * // cache a node and define the bounding box position and size - * node.cache({ - * x: -30, - * y: -30, - * width: 100, - * height: 200 - * }); - * - * // cache a node and draw a red border around the bounding box - * // for debugging purposes - * node.cache({ - * x: -30, - * y: -30, - * width: 100, - * height: 200, - * offset : 10, - * drawBorder: true - * }); - */ + * cache node to improve drawing performance, apply filters, or create more accurate + * hit regions. For all basic shapes size of cache canvas will be automatically detected. + * If you need to cache your custom `Konva.Shape` instance you have to pass shape's bounding box + * properties. Look at [https://konvajs.github.io/docs/performance/Shape_Caching.html](link to demo page) for more information. + * @method + * @memberof Konva.Node.prototype + * @param {Object} [config] + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Number} [config.offset] increase canvas size by `offset` pixel in all directions. + * @param {Boolean} [config.drawBorder] when set to true, a red border will be drawn around the cached + * region for debugging purposes + * @param {Number} [config.pixelRatio] change quality (or pixel ratio) of cached image. pixelRatio = 2 will produce 2x sized cache. + * @returns {Konva.Node} + * @example + * // cache a shape with the x,y position of the bounding box at the center and + * // the width and height of the bounding box equal to the width and height of + * // the shape obtained from shape.width() and shape.height() + * image.cache(); + * + * // cache a node and define the bounding box position and size + * node.cache({ + * x: -30, + * y: -30, + * width: 100, + * height: 200 + * }); + * + * // cache a node and draw a red border around the bounding box + * // for debugging purposes + * node.cache({ + * x: -30, + * y: -30, + * width: 100, + * height: 200, + * offset : 10, + * drawBorder: true + * }); + */ cache: function(config) { var conf = config || {}, rect = this.getClientRect({ @@ -2627,39 +2627,39 @@ return this; }, /** - * Return client rectangle {x, y, width, height} of node. This rectangle also include all styling (strokes, shadows, etc). - * The rectangle position is relative to parent container. - * @method - * @memberof Konva.Node.prototype - * @param {Object} config - * @param {Boolean} [config.skipTransform] should we apply transform to node for calculating rect? - * @param {Object} [config.relativeTo] calculate client rect relative to one of the parents - * @returns {Object} rect with {x, y, width, height} properties - * @example - * var rect = new Konva.Rect({ - * width : 100, - * height : 100, - * x : 50, - * y : 50, - * strokeWidth : 4, - * stroke : 'black', - * offsetX : 50, - * scaleY : 2 - * }); - * - * // get client rect without think off transformations (position, rotation, scale, offset, etc) - * rect.getClientRect({ skipTransform: true}); - * // returns { - * // x : -2, // two pixels for stroke / 2 - * // y : -2, - * // width : 104, // increased by 4 for stroke - * // height : 104 - * //} - * - * // get client rect with transformation applied - * rect.getClientRect(); - * // returns Object {x: -2, y: 46, width: 104, height: 208} - */ + * Return client rectangle {x, y, width, height} of node. This rectangle also include all styling (strokes, shadows, etc). + * The rectangle position is relative to parent container. + * @method + * @memberof Konva.Node.prototype + * @param {Object} config + * @param {Boolean} [config.skipTransform] should we apply transform to node for calculating rect? + * @param {Object} [config.relativeTo] calculate client rect relative to one of the parents + * @returns {Object} rect with {x, y, width, height} properties + * @example + * var rect = new Konva.Rect({ + * width : 100, + * height : 100, + * x : 50, + * y : 50, + * strokeWidth : 4, + * stroke : 'black', + * offsetX : 50, + * scaleY : 2 + * }); + * + * // get client rect without think off transformations (position, rotation, scale, offset, etc) + * rect.getClientRect({ skipTransform: true}); + * // returns { + * // x : -2, // two pixels for stroke / 2 + * // y : -2, + * // width : 104, // increased by 4 for stroke + * // height : 104 + * //} + * + * // get client rect with transformation applied + * rect.getClientRect(); + * // returns Object {x: -2, y: 46, width: 104, height: 208} + */ getClientRect: function() { // abstract method // redefine in Container and Shape @@ -2778,68 +2778,68 @@ return sceneCanvas; }, /** - * bind events to the node. KonvaJS supports mouseover, mousemove, - * mouseout, mouseenter, mouseleave, mousedown, mouseup, wheel, click, dblclick, touchstart, touchmove, - * touchend, tap, dbltap, dragstart, dragmove, and dragend events. The Konva Stage supports - * contentMouseover, contentMousemove, contentMouseout, contentMousedown, contentMouseup, contentWheel, contentContextmenu - * contentClick, contentDblclick, contentTouchstart, contentTouchmove, contentTouchend, contentTap, - * and contentDblTap. Pass in a string of events delimmited by a space to bind multiple events at once - * such as 'mousedown mouseup mousemove'. Include a namespace to bind an - * event by name such as 'click.foobar'. - * @method - * @memberof Konva.Node.prototype - * @param {String} evtStr e.g. 'click', 'mousedown touchstart', 'mousedown.foo touchstart.foo' - * @param {Function} handler The handler function is passed an event object - * @returns {Konva.Node} - * @example - * // add click listener - * node.on('click', function() { - * console.log('you clicked me!'); - * }); - * - * // get the target node - * node.on('click', function(evt) { - * console.log(evt.target); - * }); - * - * // stop event propagation - * node.on('click', function(evt) { - * evt.cancelBubble = true; - * }); - * - * // bind multiple listeners - * node.on('click touchstart', function() { - * console.log('you clicked/touched me!'); - * }); - * - * // namespace listener - * node.on('click.foo', function() { - * console.log('you clicked/touched me!'); - * }); - * - * // get the event type - * node.on('click tap', function(evt) { - * var eventType = evt.type; - * }); - * - * // get native event object - * node.on('click tap', function(evt) { - * var nativeEvent = evt.evt; - * }); - * - * // for change events, get the old and new val - * node.on('xChange', function(evt) { - * var oldVal = evt.oldVal; - * var newVal = evt.newVal; - * }); - * - * // get event targets - * // with event delegations - * layer.on('click', 'Group', function(evt) { - * var shape = evt.target; - * var group = evtn.currentTarger; - * }); - */ + * bind events to the node. KonvaJS supports mouseover, mousemove, + * mouseout, mouseenter, mouseleave, mousedown, mouseup, wheel, click, dblclick, touchstart, touchmove, + * touchend, tap, dbltap, dragstart, dragmove, and dragend events. The Konva Stage supports + * contentMouseover, contentMousemove, contentMouseout, contentMousedown, contentMouseup, contentWheel, contentContextmenu + * contentClick, contentDblclick, contentTouchstart, contentTouchmove, contentTouchend, contentTap, + * and contentDblTap. Pass in a string of events delimmited by a space to bind multiple events at once + * such as 'mousedown mouseup mousemove'. Include a namespace to bind an + * event by name such as 'click.foobar'. + * @method + * @memberof Konva.Node.prototype + * @param {String} evtStr e.g. 'click', 'mousedown touchstart', 'mousedown.foo touchstart.foo' + * @param {Function} handler The handler function is passed an event object + * @returns {Konva.Node} + * @example + * // add click listener + * node.on('click', function() { + * console.log('you clicked me!'); + * }); + * + * // get the target node + * node.on('click', function(evt) { + * console.log(evt.target); + * }); + * + * // stop event propagation + * node.on('click', function(evt) { + * evt.cancelBubble = true; + * }); + * + * // bind multiple listeners + * node.on('click touchstart', function() { + * console.log('you clicked/touched me!'); + * }); + * + * // namespace listener + * node.on('click.foo', function() { + * console.log('you clicked/touched me!'); + * }); + * + * // get the event type + * node.on('click tap', function(evt) { + * var eventType = evt.type; + * }); + * + * // get native event object + * node.on('click tap', function(evt) { + * var nativeEvent = evt.evt; + * }); + * + * // for change events, get the old and new val + * node.on('xChange', function(evt) { + * var oldVal = evt.oldVal; + * var newVal = evt.newVal; + * }); + * + * // get event targets + * // with event delegations + * layer.on('click', 'Group', function(evt) { + * var shape = evt.target; + * var group = evtn.currentTarger; + * }); + */ on: function(evtStr, handler) { if (arguments.length === 3) { return this._delegate.apply(this, arguments); @@ -2877,27 +2877,27 @@ return this; }, /** - * remove event bindings from the node. Pass in a string of - * event types delimmited by a space to remove multiple event - * bindings at once such as 'mousedown mouseup mousemove'. - * include a namespace to remove an event binding by name - * such as 'click.foobar'. If you only give a name like '.foobar', - * all events in that namespace will be removed. - * @method - * @memberof Konva.Node.prototype - * @param {String} evtStr e.g. 'click', 'mousedown touchstart', '.foobar' - * @returns {Konva.Node} - * @example - * // remove listener - * node.off('click'); - * - * // remove multiple listeners - * node.off('click touchstart'); - * - * // remove listener by name - * node.off('click.foo'); - */ - off: function(evtStr) { + * remove event bindings from the node. Pass in a string of + * event types delimmited by a space to remove multiple event + * bindings at once such as 'mousedown mouseup mousemove'. + * include a namespace to remove an event binding by name + * such as 'click.foobar'. If you only give a name like '.foobar', + * all events in that namespace will be removed. + * @method + * @memberof Konva.Node.prototype + * @param {String} evtStr e.g. 'click', 'mousedown touchstart', '.foobar' + * @returns {Konva.Node} + * @example + * // remove listener + * node.off('click'); + * + * // remove multiple listeners + * node.off('click touchstart'); + * + * // remove listener by name + * node.off('click.foo'); + */ + off: function(evtStr, callback) { var events = (evtStr || '').split(SPACE), len = events.length, n, @@ -2921,11 +2921,11 @@ if (baseEvent) { if (this.eventListeners[baseEvent]) { - this._off(baseEvent, name); + this._off(baseEvent, name, callback); } } else { for (t in this.eventListeners) { - this._off(t, name); + this._off(t, name, callback); } } } @@ -2965,13 +2965,13 @@ }); }, /** - * remove self from parent, but don't destroy - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Node} - * @example - * node.remove(); - */ + * remove self from parent, but don't destroy + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + * @example + * node.remove(); + */ remove: function() { var parent = this.getParent(); @@ -2992,12 +2992,12 @@ return this; }, /** - * remove and destroy self - * @method - * @memberof Konva.Node.prototype - * @example - * node.destroy(); - */ + * remove and destroy self + * @method + * @memberof Konva.Node.prototype + * @example + * node.destroy(); + */ destroy: function() { // remove from ids and names hashes Konva._removeId(this.getId()); @@ -3013,14 +3013,14 @@ return this; }, /** - * get attr - * @method - * @memberof Konva.Node.prototype - * @param {String} attr - * @returns {Integer|String|Object|Array} - * @example - * var x = node.getAttr('x'); - */ + * get attr + * @method + * @memberof Konva.Node.prototype + * @param {String} attr + * @returns {Integer|String|Object|Array} + * @example + * var x = node.getAttr('x'); + */ getAttr: function(attr) { var method = GET + Konva.Util._capitalize(attr); if (Konva.Util._isFunction(this[method])) { @@ -3030,15 +3030,15 @@ return this.attrs[attr]; }, /** - * get ancestors - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Collection} - * @example - * shape.getAncestors().each(function(node) { - * console.log(node.getId()); - * }) - */ + * get ancestors + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Collection} + * @example + * shape.getAncestors().each(function(node) { + * console.log(node.getId()); + * }) + */ getAncestors: function() { var parent = this.getParent(), ancestors = new Konva.Collection(); @@ -3051,26 +3051,26 @@ return ancestors; }, /** - * get attrs object literal - * @method - * @memberof Konva.Node.prototype - * @returns {Object} - */ + * get attrs object literal + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + */ getAttrs: function() { return this.attrs || {}; }, /** - * set multiple attrs at once using an object literal - * @method - * @memberof Konva.Node.prototype - * @param {Object} config object containing key value pairs - * @returns {Konva.Node} - * @example - * node.setAttrs({ - * x: 5, - * fill: 'red' - * }); - */ + * set multiple attrs at once using an object literal + * @method + * @memberof Konva.Node.prototype + * @param {Object} config object containing key value pairs + * @returns {Konva.Node} + * @example + * node.setAttrs({ + * x: 5, + * fill: 'red' + * }); + */ setAttrs: function(config) { var key, method; @@ -3093,24 +3093,24 @@ return this; }, /** - * determine if node is listening for events by taking into account ancestors. - * - * Parent | Self | isListening - * listening | listening | - * ----------+-----------+------------ - * T | T | T - * T | F | F - * F | T | T - * F | F | F - * ----------+-----------+------------ - * T | I | T - * F | I | F - * I | I | T - * - * @method - * @memberof Konva.Node.prototype - * @returns {Boolean} - */ + * determine if node is listening for events by taking into account ancestors. + * + * Parent | Self | isListening + * listening | listening | + * ----------+-----------+------------ + * T | T | T + * T | F | F + * F | T | T + * F | F | F + * ----------+-----------+------------ + * T | I | T + * F | I | F + * I | I | T + * + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ isListening: function() { return this._getCache(LISTENING, this._isListening); }, @@ -3169,12 +3169,12 @@ } }, /** - * determine if listening is enabled by taking into account descendants. If self or any children - * have _isListeningEnabled set to true, then self also has listening enabled. - * @method - * @memberof Konva.Node.prototype - * @returns {Boolean} - */ + * determine if listening is enabled by taking into account descendants. If self or any children + * have _isListeningEnabled set to true, then self also has listening enabled. + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ shouldDrawHit: function(canvas) { var layer = this.getLayer(); return ( @@ -3186,41 +3186,41 @@ ); }, /** - * show node - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Node} - */ + * show node + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ show: function() { this.setVisible(true); return this; }, /** - * hide node. Hidden nodes are no longer detectable - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Node} - */ + * hide node. Hidden nodes are no longer detectable + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ hide: function() { this.setVisible(false); return this; }, /** - * get zIndex relative to the node's siblings who share the same parent - * @method - * @memberof Konva.Node.prototype - * @returns {Integer} - */ + * get zIndex relative to the node's siblings who share the same parent + * @method + * @memberof Konva.Node.prototype + * @returns {Integer} + */ getZIndex: function() { return this.index || 0; }, /** - * get absolute z-index which takes into account sibling - * and ancestor indices - * @method - * @memberof Konva.Node.prototype - * @returns {Integer} - */ + * get absolute z-index which takes into account sibling + * and ancestor indices + * @method + * @memberof Konva.Node.prototype + * @returns {Integer} + */ getAbsoluteZIndex: function() { var depth = this.getDepth(), that = this, @@ -3257,13 +3257,13 @@ return index; }, /** - * get node depth in node tree. Returns an integer. - * e.g. Stage depth will always be 0. Layers will always be 1. Groups and Shapes will always - * be >= 2 - * @method - * @memberof Konva.Node.prototype - * @returns {Integer} - */ + * get node depth in node tree. Returns an integer. + * e.g. Stage depth will always be 0. Layers will always be 1. Groups and Shapes will always + * be >= 2 + * @method + * @memberof Konva.Node.prototype + * @returns {Integer} + */ getDepth: function() { var depth = 0, parent = this.parent; @@ -3286,13 +3286,13 @@ }; }, /** - * get absolute position relative to the top left corner of the stage container div - * or relative to passed node - * @method - * @param {Object} [top] optional parent node - * @memberof Konva.Node.prototype - * @returns {Object} - */ + * get absolute position relative to the top left corner of the stage container div + * or relative to passed node + * @method + * @param {Object} [top] optional parent node + * @memberof Konva.Node.prototype + * @returns {Object} + */ getAbsolutePosition: function(top) { var absoluteMatrix = this.getAbsoluteTransform(top).getMatrix(), absoluteTransform = new Konva.Transform(), @@ -3305,14 +3305,14 @@ return absoluteTransform.getTranslation(); }, /** - * set absolute position - * @method - * @memberof Konva.Node.prototype - * @param {Object} pos - * @param {Number} pos.x - * @param {Number} pos.y - * @returns {Konva.Node} - */ + * set absolute position + * @method + * @memberof Konva.Node.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @returns {Konva.Node} + */ setAbsolutePosition: function(pos) { var origTrans = this._clearTransform(), it; @@ -3378,20 +3378,20 @@ return trans; }, /** - * move node by an amount relative to its current position - * @method - * @memberof Konva.Node.prototype - * @param {Object} change - * @param {Number} change.x - * @param {Number} change.y - * @returns {Konva.Node} - * @example - * // move node in x direction by 1px and y direction by 2px - * node.move({ - * x: 1, - * y: 2) - * }); - */ + * move node by an amount relative to its current position + * @method + * @memberof Konva.Node.prototype + * @param {Object} change + * @param {Number} change.x + * @param {Number} change.y + * @returns {Konva.Node} + * @example + * // move node in x direction by 1px and y direction by 2px + * node.move({ + * x: 1, + * y: 2) + * }); + */ move: function(change) { var changeX = change.x, changeY = change.y, @@ -3436,22 +3436,22 @@ } }, /** - * rotate node by an amount in degrees relative to its current rotation - * @method - * @memberof Konva.Node.prototype - * @param {Number} theta - * @returns {Konva.Node} - */ + * rotate node by an amount in degrees relative to its current rotation + * @method + * @memberof Konva.Node.prototype + * @param {Number} theta + * @returns {Konva.Node} + */ rotate: function(theta) { this.setRotation(this.getRotation() + theta); return this; }, /** - * move node to the top of its siblings - * @method - * @memberof Konva.Node.prototype - * @returns {Boolean} - */ + * move node to the top of its siblings + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ moveToTop: function() { if (!this.parent) { Konva.Util.warn('Node has no parent. moveToTop function is ignored.'); @@ -3464,11 +3464,11 @@ return true; }, /** - * move node up - * @method - * @memberof Konva.Node.prototype - * @returns {Boolean} flag is moved or not - */ + * move node up + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} flag is moved or not + */ moveUp: function() { if (!this.parent) { Konva.Util.warn('Node has no parent. moveUp function is ignored.'); @@ -3485,11 +3485,11 @@ return false; }, /** - * move node down - * @method - * @memberof Konva.Node.prototype - * @returns {Boolean} - */ + * move node down + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ moveDown: function() { if (!this.parent) { Konva.Util.warn('Node has no parent. moveDown function is ignored.'); @@ -3505,11 +3505,11 @@ return false; }, /** - * move node to the bottom of its siblings - * @method - * @memberof Konva.Node.prototype - * @returns {Boolean} - */ + * move node to the bottom of its siblings + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ moveToBottom: function() { if (!this.parent) { Konva.Util.warn( @@ -3527,12 +3527,12 @@ return false; }, /** - * set zIndex relative to siblings - * @method - * @memberof Konva.Node.prototype - * @param {Integer} zIndex - * @returns {Konva.Node} - */ + * set zIndex relative to siblings + * @method + * @memberof Konva.Node.prototype + * @param {Integer} zIndex + * @returns {Konva.Node} + */ setZIndex: function(zIndex) { if (!this.parent) { Konva.Util.warn('Node has no parent. zIndex parameter is ignored.'); @@ -3545,11 +3545,11 @@ return this; }, /** - * get absolute opacity - * @method - * @memberof Konva.Node.prototype - * @returns {Number} - */ + * get absolute opacity + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + */ getAbsoluteOpacity: function() { return this._getCache(ABSOLUTE_OPACITY, this._getAbsoluteOpacity); }, @@ -3562,15 +3562,15 @@ return absOpacity; }, /** - * move node to another container - * @method - * @memberof Konva.Node.prototype - * @param {Container} newContainer - * @returns {Konva.Node} - * @example - * // move node from current layer into layer2 - * node.moveTo(layer2); - */ + * move node to another container + * @method + * @memberof Konva.Node.prototype + * @param {Container} newContainer + * @returns {Konva.Node} + * @example + * // move node from current layer into layer2 + * node.moveTo(layer2); + */ moveTo: function(newContainer) { // do nothing if new container is already parent if (this.getParent() !== newContainer) { @@ -3582,11 +3582,11 @@ return this; }, /** - * convert Node into an object for serialization. Returns an object. - * @method - * @memberof Konva.Node.prototype - * @returns {Object} - */ + * convert Node into an object for serialization. Returns an object. + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + */ toObject: function() { var obj = {}, attrs = this.getAttrs(), @@ -3614,35 +3614,35 @@ return Konva.Util._prepareToStringify(obj); }, /** - * convert Node into a JSON string. Returns a JSON string. - * @method - * @memberof Konva.Node.prototype - * @returns {String}} - */ + * convert Node into a JSON string. Returns a JSON string. + * @method + * @memberof Konva.Node.prototype + * @returns {String}} + */ toJSON: function() { return JSON.stringify(this.toObject()); }, /** - * get parent container - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Node} - */ + * get parent container + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ getParent: function() { return this.parent; }, /** - * get all ancestros (parent then parent of the parent, etc) of the node - * @method - * @memberof Konva.Node.prototype - * @param {String} [selector] selector for search - * @param {Boolean} [includeSelf] show we think that node is ancestro itself? - * @param {Konva.Node} [stopNode] optional node where we need to stop searching (one of ancestors) - * @returns {Array} [ancestors] - * @example - * // get one of the parent group - * var parentGroups = node.findAncestors('Group'); - */ + * get all ancestros (parent then parent of the parent, etc) of the node + * @method + * @memberof Konva.Node.prototype + * @param {String} [selector] selector for search + * @param {Boolean} [includeSelf] show we think that node is ancestro itself? + * @param {Konva.Node} [stopNode] optional node where we need to stop searching (one of ancestors) + * @returns {Array} [ancestors] + * @example + * // get one of the parent group + * var parentGroups = node.findAncestors('Group'); + */ findAncestors: function(selector, includeSelf, stopNode) { var res = []; @@ -3662,17 +3662,17 @@ return res; }, /** - * get ancestor (parent or parent of the parent, etc) of the node that match passed selector - * @method - * @memberof Konva.Node.prototype - * @param {String} [selector] selector for search - * @param {Boolean} [includeSelf] show we think that node is ancestro itself? - * @param {Konva.Node} [stopNode] optional node where we need to stop searching (one of ancestors) - * @returns {Konva.Node} ancestor - * @example - * // get one of the parent group - * var group = node.findAncestors('.mygroup'); - */ + * get ancestor (parent or parent of the parent, etc) of the node that match passed selector + * @method + * @memberof Konva.Node.prototype + * @param {String} [selector] selector for search + * @param {Boolean} [includeSelf] show we think that node is ancestro itself? + * @param {Konva.Node} [stopNode] optional node where we need to stop searching (one of ancestors) + * @returns {Konva.Node} ancestor + * @example + * // get one of the parent group + * var group = node.findAncestors('.mygroup'); + */ findAncestor: function(selector, includeSelf, stopNode) { return this.findAncestors(selector, includeSelf, stopNode)[0]; }, @@ -3716,21 +3716,21 @@ return false; }, /** - * get layer ancestor - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Layer} - */ + * get layer ancestor + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Layer} + */ getLayer: function() { var parent = this.getParent(); return parent ? parent.getLayer() : null; }, /** - * get stage ancestor - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Stage} - */ + * get stage ancestor + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Stage} + */ getStage: function() { return this._getCache(STAGE, this._getStage); }, @@ -3743,29 +3743,29 @@ } }, /** - * fire event - * @method - * @memberof Konva.Node.prototype - * @param {String} eventType event type. can be a regular event, like click, mouseover, or mouseout, or it can be a custom event, like myCustomEvent - * @param {Event} [evt] event object - * @param {Boolean} [bubble] setting the value to false, or leaving it undefined, will result in the event - * not bubbling. Setting the value to true will result in the event bubbling. - * @returns {Konva.Node} - * @example - * // manually fire click event - * node.fire('click'); - * - * // fire custom event - * node.fire('foo'); - * - * // fire custom event with custom event object - * node.fire('foo', { - * bar: 10 - * }); - * - * // fire click event that bubbles - * node.fire('click', null, true); - */ + * fire event + * @method + * @memberof Konva.Node.prototype + * @param {String} eventType event type. can be a regular event, like click, mouseover, or mouseout, or it can be a custom event, like myCustomEvent + * @param {Event} [evt] event object + * @param {Boolean} [bubble] setting the value to false, or leaving it undefined, will result in the event + * not bubbling. Setting the value to true will result in the event bubbling. + * @returns {Konva.Node} + * @example + * // manually fire click event + * node.fire('click'); + * + * // fire custom event + * node.fire('foo'); + * + * // fire custom event with custom event object + * node.fire('foo', { + * bar: 10 + * }); + * + * // fire click event that bubbles + * node.fire('click', null, true); + */ fire: function(eventType, evt, bubble) { evt = evt || {}; evt.target = evt.target || this; @@ -3779,12 +3779,12 @@ return this; }, /** - * get absolute transform of the node which takes into - * account its ancestor transforms - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Transform} - */ + * get absolute transform of the node which takes into + * account its ancestor transforms + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Transform} + */ getAbsoluteTransform: function(top) { // if using an argument, we can't cache the result. if (top) { @@ -3813,12 +3813,12 @@ return at; }, /** - * get absolute scale of the node which takes into - * account its ancestor scales - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Transform} - */ + * get absolute scale of the node which takes into + * account its ancestor scales + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Transform} + */ getAbsoluteScale: function(top) { // if using an argument, we can't cache the result. if (top) { @@ -3852,11 +3852,11 @@ }; }, /** - * get transform of the node - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Transform} - */ + * get transform of the node + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Transform} + */ getTransform: function() { return this._getCache(TRANSFORM, this._getTransform); }, @@ -3891,22 +3891,22 @@ return m; }, /** - * clone node. Returns a new Node instance with identical attributes. You can also override - * the node properties with an object literal, enabling you to use an existing node as a template - * for another node - * @method - * @memberof Konva.Node.prototype - * @param {Object} obj override attrs - * @returns {Konva.Node} - * @example - * // simple clone - * var clone = node.clone(); - * - * // clone a node and override the x position - * var clone = rect.clone({ - * x: 5 - * }); - */ + * clone node. Returns a new Node instance with identical attributes. You can also override + * the node properties with an object literal, enabling you to use an existing node as a template + * for another node + * @method + * @memberof Konva.Node.prototype + * @param {Object} obj override attrs + * @returns {Konva.Node} + * @example + * // simple clone + * var clone = node.clone(); + * + * // clone a node and override the x position + * var clone = rect.clone({ + * x: 5 + * }); + */ clone: function(obj) { // instantiate new node var attrs = Konva.Util.cloneObject(this.attrs), @@ -3977,41 +3977,41 @@ return canvas; }, /** - * converts node into an canvas element. - * @method - * @memberof Konva.Node.prototype - * @param {Object} config - * @param {Function} config.callback function executed when the composite has completed - * @param {Number} [config.x] x position of canvas section - * @param {Number} [config.y] y position of canvas section - * @param {Number} [config.width] width of canvas section - * @param {Number} [config.height] height of canvas section - * @paremt {Number} [config.pixelRatio] pixelRatio of ouput image. Default is 1. - * @example - * var canvas = node.toCanvas(); - */ + * converts node into an canvas element. + * @method + * @memberof Konva.Node.prototype + * @param {Object} config + * @param {Function} config.callback function executed when the composite has completed + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @paremt {Number} [config.pixelRatio] pixelRatio of ouput image. Default is 1. + * @example + * var canvas = node.toCanvas(); + */ toCanvas: function(config) { return this._toKonvaCanvas(config)._canvas; }, /** - * Creates a composite data URL. If MIME type is not - * specified, then "image/png" will result. For "image/jpeg", specify a quality - * level as quality (range 0.0 - 1.0) - * @method - * @memberof Konva.Node.prototype - * @param {Object} config - * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". - * "image/png" is the default - * @param {Number} [config.x] x position of canvas section - * @param {Number} [config.y] y position of canvas section - * @param {Number} [config.width] width of canvas section - * @param {Number} [config.height] height of canvas section - * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, - * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 - * is very high quality - * @paremt {Number} [config.pixelRatio] pixelRatio of ouput image url. Default is 1 - * @returns {String} - */ + * Creates a composite data URL. If MIME type is not + * specified, then "image/png" will result. For "image/jpeg", specify a quality + * level as quality (range 0.0 - 1.0) + * @method + * @memberof Konva.Node.prototype + * @param {Object} config + * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". + * "image/png" is the default + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, + * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 + * is very high quality + * @paremt {Number} [config.pixelRatio] pixelRatio of ouput image url. Default is 1 + * @returns {String} + */ toDataURL: function(config) { config = config || {}; var mimeType = config.mimeType || null, @@ -4019,30 +4019,30 @@ return this._toKonvaCanvas(config).toDataURL(mimeType, quality); }, /** - * converts node into an image. Since the toImage - * method is asynchronous, a callback is required. toImage is most commonly used - * to cache complex drawings as an image so that they don't have to constantly be redrawn - * @method - * @memberof Konva.Node.prototype - * @param {Object} config - * @param {Function} config.callback function executed when the composite has completed - * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". - * "image/png" is the default - * @param {Number} [config.x] x position of canvas section - * @param {Number} [config.y] y position of canvas section - * @param {Number} [config.width] width of canvas section - * @param {Number} [config.height] height of canvas section - * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, - * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 - * is very high quality - * @paremt {Number} [config.pixelRatio] pixelRatio of ouput image. Default is 1. - * @example - * var image = node.toImage({ - * callback: function(img) { - * // do stuff with img - * } - * }); - */ + * converts node into an image. Since the toImage + * method is asynchronous, a callback is required. toImage is most commonly used + * to cache complex drawings as an image so that they don't have to constantly be redrawn + * @method + * @memberof Konva.Node.prototype + * @param {Object} config + * @param {Function} config.callback function executed when the composite has completed + * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". + * "image/png" is the default + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, + * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 + * is very high quality + * @paremt {Number} [config.pixelRatio] pixelRatio of ouput image. Default is 1. + * @example + * var image = node.toImage({ + * callback: function(img) { + * // do stuff with img + * } + * }); + */ toImage: function(config) { if (!config || !config.callback) { throw 'callback required for toImage method config argument'; @@ -4069,20 +4069,20 @@ return this.attrs.height || 0; }, /** - * get class name, which may return Stage, Layer, Group, or shape class names like Rect, Circle, Text, etc. - * @method - * @memberof Konva.Node.prototype - * @returns {String} - */ + * get class name, which may return Stage, Layer, Group, or shape class names like Rect, Circle, Text, etc. + * @method + * @memberof Konva.Node.prototype + * @returns {String} + */ getClassName: function() { return this.className || this.nodeType; }, /** - * get the node type, which may return Stage, Layer, Group, or Node - * @method - * @memberof Konva.Node.prototype - * @returns {String} - */ + * get the node type, which may return Stage, Layer, Group, or Node + * @method + * @memberof Konva.Node.prototype + * @returns {String} + */ getType: function() { return this.nodeType; }, @@ -4101,20 +4101,24 @@ ? [this] : []; }, - _off: function(type, name) { + _off: function(type, name, callback) { var evtListeners = this.eventListeners[type], i, - evtName; + evtName, + handler; for (i = 0; i < evtListeners.length; i++) { evtName = evtListeners[i].name; + handler = evtListeners[i].handler; + // the following two conditions must be true in order to remove a handler: // 1) the current event name cannot be konva unless the event name is konva // this enables developers to force remove a konva specific listener for whatever reason // 2) an event name is not specified, or if one is specified, it matches the current event name if ( (evtName !== 'konva' || name === 'konva') && - (!name || evtName === name) + (!name || evtName === name) && + (!callback || callback === handler) ) { evtListeners.splice(i, 1); if (evtListeners.length === 0) { @@ -4164,16 +4168,16 @@ }, // naming methods /** - * add name to node - * @method - * @memberof Konva.Node.prototype - * @param {String} name - * @returns {Konva.Node} - * @example - * node.name('red'); - * node.addName('selected'); - * node.name(); // return 'red selected' - */ + * add name to node + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {Konva.Node} + * @example + * node.name('red'); + * node.addName('selected'); + * node.name(); // return 'red selected' + */ addName: function(name) { if (!this.hasName(name)) { var oldName = this.name(); @@ -4183,32 +4187,32 @@ return this; }, /** - * check is node has name - * @method - * @memberof Konva.Node.prototype - * @param {String} name - * @returns {Boolean} - * @example - * node.name('red'); - * node.hasName('red'); // return true - * node.hasName('selected'); // return false - */ + * check is node has name + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {Boolean} + * @example + * node.name('red'); + * node.hasName('red'); // return true + * node.hasName('selected'); // return false + */ hasName: function(name) { var names = (this.name() || '').split(/\s/g); return names.indexOf(name) !== -1; }, /** - * remove name from node - * @method - * @memberof Konva.Node.prototype - * @param {String} name - * @returns {Konva.Node} - * @example - * node.name('red selected'); - * node.removeName('selected'); - * node.hasName('selected'); // return false - * node.name(); // return 'red' - */ + * remove name from node + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {Konva.Node} + * @example + * node.name('red selected'); + * node.removeName('selected'); + * node.hasName('selected'); // return false + * node.name(); // return 'red' + */ removeName: function(name) { var names = (this.name() || '').split(/\s/g); var index = names.indexOf(name); @@ -4219,15 +4223,15 @@ return this; }, /** - * set attr - * @method - * @memberof Konva.Node.prototype - * @param {String} attr - * @param {*} val - * @returns {Konva.Node} - * @example - * node.setAttr('x', 5); - */ + * set attr + * @method + * @memberof Konva.Node.prototype + * @param {String} attr + * @param {*} val + * @returns {Konva.Node} + * @example + * node.setAttr('x', 5); + */ setAttr: function(attr, val) { var method = SET + Konva.Util._capitalize(attr), func = this[method]; @@ -4333,11 +4337,11 @@ } }, /** - * draw both scene and hit graphs. If the node being drawn is the stage, all of the layers will be cleared and redrawn - * @method - * @memberof Konva.Node.prototype - * @returns {Konva.Node} - */ + * draw both scene and hit graphs. If the node being drawn is the stage, all of the layers will be cleared and redrawn + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ draw: function() { this.drawScene(); this.drawHit(); @@ -4346,18 +4350,18 @@ }); /** - * create node with JSON string or an Object. De-serializtion does not generate custom - * shape drawing functions, images, or event handlers (this would make the - * serialized object huge). If your app uses custom shapes, images, and - * event handlers (it probably does), then you need to select the appropriate - * shapes after loading the stage and set these properties via on(), setDrawFunc(), - * and setImage() methods - * @method - * @memberof Konva.Node - * @param {String|Object} json string or object - * @param {Element} [container] optional container dom element used only if you're - * creating a stage node - */ + * create node with JSON string or an Object. De-serializtion does not generate custom + * shape drawing functions, images, or event handlers (this would make the + * serialized object huge). If your app uses custom shapes, images, and + * event handlers (it probably does), then you need to select the appropriate + * shapes after loading the stage and set these properties via on(), setDrawFunc(), + * and setImage() methods + * @method + * @memberof Konva.Node + * @param {String|Object} json string or object + * @param {Element} [container] optional container dom element used only if you're + * creating a stage node + */ Konva.Node.create = function(data, container) { if (Konva.Util._isString(data)) { data = JSON.parse(data); @@ -4391,58 +4395,58 @@ Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'position'); /** - * get/set node position relative to parent - * @name position - * @method - * @memberof Konva.Node.prototype - * @param {Object} pos - * @param {Number} pos.x - * @param {Number} pos.y - * @returns {Object} - * @example - * // get position - * var position = node.position(); - * - * // set position - * node.position({ - * x: 5 - * y: 10 - * }); - */ + * get/set node position relative to parent + * @name position + * @method + * @memberof Konva.Node.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @returns {Object} + * @example + * // get position + * var position = node.position(); + * + * // set position + * node.position({ + * x: 5 + * y: 10 + * }); + */ Konva.Factory.addGetterSetter(Konva.Node, 'x', 0); /** - * get/set x position - * @name x - * @method - * @memberof Konva.Node.prototype - * @param {Number} x - * @returns {Object} - * @example - * // get x - * var x = node.x(); - * - * // set x - * node.x(5); - */ + * get/set x position + * @name x + * @method + * @memberof Konva.Node.prototype + * @param {Number} x + * @returns {Object} + * @example + * // get x + * var x = node.x(); + * + * // set x + * node.x(5); + */ Konva.Factory.addGetterSetter(Konva.Node, 'y', 0); /** - * get/set y position - * @name y - * @method - * @memberof Konva.Node.prototype - * @param {Number} y - * @returns {Integer} - * @example - * // get y - * var y = node.y(); - * - * // set y - * node.y(5); - */ + * get/set y position + * @name y + * @method + * @memberof Konva.Node.prototype + * @param {Number} y + * @returns {Integer} + * @example + * // get y + * var y = node.y(); + * + * // set y + * node.y(5); + */ Konva.Factory.addGetterSetter( Konva.Node, @@ -4451,358 +4455,358 @@ ); /** - * get/set globalCompositeOperation of a shape - * @name globalCompositeOperation - * @method - * @memberof Konva.Node.prototype - * @param {Number} blur - * @returns {Number} - * @example - * // get shadow blur - * var globalCompositeOperation = shape.globalCompositeOperation(); - * - * // set shadow blur - * shape.globalCompositeOperation('source-in'); - */ + * get/set globalCompositeOperation of a shape + * @name globalCompositeOperation + * @method + * @memberof Konva.Node.prototype + * @param {Number} blur + * @returns {Number} + * @example + * // get shadow blur + * var globalCompositeOperation = shape.globalCompositeOperation(); + * + * // set shadow blur + * shape.globalCompositeOperation('source-in'); + */ Konva.Factory.addGetterSetter(Konva.Node, 'opacity', 1); /** - * get/set opacity. Opacity values range from 0 to 1. - * A node with an opacity of 0 is fully transparent, and a node - * with an opacity of 1 is fully opaque - * @name opacity - * @method - * @memberof Konva.Node.prototype - * @param {Object} opacity - * @returns {Number} - * @example - * // get opacity - * var opacity = node.opacity(); - * - * // set opacity - * node.opacity(0.5); - */ + * get/set opacity. Opacity values range from 0 to 1. + * A node with an opacity of 0 is fully transparent, and a node + * with an opacity of 1 is fully opaque + * @name opacity + * @method + * @memberof Konva.Node.prototype + * @param {Object} opacity + * @returns {Number} + * @example + * // get opacity + * var opacity = node.opacity(); + * + * // set opacity + * node.opacity(0.5); + */ Konva.Factory.addGetter(Konva.Node, 'name'); Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'name'); /** - * get/set name - * @name name - * @method - * @memberof Konva.Node.prototype - * @param {String} name - * @returns {String} - * @example - * // get name - * var name = node.name(); - * - * // set name - * node.name('foo'); - * - * // also node may have multiple names (as css classes) - * node.name('foo bar'); - */ + * get/set name + * @name name + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {String} + * @example + * // get name + * var name = node.name(); + * + * // set name + * node.name('foo'); + * + * // also node may have multiple names (as css classes) + * node.name('foo bar'); + */ Konva.Factory.addGetter(Konva.Node, 'id'); Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'id'); /** - * get/set id. Id is global for whole page. - * @name id - * @method - * @memberof Konva.Node.prototype - * @param {String} id - * @returns {String} - * @example - * // get id - * var name = node.id(); - * - * // set id - * node.id('foo'); - */ + * get/set id. Id is global for whole page. + * @name id + * @method + * @memberof Konva.Node.prototype + * @param {String} id + * @returns {String} + * @example + * // get id + * var name = node.id(); + * + * // set id + * node.id('foo'); + */ Konva.Factory.addGetterSetter(Konva.Node, 'rotation', 0); /** - * get/set rotation in degrees - * @name rotation - * @method - * @memberof Konva.Node.prototype - * @param {Number} rotation - * @returns {Number} - * @example - * // get rotation in degrees - * var rotation = node.rotation(); - * - * // set rotation in degrees - * node.rotation(45); - */ + * get/set rotation in degrees + * @name rotation + * @method + * @memberof Konva.Node.prototype + * @param {Number} rotation + * @returns {Number} + * @example + * // get rotation in degrees + * var rotation = node.rotation(); + * + * // set rotation in degrees + * node.rotation(45); + */ Konva.Factory.addComponentsGetterSetter(Konva.Node, 'scale', ['x', 'y']); /** - * get/set scale - * @name scale - * @param {Object} scale - * @param {Number} scale.x - * @param {Number} scale.y - * @method - * @memberof Konva.Node.prototype - * @returns {Object} - * @example - * // get scale - * var scale = node.scale(); - * - * // set scale - * shape.scale({ - * x: 2 - * y: 3 - * }); - */ + * get/set scale + * @name scale + * @param {Object} scale + * @param {Number} scale.x + * @param {Number} scale.y + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + * @example + * // get scale + * var scale = node.scale(); + * + * // set scale + * shape.scale({ + * x: 2 + * y: 3 + * }); + */ Konva.Factory.addGetterSetter(Konva.Node, 'scaleX', 1); /** - * get/set scale x - * @name scaleX - * @param {Number} x - * @method - * @memberof Konva.Node.prototype - * @returns {Number} - * @example - * // get scale x - * var scaleX = node.scaleX(); - * - * // set scale x - * node.scaleX(2); - */ + * get/set scale x + * @name scaleX + * @param {Number} x + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get scale x + * var scaleX = node.scaleX(); + * + * // set scale x + * node.scaleX(2); + */ Konva.Factory.addGetterSetter(Konva.Node, 'scaleY', 1); /** - * get/set scale y - * @name scaleY - * @param {Number} y - * @method - * @memberof Konva.Node.prototype - * @returns {Number} - * @example - * // get scale y - * var scaleY = node.scaleY(); - * - * // set scale y - * node.scaleY(2); - */ + * get/set scale y + * @name scaleY + * @param {Number} y + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get scale y + * var scaleY = node.scaleY(); + * + * // set scale y + * node.scaleY(2); + */ Konva.Factory.addComponentsGetterSetter(Konva.Node, 'skew', ['x', 'y']); /** - * get/set skew - * @name skew - * @param {Object} skew - * @param {Number} skew.x - * @param {Number} skew.y - * @method - * @memberof Konva.Node.prototype - * @returns {Object} - * @example - * // get skew - * var skew = node.skew(); - * - * // set skew - * node.skew({ - * x: 20 - * y: 10 - * }); - */ + * get/set skew + * @name skew + * @param {Object} skew + * @param {Number} skew.x + * @param {Number} skew.y + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + * @example + * // get skew + * var skew = node.skew(); + * + * // set skew + * node.skew({ + * x: 20 + * y: 10 + * }); + */ Konva.Factory.addGetterSetter(Konva.Node, 'skewX', 0); /** - * get/set skew x - * @name skewX - * @param {Number} x - * @method - * @memberof Konva.Node.prototype - * @returns {Number} - * @example - * // get skew x - * var skewX = node.skewX(); - * - * // set skew x - * node.skewX(3); - */ + * get/set skew x + * @name skewX + * @param {Number} x + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get skew x + * var skewX = node.skewX(); + * + * // set skew x + * node.skewX(3); + */ Konva.Factory.addGetterSetter(Konva.Node, 'skewY', 0); /** - * get/set skew y - * @name skewY - * @param {Number} y - * @method - * @memberof Konva.Node.prototype - * @returns {Number} - * @example - * // get skew y - * var skewY = node.skewY(); - * - * // set skew y - * node.skewY(3); - */ + * get/set skew y + * @name skewY + * @param {Number} y + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get skew y + * var skewY = node.skewY(); + * + * // set skew y + * node.skewY(3); + */ Konva.Factory.addComponentsGetterSetter(Konva.Node, 'offset', ['x', 'y']); /** - * get/set offset. Offsets the default position and rotation point - * @method - * @memberof Konva.Node.prototype - * @param {Object} offset - * @param {Number} offset.x - * @param {Number} offset.y - * @returns {Object} - * @example - * // get offset - * var offset = node.offset(); - * - * // set offset - * node.offset({ - * x: 20 - * y: 10 - * }); - */ + * get/set offset. Offsets the default position and rotation point + * @method + * @memberof Konva.Node.prototype + * @param {Object} offset + * @param {Number} offset.x + * @param {Number} offset.y + * @returns {Object} + * @example + * // get offset + * var offset = node.offset(); + * + * // set offset + * node.offset({ + * x: 20 + * y: 10 + * }); + */ Konva.Factory.addGetterSetter(Konva.Node, 'offsetX', 0); /** - * get/set offset x - * @name offsetX - * @method - * @memberof Konva.Node.prototype - * @param {Number} x - * @returns {Number} - * @example - * // get offset x - * var offsetX = node.offsetX(); - * - * // set offset x - * node.offsetX(3); - */ + * get/set offset x + * @name offsetX + * @method + * @memberof Konva.Node.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get offset x + * var offsetX = node.offsetX(); + * + * // set offset x + * node.offsetX(3); + */ Konva.Factory.addGetterSetter(Konva.Node, 'offsetY', 0); /** - * get/set offset y - * @name offsetY - * @method - * @memberof Konva.Node.prototype - * @param {Number} y - * @returns {Number} - * @example - * // get offset y - * var offsetY = node.offsetY(); - * - * // set offset y - * node.offsetY(3); - */ + * get/set offset y + * @name offsetY + * @method + * @memberof Konva.Node.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get offset y + * var offsetY = node.offsetY(); + * + * // set offset y + * node.offsetY(3); + */ Konva.Factory.addSetter(Konva.Node, 'dragDistance'); Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'dragDistance'); /** - * get/set drag distance - * @name dragDistance - * @method - * @memberof Konva.Node.prototype - * @param {Number} distance - * @returns {Number} - * @example - * // get drag distance - * var dragDistance = node.dragDistance(); - * - * // set distance - * // node starts dragging only if pointer moved more then 3 pixels - * node.dragDistance(3); - * // or set globally - * Konva.dragDistance = 3; - */ + * get/set drag distance + * @name dragDistance + * @method + * @memberof Konva.Node.prototype + * @param {Number} distance + * @returns {Number} + * @example + * // get drag distance + * var dragDistance = node.dragDistance(); + * + * // set distance + * // node starts dragging only if pointer moved more then 3 pixels + * node.dragDistance(3); + * // or set globally + * Konva.dragDistance = 3; + */ Konva.Factory.addSetter(Konva.Node, 'width', 0); Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'width'); /** - * get/set width - * @name width - * @method - * @memberof Konva.Node.prototype - * @param {Number} width - * @returns {Number} - * @example - * // get width - * var width = node.width(); - * - * // set width - * node.width(100); - */ + * get/set width + * @name width + * @method + * @memberof Konva.Node.prototype + * @param {Number} width + * @returns {Number} + * @example + * // get width + * var width = node.width(); + * + * // set width + * node.width(100); + */ Konva.Factory.addSetter(Konva.Node, 'height', 0); Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'height'); /** - * get/set height - * @name height - * @method - * @memberof Konva.Node.prototype - * @param {Number} height - * @returns {Number} - * @example - * // get height - * var height = node.height(); - * - * // set height - * node.height(100); - */ + * get/set height + * @name height + * @method + * @memberof Konva.Node.prototype + * @param {Number} height + * @returns {Number} + * @example + * // get height + * var height = node.height(); + * + * // set height + * node.height(100); + */ Konva.Factory.addGetterSetter(Konva.Node, 'listening', 'inherit'); /** - * get/set listenig attr. If you need to determine if a node is listening or not - * by taking into account its parents, use the isListening() method - * @name listening - * @method - * @memberof Konva.Node.prototype - * @param {Boolean|String} listening Can be "inherit", true, or false. The default is "inherit". - * @returns {Boolean|String} - * @example - * // get listening attr - * var listening = node.listening(); - * - * // stop listening for events - * node.listening(false); - * - * // listen for events - * node.listening(true); - * - * // listen to events according to the parent - * node.listening('inherit'); - */ + * get/set listenig attr. If you need to determine if a node is listening or not + * by taking into account its parents, use the isListening() method + * @name listening + * @method + * @memberof Konva.Node.prototype + * @param {Boolean|String} listening Can be "inherit", true, or false. The default is "inherit". + * @returns {Boolean|String} + * @example + * // get listening attr + * var listening = node.listening(); + * + * // stop listening for events + * node.listening(false); + * + * // listen for events + * node.listening(true); + * + * // listen to events according to the parent + * node.listening('inherit'); + */ /** - * get/set preventDefault - * By default all shapes will prevent default behaviour - * of a browser on a pointer move or tap. - * that will prevent native scrolling when you are trying to drag&drop a node - * but sometimes you may need to enable default actions - * in that case you can set the property to false - * @name preventDefault - * @method - * @memberof Konva.Node.prototype - * @param {Number} preventDefault - * @returns {Number} - * @example - * // get preventDefault - * var shouldPrevent = shape.preventDefault(); - * - * // set preventDefault - * shape.preventDefault(false); - */ + * get/set preventDefault + * By default all shapes will prevent default behaviour + * of a browser on a pointer move or tap. + * that will prevent native scrolling when you are trying to drag&drop a node + * but sometimes you may need to enable default actions + * in that case you can set the property to false + * @name preventDefault + * @method + * @memberof Konva.Node.prototype + * @param {Number} preventDefault + * @returns {Number} + * @example + * // get preventDefault + * var shouldPrevent = shape.preventDefault(); + * + * // set preventDefault + * shape.preventDefault(false); + */ Konva.Factory.addGetterSetter(Konva.Node, 'preventDefault', true); @@ -4813,92 +4817,92 @@ return val; }); /** - * get/set filters. Filters are applied to cached canvases - * @name filters - * @method - * @memberof Konva.Node.prototype - * @param {Array} filters array of filters - * @returns {Array} - * @example - * // get filters - * var filters = node.filters(); - * - * // set a single filter - * node.cache(); - * node.filters([Konva.Filters.Blur]); - * - * // set multiple filters - * node.cache(); - * node.filters([ - * Konva.Filters.Blur, - * Konva.Filters.Sepia, - * Konva.Filters.Invert - * ]); - */ + * get/set filters. Filters are applied to cached canvases + * @name filters + * @method + * @memberof Konva.Node.prototype + * @param {Array} filters array of filters + * @returns {Array} + * @example + * // get filters + * var filters = node.filters(); + * + * // set a single filter + * node.cache(); + * node.filters([Konva.Filters.Blur]); + * + * // set multiple filters + * node.cache(); + * node.filters([ + * Konva.Filters.Blur, + * Konva.Filters.Sepia, + * Konva.Filters.Invert + * ]); + */ Konva.Factory.addGetterSetter(Konva.Node, 'visible', 'inherit'); /** - * get/set visible attr. Can be "inherit", true, or false. The default is "inherit". - * If you need to determine if a node is visible or not - * by taking into account its parents, use the isVisible() method - * @name visible - * @method - * @memberof Konva.Node.prototype - * @param {Boolean|String} visible - * @returns {Boolean|String} - * @example - * // get visible attr - * var visible = node.visible(); - * - * // make invisible - * node.visible(false); - * - * // make visible - * node.visible(true); - * - * // make visible according to the parent - * node.visible('inherit'); - */ + * get/set visible attr. Can be "inherit", true, or false. The default is "inherit". + * If you need to determine if a node is visible or not + * by taking into account its parents, use the isVisible() method + * @name visible + * @method + * @memberof Konva.Node.prototype + * @param {Boolean|String} visible + * @returns {Boolean|String} + * @example + * // get visible attr + * var visible = node.visible(); + * + * // make invisible + * node.visible(false); + * + * // make visible + * node.visible(true); + * + * // make visible according to the parent + * node.visible('inherit'); + */ Konva.Factory.addGetterSetter(Konva.Node, 'transformsEnabled', 'all'); /** - * get/set transforms that are enabled. Can be "all", "none", or "position". The default - * is "all" - * @name transformsEnabled - * @method - * @memberof Konva.Node.prototype - * @param {String} enabled - * @returns {String} - * @example - * // enable position transform only to improve draw performance - * node.transformsEnabled('position'); - * - * // enable all transforms - * node.transformsEnabled('all'); - */ + * get/set transforms that are enabled. Can be "all", "none", or "position". The default + * is "all" + * @name transformsEnabled + * @method + * @memberof Konva.Node.prototype + * @param {String} enabled + * @returns {String} + * @example + * // enable position transform only to improve draw performance + * node.transformsEnabled('position'); + * + * // enable all transforms + * node.transformsEnabled('all'); + */ /** - * get/set node size - * @name size - * @method - * @memberof Konva.Node.prototype - * @param {Object} size - * @param {Number} size.width - * @param {Number} size.height - * @returns {Object} - * @example - * // get node size - * var size = node.size(); - * var x = size.x; - * var y = size.y; - * - * // set size - * node.size({ - * width: 100, - * height: 200 - * }); - */ + * get/set node size + * @name size + * @method + * @memberof Konva.Node.prototype + * @param {Object} size + * @param {Number} size.width + * @param {Number} size.height + * @returns {Object} + * @example + * // get node size + * var size = node.size(); + * var x = size.x; + * var y = size.y; + * + * // set size + * node.size({ + * width: 100, + * height: 200 + * }); + */ Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'size'); Konva.Factory.backCompat(Konva.Node, { diff --git a/konva.min.js b/konva.min.js index 6d172b2c..4e5fe97f 100644 --- a/konva.min.js +++ b/konva.min.js @@ -26,7 +26,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -!function(){"use strict";var t=Math.PI/180,e={version:"1.7.6",stages:[],idCounter:0,ids:{},names:{},shapes:{},listenClickTap:!1,inDblClickWindow:!1,isBrowser:"undefined"!=typeof window&&("[object Window]"==={}.toString.call(window)||"[object global]"==={}.toString.call(window)),enableTrace:!1,traceArrMax:100,dblClickWindow:400,pixelRatio:void 0,dragDistance:3,angleDeg:!0,showWarnings:!0,Filters:{},isDragging:function(){var t=e.DD;return!!t&&t.isDragging},isDragReady:function(){var t=e.DD;return!!t&&!!t.node},_addId:function(t,e){void 0!==e&&(this.ids[e]=t)},_removeId:function(t){void 0!==t&&delete this.ids[t]},_addName:function(t,e){e&&(this.names[e]||(this.names[e]=[]),this.names[e].push(t))},_removeName:function(t,e){if(t){var n=this.names[t];if(n){for(var i=0;i0)return parseInt(t.substring(e+5,t.indexOf(".",e)),10);if(t.indexOf("trident/")>0){var n=t.indexOf("rv:");return parseInt(t.substring(n+3,t.indexOf(".",n)),10)}var i=t.indexOf("edge/");return i>0&&parseInt(t.substring(i+5,t.indexOf(".",i)),10)},_parseUA:function(t){var n=t.toLowerCase(),i=/(chrome)[ /]([\w.]+)/.exec(n)||/(webkit)[ /]([\w.]+)/.exec(n)||/(opera)(?:.*version|)[ /]([\w.]+)/.exec(n)||/(msie) ([\w.]+)/.exec(n)||n.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(n)||[],a=!!t.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i),r=!!t.match(/IEMobile/i);return{browser:i[1]||"",version:i[2]||"0",isIE:e._detectIE(n),mobile:a,ieMobile:r}},UA:void 0},n="undefined"!=typeof global?global:"undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope?self:{};e.UA=e._parseUA(n.navigator&&n.navigator.userAgent||""),n.Konva&&console.error("Konva instance is already exist in current eviroment. Please use only one instance."),n.Konva=e,e.global=n,e.window=n,e.document=n.document,"object"==typeof exports?module.exports=e:"function"==typeof define&&define.amd&&define(function(){return e})}(),function(){"use strict";Konva.Collection=function(){var t=[].slice.call(arguments),e=t.length,n=0;for(this.length=e;n0},isValidSelector:function(t){if("string"!=typeof t)return!1;var e=t[0];return"#"===e||"."===e||e===e.toUpperCase()},createCanvasElement:function(){var t=Konva.isBrowser?Konva.document.createElement("canvas"):new Konva._nodeCanvas;try{t.style=t.style||{}}catch(t){}return t},_isInDocument:function(t){for(;t=t.parentNode;)if(t==Konva.document)return!0;return!1},_simplifyArray:function(t){var e,n,i=[],a=t.length,r=Konva.Util;for(e=0;e>16&255,g:e>>8&255,b:255&e}},getRandomColor:function(){for(var t=(16777215*Math.random()<<0).toString(16);t.length<6;)t="0"+t;return"#"+t},get:function(t,e){return void 0===t?e:t},getRGB:function(t){var e;return t in i?(e=i[t],{r:e[0],g:e[1],b:e[2]}):"#"===t[0]?this._hexToRgb(t.substring(1)):"rgb("===t.substr(0,4)?(e=a.exec(t.replace(/ /g,"")),{r:parseInt(e[1],10),g:parseInt(e[2],10),b:parseInt(e[3],10)}):{r:0,g:0,b:0}},colorToRGBA:function(t){return t=t||"black",Konva.Util._namedColorToRBA(t)||Konva.Util._hex3ColorToRGBA(t)||Konva.Util._hex6ColorToRGBA(t)||Konva.Util._rgbColorToRGBA(t)||Konva.Util._rgbaColorToRGBA(t)},_namedColorToRBA:function(t){var e=i[t.toLowerCase()];return e?{r:e[0],g:e[1],b:e[2],a:1}:null},_rgbColorToRGBA:function(t){if(0===t.indexOf("rgb(")){var e=(t=t.match(/rgb\(([^)]+)\)/)[1]).split(/ *, */).map(Number);return{r:e[0],g:e[1],b:e[2],a:1}}},_rgbaColorToRGBA:function(t){if(0===t.indexOf("rgba(")){var e=(t=t.match(/rgba\(([^)]+)\)/)[1]).split(/ *, */).map(Number);return{r:e[0],g:e[1],b:e[2],a:e[3]}}},_hex6ColorToRGBA:function(t){if("#"===t[0]&&7===t.length)return{r:parseInt(t.slice(1,3),16),g:parseInt(t.slice(3,5),16),b:parseInt(t.slice(5,7),16),a:1}},_hex3ColorToRGBA:function(t){if("#"===t[0]&&4===t.length)return{r:parseInt(t[1]+t[1],16),g:parseInt(t[2]+t[2],16),b:parseInt(t[3]+t[3],16),a:1}},_merge:function(t,e){var n=this._clone(e);for(var i in t)this._isObject(t[i])?n[i]=this._merge(t[i],n[i]):n[i]=t[i];return n},cloneObject:function(t){var e={};for(var n in t)this._isObject(t[n])?e[n]=this.cloneObject(t[n]):this._isArray(t[n])?e[n]=this.cloneArray(t[n]):e[n]=t[n];return e},cloneArray:function(t){return t.slice(0)},_degToRad:function(e){return e*t},_radToDeg:function(t){return t*e},_capitalize:function(t){return t.charAt(0).toUpperCase()+t.slice(1)},throw:function(t){throw new Error(n+t)},error:function(t){console.error(n+t)},warn:function(t){Konva.global.console&&console.warn&&Konva.showWarnings&&console.warn("Konva warning: "+t)},extend:function(t,e){function n(){this.constructor=t}n.prototype=e.prototype;var i=t.prototype;t.prototype=new n;for(var a in i)i.hasOwnProperty(a)&&(t.prototype[a]=i[a]);t.__super__=e.prototype,t.super=e},addMethods:function(t,e){var n;for(n in e)t.prototype[n]=e[n]},_getControlPoints:function(t,e,n,i,a,r,o){var s=Math.sqrt(Math.pow(n-t,2)+Math.pow(i-e,2)),h=Math.sqrt(Math.pow(a-n,2)+Math.pow(r-i,2)),c=o*s/(s+h),l=o*h/(s+h);return[n-c*(a-t),i-c*(r-e),n+l*(a-t),i+l*(r-e)]},_expandPoints:function(t,e){var n,i,a=t.length,r=[];for(n=2;n1?(o=n,s=i,h=(n-a)*(n-a)+(i-r)*(i-r)):h=((o=t+l*(n-t))-a)*(o-a)+((s=e+l*(i-e))-r)*(s-r)}return[o,s,h]},_getProjectionToLine:function(t,e,n){var i=Konva.Util.cloneObject(t),a=Number.MAX_VALUE;return e.forEach(function(r,o){if(n||o!==e.length-1){var s=e[(o+1)%e.length],h=Konva.Util._getProjectionToSegment(r.x,r.y,s.x,s.y,t.x,t.y),c=h[0],l=h[1],d=h[2];de.length){var o=e;e=t,t=o}for(i=0;i=Konva.traceArrMax&&e.shift()},reset:function(){var t=this.getCanvas().getPixelRatio();this.setTransform(1*t,0,0,1*t,0,0)},getCanvas:function(){return this.canvas},clear:function(t){var e=this.getCanvas();t?this.clearRect(t.x||0,t.y||0,t.width||0,t.height||0):this.clearRect(0,0,e.getWidth()/e.pixelRatio,e.getHeight()/e.pixelRatio)},_applyLineCap:function(t){var e=t.getLineCap();e&&this.setAttr("lineCap",e)},_applyOpacity:function(t){var e=t.getAbsoluteOpacity();1!==e&&this.setAttr("globalAlpha",e)},_applyLineJoin:function(t){var e=t.getLineJoin();e&&this.setAttr("lineJoin",e)},setAttr:function(t,e){this._context[t]=e},arc:function(){var t=arguments;this._context.arc(t[0],t[1],t[2],t[3],t[4],t[5])},beginPath:function(){this._context.beginPath()},bezierCurveTo:function(){var t=arguments;this._context.bezierCurveTo(t[0],t[1],t[2],t[3],t[4],t[5])},clearRect:function(){var t=arguments;this._context.clearRect(t[0],t[1],t[2],t[3])},clip:function(){this._context.clip()},closePath:function(){this._context.closePath()},createImageData:function(){var t=arguments;return 2===t.length?this._context.createImageData(t[0],t[1]):1===t.length?this._context.createImageData(t[0]):void 0},createLinearGradient:function(){var t=arguments;return this._context.createLinearGradient(t[0],t[1],t[2],t[3])},createPattern:function(){var t=arguments;return this._context.createPattern(t[0],t[1])},createRadialGradient:function(){var t=arguments;return this._context.createRadialGradient(t[0],t[1],t[2],t[3],t[4],t[5])},drawImage:function(){var t=arguments,e=this._context;3===t.length?e.drawImage(t[0],t[1],t[2]):5===t.length?e.drawImage(t[0],t[1],t[2],t[3],t[4]):9===t.length&&e.drawImage(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},isPointInPath:function(t,e){return this._context.isPointInPath(t,e)},fill:function(){this._context.fill()},fillRect:function(t,e,n,i){this._context.fillRect(t,e,n,i)},strokeRect:function(t,e,n,i){this._context.strokeRect(t,e,n,i)},fillText:function(){var t=arguments;this._context.fillText(t[0],t[1],t[2])},measureText:function(t){return this._context.measureText(t)},getImageData:function(){var t=arguments;return this._context.getImageData(t[0],t[1],t[2],t[3])},lineTo:function(){var t=arguments;this._context.lineTo(t[0],t[1])},moveTo:function(){var t=arguments;this._context.moveTo(t[0],t[1])},rect:function(){var t=arguments;this._context.rect(t[0],t[1],t[2],t[3])},putImageData:function(){var t=arguments;this._context.putImageData(t[0],t[1],t[2])},quadraticCurveTo:function(){var t=arguments;this._context.quadraticCurveTo(t[0],t[1],t[2],t[3])},restore:function(){this._context.restore()},rotate:function(){var t=arguments;this._context.rotate(t[0])},save:function(){this._context.save()},scale:function(){var t=arguments;this._context.scale(t[0],t[1])},setLineDash:function(){var t=arguments,e=this._context;this._context.setLineDash?e.setLineDash(t[0]):"mozDash"in e?e.mozDash=t[0]:"webkitLineDash"in e&&(e.webkitLineDash=t[0])},getLineDash:function(){return this._context.getLineDash()},setTransform:function(){var t=arguments;this._context.setTransform(t[0],t[1],t[2],t[3],t[4],t[5])},stroke:function(){this._context.stroke()},strokeText:function(){var t=arguments;this._context.strokeText(t[0],t[1],t[2])},transform:function(){var t=arguments;this._context.transform(t[0],t[1],t[2],t[3],t[4],t[5])},translate:function(){var t=arguments;this._context.translate(t[0],t[1])},_enableTrace:function(){var e,n,i=this,a=t.length,r=Konva.Util._simplifyArray,o=this.setAttr,s=function(t){var e,a=i[t];i[t]=function(){return n=r(Array.prototype.slice.call(arguments,0)),e=a.apply(i,arguments),i._trace({method:t,args:n}),e}};for(e=0;e255?255:t<0?0:Math.round(t)},alphaComponent:function(t){return t>1?1:t<1e-4?1e-4:t}}}(),function(t){"use strict";var e="absoluteOpacity",n="absoluteTransform",i="absoluteScale",a="listening",r="Shape",o="transform",s=["id"],h=["xChange.konva","yChange.konva","scaleXChange.konva","scaleYChange.konva","skewXChange.konva","skewYChange.konva","rotationChange.konva","offsetXChange.konva","offsetYChange.konva","transformsEnabledChange.konva"].join(" "),c=["scaleXChange.konva","scaleYChange.konva"].join(" ");t.Node=function(t){this._init(t)},t.Util.addMethods(t.Node,{_init:function(r){var s=this;this._id=t.idCounter++,this.eventListeners={},this.attrs={},this._cache={},this._filterUpToDate=!1,this._isUnderCache=!1,this.setAttrs(r),this.on(h,function(){this._clearCache(o),s._clearSelfAndDescendantCache(n)}),this.on(c,function(){s._clearSelfAndDescendantCache(i)}),this.on("visibleChange.konva",function(){s._clearSelfAndDescendantCache("visible")}),this.on("listeningChange.konva",function(){s._clearSelfAndDescendantCache(a)}),this.on("opacityChange.konva",function(){s._clearSelfAndDescendantCache(e)})},_clearCache:function(t){t?delete this._cache[t]:this._cache={}},_getCache:function(t,e){return void 0===this._cache[t]&&(this._cache[t]=e.call(this)),this._cache[t]},_clearSelfAndDescendantCache:function(t){this._clearCache(t),this.children&&this.getChildren().each(function(e){e._clearSelfAndDescendantCache(t)})},clearCache:function(){return delete this._cache.canvas,this._filterUpToDate=!1,this},cache:function(n){var a=n||{},r=this.getClientRect({skipTransform:!0,relativeTo:this.getParent()}),o=a.width||r.width,s=a.height||r.height,h=a.pixelRatio,c=a.x||r.x,l=a.y||r.y,d=a.offset||0,u=a.drawBorder||!1;{if(o&&s){o+=2*d,s+=2*d,c-=d,l-=d;var f=new t.SceneCanvas({pixelRatio:h,width:o,height:s}),g=new t.SceneCanvas({pixelRatio:h,width:o,height:s}),v=new t.HitCanvas({pixelRatio:1,width:o,height:s}),p=f.getContext(),m=v.getContext();return v.isCache=!0,this.clearCache(),p.save(),m.save(),p.translate(-c,-l),m.translate(-c,-l),this._isUnderCache=!0,this._clearSelfAndDescendantCache(e),this._clearSelfAndDescendantCache(i),this.drawScene(f,this,!0),this.drawHit(v,this,!0),this._isUnderCache=!1,p.restore(),m.restore(),u&&(p.save(),p.beginPath(),p.rect(0,0,o,s),p.closePath(),p.setAttr("strokeStyle","red"),p.setAttr("lineWidth",5),p.stroke(),p.restore()),this._cache.canvas={scene:f,filter:g,hit:v,x:c,y:l},this}setTimeout(function(){t.Util.throw("Width or height of caching configuration equals 0. Caching is ignored.")})}},getClientRect:function(){throw new Error('abstract "getClientRect" method call')},_transformedRect:function(t,e){var n,i,a,r,o=[{x:t.x,y:t.y},{x:t.x+t.width,y:t.y},{x:t.x+t.width,y:t.y+t.height},{x:t.x,y:t.y+t.height}],s=this.getAbsoluteTransform(e);return o.forEach(function(t){var e=s.point(t);void 0===n&&(n=a=e.x,i=r=e.y),n=Math.min(n,e.x),i=Math.min(i,e.y),a=Math.max(a,e.x),r=Math.max(r,e.y)}),{x:n,y:i,width:a-n,height:r-i}},_drawCachedSceneCanvas:function(t){t.save(),t._applyOpacity(this),t._applyGlobalCompositeOperation(this),t.translate(this._cache.canvas.x,this._cache.canvas.y);var e=this._getCachedSceneCanvas(),n=e.pixelRatio;t.drawImage(e._canvas,0,0,e.width/n,e.height/n),t.restore()},_drawCachedHitCanvas:function(t){var e=this._cache.canvas.hit;t.save(),t.translate(this._cache.canvas.x,this._cache.canvas.y),t.drawImage(e._canvas,0,0),t.restore()},_getCachedSceneCanvas:function(){var e,n,i,a,r=this.filters(),o=this._cache.canvas,s=o.scene,h=o.filter,c=h.getContext();if(r){if(!this._filterUpToDate){var l=s.pixelRatio;try{for(e=r.length,c.clear(),c.drawImage(s._canvas,0,0,s.getWidth()/l,s.getHeight()/l),n=c.getImageData(0,0,h.getWidth(),h.getHeight()),i=0;i0&&e[0].getDepth()<=o&&t(e)}var e,n,i,a,o=this.getDepth(),s=this,h=0;return"Stage"!==s.nodeType&&t(s.getStage().getChildren()),h},getDepth:function(){for(var t=0,e=this.parent;e;)t++,e=e.parent;return t},setPosition:function(t){return this.setX(t.x),this.setY(t.y),this},getPosition:function(){return{x:this.getX(),y:this.getY()}},getAbsolutePosition:function(e){var n=this.getAbsoluteTransform(e).getMatrix(),i=new t.Transform,a=this.offset();return i.m=n.slice(),i.translate(a.x,a.y),i.getTranslation()},setAbsolutePosition:function(t){var e,n=this._clearTransform();return this.attrs.x=n.x,this.attrs.y=n.y,delete n.x,delete n.y,(e=this.getAbsoluteTransform()).invert(),e.translate(t.x,t.y),t={x:this.attrs.x+e.getTranslation().x,y:this.attrs.y+e.getTranslation().y},this.setPosition({x:t.x,y:t.y}),this._setTransform(n),this},_setTransform:function(t){var e;for(e in t)this.attrs[e]=t[e];this._clearCache(o),this._clearSelfAndDescendantCache(n)},_clearTransform:function(){var t={x:this.getX(),y:this.getY(),rotation:this.getRotation(),scaleX:this.getScaleX(),scaleY:this.getScaleY(),offsetX:this.getOffsetX(),offsetY:this.getOffsetY(),skewX:this.getSkewX(),skewY:this.getSkewY()};return this.attrs.x=0,this.attrs.y=0,this.attrs.rotation=0,this.attrs.scaleX=1,this.attrs.scaleY=1,this.attrs.offsetX=0,this.attrs.offsetY=0,this.attrs.skewX=0,this.attrs.skewY=0,this._clearCache(o),this._clearSelfAndDescendantCache(n),t},move:function(t){var e=t.x,n=t.y,i=this.getX(),a=this.getY();return void 0!==e&&(i+=e),void 0!==n&&(a+=n),this.setPosition({x:i,y:a}),this},_eachAncestorReverse:function(t,e){var n,i,a=[],r=this.getParent();if(e&&e._id===this._id)return t(this),!0;for(a.unshift(this);r&&(!e||r._id!==e._id);)a.unshift(r),r=r.parent;for(n=a.length,i=0;i0&&(this.parent.children.splice(e,1),this.parent.children.splice(e-1,0,this),this.parent._setChildrenIndices(),!0)},moveToBottom:function(){if(!this.parent)return t.Util.warn("Node has no parent. moveToBottom function is ignored."),!1;var e=this.index;return e>0&&(this.parent.children.splice(e,1),this.parent.children.unshift(this),this.parent._setChildrenIndices(),!0)},setZIndex:function(e){if(!this.parent)return t.Util.warn("Node has no parent. zIndex parameter is ignored."),!1;var n=this.index;return this.parent.children.splice(n,1),this.parent.children.splice(e,0,this),this.parent._setChildrenIndices(),this},getAbsoluteOpacity:function(){return this._getCache(e,this._getAbsoluteOpacity)},_getAbsoluteOpacity:function(){var t=this.getOpacity(),e=this.getParent();return e&&!e._isUnderCache&&(t*=this.getParent().getAbsoluteOpacity()),t},moveTo:function(t){return this.getParent()!==t&&((this.__originalRemove||this.remove).call(this),t.add(this)),this},toObject:function(){var e,n,i,a,r={},o=this.getAttrs();r.attrs={};for(e in o)n=o[e],i=this[e],delete o[e],a=i?i.call(this):null,o[e]=n,a!==n&&(r.attrs[e]=n);return r.className=this.getClassName(),t.Util._prepareToStringify(r)},toJSON:function(){return JSON.stringify(this.toObject())},getParent:function(){return this.parent},findAncestors:function(t,e,n){var i=[];e&&this._isMatch(t)&&i.push(this);for(var a=this.parent;a;){if(a===n)return i;a._isMatch(t)&&i.push(a),a=a.parent}return i},findAncestor:function(t,e,n){return this.findAncestors(t,e,n)[0]},_isMatch:function(e){if(!e)return!1;var n,i,a=e.replace(/ /g,"").split(","),r=a.length;for(n=0;n0&&function(t,a){var r,o,s,h,c,l,d,u,f,g,v,p,m,_,y,S,K,x,C,w,b,F,T,P,A=t.data,M=t.width,k=t.height,G=a+a+1,D=M-1,R=k-1,L=a+1,O=L*(L+1)/2,I=new e,N=null,U=I,E=null,B=null,H=n[a],W=i[a];for(s=1;s>W,0!==T?(T=255/T,A[l]=(u*H>>W)*T,A[l+1]=(f*H>>W)*T,A[l+2]=(g*H>>W)*T):A[l]=A[l+1]=A[l+2]=0,u-=p,f-=m,g-=_,v-=y,p-=E.r,m-=E.g,_-=E.b,y-=E.a,h=d+((h=r+a+1)>W,T>0?(T=255/T,A[h]=(u*H>>W)*T,A[h+1]=(f*H>>W)*T,A[h+2]=(g*H>>W)*T):A[h]=A[h+1]=A[h+2]=0,u-=p,f-=m,g-=_,v-=y,p-=E.r,m-=E.g,_-=E.b,y-=E.a,h=r+((h=o+L)=0&&f=0&&g=0&&f=0&&g=1020?255:0}return o}(i=function(t,e,n){for(var i=[1,1,1,1,0,1,1,1,1],a=Math.round(Math.sqrt(i.length)),r=Math.floor(a/2),o=[],s=0;s=0&&f=0&&g255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"green",0,function(t){return this._filterUpToDate=!1,t>255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"blue",0,Konva.Validators.RGBComponent,Konva.Factory.afterSetFilter)}(),function(){"use strict";Konva.Filters.RGBA=function(t){var e,n,i=t.data,a=i.length,r=this.red(),o=this.green(),s=this.blue(),h=this.alpha();for(e=0;e255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"green",0,function(t){return this._filterUpToDate=!1,t>255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"blue",0,Konva.Validators.RGBComponent,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"alpha",1,function(t){return this._filterUpToDate=!1,t>1?1:t<0?0:t})}(),function(){"use strict";Konva.Filters.HSV=function(t){var e,n,i,a,r,o=t.data,s=o.length,h=Math.pow(2,this.value()),c=Math.pow(2,this.saturation()),l=Math.abs(this.hue()+360)%360,d=h*c*Math.cos(l*Math.PI/180),u=h*c*Math.sin(l*Math.PI/180),f=.299*h+.701*d+.167*u,g=.587*h-.587*d+.33*u,v=.114*h-.114*d-.497*u,p=.299*h-.299*d-.328*u,m=.587*h+.413*d+.035*u,_=.114*h-.114*d+.293*u,y=.299*h-.3*d+1.25*u,S=.587*h-.586*d-1.05*u,K=.114*h+.886*d-.2*u;for(e=0;ec&&(f=0);var g=(d-1+f)*h*4,v=h;do{var p=u+4*(v-1),m=o;v+m<1&&(m=0),v+m>h&&(m=0);var _=g+4*(v-1+m),y=s[p]-s[_],S=s[p+1]-s[_+1],K=s[p+2]-s[_+2],x=y,C=x>0?x:-x;if((S>0?S:-S)>C&&(x=S),(K>0?K:-K)>C&&(x=K),x*=e,a){var w=s[p]+x,b=s[p+1]+x,F=s[p+2]+x;s[p]=w>255?255:w<0?0:w,s[p+1]=b>255?255:b<0?0:b,s[p+2]=F>255?255:F<0?0:F}else{var T=n-x;T<0?T=0:T>255&&(T=255),s[p]=s[p+1]=s[p+2]=T}}while(--v)}while(--d)},Konva.Factory.addGetterSetter(Konva.Node,"embossStrength",.5,null,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"embossWhiteLevel",.5,null,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"embossDirection","top-left",null,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"embossBlend",!1,null,Konva.Factory.afterSetFilter)}(),function(){"use strict";function t(t,e,n,i,a){var r,o=n-e,s=a-i;return 0===o?i+s/2:0===s?i:(r=(t-e)/o,r=s*r+i)}Konva.Filters.Enhance=function(e){var n,i,a,r,o=e.data,s=o.length,h=o[0],c=h,l=o[1],d=l,u=o[2],f=u,g=this.enhance();if(0!==g){for(r=0;rc&&(c=n),(i=o[r+1])d&&(d=i),(a=o[r+2])f&&(f=a);c===h&&(c=255,h=0),d===l&&(d=255,l=0),f===u&&(f=255,u=0);var v,p,m,_,y,S,K,x,C;for(g>0?(p=c+g*(255-c),m=h-g*(h-0),y=d+g*(255-d),S=l-g*(l-0),x=f+g*(255-f),C=u-g*(u-0)):(p=c+g*(c-(v=.5*(c+h))),m=h+g*(h-v),y=d+g*(d-(_=.5*(d+l))),S=l+g*(l-_),x=f+g*(f-(K=.5*(f+u))),C=u+g*(u-K)),r=0;r=p))for(n=l;n=m||(a+=t[(i=4*(p*n+e))+0],r+=t[i+1],o+=t[i+2],s+=t[i+3],g+=1);for(a/=g,r/=g,o/=g,e=h;e=p))for(n=l;n=m||(t[(i=4*(p*n+e))+0]=a,t[i+1]=r,t[i+2]=o,t[i+3]=s)}},Konva.Factory.addGetterSetter(Konva.Node,"pixelSize",8,null,Konva.Factory.afterSetFilter)}(),function(){"use strict";Konva.Filters.Threshold=function(t){var e,n=255*this.threshold(),i=t.data,a=i.length;for(e=0;e0)return parseInt(t.substring(e+5,t.indexOf(".",e)),10);if(t.indexOf("trident/")>0){var n=t.indexOf("rv:");return parseInt(t.substring(n+3,t.indexOf(".",n)),10)}var i=t.indexOf("edge/");return i>0&&parseInt(t.substring(i+5,t.indexOf(".",i)),10)},_parseUA:function(t){var n=t.toLowerCase(),i=/(chrome)[ /]([\w.]+)/.exec(n)||/(webkit)[ /]([\w.]+)/.exec(n)||/(opera)(?:.*version|)[ /]([\w.]+)/.exec(n)||/(msie) ([\w.]+)/.exec(n)||n.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(n)||[],a=!!t.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i),r=!!t.match(/IEMobile/i);return{browser:i[1]||"",version:i[2]||"0",isIE:e._detectIE(n),mobile:a,ieMobile:r}},UA:void 0},n="undefined"!=typeof global?global:"undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope?self:{};e.UA=e._parseUA(n.navigator&&n.navigator.userAgent||""),n.Konva&&console.error("Konva instance is already exist in current eviroment. Please use only one instance."),n.Konva=e,e.global=n,e.window=n,e.document=n.document,"object"==typeof exports?module.exports=e:"function"==typeof define&&define.amd&&define(function(){return e})}(),function(){"use strict";Konva.Collection=function(){var t=[].slice.call(arguments),e=t.length,n=0;for(this.length=e;n0},isValidSelector:function(t){if("string"!=typeof t)return!1;var e=t[0];return"#"===e||"."===e||e===e.toUpperCase()},createCanvasElement:function(){var t=Konva.isBrowser?Konva.document.createElement("canvas"):new Konva._nodeCanvas;try{t.style=t.style||{}}catch(t){}return t},_isInDocument:function(t){for(;t=t.parentNode;)if(t==Konva.document)return!0;return!1},_simplifyArray:function(t){var e,n,i=[],a=t.length,r=Konva.Util;for(e=0;e>16&255,g:e>>8&255,b:255&e}},getRandomColor:function(){for(var t=(16777215*Math.random()<<0).toString(16);t.length<6;)t="0"+t;return"#"+t},get:function(t,e){return void 0===t?e:t},getRGB:function(t){var e;return t in i?(e=i[t],{r:e[0],g:e[1],b:e[2]}):"#"===t[0]?this._hexToRgb(t.substring(1)):"rgb("===t.substr(0,4)?(e=a.exec(t.replace(/ /g,"")),{r:parseInt(e[1],10),g:parseInt(e[2],10),b:parseInt(e[3],10)}):{r:0,g:0,b:0}},colorToRGBA:function(t){return t=t||"black",Konva.Util._namedColorToRBA(t)||Konva.Util._hex3ColorToRGBA(t)||Konva.Util._hex6ColorToRGBA(t)||Konva.Util._rgbColorToRGBA(t)||Konva.Util._rgbaColorToRGBA(t)},_namedColorToRBA:function(t){var e=i[t.toLowerCase()];return e?{r:e[0],g:e[1],b:e[2],a:1}:null},_rgbColorToRGBA:function(t){if(0===t.indexOf("rgb(")){var e=(t=t.match(/rgb\(([^)]+)\)/)[1]).split(/ *, */).map(Number);return{r:e[0],g:e[1],b:e[2],a:1}}},_rgbaColorToRGBA:function(t){if(0===t.indexOf("rgba(")){var e=(t=t.match(/rgba\(([^)]+)\)/)[1]).split(/ *, */).map(Number);return{r:e[0],g:e[1],b:e[2],a:e[3]}}},_hex6ColorToRGBA:function(t){if("#"===t[0]&&7===t.length)return{r:parseInt(t.slice(1,3),16),g:parseInt(t.slice(3,5),16),b:parseInt(t.slice(5,7),16),a:1}},_hex3ColorToRGBA:function(t){if("#"===t[0]&&4===t.length)return{r:parseInt(t[1]+t[1],16),g:parseInt(t[2]+t[2],16),b:parseInt(t[3]+t[3],16),a:1}},_merge:function(t,e){var n=this._clone(e);for(var i in t)this._isObject(t[i])?n[i]=this._merge(t[i],n[i]):n[i]=t[i];return n},cloneObject:function(t){var e={};for(var n in t)this._isObject(t[n])?e[n]=this.cloneObject(t[n]):this._isArray(t[n])?e[n]=this.cloneArray(t[n]):e[n]=t[n];return e},cloneArray:function(t){return t.slice(0)},_degToRad:function(e){return e*t},_radToDeg:function(t){return t*e},_capitalize:function(t){return t.charAt(0).toUpperCase()+t.slice(1)},throw:function(t){throw new Error(n+t)},error:function(t){console.error(n+t)},warn:function(t){Konva.global.console&&console.warn&&Konva.showWarnings&&console.warn("Konva warning: "+t)},extend:function(t,e){function n(){this.constructor=t}n.prototype=e.prototype;var i=t.prototype;t.prototype=new n;for(var a in i)i.hasOwnProperty(a)&&(t.prototype[a]=i[a]);t.__super__=e.prototype,t.super=e},addMethods:function(t,e){var n;for(n in e)t.prototype[n]=e[n]},_getControlPoints:function(t,e,n,i,a,r,o){var s=Math.sqrt(Math.pow(n-t,2)+Math.pow(i-e,2)),h=Math.sqrt(Math.pow(a-n,2)+Math.pow(r-i,2)),c=o*s/(s+h),l=o*h/(s+h);return[n-c*(a-t),i-c*(r-e),n+l*(a-t),i+l*(r-e)]},_expandPoints:function(t,e){var n,i,a=t.length,r=[];for(n=2;n1?(o=n,s=i,h=(n-a)*(n-a)+(i-r)*(i-r)):h=((o=t+l*(n-t))-a)*(o-a)+((s=e+l*(i-e))-r)*(s-r)}return[o,s,h]},_getProjectionToLine:function(t,e,n){var i=Konva.Util.cloneObject(t),a=Number.MAX_VALUE;return e.forEach(function(r,o){if(n||o!==e.length-1){var s=e[(o+1)%e.length],h=Konva.Util._getProjectionToSegment(r.x,r.y,s.x,s.y,t.x,t.y),c=h[0],l=h[1],d=h[2];de.length){var o=e;e=t,t=o}for(i=0;i=Konva.traceArrMax&&e.shift()},reset:function(){var t=this.getCanvas().getPixelRatio();this.setTransform(1*t,0,0,1*t,0,0)},getCanvas:function(){return this.canvas},clear:function(t){var e=this.getCanvas();t?this.clearRect(t.x||0,t.y||0,t.width||0,t.height||0):this.clearRect(0,0,e.getWidth()/e.pixelRatio,e.getHeight()/e.pixelRatio)},_applyLineCap:function(t){var e=t.getLineCap();e&&this.setAttr("lineCap",e)},_applyOpacity:function(t){var e=t.getAbsoluteOpacity();1!==e&&this.setAttr("globalAlpha",e)},_applyLineJoin:function(t){var e=t.getLineJoin();e&&this.setAttr("lineJoin",e)},setAttr:function(t,e){this._context[t]=e},arc:function(){var t=arguments;this._context.arc(t[0],t[1],t[2],t[3],t[4],t[5])},beginPath:function(){this._context.beginPath()},bezierCurveTo:function(){var t=arguments;this._context.bezierCurveTo(t[0],t[1],t[2],t[3],t[4],t[5])},clearRect:function(){var t=arguments;this._context.clearRect(t[0],t[1],t[2],t[3])},clip:function(){this._context.clip()},closePath:function(){this._context.closePath()},createImageData:function(){var t=arguments;return 2===t.length?this._context.createImageData(t[0],t[1]):1===t.length?this._context.createImageData(t[0]):void 0},createLinearGradient:function(){var t=arguments;return this._context.createLinearGradient(t[0],t[1],t[2],t[3])},createPattern:function(){var t=arguments;return this._context.createPattern(t[0],t[1])},createRadialGradient:function(){var t=arguments;return this._context.createRadialGradient(t[0],t[1],t[2],t[3],t[4],t[5])},drawImage:function(){var t=arguments,e=this._context;3===t.length?e.drawImage(t[0],t[1],t[2]):5===t.length?e.drawImage(t[0],t[1],t[2],t[3],t[4]):9===t.length&&e.drawImage(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},isPointInPath:function(t,e){return this._context.isPointInPath(t,e)},fill:function(){this._context.fill()},fillRect:function(t,e,n,i){this._context.fillRect(t,e,n,i)},strokeRect:function(t,e,n,i){this._context.strokeRect(t,e,n,i)},fillText:function(){var t=arguments;this._context.fillText(t[0],t[1],t[2])},measureText:function(t){return this._context.measureText(t)},getImageData:function(){var t=arguments;return this._context.getImageData(t[0],t[1],t[2],t[3])},lineTo:function(){var t=arguments;this._context.lineTo(t[0],t[1])},moveTo:function(){var t=arguments;this._context.moveTo(t[0],t[1])},rect:function(){var t=arguments;this._context.rect(t[0],t[1],t[2],t[3])},putImageData:function(){var t=arguments;this._context.putImageData(t[0],t[1],t[2])},quadraticCurveTo:function(){var t=arguments;this._context.quadraticCurveTo(t[0],t[1],t[2],t[3])},restore:function(){this._context.restore()},rotate:function(){var t=arguments;this._context.rotate(t[0])},save:function(){this._context.save()},scale:function(){var t=arguments;this._context.scale(t[0],t[1])},setLineDash:function(){var t=arguments,e=this._context;this._context.setLineDash?e.setLineDash(t[0]):"mozDash"in e?e.mozDash=t[0]:"webkitLineDash"in e&&(e.webkitLineDash=t[0])},getLineDash:function(){return this._context.getLineDash()},setTransform:function(){var t=arguments;this._context.setTransform(t[0],t[1],t[2],t[3],t[4],t[5])},stroke:function(){this._context.stroke()},strokeText:function(){var t=arguments;this._context.strokeText(t[0],t[1],t[2])},transform:function(){var t=arguments;this._context.transform(t[0],t[1],t[2],t[3],t[4],t[5])},translate:function(){var t=arguments;this._context.translate(t[0],t[1])},_enableTrace:function(){var e,n,i=this,a=t.length,r=Konva.Util._simplifyArray,o=this.setAttr,s=function(t){var e,a=i[t];i[t]=function(){return n=r(Array.prototype.slice.call(arguments,0)),e=a.apply(i,arguments),i._trace({method:t,args:n}),e}};for(e=0;e255?255:t<0?0:Math.round(t)},alphaComponent:function(t){return t>1?1:t<1e-4?1e-4:t}}}(),function(t){"use strict";var e="absoluteOpacity",n="absoluteTransform",i="absoluteScale",a="listening",r="Shape",o="transform",s=["id"],h=["xChange.konva","yChange.konva","scaleXChange.konva","scaleYChange.konva","skewXChange.konva","skewYChange.konva","rotationChange.konva","offsetXChange.konva","offsetYChange.konva","transformsEnabledChange.konva"].join(" "),c=["scaleXChange.konva","scaleYChange.konva"].join(" ");t.Node=function(t){this._init(t)},t.Util.addMethods(t.Node,{_init:function(r){var s=this;this._id=t.idCounter++,this.eventListeners={},this.attrs={},this._cache={},this._filterUpToDate=!1,this._isUnderCache=!1,this.setAttrs(r),this.on(h,function(){this._clearCache(o),s._clearSelfAndDescendantCache(n)}),this.on(c,function(){s._clearSelfAndDescendantCache(i)}),this.on("visibleChange.konva",function(){s._clearSelfAndDescendantCache("visible")}),this.on("listeningChange.konva",function(){s._clearSelfAndDescendantCache(a)}),this.on("opacityChange.konva",function(){s._clearSelfAndDescendantCache(e)})},_clearCache:function(t){t?delete this._cache[t]:this._cache={}},_getCache:function(t,e){return void 0===this._cache[t]&&(this._cache[t]=e.call(this)),this._cache[t]},_clearSelfAndDescendantCache:function(t){this._clearCache(t),this.children&&this.getChildren().each(function(e){e._clearSelfAndDescendantCache(t)})},clearCache:function(){return delete this._cache.canvas,this._filterUpToDate=!1,this},cache:function(n){var a=n||{},r=this.getClientRect({skipTransform:!0,relativeTo:this.getParent()}),o=a.width||r.width,s=a.height||r.height,h=a.pixelRatio,c=a.x||r.x,l=a.y||r.y,d=a.offset||0,u=a.drawBorder||!1;{if(o&&s){o+=2*d,s+=2*d,c-=d,l-=d;var f=new t.SceneCanvas({pixelRatio:h,width:o,height:s}),g=new t.SceneCanvas({pixelRatio:h,width:o,height:s}),v=new t.HitCanvas({pixelRatio:1,width:o,height:s}),p=f.getContext(),m=v.getContext();return v.isCache=!0,this.clearCache(),p.save(),m.save(),p.translate(-c,-l),m.translate(-c,-l),this._isUnderCache=!0,this._clearSelfAndDescendantCache(e),this._clearSelfAndDescendantCache(i),this.drawScene(f,this,!0),this.drawHit(v,this,!0),this._isUnderCache=!1,p.restore(),m.restore(),u&&(p.save(),p.beginPath(),p.rect(0,0,o,s),p.closePath(),p.setAttr("strokeStyle","red"),p.setAttr("lineWidth",5),p.stroke(),p.restore()),this._cache.canvas={scene:f,filter:g,hit:v,x:c,y:l},this}setTimeout(function(){t.Util.throw("Width or height of caching configuration equals 0. Caching is ignored.")})}},getClientRect:function(){throw new Error('abstract "getClientRect" method call')},_transformedRect:function(t,e){var n,i,a,r,o=[{x:t.x,y:t.y},{x:t.x+t.width,y:t.y},{x:t.x+t.width,y:t.y+t.height},{x:t.x,y:t.y+t.height}],s=this.getAbsoluteTransform(e);return o.forEach(function(t){var e=s.point(t);void 0===n&&(n=a=e.x,i=r=e.y),n=Math.min(n,e.x),i=Math.min(i,e.y),a=Math.max(a,e.x),r=Math.max(r,e.y)}),{x:n,y:i,width:a-n,height:r-i}},_drawCachedSceneCanvas:function(t){t.save(),t._applyOpacity(this),t._applyGlobalCompositeOperation(this),t.translate(this._cache.canvas.x,this._cache.canvas.y);var e=this._getCachedSceneCanvas(),n=e.pixelRatio;t.drawImage(e._canvas,0,0,e.width/n,e.height/n),t.restore()},_drawCachedHitCanvas:function(t){var e=this._cache.canvas.hit;t.save(),t.translate(this._cache.canvas.x,this._cache.canvas.y),t.drawImage(e._canvas,0,0),t.restore()},_getCachedSceneCanvas:function(){var e,n,i,a,r=this.filters(),o=this._cache.canvas,s=o.scene,h=o.filter,c=h.getContext();if(r){if(!this._filterUpToDate){var l=s.pixelRatio;try{for(e=r.length,c.clear(),c.drawImage(s._canvas,0,0,s.getWidth()/l,s.getHeight()/l),n=c.getImageData(0,0,h.getWidth(),h.getHeight()),i=0;i0&&e[0].getDepth()<=o&&t(e)}var e,n,i,a,o=this.getDepth(),s=this,h=0;return"Stage"!==s.nodeType&&t(s.getStage().getChildren()),h},getDepth:function(){for(var t=0,e=this.parent;e;)t++,e=e.parent;return t},setPosition:function(t){return this.setX(t.x),this.setY(t.y),this},getPosition:function(){return{x:this.getX(),y:this.getY()}},getAbsolutePosition:function(e){var n=this.getAbsoluteTransform(e).getMatrix(),i=new t.Transform,a=this.offset();return i.m=n.slice(),i.translate(a.x,a.y),i.getTranslation()},setAbsolutePosition:function(t){var e,n=this._clearTransform();return this.attrs.x=n.x,this.attrs.y=n.y,delete n.x,delete n.y,(e=this.getAbsoluteTransform()).invert(),e.translate(t.x,t.y),t={x:this.attrs.x+e.getTranslation().x,y:this.attrs.y+e.getTranslation().y},this.setPosition({x:t.x,y:t.y}),this._setTransform(n),this},_setTransform:function(t){var e;for(e in t)this.attrs[e]=t[e];this._clearCache(o),this._clearSelfAndDescendantCache(n)},_clearTransform:function(){var t={x:this.getX(),y:this.getY(),rotation:this.getRotation(),scaleX:this.getScaleX(),scaleY:this.getScaleY(),offsetX:this.getOffsetX(),offsetY:this.getOffsetY(),skewX:this.getSkewX(),skewY:this.getSkewY()};return this.attrs.x=0,this.attrs.y=0,this.attrs.rotation=0,this.attrs.scaleX=1,this.attrs.scaleY=1,this.attrs.offsetX=0,this.attrs.offsetY=0,this.attrs.skewX=0,this.attrs.skewY=0,this._clearCache(o),this._clearSelfAndDescendantCache(n),t},move:function(t){var e=t.x,n=t.y,i=this.getX(),a=this.getY();return void 0!==e&&(i+=e),void 0!==n&&(a+=n),this.setPosition({x:i,y:a}),this},_eachAncestorReverse:function(t,e){var n,i,a=[],r=this.getParent();if(e&&e._id===this._id)return t(this),!0;for(a.unshift(this);r&&(!e||r._id!==e._id);)a.unshift(r),r=r.parent;for(n=a.length,i=0;i0&&(this.parent.children.splice(e,1),this.parent.children.splice(e-1,0,this),this.parent._setChildrenIndices(),!0)},moveToBottom:function(){if(!this.parent)return t.Util.warn("Node has no parent. moveToBottom function is ignored."),!1;var e=this.index;return e>0&&(this.parent.children.splice(e,1),this.parent.children.unshift(this),this.parent._setChildrenIndices(),!0)},setZIndex:function(e){if(!this.parent)return t.Util.warn("Node has no parent. zIndex parameter is ignored."),!1;var n=this.index;return this.parent.children.splice(n,1),this.parent.children.splice(e,0,this),this.parent._setChildrenIndices(),this},getAbsoluteOpacity:function(){return this._getCache(e,this._getAbsoluteOpacity)},_getAbsoluteOpacity:function(){var t=this.getOpacity(),e=this.getParent();return e&&!e._isUnderCache&&(t*=this.getParent().getAbsoluteOpacity()),t},moveTo:function(t){return this.getParent()!==t&&((this.__originalRemove||this.remove).call(this),t.add(this)),this},toObject:function(){var e,n,i,a,r={},o=this.getAttrs();r.attrs={};for(e in o)n=o[e],i=this[e],delete o[e],a=i?i.call(this):null,o[e]=n,a!==n&&(r.attrs[e]=n);return r.className=this.getClassName(),t.Util._prepareToStringify(r)},toJSON:function(){return JSON.stringify(this.toObject())},getParent:function(){return this.parent},findAncestors:function(t,e,n){var i=[];e&&this._isMatch(t)&&i.push(this);for(var a=this.parent;a;){if(a===n)return i;a._isMatch(t)&&i.push(a),a=a.parent}return i},findAncestor:function(t,e,n){return this.findAncestors(t,e,n)[0]},_isMatch:function(e){if(!e)return!1;var n,i,a=e.replace(/ /g,"").split(","),r=a.length;for(n=0;n0&&function(t,a){var r,o,s,h,c,l,d,u,f,g,v,p,m,_,y,S,K,x,C,w,b,F,T,P,A=t.data,M=t.width,k=t.height,G=a+a+1,D=M-1,R=k-1,L=a+1,O=L*(L+1)/2,I=new e,N=null,U=I,E=null,B=null,H=n[a],W=i[a];for(s=1;s>W,0!==T?(T=255/T,A[l]=(u*H>>W)*T,A[l+1]=(f*H>>W)*T,A[l+2]=(g*H>>W)*T):A[l]=A[l+1]=A[l+2]=0,u-=p,f-=m,g-=_,v-=y,p-=E.r,m-=E.g,_-=E.b,y-=E.a,h=d+((h=r+a+1)>W,T>0?(T=255/T,A[h]=(u*H>>W)*T,A[h+1]=(f*H>>W)*T,A[h+2]=(g*H>>W)*T):A[h]=A[h+1]=A[h+2]=0,u-=p,f-=m,g-=_,v-=y,p-=E.r,m-=E.g,_-=E.b,y-=E.a,h=r+((h=o+L)=0&&f=0&&g=0&&f=0&&g=1020?255:0}return o}(i=function(t,e,n){for(var i=[1,1,1,1,0,1,1,1,1],a=Math.round(Math.sqrt(i.length)),r=Math.floor(a/2),o=[],s=0;s=0&&f=0&&g255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"green",0,function(t){return this._filterUpToDate=!1,t>255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"blue",0,Konva.Validators.RGBComponent,Konva.Factory.afterSetFilter)}(),function(){"use strict";Konva.Filters.RGBA=function(t){var e,n,i=t.data,a=i.length,r=this.red(),o=this.green(),s=this.blue(),h=this.alpha();for(e=0;e255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"green",0,function(t){return this._filterUpToDate=!1,t>255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"blue",0,Konva.Validators.RGBComponent,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"alpha",1,function(t){return this._filterUpToDate=!1,t>1?1:t<0?0:t})}(),function(){"use strict";Konva.Filters.HSV=function(t){var e,n,i,a,r,o=t.data,s=o.length,h=Math.pow(2,this.value()),c=Math.pow(2,this.saturation()),l=Math.abs(this.hue()+360)%360,d=h*c*Math.cos(l*Math.PI/180),u=h*c*Math.sin(l*Math.PI/180),f=.299*h+.701*d+.167*u,g=.587*h-.587*d+.33*u,v=.114*h-.114*d-.497*u,p=.299*h-.299*d-.328*u,m=.587*h+.413*d+.035*u,_=.114*h-.114*d+.293*u,y=.299*h-.3*d+1.25*u,S=.587*h-.586*d-1.05*u,K=.114*h+.886*d-.2*u;for(e=0;ec&&(f=0);var g=(d-1+f)*h*4,v=h;do{var p=u+4*(v-1),m=o;v+m<1&&(m=0),v+m>h&&(m=0);var _=g+4*(v-1+m),y=s[p]-s[_],S=s[p+1]-s[_+1],K=s[p+2]-s[_+2],x=y,C=x>0?x:-x;if((S>0?S:-S)>C&&(x=S),(K>0?K:-K)>C&&(x=K),x*=e,a){var w=s[p]+x,b=s[p+1]+x,F=s[p+2]+x;s[p]=w>255?255:w<0?0:w,s[p+1]=b>255?255:b<0?0:b,s[p+2]=F>255?255:F<0?0:F}else{var T=n-x;T<0?T=0:T>255&&(T=255),s[p]=s[p+1]=s[p+2]=T}}while(--v)}while(--d)},Konva.Factory.addGetterSetter(Konva.Node,"embossStrength",.5,null,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"embossWhiteLevel",.5,null,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"embossDirection","top-left",null,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"embossBlend",!1,null,Konva.Factory.afterSetFilter)}(),function(){"use strict";function t(t,e,n,i,a){var r,o=n-e,s=a-i;return 0===o?i+s/2:0===s?i:(r=(t-e)/o,r=s*r+i)}Konva.Filters.Enhance=function(e){var n,i,a,r,o=e.data,s=o.length,h=o[0],c=h,l=o[1],d=l,u=o[2],f=u,g=this.enhance();if(0!==g){for(r=0;rc&&(c=n),(i=o[r+1])d&&(d=i),(a=o[r+2])f&&(f=a);c===h&&(c=255,h=0),d===l&&(d=255,l=0),f===u&&(f=255,u=0);var v,p,m,_,y,S,K,x,C;for(g>0?(p=c+g*(255-c),m=h-g*(h-0),y=d+g*(255-d),S=l-g*(l-0),x=f+g*(255-f),C=u-g*(u-0)):(p=c+g*(c-(v=.5*(c+h))),m=h+g*(h-v),y=d+g*(d-(_=.5*(d+l))),S=l+g*(l-_),x=f+g*(f-(K=.5*(f+u))),C=u+g*(u-K)),r=0;r=p))for(n=l;n=m||(a+=t[(i=4*(p*n+e))+0],r+=t[i+1],o+=t[i+2],s+=t[i+3],g+=1);for(a/=g,r/=g,o/=g,e=h;e=p))for(n=l;n=m||(t[(i=4*(p*n+e))+0]=a,t[i+1]=r,t[i+2]=o,t[i+3]=s)}},Konva.Factory.addGetterSetter(Konva.Node,"pixelSize",8,null,Konva.Factory.afterSetFilter)}(),function(){"use strict";Konva.Filters.Threshold=function(t){var e,n=255*this.threshold(),i=t.data,a=i.length;for(e=0;e