From dd244e6988a51d7a94412f4b9fcbe2da70438b9a Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 21 Dec 2012 12:33:28 +0100 Subject: [PATCH 1/3] Use transitionend listeners where available In addition to relying on removeBackBufferDelay, we can remove the backbuffer earlier without flicker in an ontransitionend listener on the last loaded tile. --- lib/OpenLayers/Layer/Grid.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 815eb0d0ae..c2ad2abfaa 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -300,6 +300,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { arguments); this.grid = []; this.tileQueue = []; + this._removeBackBuffer = OpenLayers.Function.bind(this.removeBackBuffer, this); if (this.removeBackBufferDelay === null) { this.removeBackBufferDelay = this.singleTile ? 0 : 2500; @@ -757,6 +758,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { * Remove back buffer from DOM. */ removeBackBuffer: function() { + if (this._transitionElement) { + OpenLayers.Event.stopObserving(this._transitionElement, 'transitionend', this._removeBackBuffer); + OpenLayers.Event.stopObserving(this._transitionElement, 'webkitTransitionEnd', this._removeBackBuffer); + OpenLayers.Event.stopObserving(this._transitionElement, 'otransitionend', this._removeBackBuffer); + delete this._transitionElement; + } if(this.backBuffer) { this.div.removeChild(this.backBuffer); this.backBuffer = null; @@ -1120,11 +1127,13 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { this.loading = false; this.events.triggerEvent("loadend"); if(this.backBuffer) { - // the removal of the back buffer is delayed to prevent flash - // effects due to the animation of tile displaying + this._transitionElement = tile.imgDiv; + OpenLayers.Event.observe(this._transitionElement, 'transitionend', this._removeBackBuffer); + OpenLayers.Event.observe(this._transitionElement, 'webkitTransitionEnd', this._removeBackBuffer); + OpenLayers.Event.observe(this._transitionElement, 'otransitionend', this._removeBackBuffer); + // the removal of the back buffer is delayed to prevent // flash effects due to the animation of tile displaying this.backBufferTimerId = window.setTimeout( - OpenLayers.Function.bind(this.removeBackBuffer, this), - this.removeBackBufferDelay + this._removeBackBuffer, this.removeBackBufferDelay ); } } From 43c646b6da507cb2a667fd7418f3ceb7bada6ed6 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 21 Dec 2012 13:01:15 +0100 Subject: [PATCH 2/3] Use new Opera event name as well As pointed out by @bartvde, according to http://stackoverflow.com/questions/5819912/webkit-transition-end-in-mozilla-and-opera, Opera uses otransitionend or oTransitionEnd, depending on the version. --- lib/OpenLayers/Layer/Grid.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index c2ad2abfaa..7819fe3396 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -762,6 +762,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { OpenLayers.Event.stopObserving(this._transitionElement, 'transitionend', this._removeBackBuffer); OpenLayers.Event.stopObserving(this._transitionElement, 'webkitTransitionEnd', this._removeBackBuffer); OpenLayers.Event.stopObserving(this._transitionElement, 'otransitionend', this._removeBackBuffer); + OpenLayers.Event.stopObserving(this._transitionElement, 'oTransitionEnd', this._removeBackBuffer); delete this._transitionElement; } if(this.backBuffer) { @@ -1131,6 +1132,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { OpenLayers.Event.observe(this._transitionElement, 'transitionend', this._removeBackBuffer); OpenLayers.Event.observe(this._transitionElement, 'webkitTransitionEnd', this._removeBackBuffer); OpenLayers.Event.observe(this._transitionElement, 'otransitionend', this._removeBackBuffer); + OpenLayers.Event.observe(this._transitionElement, 'oTransitionEnd', this._removeBackBuffer); // the removal of the back buffer is delayed to prevent // flash effects due to the animation of tile displaying this.backBufferTimerId = window.setTimeout( this._removeBackBuffer, this.removeBackBufferDelay From fcd8586883df12dc6f63dfdec1065d2c92720725 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 21 Dec 2012 13:07:36 +0100 Subject: [PATCH 3/3] Using an array for the transitionend event names --- lib/OpenLayers/Layer/Grid.js | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 7819fe3396..a8c1912730 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -285,6 +285,15 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { */ rowSign: null, + /** + * Property: transitionendEvents + * {Array} Event names for transitionend + */ + transitionendEvents: [ + 'transitionend', 'webkitTransitionEnd', 'otransitionend', + 'oTransitionEnd' + ], + /** * Constructor: OpenLayers.Layer.Grid * Create a new grid layer @@ -759,10 +768,10 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { */ removeBackBuffer: function() { if (this._transitionElement) { - OpenLayers.Event.stopObserving(this._transitionElement, 'transitionend', this._removeBackBuffer); - OpenLayers.Event.stopObserving(this._transitionElement, 'webkitTransitionEnd', this._removeBackBuffer); - OpenLayers.Event.stopObserving(this._transitionElement, 'otransitionend', this._removeBackBuffer); - OpenLayers.Event.stopObserving(this._transitionElement, 'oTransitionEnd', this._removeBackBuffer); + for (var i=this.transitionendEvents.length-1; i>=0; --i) { + OpenLayers.Event.stopObserving(this._transitionElement, + this.transitionendEvents[i], this._removeBackBuffer); + } delete this._transitionElement; } if(this.backBuffer) { @@ -1129,10 +1138,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { this.events.triggerEvent("loadend"); if(this.backBuffer) { this._transitionElement = tile.imgDiv; - OpenLayers.Event.observe(this._transitionElement, 'transitionend', this._removeBackBuffer); - OpenLayers.Event.observe(this._transitionElement, 'webkitTransitionEnd', this._removeBackBuffer); - OpenLayers.Event.observe(this._transitionElement, 'otransitionend', this._removeBackBuffer); - OpenLayers.Event.observe(this._transitionElement, 'oTransitionEnd', this._removeBackBuffer); + for (var i=this.transitionendEvents.length-1; i>=0; --i) { + OpenLayers.Event.observe(this._transitionElement, + this.transitionendEvents[i], + this._removeBackBuffer); + } // the removal of the back buffer is delayed to prevent // flash effects due to the animation of tile displaying this.backBufferTimerId = window.setTimeout( this._removeBackBuffer, this.removeBackBufferDelay