no longer rely on the transitionend event, unwanted flashes are avoid using a timer
This commit is contained in:
@@ -138,6 +138,14 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
*/
|
*/
|
||||||
backBufferLonLat: null,
|
backBufferLonLat: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property; backBufferTimerId
|
||||||
|
* {Number} The id of the back buffer timer. This timer is used to
|
||||||
|
* delay the removal of the back buffer, thereby preventing
|
||||||
|
* flash effects caused by tile animation.
|
||||||
|
*/
|
||||||
|
backBufferTimerId: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a listener for a particular event with the following syntax:
|
* Register a listener for a particular event with the following syntax:
|
||||||
* (code)
|
* (code)
|
||||||
@@ -190,6 +198,10 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
window.clearTimeout(this.timerId);
|
window.clearTimeout(this.timerId);
|
||||||
this.timerId = null;
|
this.timerId = null;
|
||||||
}
|
}
|
||||||
|
if(this.backBufferTimerId !== null) {
|
||||||
|
window.clearTimeout(this.backBufferTimerId);
|
||||||
|
this.backBufferTimerId = null;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -197,9 +209,8 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
* Deconstruct the layer and clear the grid.
|
* Deconstruct the layer and clear the grid.
|
||||||
*/
|
*/
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
|
this.removeBackBuffer();
|
||||||
this.clearGrid();
|
this.clearGrid();
|
||||||
// clearGrid should remove any back buffer from the layer,
|
|
||||||
// so no need to call removeBackBuffer here
|
|
||||||
|
|
||||||
this.grid = null;
|
this.grid = null;
|
||||||
this.tileSize = null;
|
this.tileSize = null;
|
||||||
@@ -530,6 +541,17 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: scheduleBackBufferRemoval
|
||||||
|
*/
|
||||||
|
scheduleBackBufferRemoval: function() {
|
||||||
|
if(this.backBufferTimerId !== null) {
|
||||||
|
window.clearTimeout(this.backBufferTimerId);
|
||||||
|
}
|
||||||
|
this.backBufferTimerId = window.setTimeout(
|
||||||
|
OpenLayers.Function.bind(this.removeBackBuffer, this), 800);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method: moveByPx
|
* Method: moveByPx
|
||||||
* Move the layer based on pixel vector.
|
* Move the layer based on pixel vector.
|
||||||
@@ -930,8 +952,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
//if that was the last tile, then trigger a 'loadend' on the layer
|
//if that was the last tile, then trigger a 'loadend' on the layer
|
||||||
if (this.numLoadingTiles == 0) {
|
if (this.numLoadingTiles == 0) {
|
||||||
this.events.triggerEvent("loadend");
|
this.events.triggerEvent("loadend");
|
||||||
this.removeBackBuffer();
|
if(this.backBuffer) {
|
||||||
}
|
// the removal of the back buffer is delayed to prevent flash
|
||||||
|
// effects due to the animation of tile displaying
|
||||||
|
this.scheduleBackBufferRemoval();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
tile.events.register("loadend", this, tile.onLoadEnd);
|
tile.events.register("loadend", this, tile.onLoadEnd);
|
||||||
tile.events.register("unload", this, tile.onLoadEnd);
|
tile.events.register("unload", this, tile.onLoadEnd);
|
||||||
|
|||||||
@@ -359,27 +359,12 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
|||||||
var img = this.imgDiv;
|
var img = this.imgDiv;
|
||||||
OpenLayers.Event.stopObservingElement(img);
|
OpenLayers.Event.stopObservingElement(img);
|
||||||
|
|
||||||
var opacity = this.layer.opacity,
|
|
||||||
tileAnimation = this.layer.map.tileAnimation;
|
|
||||||
|
|
||||||
if (OpenLayers.Tile.Image.TRANSITION && tileAnimation && opacity) {
|
|
||||||
// if the displaying of the tile is animated we delay the
|
|
||||||
// loadend event until after the end of the transition, this
|
|
||||||
// to avoid flash effects because the backbuffer is removed
|
|
||||||
// before the tile is actually displayed
|
|
||||||
OpenLayers.Event.observe(img, OpenLayers.Tile.Image.TRANSITION_END,
|
|
||||||
OpenLayers.Function.bind(this.onTransitionEnd, this)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
img.style.visibility = 'inherit';
|
img.style.visibility = 'inherit';
|
||||||
img.style.opacity = opacity;
|
img.style.opacity = this.layer.opacity;
|
||||||
img.style.filter = 'alpha(opacity=' + (opacity * 100) + ')';
|
img.style.filter = 'alpha(opacity=' + (this.layer.opacity * 100) + ')';
|
||||||
|
|
||||||
if (!OpenLayers.Tile.Image.TRANSITION || !tileAnimation || !opacity) {
|
this.isLoading = false;
|
||||||
this.isLoading = false;
|
this.events.triggerEvent("loadend");
|
||||||
this.events.triggerEvent("loadend");
|
|
||||||
}
|
|
||||||
|
|
||||||
// IE<7 needs a reflow when the tiles are loaded because of the
|
// IE<7 needs a reflow when the tiles are loaded because of the
|
||||||
// percentage based positioning. Otherwise nothing is shown
|
// percentage based positioning. Otherwise nothing is shown
|
||||||
@@ -432,34 +417,3 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
|||||||
CLASS_NAME: "OpenLayers.Tile.Image"
|
CLASS_NAME: "OpenLayers.Tile.Image"
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test for support of CSS transitions and store appropriate property names
|
|
||||||
(function() {
|
|
||||||
function testProp(props) {
|
|
||||||
var style = document.documentElement.style;
|
|
||||||
for (var i=0; i<props.length; i++) {
|
|
||||||
if(props[i] in style) {
|
|
||||||
return props[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var TRANSITION = testProp([
|
|
||||||
'transition', 'webkitTransition', 'MozTransition'
|
|
||||||
]);
|
|
||||||
|
|
||||||
var TRANSITION_END = TRANSITION === 'webkitTransition' ?
|
|
||||||
TRANSITION + 'End' : 'transitionend';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constant: OpenLayers.Tile.Image.TRANSITION
|
|
||||||
*/
|
|
||||||
OpenLayers.Tile.Image.TRANSITION = TRANSITION;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constant: OpenLayers.Tile.Image.TRANSITION_END
|
|
||||||
*/
|
|
||||||
OpenLayers.Tile.Image.TRANSITION_END = TRANSITION_END;
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|||||||
+4
-49
@@ -344,7 +344,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_onImageLoad(t) {
|
function test_onImageLoad(t) {
|
||||||
t.plan(12);
|
t.plan(3);
|
||||||
|
|
||||||
var map = new OpenLayers.Map('map');
|
var map = new OpenLayers.Map('map');
|
||||||
var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
|
var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
|
||||||
@@ -357,61 +357,16 @@
|
|||||||
var log;
|
var log;
|
||||||
tile.events.on({loadend: function() { log++; }});
|
tile.events.on({loadend: function() { log++; }});
|
||||||
|
|
||||||
var T = OpenLayers.Tile.Image.TRANSITION;
|
|
||||||
var TE = OpenLayers.Tile.Image.TRANSITION_END;
|
|
||||||
OpenLayers.Tile.Image.TRANSITION_END = 'transitionend';
|
|
||||||
|
|
||||||
function firstObserverName() {
|
|
||||||
var cacheID = tile.imgDiv._eventCacheID,
|
|
||||||
observers = OpenLayers.Event.observers[cacheID];
|
|
||||||
return observers && observers.length > 0 ? observers[0].name : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenLayers.Tile.Image.TRANSITION = true;
|
|
||||||
map.tileAnimation = true;
|
|
||||||
log = 0;
|
log = 0;
|
||||||
tile.onImageLoad();
|
tile.onImageLoad();
|
||||||
t.eq(tile.imgDiv.style.visibility, 'inherit',
|
t.eq(tile.imgDiv.style.visibility, 'inherit',
|
||||||
'[a] onImageLoad makes the image visible');
|
'onImageLoad makes the image visible');
|
||||||
t.eq(parseFloat(tile.imgDiv.style.opacity), 0.5,
|
t.eq(parseFloat(tile.imgDiv.style.opacity), 0.5,
|
||||||
'[a] onImageLoad sets the expected opacity for the image');
|
'onImageLoad sets the expected opacity for the image');
|
||||||
t.eq(log, 0,
|
|
||||||
'[a] onImageLoad does not trigger loadend');
|
|
||||||
t.eq(firstObserverName(), 'transitionend',
|
|
||||||
'[a] onImageLoad registers a transitionend observer');
|
|
||||||
OpenLayers.Event.stopObservingElement(tile.imgDiv);
|
|
||||||
|
|
||||||
OpenLayers.Tile.Image.TRANSITION = true;
|
|
||||||
map.tileAnimation = false;
|
|
||||||
log = 0;
|
|
||||||
tile.onImageLoad();
|
|
||||||
t.eq(tile.imgDiv.style.visibility, 'inherit',
|
|
||||||
'[b] onImageLoad makes the image visible');
|
|
||||||
t.eq(parseFloat(tile.imgDiv.style.opacity), 0.5,
|
|
||||||
'[b] onImageLoad sets the expected opacity for the image');
|
|
||||||
t.eq(log, 1,
|
t.eq(log, 1,
|
||||||
'[b] onImageLoad does trigger loadend');
|
'onImageLoad does not trigger loadend');
|
||||||
t.eq(firstObserverName(), undefined,
|
|
||||||
'[b] onImageLoad does not register a transitionend observer');
|
|
||||||
OpenLayers.Event.stopObservingElement(tile.imgDiv);
|
|
||||||
|
|
||||||
OpenLayers.Tile.Image.TRANSITION = false;
|
|
||||||
map.tileAnimation = true;
|
|
||||||
log = 0;
|
|
||||||
tile.onImageLoad();
|
|
||||||
t.eq(tile.imgDiv.style.visibility, 'inherit',
|
|
||||||
'[c] onImageLoad makes the image visible');
|
|
||||||
t.eq(parseFloat(tile.imgDiv.style.opacity), 0.5,
|
|
||||||
'[c] onImageLoad sets the expected opacity for the image');
|
|
||||||
t.eq(log, 1,
|
|
||||||
'[c] onImageLoad does trigger loadend');
|
|
||||||
t.eq(firstObserverName(), undefined,
|
|
||||||
'[c] onImageLoad does not register a transitionend observer');
|
|
||||||
OpenLayers.Event.stopObservingElement(tile.imgDiv);
|
|
||||||
|
|
||||||
map.destroy();
|
map.destroy();
|
||||||
OpenLayers.Tile.Image.TRANSITION = T;
|
|
||||||
OpenLayers.Tile.Image.TRANSITION_END = TE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user