diff --git a/konva.js b/konva.js index 196dceb8..94eda3c6 100644 --- a/konva.js +++ b/konva.js @@ -2644,6 +2644,7 @@ this.index = 0; this.parent = null; this._cache = new Map(); + this._attachedDepsListeners = new Map(); this._lastPos = null; this._batchingTransformChange = false; this._needClearTransformCache = false; @@ -2706,6 +2707,20 @@ } return cache; }; + Node.prototype._calculate = function (name, deps, getter) { + var _this = this; + // if we are trying to calculate function for the first time + // we need to attach listeners for change events + if (!this._attachedDepsListeners.get(name)) { + var depsString = deps.map(function (dep) { return dep + 'Change.konva'; }).join(SPACE); + this.on(depsString, function () { + _this._clearCache(name); + }); + this._attachedDepsListeners.set(name, true); + } + // just use cache function + return this._getCache(name, getter); + }; Node.prototype._getCanvasCache = function () { return this._cache.get(CANVAS); }; @@ -4044,6 +4059,9 @@ Node.prototype._getTransform = function () { var m = this._cache.get(TRANSFORM) || new Transform(); m.reset(); + // I was trying to use attributes directly here + // but it doesn't work for Transformer well + // because it overwrite x,y getters var x = this.x(), y = this.y(), rotation = Konva.getAngle(this.rotation()), scaleX = this.scaleX(), scaleY = this.scaleY(), skewX = this.skewX(), skewY = this.skewY(), offsetX = this.offsetX(), offsetY = this.offsetY(); if (x !== 0 || y !== 0) { m.translate(x, y); @@ -6964,11 +6982,20 @@ * @returns {Boolean} */ Shape.prototype.hasFill = function () { - return (this.fillEnabled() && - !!(this.fill() || - this.fillPatternImage() || - this.fillLinearGradientColorStops() || - this.fillRadialGradientColorStops())); + var _this = this; + return this._calculate('hasFill', [ + 'fillEnabled', + 'fill', + 'fillPatternImage', + 'fillLinearGradientColorStops', + 'fillRadialGradientColorStops', + ], function () { + return (_this.fillEnabled() && + !!(_this.fill() || + _this.fillPatternImage() || + _this.fillLinearGradientColorStops() || + _this.fillRadialGradientColorStops())); + }); }; /** * returns whether or not the shape will be stroked @@ -6977,11 +7004,25 @@ * @returns {Boolean} */ Shape.prototype.hasStroke = function () { - return (this.strokeEnabled() && - this.strokeWidth() && - !!(this.stroke() || this.strokeLinearGradientColorStops()) - // this.getStrokeRadialGradientColorStops() - ); + var _this = this; + return this._calculate('hasStroke', [ + 'strokeEnabled', + 'strokeWidth', + 'stroke', + 'strokeLinearGradientColorStops', + ], function () { + return (_this.strokeEnabled() && + _this.strokeWidth() && + !!(_this.stroke() || _this.strokeLinearGradientColorStops()) + // this.getStrokeRadialGradientColorStops() + ); + }); + // return ( + // this.strokeEnabled() && + // this.strokeWidth() && + // !!(this.stroke() || this.strokeLinearGradientColorStops()) + // // this.getStrokeRadialGradientColorStops() + // ); }; Shape.prototype.hasHitStroke = function () { var width = this.hitStrokeWidth(); @@ -14806,7 +14847,7 @@ var lastPos; node.on("dragstart." + EVENTS_NAME, function (e) { lastPos = node.getAbsolutePosition(); - _this.fire('dragstart', e); + // this.fire('dragstart', e); }); node.on("dragmove." + EVENTS_NAME, function (e) { if (!lastPos) { @@ -14828,12 +14869,10 @@ y: otherAbs.y + dy, }); otherNode.startDrag(); - // TODO: how to trigger event after all nodes are dragged? - _this.fire('dragmove', e); - }); - node.on("dragend." + EVENTS_NAME, function (e) { - _this.fire('dragend', e); }); + // node.on(`dragend.${EVENTS_NAME}`, (e) => { + // this.fire('dragend', e); + // }); lastPos = null; }); }; diff --git a/konva.min.js b/konva.min.js index dec191ae..1a95e56f 100644 --- a/konva.min.js +++ b/konva.min.js @@ -9,4 +9,4 @@ * Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva) * * @license - */var e=Math.PI/180;function t(t){var e=t.toLowerCase(),i=/(chrome)[ /]([\w.]+)/.exec(e)||/(webkit)[ /]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ /]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[],n=!!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:function(t){var e=t.indexOf("msie ");if(0>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 p?{r:(e=p[t])[0],g:e[1],b:e[2]}:"#"===t[0]?this._hexToRgb(t.substring(1)):"rgb("===t.substr(0,4)?(e=u.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",A._namedColorToRBA(t)||A._hex3ColorToRGBA(t)||A._hex6ColorToRGBA(t)||A._rgbColorToRGBA(t)||A._rgbaColorToRGBA(t)||A._hslColorToRGBA(t)},_namedColorToRBA:function(t){var e=p[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}},_hslColorToRGBA:function(t){if(/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.test(t)){var e=/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(t),i=(e[0],e.slice(1)),n=Number(i[0])/360,r=Number(i[1])/100,o=Number(i[2])/100,a=void 0,s=void 0,h=void 0;if(0==r)return h=255*o,{r:Math.round(h),g:Math.round(h),b:Math.round(h),a:1};for(var c=2*o-(a=o<.5?o*(1+r):o+r-o*r),l=[0,0,0],d=0;d<3;d++)(s=n+1/3*-(d-1))<0&&s++,1t.x+t.width||e.x+e.widtht.y+t.height||e.y+e.heighte.length&&(r=e,e=t,t=r),n=0;n=this.parent.children.length)&&A.warn("Unexpected value "+t+" for zIndex property. zIndex is just index of a node in children of its parent. Expected value is from 0 to "+(this.parent.children.length-1)+".");var e=this.index;return this.parent.children.splice(e,1),this.parent.children.splice(t,0,this),this.parent._setChildrenIndices(),this},dt.prototype.getAbsoluteOpacity=function(){return this._getCache(Z,this._getAbsoluteOpacity)},dt.prototype._getAbsoluteOpacity=function(){var t=this.opacity(),e=this.getParent();return e&&!e._isUnderCache&&(t*=e.getAbsoluteOpacity()),t},dt.prototype.moveTo=function(t){return this.getParent()!==t&&(this._remove(),t.add(this)),this},dt.prototype.toObject=function(){var t,e,i,n={},r=this.getAttrs();for(t in n.attrs={},r)e=r[t],A.isObject(e)&&!A._isPlainObject(e)&&!A._isArray(e)||(i="function"==typeof this[t]&&this[t],delete r[t],(i?i.call(this):null)!==(r[t]=e)&&(n.attrs[t]=e));return n.className=this.getClassName(),A._prepareToStringify(n)},dt.prototype.toJSON=function(){return JSON.stringify(this.toObject())},dt.prototype.getParent=function(){return this.parent},dt.prototype.findAncestors=function(t,e,i){var n=[];e&&this._isMatch(t)&&n.push(this);for(var r=this.parent;r;){if(r===i)return n;r._isMatch(t)&&n.push(r),r=r.parent}return n},dt.prototype.isAncestorOf=function(t){return!1},dt.prototype.findAncestor=function(t,e,i){return this.findAncestors(t,e,i)[0]},dt.prototype._isMatch=function(t){if(!t)return!1;if("function"==typeof t)return t(this);for(var e,i=t.replace(/ /g,"").split(","),n=i.length,r=0;rthis.duration?this.yoyo?(this._time=this.duration,this.reverse()):this.finish():t<0?this.yoyo?(this._time=0,this.play()):this.reset():(this._time=t,this.update())},Ae.prototype.getTime=function(){return this._time},Ae.prototype.setPosition=function(t){this.prevPos=this._pos,this.propFunc(t),this._pos=t},Ae.prototype.getPosition=function(t){return void 0===t&&(t=this._time),this.func(t,this.begin,this._change,this.duration)},Ae.prototype.play=function(){this.state=2,this._startTime=this.getTimer()-this._time,this.onEnterFrame(),this.fire("onPlay")},Ae.prototype.reverse=function(){this.state=3,this._time=this.duration-this._time,this._startTime=this.getTimer()-this._time,this.onEnterFrame(),this.fire("onReverse")},Ae.prototype.seek=function(t){this.pause(),this._time=t,this.update(),this.fire("onSeek")},Ae.prototype.reset=function(){this.pause(),this._time=0,this.update(),this.fire("onReset")},Ae.prototype.finish=function(){this.pause(),this._time=this.duration,this.update(),this.fire("onFinish")},Ae.prototype.update=function(){this.setPosition(this.getPosition(this._time))},Ae.prototype.onEnterFrame=function(){var t=this.getTimer()-this._startTime;2===this.state?this.setTime(t):3===this.state&&this.setTime(this.duration-t)},Ae.prototype.pause=function(){this.state=1,this.fire("onPause")},Ae.prototype.getTimer=function(){return(new Date).getTime()},Ae);function Ae(t,e,i,n,r,o,a){this.prop=t,this.propFunc=e,this.begin=n,this._pos=n,this.duration=o,this._change=0,this.prevPos=0,this.yoyo=a,this._time=0,this._position=0,this._startTime=0,this._finish=0,this.func=i,this._change=r-this.begin,this.pause()}var Me=(Ge.prototype._addAttr=function(t,e){var i,n,r,o,a,s,h,c,l=this.node,d=l._id,p=Ge.tweens[d][t];if(p&&delete Ge.attrs[d][p][t],i=l.getAttr(t),A._isArray(e))if(n=[],o=Math.max(e.length,i.length),"points"===t&&e.length!==i.length&&(e.length>i.length?(s=i,i=A._prepareArrayForTween(i,e,l.closed())):(a=e,e=A._prepareArrayForTween(e,i,l.closed()))),0===t.indexOf("fill"))for(r=0;rthis.dataArray[i].pathLength;)t-=this.dataArray[i].pathLength,++i;if(i===n)return{x:(e=this.dataArray[i-1].points.slice(-2))[0],y:e[1]};if(t<.01)return{x:(e=this.dataArray[i].points.slice(0,2))[0],y:e[1]};var r=this.dataArray[i],o=r.points;switch(r.command){case"L":return li.getPointOnLine(t,r.start.x,r.start.y,o[0],o[1]);case"C":return li.getPointOnCubicBezier(t/r.pathLength,r.start.x,r.start.y,o[0],o[1],o[2],o[3],o[4],o[5]);case"Q":return li.getPointOnQuadraticBezier(t/r.pathLength,r.start.x,r.start.y,o[0],o[1],o[2],o[3]);case"A":var a=o[0],s=o[1],h=o[2],c=o[3],l=o[4],d=o[5],p=o[6];return l+=d*t/r.pathLength,li.getPointOnEllipticalArc(a,s,h,c,l,p)}return null},li.getLineLength=function(t,e,i,n){return Math.sqrt((i-t)*(i-t)+(n-e)*(n-e))},li.getPointOnLine=function(t,e,i,n,r,o,a){void 0===o&&(o=e),void 0===a&&(a=i);var s=(r-i)/(n-e+1e-8),h=Math.sqrt(t*t/(1+s*s));n>>1,A=_.slice(0,1+T),M=this._getTextWidth(A)+y;M<=c?(w=1+T,P=A+(g?"…":""),k=M):C=T}if(!P)break;if(!f||0<(S=(" "===(x=_[P.length])||"-"===x)&&k<=c?P.length:Math.max(P.lastIndexOf(" "),P.lastIndexOf("-"))+1)&&(w=S,P=P.slice(0,w),k=this._getTextWidth(P)),P=P.trimRight(),this._addTextLine(P),i=Math.max(i,k),d+=n,!u||s&&le?g=ci.getPointOnLine(e,f.x,f.y,y.points[0],y.points[1],f.x,f.y):y=void 0;break;case"A":var a=y.points[4],s=y.points[5],h=y.points[4]+s;0===m?m=a+1e-8:iy.pathLength?1e-8:e/y.pathLength:ic.x?-1:1,d=this.findOne(".top-left").y()>c.y?-1:1,w=s*this.cos*l,C=s*this.sin*d,this.findOne(".top-left").x(c.x-w),this.findOne(".top-left").y(c.y-C)):"top-center"===this._movingAnchorName?this.findOne(".top-left").y(e.y()):"top-right"===this._movingAnchorName?(a&&(c=p?{x:this.width()/2,y:this.height()/2}:{x:this.findOne(".bottom-left").x(),y:this.findOne(".bottom-left").y()},s=Math.sqrt(Math.pow(e.x()-c.x,2)+Math.pow(c.y-e.y(),2)),l=this.findOne(".top-right").x()c.y?-1:1,w=s*this.cos*l,C=s*this.sin*d,this.findOne(".top-right").x(c.x+w),this.findOne(".top-right").y(c.y-C)),h=e.position(),this.findOne(".top-left").y(h.y),this.findOne(".bottom-right").x(h.x)):"middle-left"===this._movingAnchorName?this.findOne(".top-left").x(e.x()):"middle-right"===this._movingAnchorName?this.findOne(".bottom-right").x(e.x()):"bottom-left"===this._movingAnchorName?(a&&(c=p?{x:this.width()/2,y:this.height()/2}:{x:this.findOne(".top-right").x(),y:this.findOne(".top-right").y()},s=Math.sqrt(Math.pow(c.x-e.x(),2)+Math.pow(e.y()-c.y,2)),l=c.x>N,0!==w?(w=255/w,P[a]=(h*B>>N)*w,P[a+1]=(c*B>>N)*w,P[a+2]=(l*B>>N)*w):P[a]=P[a+1]=P[a+2]=0,h-=p,c-=u,l-=f,d-=g,p-=O.r,u-=O.g,f-=O.b,g-=O.a,r=s+((r=i+e+1)>N,0>N)*w,P[r+1]=(c*B>>N)*w,P[r+2]=(l*B>>N)*w):P[r]=P[r+1]=P[r+2]=0,h-=p,c-=u,l-=f,d-=g,p-=O.r,u-=O.g,f-=O.b,g-=O.a,r=i+((r=n+R)>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 p?{r:(e=p[t])[0],g:e[1],b:e[2]}:"#"===t[0]?this._hexToRgb(t.substring(1)):"rgb("===t.substr(0,4)?(e=u.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",A._namedColorToRBA(t)||A._hex3ColorToRGBA(t)||A._hex6ColorToRGBA(t)||A._rgbColorToRGBA(t)||A._rgbaColorToRGBA(t)||A._hslColorToRGBA(t)},_namedColorToRBA:function(t){var e=p[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}},_hslColorToRGBA:function(t){if(/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.test(t)){var e=/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(t),i=(e[0],e.slice(1)),n=Number(i[0])/360,r=Number(i[1])/100,o=Number(i[2])/100,a=void 0,s=void 0,h=void 0;if(0==r)return h=255*o,{r:Math.round(h),g:Math.round(h),b:Math.round(h),a:1};for(var c=2*o-(a=o<.5?o*(1+r):o+r-o*r),l=[0,0,0],d=0;d<3;d++)(s=n+1/3*-(d-1))<0&&s++,1t.x+t.width||e.x+e.widtht.y+t.height||e.y+e.heighte.length&&(r=e,e=t,t=r),n=0;n=this.parent.children.length)&&A.warn("Unexpected value "+t+" for zIndex property. zIndex is just index of a node in children of its parent. Expected value is from 0 to "+(this.parent.children.length-1)+".");var e=this.index;return this.parent.children.splice(e,1),this.parent.children.splice(t,0,this),this.parent._setChildrenIndices(),this},dt.prototype.getAbsoluteOpacity=function(){return this._getCache(Z,this._getAbsoluteOpacity)},dt.prototype._getAbsoluteOpacity=function(){var t=this.opacity(),e=this.getParent();return e&&!e._isUnderCache&&(t*=e.getAbsoluteOpacity()),t},dt.prototype.moveTo=function(t){return this.getParent()!==t&&(this._remove(),t.add(this)),this},dt.prototype.toObject=function(){var t,e,i,n={},r=this.getAttrs();for(t in n.attrs={},r)e=r[t],A.isObject(e)&&!A._isPlainObject(e)&&!A._isArray(e)||(i="function"==typeof this[t]&&this[t],delete r[t],(i?i.call(this):null)!==(r[t]=e)&&(n.attrs[t]=e));return n.className=this.getClassName(),A._prepareToStringify(n)},dt.prototype.toJSON=function(){return JSON.stringify(this.toObject())},dt.prototype.getParent=function(){return this.parent},dt.prototype.findAncestors=function(t,e,i){var n=[];e&&this._isMatch(t)&&n.push(this);for(var r=this.parent;r;){if(r===i)return n;r._isMatch(t)&&n.push(r),r=r.parent}return n},dt.prototype.isAncestorOf=function(t){return!1},dt.prototype.findAncestor=function(t,e,i){return this.findAncestors(t,e,i)[0]},dt.prototype._isMatch=function(t){if(!t)return!1;if("function"==typeof t)return t(this);for(var e,i=t.replace(/ /g,"").split(","),n=i.length,r=0;rthis.duration?this.yoyo?(this._time=this.duration,this.reverse()):this.finish():t<0?this.yoyo?(this._time=0,this.play()):this.reset():(this._time=t,this.update())},Ae.prototype.getTime=function(){return this._time},Ae.prototype.setPosition=function(t){this.prevPos=this._pos,this.propFunc(t),this._pos=t},Ae.prototype.getPosition=function(t){return void 0===t&&(t=this._time),this.func(t,this.begin,this._change,this.duration)},Ae.prototype.play=function(){this.state=2,this._startTime=this.getTimer()-this._time,this.onEnterFrame(),this.fire("onPlay")},Ae.prototype.reverse=function(){this.state=3,this._time=this.duration-this._time,this._startTime=this.getTimer()-this._time,this.onEnterFrame(),this.fire("onReverse")},Ae.prototype.seek=function(t){this.pause(),this._time=t,this.update(),this.fire("onSeek")},Ae.prototype.reset=function(){this.pause(),this._time=0,this.update(),this.fire("onReset")},Ae.prototype.finish=function(){this.pause(),this._time=this.duration,this.update(),this.fire("onFinish")},Ae.prototype.update=function(){this.setPosition(this.getPosition(this._time))},Ae.prototype.onEnterFrame=function(){var t=this.getTimer()-this._startTime;2===this.state?this.setTime(t):3===this.state&&this.setTime(this.duration-t)},Ae.prototype.pause=function(){this.state=1,this.fire("onPause")},Ae.prototype.getTimer=function(){return(new Date).getTime()},Ae);function Ae(t,e,i,n,r,o,a){this.prop=t,this.propFunc=e,this.begin=n,this._pos=n,this.duration=o,this._change=0,this.prevPos=0,this.yoyo=a,this._time=0,this._position=0,this._startTime=0,this._finish=0,this.func=i,this._change=r-this.begin,this.pause()}var Me=(Ge.prototype._addAttr=function(t,e){var i,n,r,o,a,s,h,c,l=this.node,d=l._id,p=Ge.tweens[d][t];if(p&&delete Ge.attrs[d][p][t],i=l.getAttr(t),A._isArray(e))if(n=[],o=Math.max(e.length,i.length),"points"===t&&e.length!==i.length&&(e.length>i.length?(s=i,i=A._prepareArrayForTween(i,e,l.closed())):(a=e,e=A._prepareArrayForTween(e,i,l.closed()))),0===t.indexOf("fill"))for(r=0;rthis.dataArray[i].pathLength;)t-=this.dataArray[i].pathLength,++i;if(i===n)return{x:(e=this.dataArray[i-1].points.slice(-2))[0],y:e[1]};if(t<.01)return{x:(e=this.dataArray[i].points.slice(0,2))[0],y:e[1]};var r=this.dataArray[i],o=r.points;switch(r.command){case"L":return li.getPointOnLine(t,r.start.x,r.start.y,o[0],o[1]);case"C":return li.getPointOnCubicBezier(t/r.pathLength,r.start.x,r.start.y,o[0],o[1],o[2],o[3],o[4],o[5]);case"Q":return li.getPointOnQuadraticBezier(t/r.pathLength,r.start.x,r.start.y,o[0],o[1],o[2],o[3]);case"A":var a=o[0],s=o[1],h=o[2],c=o[3],l=o[4],d=o[5],p=o[6];return l+=d*t/r.pathLength,li.getPointOnEllipticalArc(a,s,h,c,l,p)}return null},li.getLineLength=function(t,e,i,n){return Math.sqrt((i-t)*(i-t)+(n-e)*(n-e))},li.getPointOnLine=function(t,e,i,n,r,o,a){void 0===o&&(o=e),void 0===a&&(a=i);var s=(r-i)/(n-e+1e-8),h=Math.sqrt(t*t/(1+s*s));n>>1,A=_.slice(0,1+T),M=this._getTextWidth(A)+y;M<=c?(w=1+T,P=A+(g?"…":""),k=M):C=T}if(!P)break;if(!f||0<(S=(" "===(x=_[P.length])||"-"===x)&&k<=c?P.length:Math.max(P.lastIndexOf(" "),P.lastIndexOf("-"))+1)&&(w=S,P=P.slice(0,w),k=this._getTextWidth(P)),P=P.trimRight(),this._addTextLine(P),i=Math.max(i,k),d+=n,!u||s&&le?g=ci.getPointOnLine(e,f.x,f.y,y.points[0],y.points[1],f.x,f.y):y=void 0;break;case"A":var a=y.points[4],s=y.points[5],h=y.points[4]+s;0===m?m=a+1e-8:iy.pathLength?1e-8:e/y.pathLength:ic.x?-1:1,d=this.findOne(".top-left").y()>c.y?-1:1,w=s*this.cos*l,C=s*this.sin*d,this.findOne(".top-left").x(c.x-w),this.findOne(".top-left").y(c.y-C)):"top-center"===this._movingAnchorName?this.findOne(".top-left").y(e.y()):"top-right"===this._movingAnchorName?(a&&(c=p?{x:this.width()/2,y:this.height()/2}:{x:this.findOne(".bottom-left").x(),y:this.findOne(".bottom-left").y()},s=Math.sqrt(Math.pow(e.x()-c.x,2)+Math.pow(c.y-e.y(),2)),l=this.findOne(".top-right").x()c.y?-1:1,w=s*this.cos*l,C=s*this.sin*d,this.findOne(".top-right").x(c.x+w),this.findOne(".top-right").y(c.y-C)),h=e.position(),this.findOne(".top-left").y(h.y),this.findOne(".bottom-right").x(h.x)):"middle-left"===this._movingAnchorName?this.findOne(".top-left").x(e.x()):"middle-right"===this._movingAnchorName?this.findOne(".bottom-right").x(e.x()):"bottom-left"===this._movingAnchorName?(a&&(c=p?{x:this.width()/2,y:this.height()/2}:{x:this.findOne(".top-right").x(),y:this.findOne(".top-right").y()},s=Math.sqrt(Math.pow(c.x-e.x(),2)+Math.pow(e.y()-c.y,2)),l=c.x>N,0!==w?(w=255/w,P[a]=(h*B>>N)*w,P[a+1]=(c*B>>N)*w,P[a+2]=(l*B>>N)*w):P[a]=P[a+1]=P[a+2]=0,h-=p,c-=u,l-=f,d-=g,p-=O.r,u-=O.g,f-=O.b,g-=O.a,r=s+((r=i+e+1)>N,0>N)*w,P[r+1]=(c*B>>N)*w,P[r+2]=(l*B>>N)*w):P[r]=P[r+1]=P[r+2]=0,h-=p,c-=u,l-=f,d-=g,p-=O.r,u-=O.g,f-=O.b,g-=O.a,r=i+((r=n+R) { index = 0; parent: Container | null = null; _cache: Map = new Map(); + _attachedDepsListeners: Map = new Map(); _lastPos: Vector2d = null; _attrsAffectingSize!: string[]; _batchingTransformChange = false; @@ -273,6 +274,21 @@ export abstract class Node { return cache; } + + _calculate(name, deps, getter) { + // if we are trying to calculate function for the first time + // we need to attach listeners for change events + if (!this._attachedDepsListeners.get(name)) { + const depsString = deps.map((dep) => dep + 'Change.konva').join(SPACE); + this.on(depsString, () => { + this._clearCache(name); + }); + this._attachedDepsListeners.set(name, true); + } + // just use cache function + return this._getCache(name, getter); + } + _getCanvasCache() { return this._cache.get(CANVAS); } @@ -1786,6 +1802,9 @@ export abstract class Node { var m: Transform = this._cache.get(TRANSFORM) || new Transform(); m.reset(); + // I was trying to use attributes directly here + // but it doesn't work for Transformer well + // because it overwrite x,y getters var x = this.x(), y = this.y(), rotation = Konva.getAngle(this.rotation()), diff --git a/src/Shape.ts b/src/Shape.ts index 5ca625af..58f6c0ad 100644 --- a/src/Shape.ts +++ b/src/Shape.ts @@ -351,14 +351,26 @@ export class Shape extends Node< * @returns {Boolean} */ hasFill() { - return ( - this.fillEnabled() && - !!( - this.fill() || - this.fillPatternImage() || - this.fillLinearGradientColorStops() || - this.fillRadialGradientColorStops() - ) + return this._calculate( + 'hasFill', + [ + 'fillEnabled', + 'fill', + 'fillPatternImage', + 'fillLinearGradientColorStops', + 'fillRadialGradientColorStops', + ], + () => { + return ( + this.fillEnabled() && + !!( + this.fill() || + this.fillPatternImage() || + this.fillLinearGradientColorStops() || + this.fillRadialGradientColorStops() + ) + ); + } ); } /** @@ -368,12 +380,29 @@ export class Shape extends Node< * @returns {Boolean} */ hasStroke() { - return ( - this.strokeEnabled() && - this.strokeWidth() && - !!(this.stroke() || this.strokeLinearGradientColorStops()) - // this.getStrokeRadialGradientColorStops() + return this._calculate( + 'hasStroke', + [ + 'strokeEnabled', + 'strokeWidth', + 'stroke', + 'strokeLinearGradientColorStops', + ], + () => { + return ( + this.strokeEnabled() && + this.strokeWidth() && + !!(this.stroke() || this.strokeLinearGradientColorStops()) + // this.getStrokeRadialGradientColorStops() + ); + } ); + // return ( + // this.strokeEnabled() && + // this.strokeWidth() && + // !!(this.stroke() || this.strokeLinearGradientColorStops()) + // // this.getStrokeRadialGradientColorStops() + // ); } hasHitStroke() { const width = this.hitStrokeWidth(); diff --git a/src/shapes/Transformer.ts b/src/shapes/Transformer.ts index ec4cc86d..b3d852a4 100644 --- a/src/shapes/Transformer.ts +++ b/src/shapes/Transformer.ts @@ -316,7 +316,7 @@ export class Transformer extends Group { let lastPos; node.on(`dragstart.${EVENTS_NAME}`, (e) => { lastPos = node.getAbsolutePosition(); - this.fire('dragstart', e); + // this.fire('dragstart', e); }); node.on(`dragmove.${EVENTS_NAME}`, (e) => { if (!lastPos) { @@ -338,12 +338,10 @@ export class Transformer extends Group { y: otherAbs.y + dy, }); otherNode.startDrag(); - // TODO: how to trigger event after all nodes are dragged? - this.fire('dragmove', e); - }); - node.on(`dragend.${EVENTS_NAME}`, (e) => { - this.fire('dragend', e); }); + // node.on(`dragend.${EVENTS_NAME}`, (e) => { + // this.fire('dragend', e); + // }); lastPos = null; }); } diff --git a/test/performance/bunnies.html b/test/performance/bunnies.html index cdc290b1..0af569d1 100644 --- a/test/performance/bunnies.html +++ b/test/performance/bunnies.html @@ -92,6 +92,7 @@ transformsEnabled: 'position', x: 10, y: 10, + perfectDrawEnabled: false, }); bunny.speedX = Math.random() * 10; @@ -122,6 +123,7 @@ transformsEnabled: 'position', x: 0, y: 0, + perfectDrawEnabled: false, }); bunny.speedX = Math.random() * 10; bunny.speedY = Math.random() * 10 - 5; diff --git a/test/unit/shapes/Transformer-test.js b/test/unit/shapes/Transformer-test.js index 1408fea3..0d277e7f 100644 --- a/test/unit/shapes/Transformer-test.js +++ b/test/unit/shapes/Transformer-test.js @@ -3861,9 +3861,9 @@ suite('Transformer', function () { // proxy drag to other nodes assert.equal(rect2.x(), 105); assert.equal(rect2.y(), 105); - assert.equal(dragstart, 2); - assert.equal(dragmove, 2); - assert.equal(dragend, 2); + assert.equal(dragstart, 1); + assert.equal(dragmove, 1); + assert.equal(dragend, 1); }); test('reattach from several and drag one', function () {