Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4c4a81afb | ||
|
|
7478e82b9a | ||
|
|
4b586df2b5 | ||
|
|
ed62203527 |
10
changelog/v3.14.1.md
Normal file
10
changelog/v3.14.1.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# v3.14.1
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
The v3.14.1 release is a patch release that addresses a few regressions in the v3.14.0 release. See the [v3.14.0 release notes](https://github.com/openlayers/ol3/releases/tag/v3.14.0) for details on upgrading from v3.13.x.
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
* [#4939](https://github.com/openlayers/ol3/pull/4939) - Fix rendering of opaque layers with opacity != 1 ([@ahocevar](https://github.com/ahocevar))
|
||||||
|
* [#4921](https://github.com/openlayers/ol3/pull/4921) - Unlisten before calling listener and bind to target by default ([@ahocevar](https://github.com/ahocevar))
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "openlayers",
|
"name": "openlayers",
|
||||||
"version": "3.14.0",
|
"version": "3.14.1",
|
||||||
"description": "Build tools and sources for developing OpenLayers based mapping applications",
|
"description": "Build tools and sources for developing OpenLayers based mapping applications",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"map",
|
"map",
|
||||||
|
|||||||
@@ -107,11 +107,12 @@ ol.events.ListenerObjType;
|
|||||||
*/
|
*/
|
||||||
ol.events.bindListener_ = function(listenerObj) {
|
ol.events.bindListener_ = function(listenerObj) {
|
||||||
var boundListener = function(evt) {
|
var boundListener = function(evt) {
|
||||||
var rv = listenerObj.listener.call(listenerObj.bindTo, evt);
|
var listener = listenerObj.listener;
|
||||||
|
var bindTo = listenerObj.bindTo || listenerObj.target;
|
||||||
if (listenerObj.callOnce) {
|
if (listenerObj.callOnce) {
|
||||||
ol.events.unlistenByKey(listenerObj);
|
ol.events.unlistenByKey(listenerObj);
|
||||||
}
|
}
|
||||||
return rv;
|
return listener.call(bindTo, evt);
|
||||||
}
|
}
|
||||||
listenerObj.boundListener = boundListener;
|
listenerObj.boundListener = boundListener;
|
||||||
return boundListener;
|
return boundListener;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ goog.require('ol.array');
|
|||||||
goog.require('ol.dom');
|
goog.require('ol.dom');
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.layer.Tile');
|
goog.require('ol.layer.Tile');
|
||||||
|
goog.require('ol.object');
|
||||||
goog.require('ol.render.EventType');
|
goog.require('ol.render.EventType');
|
||||||
goog.require('ol.renderer.canvas.Layer');
|
goog.require('ol.renderer.canvas.Layer');
|
||||||
goog.require('ol.source.Tile');
|
goog.require('ol.source.Tile');
|
||||||
@@ -25,9 +26,9 @@ ol.renderer.canvas.TileLayer = function(tileLayer) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {Object.<string, Array.<ol.Extent>>}
|
* @type {!Object.<string, Array.<ol.TileCoord>>}
|
||||||
*/
|
*/
|
||||||
this.clipExtents_ = null;
|
this.clipTileCoords_ = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -68,7 +69,6 @@ ol.renderer.canvas.TileLayer.prototype.composeFrame = function(
|
|||||||
goog.asserts.assertInstanceof(source, ol.source.Tile,
|
goog.asserts.assertInstanceof(source, ol.source.Tile,
|
||||||
'source is an ol.source.Tile');
|
'source is an ol.source.Tile');
|
||||||
var tileGutter = source.getGutter(projection);
|
var tileGutter = source.getGutter(projection);
|
||||||
var opaque = source.getOpaque(projection);
|
|
||||||
|
|
||||||
var transform = this.getTransform(frameState, 0);
|
var transform = this.getTransform(frameState, 0);
|
||||||
|
|
||||||
@@ -95,60 +95,60 @@ ol.renderer.canvas.TileLayer.prototype.composeFrame = function(
|
|||||||
var tileGrid = source.getTileGridForProjection(projection);
|
var tileGrid = source.getTileGridForProjection(projection);
|
||||||
var tilesToDraw = this.renderedTiles_;
|
var tilesToDraw = this.renderedTiles_;
|
||||||
|
|
||||||
var clipExtents, clipExtent, currentZ, i, ii, j, jj, insertPoint;
|
var clipExtent, clipH, clipLeft, clipOrigin, clipTileCoord, clipTileCoords;
|
||||||
var origin, tile, tileExtent, tileHeight, tileOffsetX, tileOffsetY;
|
var clipTop, clipW, currentZ, h, i, ii, j, jj, left, origin, tile, tileExtent;
|
||||||
var tilePixelSize, tileWidth;
|
var tilePixelSize, top, w;
|
||||||
for (i = 0, ii = tilesToDraw.length; i < ii; ++i) {
|
for (i = 0, ii = tilesToDraw.length; i < ii; ++i) {
|
||||||
tile = tilesToDraw[i];
|
tile = tilesToDraw[i];
|
||||||
tileExtent = tileGrid.getTileCoordExtent(
|
tileExtent = tileGrid.getTileCoordExtent(
|
||||||
tile.getTileCoord(), this.tmpExtent_);
|
tile.getTileCoord(), this.tmpExtent_);
|
||||||
clipExtents = !opaque && this.clipExtents_[tile.tileCoord.toString()];
|
currentZ = tile.getTileCoord()[0];
|
||||||
if (clipExtents) {
|
// Calculate all insert points by tile widths from a common origin to avoid
|
||||||
|
// gaps caused by rounding
|
||||||
|
origin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(
|
||||||
|
tileGrid.getTileCoordForCoordAndZ(center, currentZ)));
|
||||||
|
w = Math.round(ol.extent.getWidth(tileExtent) * pixelScale);
|
||||||
|
h = Math.round(ol.extent.getHeight(tileExtent) * pixelScale);
|
||||||
|
left = Math.round((tileExtent[0] - origin[0]) * pixelScale / w) * w +
|
||||||
|
offsetX + Math.round((origin[0] - center[0]) * pixelScale);
|
||||||
|
top = Math.round((origin[1] - tileExtent[3]) * pixelScale / h) * h +
|
||||||
|
offsetY + Math.round((center[1] - origin[1]) * pixelScale);
|
||||||
|
clipTileCoords = this.clipTileCoords_[tile.tileCoord.toString()];
|
||||||
|
if (clipTileCoords) {
|
||||||
// Create a clip mask for regions in this low resolution tile that will be
|
// Create a clip mask for regions in this low resolution tile that will be
|
||||||
// filled by a higher resolution tile
|
// filled by a higher resolution tile
|
||||||
renderContext.save();
|
renderContext.save();
|
||||||
renderContext.beginPath();
|
renderContext.beginPath();
|
||||||
renderContext.moveTo((tileExtent[0] - center[0]) * pixelScale + offsetX,
|
// counter-clockwise (outer ring) for current tile
|
||||||
(center[1] - tileExtent[1]) * pixelScale + offsetY);
|
renderContext.moveTo(left + w, top);
|
||||||
renderContext.lineTo((tileExtent[2] - center[0]) * pixelScale + offsetX,
|
renderContext.lineTo(left, top);
|
||||||
(center[1] - tileExtent[1]) * pixelScale + offsetY);
|
renderContext.lineTo(left, top + h);
|
||||||
renderContext.lineTo((tileExtent[2] - center[0]) * pixelScale + offsetX,
|
renderContext.lineTo(left + w, top + h);
|
||||||
(center[1] - tileExtent[3]) * pixelScale + offsetY);
|
|
||||||
renderContext.lineTo((tileExtent[0] - center[0]) * pixelScale + offsetX,
|
|
||||||
(center[1] - tileExtent[3]) * pixelScale + offsetY);
|
|
||||||
renderContext.closePath();
|
renderContext.closePath();
|
||||||
for (j = 0, jj = clipExtents.length; j < jj; ++j) {
|
// clockwise (inner rings) for lower resolution tiles
|
||||||
clipExtent = clipExtents[j];
|
for (j = 0, jj = clipTileCoords.length; j < jj; ++j) {
|
||||||
renderContext.moveTo((clipExtent[0] - center[0]) * pixelScale + offsetX,
|
clipTileCoord = clipTileCoords[j];
|
||||||
(center[1] - clipExtent[1]) * pixelScale + offsetY);
|
clipExtent = tileGrid.getTileCoordExtent(clipTileCoord);
|
||||||
renderContext.lineTo((clipExtent[0] - center[0]) * pixelScale + offsetX,
|
clipOrigin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(
|
||||||
(center[1] - clipExtent[3]) * pixelScale + offsetY);
|
tileGrid.getTileCoordForCoordAndZ(center, clipTileCoord[0])));
|
||||||
renderContext.lineTo((clipExtent[2] - center[0]) * pixelScale + offsetX,
|
clipW = Math.round(ol.extent.getWidth(clipExtent) * pixelScale);
|
||||||
(center[1] - clipExtent[3]) * pixelScale + offsetY);
|
clipH = Math.round(ol.extent.getHeight(clipExtent) * pixelScale);
|
||||||
renderContext.lineTo((clipExtent[2] - center[0]) * pixelScale + offsetX,
|
clipLeft = Math.round((clipExtent[0] - clipOrigin[0]) * pixelScale / clipW) * clipW +
|
||||||
(center[1] - clipExtent[1]) * pixelScale + offsetY);
|
offsetX + Math.round((clipOrigin[0] - center[0]) * pixelScale);
|
||||||
|
clipTop = Math.round((clipOrigin[1] - clipExtent[3]) * pixelScale / clipH) * clipH +
|
||||||
|
offsetY + Math.round((center[1] - clipOrigin[1]) * pixelScale);
|
||||||
|
renderContext.moveTo(clipLeft, clipTop + clipH);
|
||||||
|
renderContext.lineTo(clipLeft, clipTop);
|
||||||
|
renderContext.lineTo(clipLeft + clipW, clipTop);
|
||||||
|
renderContext.lineTo(clipLeft + clipW, clipTop + clipH);
|
||||||
renderContext.closePath();
|
renderContext.closePath();
|
||||||
}
|
}
|
||||||
renderContext.clip();
|
renderContext.clip();
|
||||||
}
|
}
|
||||||
currentZ = tile.getTileCoord()[0];
|
|
||||||
tilePixelSize = source.getTilePixelSize(currentZ, pixelRatio, projection);
|
tilePixelSize = source.getTilePixelSize(currentZ, pixelRatio, projection);
|
||||||
insertPoint = ol.extent.getTopLeft(tileExtent);
|
|
||||||
tileWidth = Math.round(ol.extent.getWidth(tileExtent) * pixelScale);
|
|
||||||
tileHeight = Math.round(ol.extent.getHeight(tileExtent) * pixelScale);
|
|
||||||
// Calculate all insert points from a common origin and tile widths to avoid
|
|
||||||
// gaps caused by rounding
|
|
||||||
origin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(
|
|
||||||
tileGrid.getTileCoordForCoordAndZ(center, currentZ)));
|
|
||||||
tileOffsetX = offsetX + Math.round((origin[0] - center[0]) * pixelScale);
|
|
||||||
tileOffsetY = offsetY + Math.round((center[1] - origin[1]) * pixelScale);
|
|
||||||
renderContext.drawImage(tile.getImage(), tileGutter, tileGutter,
|
renderContext.drawImage(tile.getImage(), tileGutter, tileGutter,
|
||||||
tilePixelSize[0], tilePixelSize[1],
|
tilePixelSize[0], tilePixelSize[1], left, top, w, h);
|
||||||
Math.round((insertPoint[0] - origin[0]) * pixelScale / tileWidth) *
|
if (clipTileCoords) {
|
||||||
tileWidth + tileOffsetX,
|
|
||||||
Math.round((origin[1] - insertPoint[1]) * pixelScale / tileHeight) *
|
|
||||||
tileHeight + tileOffsetY, tileWidth, tileHeight);
|
|
||||||
if (clipExtents) {
|
|
||||||
renderContext.restore();
|
renderContext.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,8 +266,9 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.renderedTiles_ = renderables;
|
this.renderedTiles_ = renderables;
|
||||||
if (!tileSource.getOpaque(projection)) {
|
ol.object.clear(this.clipTileCoords_);
|
||||||
var clipExtents = {};
|
if (!(tileSource.getOpaque(projection) && layerState.opacity == 1)) {
|
||||||
|
var clipTileCoords = this.clipTileCoords_;
|
||||||
var tileCoord;
|
var tileCoord;
|
||||||
for (i = renderables.length - 1; i >= 0; --i) {
|
for (i = renderables.length - 1; i >= 0; --i) {
|
||||||
tileCoord = renderables[i].getTileCoord();
|
tileCoord = renderables[i].getTileCoord();
|
||||||
@@ -280,10 +281,10 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(
|
|||||||
tile = tiles[key];
|
tile = tiles[key];
|
||||||
if (tileRange.contains(tile.getTileCoord()) &&
|
if (tileRange.contains(tile.getTileCoord()) &&
|
||||||
tile.getState() == ol.TileState.LOADED) {
|
tile.getState() == ol.TileState.LOADED) {
|
||||||
if (!(key in clipExtents)) {
|
if (!(key in clipTileCoords)) {
|
||||||
clipExtents[key] = [];
|
clipTileCoords[key] = [];
|
||||||
}
|
}
|
||||||
clipExtents[key].push(tileGrid.getTileCoordExtent(tileCoord));
|
clipTileCoords[key].push(tileCoord);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,7 +292,6 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(
|
|||||||
return false;
|
return false;
|
||||||
}, this, tmpTileRange, tmpExtent);
|
}, this, tmpTileRange, tmpExtent);
|
||||||
}
|
}
|
||||||
this.clipExtents_ = clipExtents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
||||||
|
|||||||
@@ -24,23 +24,32 @@ describe('ol.events', function() {
|
|||||||
boundListener();
|
boundListener();
|
||||||
expect(listenerObj.listener.thisValues[0]).to.equal(listenerObj.bindTo);
|
expect(listenerObj.listener.thisValues[0]).to.equal(listenerObj.bindTo);
|
||||||
});
|
});
|
||||||
it('binds a self-unregistering listener when callOnce is true', function() {
|
it('binds to the target when bindTo is not provided', function() {
|
||||||
var bindTo = {id: 1};
|
|
||||||
var listener = sinon.spy();
|
|
||||||
target.removeEventListener = function() {};
|
|
||||||
var listenerObj = {
|
var listenerObj = {
|
||||||
type: 'foo',
|
listener: sinon.spy(),
|
||||||
target: target,
|
target: {id: 1}
|
||||||
listener: listener,
|
|
||||||
bindTo: bindTo,
|
|
||||||
callOnce: true
|
|
||||||
};
|
};
|
||||||
var boundListener = ol.events.bindListener_(listenerObj);
|
var boundListener = ol.events.bindListener_(listenerObj);
|
||||||
expect(listenerObj.boundListener).to.equal(boundListener);
|
expect(listenerObj.boundListener).to.equal(boundListener);
|
||||||
var spy = sinon.spy(ol.events, 'unlistenByKey');
|
|
||||||
boundListener();
|
boundListener();
|
||||||
expect(listener.thisValues[0]).to.equal(bindTo);
|
expect(listenerObj.listener.thisValues[0]).to.equal(listenerObj.target);
|
||||||
expect(spy.firstCall.args[0]).to.eql(listenerObj);
|
});
|
||||||
|
it('binds a self-unregistering listener when callOnce is true', function() {
|
||||||
|
var bindTo = {id: 1};
|
||||||
|
var listenerObj = {
|
||||||
|
type: 'foo',
|
||||||
|
target: target,
|
||||||
|
bindTo: bindTo,
|
||||||
|
callOnce: true
|
||||||
|
};
|
||||||
|
var unlistenSpy = sinon.spy(ol.events, 'unlistenByKey');
|
||||||
|
listenerObj.listener = function() {
|
||||||
|
expect(this).to.equal(bindTo);
|
||||||
|
expect(unlistenSpy.firstCall.args[0]).to.eql(listenerObj);
|
||||||
|
}
|
||||||
|
var boundListener = ol.events.bindListener_(listenerObj);
|
||||||
|
expect(listenerObj.boundListener).to.equal(boundListener);
|
||||||
|
boundListener();
|
||||||
ol.events.unlistenByKey.restore();
|
ol.events.unlistenByKey.restore();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user