From 60925301ff6df61239788b693411ddb3a80e456c Mon Sep 17 00:00:00 2001 From: Merott Movahedi Date: Fri, 31 Jul 2015 16:21:56 +0100 Subject: [PATCH] fix resizing collisions caused by asynchronous nature of scope.$watch The resizing sometimes wouldn't work as expected because the resize function was being called at different times with different values, and not always the most recent would win. By implementing a short delay, and ensuring that previous calls to resize() are cancelled, the resizing can be done more reliably --- src/ng-FitText.js | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/ng-FitText.js b/src/ng-FitText.js index e5cc8a3..009ef21 100644 --- a/src/ng-FitText.js +++ b/src/ng-FitText.js @@ -33,6 +33,7 @@ element[0].style.display = 'inline-block'; element[0].style.lineHeight = '1'; + var resizePromise; var parent = element.parent(); var compressor = attrs.fittext || 1; var loadDelay = attrs.fittextLoadDelay || config.loadDelay; @@ -41,19 +42,35 @@ var maxFontSize = attrs.fittextMax || config.max || Number.POSITIVE_INFINITY; var resizer = function() { - element[0].style.fontSize = '10px'; - var ratio = element[0].offsetHeight / element[0].offsetWidth / nl; - element[0].style.fontSize = Math.max( - Math.min((parent[0].offsetWidth - 6) * ratio * compressor, - parseFloat(maxFontSize) - ), - parseFloat(minFontSize) - ) + 'px'; + if(resizePromise) { + $timeout.cancel(resizePromise); + } + + resizePromise = $timeout(function() { + resizePromise = null; + + element[0].style.fontSize = '10px'; + var ratio = element[0].offsetHeight / element[0].offsetWidth / nl; + element[0].style.fontSize = Math.max( + Math.min((parent[0].offsetWidth - 6) * ratio * compressor, + parseFloat(maxFontSize) + ), + parseFloat(minFontSize) + ) + 'px'; + }, 5); }; $timeout( function() { resizer() }, loadDelay); - scope.$watch(attrs.ngModel, function() { resizer() }); + scope.$watch(function() { + return [ + scope.$eval(attrs.ngModel), + parent[0].offsetWidth, + element[0].offsetWidth + ].join('_'); + }, function() { + resizer(); + }); config.debounce ? angular.element(window).bind('resize', config.debounce(function(){ scope.$apply(resizer)}, config.delay))