From c68cd693cc39d7de8113f027038f6bce28efbda9 Mon Sep 17 00:00:00 2001 From: Karl-Petter Lindegaard <5760583+kplindegaard@users.noreply.github.com> Date: Sat, 15 Jun 2019 15:43:08 +0200 Subject: [PATCH] Prevent memory leaks in AnimationUpdater (#216) AnimationUpdate removes finished references to prevent memory leaks. --- README.md | 7 +++++++ bower.json | 2 +- dist/gauge.coffee | 15 +++++++++++++-- dist/gauge.js | 44 +++++++++++++++++++++++++++++--------------- dist/gauge.min.js | 2 +- index.html | 8 ++++++++ package.json | 2 +- 7 files changed, 60 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 1d8f875..4220b9a 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,10 @@ gauge.set(1250); // set actual value ``` For an interactive demo and a list of all supported options please refer to the [project's homepage](http://bernii.github.com/gauge.js). + +## Wrappers + +gauge.js can be wrapped to a number of frameworks. Here are some examples: + +* **Vue** + * [vgauge](https://github.com/amroessam/vgauge) diff --git a/bower.json b/bower.json index 7dccd9c..7718860 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "gauge.js", - "version": "1.3.6", + "version": "1.3.7", "main": [ "dist/gauge.js", "dist/gauge.min.js", diff --git a/dist/gauge.coffee b/dist/gauge.coffee index 924066b..5f41a68 100644 --- a/dist/gauge.coffee +++ b/dist/gauge.coffee @@ -386,6 +386,7 @@ class Gauge extends BaseGauge @value = Math.max(Math.min(value[value.length - 1], @maxValue), @minValue) # TODO: Span maybe?? # Force first .set() + AnimationUpdater.add(@) AnimationUpdater.run(@forceUpdate) @forceUpdate = false @@ -624,6 +625,7 @@ class BaseDonut extends BaseGauge else @minValue = @value + AnimationUpdater.add(@) AnimationUpdater.run(@forceUpdate) @forceUpdate = false @@ -683,7 +685,8 @@ window.AnimationUpdater = AnimationUpdater.elements.push(elem) add: (object) -> - AnimationUpdater.elements.push(object) + if object not in AnimationUpdater.elements + AnimationUpdater.elements.push object run: (force = false) -> # 'force' can take three values, for which these paths should be taken @@ -693,9 +696,17 @@ window.AnimationUpdater = isCallback = isFinite(parseFloat(force)) if isCallback or force is true finished = true - for elem in AnimationUpdater.elements + toRemove = [] + for elem, k in AnimationUpdater.elements if elem.update(force is true) finished = false + else + toRemove.push k + + # Remove finished elements + for k in toRemove by -1 + AnimationUpdater.elements.splice k, 1 + AnimationUpdater.animId = if finished then null else requestAnimationFrame(AnimationUpdater.run) else if force is false if AnimationUpdater.animId is not null diff --git a/dist/gauge.js b/dist/gauge.js index 66901b0..8feb256 100644 --- a/dist/gauge.js +++ b/dist/gauge.js @@ -1,9 +1,10 @@ -// Generated by CoffeeScript 1.10.0 +// Generated by CoffeeScript 1.11.1 (function() { var AnimatedText, AnimatedTextFactory, Bar, BaseDonut, BaseGauge, Donut, Gauge, GaugePointer, TextRenderer, ValueUpdater, addCommas, cutHex, formatNumber, mergeObjects, secondsToString, slice = [].slice, hasProp = {}.hasOwnProperty, - extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; (function() { var browserRequestAnimationFrame, isCancelled, j, lastId, len, vendor, vendors; @@ -522,7 +523,7 @@ }; Gauge.prototype.set = function(value) { - var gp, i, j, k, l, len, ref, ref1, val; + var gp, i, j, l, len, m, ref, ref1, val; if (!(value instanceof Array)) { value = [value]; } @@ -530,7 +531,7 @@ value[i] = this.parseValue(value[i]); } if (value.length > this.gp.length) { - for (i = k = 0, ref1 = value.length - this.gp.length; 0 <= ref1 ? k < ref1 : k > ref1; i = 0 <= ref1 ? ++k : --k) { + for (i = l = 0, ref1 = value.length - this.gp.length; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) { gp = new GaugePointer(this); gp.setOptions(this.options.pointer); this.gp.push(gp); @@ -539,8 +540,8 @@ this.gp = this.gp.slice(this.gp.length - value.length); } i = 0; - for (l = 0, len = value.length; l < len; l++) { - val = value[l]; + for (m = 0, len = value.length; m < len; m++) { + val = value[m]; if (val > this.maxValue) { if (this.options.limitMax) { val = this.maxValue; @@ -562,6 +563,7 @@ }); } this.value = Math.max(Math.min(value[value.length - 1], this.maxValue), this.minValue); + AnimationUpdater.add(this); AnimationUpdater.run(this.forceUpdate); return this.forceUpdate = false; }; @@ -673,9 +675,9 @@ currentDivision += rangeDivisions; if (t !== ticksOptions.divisions && subdivisionCount > 0) { results.push((function() { - var k, ref1, results1; + var l, ref1, results1; results1 = []; - for (st = k = 0, ref1 = subdivisionCount - 1; k < ref1; st = k += 1) { + for (st = l = 0, ref1 = subdivisionCount - 1; l < ref1; st = l += 1) { this.ctx.lineWidth = this.lineWidth * subLength; scaleMutate = (this.lineWidth / 2) * (1 - subLength); tmpRadius = (this.radius * this.options.radiusScale) + scaleMutate; @@ -696,7 +698,7 @@ }; Gauge.prototype.render = function() { - var displayedAngle, fillStyle, gauge, h, j, k, len, len1, max, min, radius, ref, ref1, scaleMutate, tmpRadius, w, zone; + var displayedAngle, fillStyle, gauge, h, j, l, len, len1, max, min, radius, ref, ref1, scaleMutate, tmpRadius, w, zone; w = this.canvas.width / 2; h = (this.canvas.height * this.paddingTop + this.availableHeight) - ((this.radius + this.lineWidth / 2) * this.extraPadding); displayedAngle = this.getAngle(this.displayedValue); @@ -768,8 +770,8 @@ this.ctx.restore(); this.ctx.translate(w, h); ref1 = this.gp; - for (k = 0, len1 = ref1.length; k < len1; k++) { - gauge = ref1[k]; + for (l = 0, len1 = ref1.length; l < len1; l++) { + gauge = ref1[l]; gauge.update(true); } return this.ctx.translate(-w, -h); @@ -842,6 +844,7 @@ this.minValue = this.value; } } + AnimationUpdater.add(this); AnimationUpdater.run(this.forceUpdate); return this.forceUpdate = false; }; @@ -924,23 +927,32 @@ return results; }, add: function(object) { - return AnimationUpdater.elements.push(object); + if (indexOf.call(AnimationUpdater.elements, object) < 0) { + return AnimationUpdater.elements.push(object); + } }, run: function(force) { - var elem, finished, isCallback, j, len, ref; + var elem, finished, isCallback, j, k, l, len, ref, toRemove; if (force == null) { force = false; } isCallback = isFinite(parseFloat(force)); if (isCallback || force === true) { finished = true; + toRemove = []; ref = AnimationUpdater.elements; - for (j = 0, len = ref.length; j < len; j++) { - elem = ref[j]; + for (k = j = 0, len = ref.length; j < len; k = ++j) { + elem = ref[k]; if (elem.update(force === true)) { finished = false; + } else { + toRemove.push(k); } } + for (l = toRemove.length - 1; l >= 0; l += -1) { + k = toRemove[l]; + AnimationUpdater.elements.splice(k, 1); + } return AnimationUpdater.animId = finished ? null : requestAnimationFrame(AnimationUpdater.run); } else if (force === false) { if (AnimationUpdater.animId === !null) { @@ -975,3 +987,5 @@ } }).call(this); + +//# sourceMappingURL=gauge.js.map diff --git a/dist/gauge.min.js b/dist/gauge.min.js index 227cc31..1b77c1c 100644 --- a/dist/gauge.min.js +++ b/dist/gauge.min.js @@ -1 +1 @@ -(function(){var t,i,e,s,n,o,a,h,r,l,p,c,u,d=[].slice,g={}.hasOwnProperty,m=function(t,i){function e(){this.constructor=t}for(var s in i)g.call(i,s)&&(t[s]=i[s]);return e.prototype=i.prototype,t.prototype=new e,t.__super__=i.prototype,t};!function(){var t,i,e,s,n,o,a;for(a=["ms","moz","webkit","o"],e=0,n=a.length;e1&&(n="."+e[1]),i=/(\d+)(\d{3})/;i.test(s);)s=s.replace(i,"$1,$2");return s+n},l=function(t){return"#"===t.charAt(0)?t.substring(1,7):t},h=function(){function t(t,i){null==t&&(t=!0),this.clear=null==i||i,t&&AnimationUpdater.add(this)}return t.prototype.animationSpeed=32,t.prototype.update=function(t){var i;return null==t&&(t=!1),!(!t&&this.displayedValue===this.value)&&(this.ctx&&this.clear&&this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),i=this.value-this.displayedValue,Math.abs(i/this.animationSpeed)<=.001?this.displayedValue=this.value:this.displayedValue=this.displayedValue+i/this.animationSpeed,this.render(),!0)},t}(),e=function(t){function i(){return i.__super__.constructor.apply(this,arguments)}return m(i,t),i.prototype.displayScale=1,i.prototype.forceUpdate=!0,i.prototype.setTextField=function(t,i){return this.textField=t instanceof a?t:new a(t,i)},i.prototype.setMinValue=function(t,i){var e,s,n,o,a;if(this.minValue=t,null==i&&(i=!0),i){for(this.displayedValue=this.minValue,o=this.gp||[],a=[],s=0,n=o.length;s.5&&(this.options.angle=.5),this.configDisplayScale(),this},i.prototype.configDisplayScale=function(){var t,i,e,s,n;return s=this.displayScale,!1===this.options.highDpiSupport?delete this.displayScale:(i=window.devicePixelRatio||1,t=this.ctx.webkitBackingStorePixelRatio||this.ctx.mozBackingStorePixelRatio||this.ctx.msBackingStorePixelRatio||this.ctx.oBackingStorePixelRatio||this.ctx.backingStorePixelRatio||1,this.displayScale=i/t),this.displayScale!==s&&(n=this.canvas.G__width||this.canvas.width,e=this.canvas.G__height||this.canvas.height,this.canvas.width=n*this.displayScale,this.canvas.height=e*this.displayScale,this.canvas.style.width=n+"px",this.canvas.style.height=e+"px",this.canvas.G__width=n,this.canvas.G__height=e),this},i.prototype.parseValue=function(t){return t=parseFloat(t)||Number(t),isFinite(t)?t:0},i}(h),a=function(){function t(t,i){this.el=t,this.fractionDigits=i}return t.prototype.render=function(t){return this.el.innerHTML=p(t.displayedValue,this.fractionDigits)},t}(),t=function(t){function i(t,e){if(this.elem=t,this.text=null!=e&&e,i.__super__.constructor.call(this),void 0===this.elem)throw new Error("The element isn't defined.");this.value=1*this.elem.innerHTML,this.text&&(this.value=0)}return m(i,t),i.prototype.displayedValue=0,i.prototype.value=0,i.prototype.setVal=function(t){return this.value=1*t},i.prototype.render=function(){var t;return t=this.text?u(this.displayedValue.toFixed(0)):r(p(this.displayedValue)),this.elem.innerHTML=t},i}(h),o=function(t){function i(t){if(this.gauge=t,void 0===this.gauge)throw new Error("The element isn't defined.");this.ctx=this.gauge.ctx,this.canvas=this.gauge.canvas,i.__super__.constructor.call(this,!1,!1),this.setOptions()}return m(i,t),i.prototype.displayedValue=0,i.prototype.value=0,i.prototype.options={strokeWidth:.035,length:.1,color:"#000000",iconPath:null,iconScale:1,iconAngle:0},i.prototype.img=null,i.prototype.setOptions=function(t){if(null==t&&(t=null),this.options=c(this.options,t),this.length=2*this.gauge.radius*this.gauge.options.radiusScale*this.options.length,this.strokeWidth=this.canvas.height*this.options.strokeWidth,this.maxValue=this.gauge.maxValue,this.minValue=this.gauge.minValue,this.animationSpeed=this.gauge.animationSpeed,this.options.angle=this.gauge.options.angle,this.options.iconPath)return this.img=new Image,this.img.src=this.options.iconPath},i.prototype.render=function(){var t,i,e,s,n,o,a,h,r;if(t=this.gauge.getAngle.call(this,this.displayedValue),h=Math.round(this.length*Math.cos(t)),r=Math.round(this.length*Math.sin(t)),o=Math.round(this.strokeWidth*Math.cos(t-Math.PI/2)),a=Math.round(this.strokeWidth*Math.sin(t-Math.PI/2)),i=Math.round(this.strokeWidth*Math.cos(t+Math.PI/2)),e=Math.round(this.strokeWidth*Math.sin(t+Math.PI/2)),this.ctx.beginPath(),this.ctx.fillStyle=this.options.color,this.ctx.arc(0,0,this.strokeWidth,0,2*Math.PI,!1),this.ctx.fill(),this.ctx.beginPath(),this.ctx.moveTo(o,a),this.ctx.lineTo(h,r),this.ctx.lineTo(i,e),this.ctx.fill(),this.img)return s=Math.round(this.img.width*this.options.iconScale),n=Math.round(this.img.height*this.options.iconScale),this.ctx.save(),this.ctx.translate(h,r),this.ctx.rotate(t+Math.PI/180*(90+this.options.iconAngle)),this.ctx.drawImage(this.img,-s/2,-n/2,s,n),this.ctx.restore()},i}(h),function(){function t(t){this.elem=t}t.prototype.updateValues=function(t){return this.value=t[0],this.maxValue=t[1],this.avgValue=t[2],this.render()},t.prototype.render=function(){var t,i;return this.textField&&this.textField.text(p(this.value)),0===this.maxValue&&(this.maxValue=2*this.avgValue),i=this.value/this.maxValue*100,t=this.avgValue/this.maxValue*100,$(".bar-value",this.elem).css({width:i+"%"}),$(".typical-value",this.elem).css({width:t+"%"})}}(),n=function(t){function i(t){var e,s;this.canvas=t,i.__super__.constructor.call(this),this.percentColors=null,"undefined"!=typeof G_vmlCanvasManager&&(this.canvas=window.G_vmlCanvasManager.initElement(this.canvas)),this.ctx=this.canvas.getContext("2d"),e=this.canvas.clientHeight,s=this.canvas.clientWidth,this.canvas.height=e,this.canvas.width=s,this.gp=[new o(this)],this.setOptions()}return m(i,t),i.prototype.elem=null,i.prototype.value=[20],i.prototype.maxValue=80,i.prototype.minValue=0,i.prototype.displayedAngle=0,i.prototype.displayedValue=0,i.prototype.lineWidth=40,i.prototype.paddingTop=.1,i.prototype.paddingBottom=.1,i.prototype.percentColors=null,i.prototype.options={colorStart:"#6fadcf",colorStop:void 0,gradientType:0,strokeColor:"#e0e0e0",pointer:{length:.8,strokeWidth:.035,iconScale:1},angle:.15,lineWidth:.44,radiusScale:1,fontSize:40,limitMax:!1,limitMin:!1},i.prototype.setOptions=function(t){var e,s,n,o,a;for(null==t&&(t=null),i.__super__.setOptions.call(this,t),this.configPercentColors(),this.extraPadding=0,this.options.angle<0&&(o=Math.PI*(1+this.options.angle),this.extraPadding=Math.sin(o)),this.availableHeight=this.canvas.height*(1-this.paddingTop-this.paddingBottom),this.lineWidth=this.availableHeight*this.options.lineWidth,this.radius=(this.availableHeight-this.lineWidth/2)/(1+this.extraPadding),this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),a=this.gp,s=0,n=a.length;s=n;e=0<=n?++s:--s)a=parseInt(l(this.options.percentColors[e][1]).substring(0,2),16),i=parseInt(l(this.options.percentColors[e][1]).substring(2,4),16),t=parseInt(l(this.options.percentColors[e][1]).substring(4,6),16),o.push(this.percentColors[e]={pct:this.options.percentColors[e][0],color:{r:a,g:i,b:t}});return o}},i.prototype.set=function(t){var i,e,s,n,a,h,r,l,p;for(t instanceof Array||(t=[t]),e=s=0,r=t.length-1;0<=r?s<=r:s>=r;e=0<=r?++s:--s)t[e]=this.parseValue(t[e]);if(t.length>this.gp.length)for(e=n=0,l=t.length-this.gp.length;0<=l?nl;e=0<=l?++n:--n)i=new o(this),i.setOptions(this.options.pointer),this.gp.push(i);else t.lengththis.maxValue?this.options.limitMax?p=this.maxValue:this.maxValue=p+1:p=h;n=0<=h?++o:--o)if(t<=this.percentColors[n].pct){!0===i?(r=this.percentColors[n-1]||this.percentColors[0],s=this.percentColors[n],a=(t-r.pct)/(s.pct-r.pct),e={r:Math.floor(r.color.r*(1-a)+s.color.r*a),g:Math.floor(r.color.g*(1-a)+s.color.g*a),b:Math.floor(r.color.b*(1-a)+s.color.b*a)}):e=this.percentColors[n].color;break}return"rgb("+[e.r,e.g,e.b].join(",")+")"},i.prototype.getColorForValue=function(t,i){var e;return e=(t-this.minValue)/(this.maxValue-this.minValue),this.getColorForPercentage(e,i)},i.prototype.renderStaticLabels=function(t,i,e,s){var n,o,a,h,r,l,c,u,d,g;for(this.ctx.save(),this.ctx.translate(i,e),n=t.font||"10px Times",l=/\d+\.?\d?/,r=n.match(l)[0],u=n.slice(r.length),o=parseFloat(r)*this.displayScale,this.ctx.font=o+u,this.ctx.fillStyle=t.color||"#000000",this.ctx.textBaseline="bottom",this.ctx.textAlign="center",c=t.labels,a=0,h=c.length;a=this.minValue)&&(!this.options.limitMax||g<=this.maxValue)&&(n=g.font||t.font,r=n.match(l)[0],u=n.slice(r.length),o=parseFloat(r)*this.displayScale,this.ctx.font=o+u,d=this.getAngle(g.label)-3*Math.PI/2,this.ctx.rotate(d),this.ctx.fillText(p(g.label,t.fractionDigits),0,-s-this.lineWidth/2),this.ctx.rotate(-d)):(!this.options.limitMin||g>=this.minValue)&&(!this.options.limitMax||g<=this.maxValue)&&(d=this.getAngle(g)-3*Math.PI/2,this.ctx.rotate(d),this.ctx.fillText(p(g,t.fractionDigits),0,-s-this.lineWidth/2),this.ctx.rotate(-d));return this.ctx.restore()},i.prototype.renderTicks=function(t,i,e,s){var n,o,a,h,r,l,p,c,u,d,g,m,x,f,v,y,V,w,S,M,C;if(t!=={}){for(l=t.divisions||0,S=t.subDivisions||0,a=t.divColor||"#fff",v=t.subColor||"#fff",h=t.divLength||.7,V=t.subLength||.2,u=parseFloat(this.maxValue)-parseFloat(this.minValue),d=parseFloat(u)/parseFloat(t.divisions),y=parseFloat(d)/parseFloat(t.subDivisions),n=parseFloat(this.minValue),o=0+y,c=u/400,r=c*(t.divWidth||1),w=c*(t.subWidth||1),m=[],M=p=0,g=l+1;p0?m.push(function(){var t,i,e;for(e=[],f=t=0,i=S-1;tthis.maxValue&&(r=this.maxValue),g=this.radius*this.options.radiusScale,x.height&&(this.ctx.lineWidth=this.lineWidth*x.height,d=this.lineWidth/2*(x.offset||1-x.height),g=this.radius*this.options.radiusScale+d),this.ctx.strokeStyle=x.strokeStyle,this.ctx.beginPath(),this.ctx.arc(0,0,g,this.getAngle(l),this.getAngle(r),!1),this.ctx.stroke();else void 0!==this.options.customFillStyle?i=this.options.customFillStyle(this):null!==this.percentColors?i=this.getColorForValue(this.displayedValue,this.options.generateGradient):void 0!==this.options.colorStop?(i=0===this.options.gradientType?this.ctx.createRadialGradient(m,s,9,m,s,70):this.ctx.createLinearGradient(0,0,m,0),i.addColorStop(0,this.options.colorStart),i.addColorStop(1,this.options.colorStop)):i=this.options.colorStart,this.ctx.strokeStyle=i,this.ctx.beginPath(),this.ctx.arc(m,s,p,(1+this.options.angle)*Math.PI,t,!1),this.ctx.lineWidth=this.lineWidth,this.ctx.stroke(),this.ctx.strokeStyle=this.options.strokeColor,this.ctx.beginPath(),this.ctx.arc(m,s,p,t,(2-this.options.angle)*Math.PI,!1),this.ctx.stroke(),this.ctx.save(),this.ctx.translate(m,s);for(this.options.renderTicks&&this.renderTicks(this.options.renderTicks,m,s,p),this.ctx.restore(),this.ctx.translate(m,s),u=this.gp,o=0,h=u.length;othis.maxValue?this.options.limitMax?this.value=this.maxValue:this.maxValue=this.value:this.valuethis.gp.length)for(e=n=0,r=t.length-this.gp.length;0<=r?nthis.maxValue?this.options.limitMax?l=this.maxValue:this.maxValue=l+1:l=this.minValue)&&(!this.options.limitMax||d<=this.maxValue)&&(r=(n=d.font||t.font).match(l)[0],c=n.slice(r.length),o=parseFloat(r)*this.displayScale,this.ctx.font=o+c,u=this.getAngle(d.label)-3*Math.PI/2,this.ctx.rotate(u),this.ctx.fillText(g(d.label,t.fractionDigits),0,-s-this.lineWidth/2),this.ctx.rotate(-u)):(!this.options.limitMin||d>=this.minValue)&&(!this.options.limitMax||d<=this.maxValue)&&(u=this.getAngle(d)-3*Math.PI/2,this.ctx.rotate(u),this.ctx.fillText(g(d,t.fractionDigits),0,-s-this.lineWidth/2),this.ctx.rotate(-u));return this.ctx.restore()},M.prototype.renderTicks=function(t,i,e,s){var n,o,a,h,r,l,p,c,u,d,g,m,x,f,v,y,V,w,S,M;if(t!=={}){for(l=t.divisions||0,w=t.subDivisions||0,a=t.divColor||"#fff",f=t.subColor||"#fff",h=t.divLength||.7,y=t.subLength||.2,u=parseFloat(this.maxValue)-parseFloat(this.minValue),d=parseFloat(u)/parseFloat(t.divisions),v=parseFloat(d)/parseFloat(t.subDivisions),n=parseFloat(this.minValue),o=0+v,r=(c=u/400)*(t.divWidth||1),V=c*(t.subWidth||1),m=[],S=p=0,g=l+1;pthis.maxValue&&(h=this.maxValue),d=this.radius*this.options.radiusScale,m.height&&(this.ctx.lineWidth=this.lineWidth*m.height,u=this.lineWidth/2*(m.offset||1-m.height),d=this.radius*this.options.radiusScale+u),this.ctx.strokeStyle=m.strokeStyle,this.ctx.beginPath(),this.ctx.arc(0,0,d,this.getAngle(r),this.getAngle(h),!1),this.ctx.stroke();else void 0!==this.options.customFillStyle?i=this.options.customFillStyle(this):null!==this.percentColors?i=this.getColorForValue(this.displayedValue,this.options.generateGradient):void 0!==this.options.colorStop?((i=0===this.options.gradientType?this.ctx.createRadialGradient(g,e,9,g,e,70):this.ctx.createLinearGradient(0,0,g,0)).addColorStop(0,this.options.colorStart),i.addColorStop(1,this.options.colorStop)):i=this.options.colorStart,this.ctx.strokeStyle=i,this.ctx.beginPath(),this.ctx.arc(g,e,l,(1+this.options.angle)*Math.PI,t,!1),this.ctx.lineWidth=this.lineWidth,this.ctx.stroke(),this.ctx.strokeStyle=this.options.strokeColor,this.ctx.beginPath(),this.ctx.arc(g,e,l,t,(2-this.options.angle)*Math.PI,!1),this.ctx.stroke(),this.ctx.save(),this.ctx.translate(g,e);for(this.options.renderTicks&&this.renderTicks(this.options.renderTicks,g,e,l),this.ctx.restore(),this.ctx.translate(g,e),n=0,a=(c=this.gp).length;nthis.maxValue?this.options.limitMax?this.value=this.maxValue:this.maxValue=this.value:this.valueSupported browsers

Changes

+ +

Version 1.3.7 (15.06.2019)

+

+

    +
  • AnimationUpdater now removes references finished rendering to prevent memory leaks.
  • +
+

+

Version 1.3.6 (28.11.2017)

    diff --git a/package.json b/package.json index ca4788e..c96408f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gaugeJS", - "version": "1.3.6", + "version": "1.3.7", "description": "100% native and cool looking animated JavaScript/CoffeeScript gauge", "main": "dist/gauge.js", "repository": {