From 2f5e6906b94723c523eed160228a0c8afb9d4959 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 15 Sep 2021 19:18:04 +0200 Subject: [PATCH] Fix opacity handling for tile and vector layers --- src/ol/css.js | 8 ++++++++ src/ol/renderer/canvas/Layer.js | 3 ++- src/ol/renderer/canvas/TileLayer.js | 17 ++++++++++------- src/ol/renderer/canvas/VectorLayer.js | 7 ++++--- test/node/ol/css.test.js | 8 +++++++- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/ol/css.js b/src/ol/css.js index 1175a9949a..89d000e1de 100644 --- a/src/ol/css.js +++ b/src/ol/css.js @@ -114,3 +114,11 @@ export const getFontParameters = function (fontSpec) { style.families = style.family.split(/,\s?/); return style; }; + +/** + * @param {number} opacity Opacity (0..1). + * @return {string} CSS opacity. + */ +export function cssOpacity(opacity) { + return opacity === 1 ? '' : String(Math.round(opacity * 100) / 100); +} diff --git a/src/ol/renderer/canvas/Layer.js b/src/ol/renderer/canvas/Layer.js index c8f7fbc088..b04e2ede97 100644 --- a/src/ol/renderer/canvas/Layer.js +++ b/src/ol/renderer/canvas/Layer.js @@ -17,6 +17,7 @@ import { getTopRight, } from '../../extent.js'; import {createCanvasContext2D} from '../../dom.js'; +import {cssOpacity} from '../../css.js'; /** * @abstract @@ -88,7 +89,7 @@ class CanvasLayerRenderer extends LayerRenderer { let container, context; if ( target && - target.style.opacity === '' && + target.style.opacity === cssOpacity(opacity) && target.className === layerClassName ) { const canvas = target.firstElementChild; diff --git a/src/ol/renderer/canvas/TileLayer.js b/src/ol/renderer/canvas/TileLayer.js index 371f1a2c18..3485fddcf7 100644 --- a/src/ol/renderer/canvas/TileLayer.js +++ b/src/ol/renderer/canvas/TileLayer.js @@ -16,6 +16,7 @@ import { getIntersection, getTopLeft, } from '../../extent.js'; +import {cssOpacity} from '../../css.js'; import {fromUserExtent} from '../../proj.js'; import {getUid} from '../../util.js'; import {numberSafeCompareFunction} from '../../array.js'; @@ -410,8 +411,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { w, h, tileGutter, - transition, - layerState.opacity + transition ); if (clips && !inTransition) { context.restore(); @@ -452,6 +452,11 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { if (canvasTransform !== canvas.style.transform) { canvas.style.transform = canvasTransform; } + const opacity = cssOpacity(layerState.opacity); + const container = this.container; + if (opacity !== container.style.opacity) { + container.style.opacity = opacity; + } return this.container; } @@ -465,16 +470,14 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { * @param {number} h Height of the tile. * @param {number} gutter Tile gutter. * @param {boolean} transition Apply an alpha transition. - * @param {number} opacity Opacity. */ - drawTileImage(tile, frameState, x, y, w, h, gutter, transition, opacity) { + drawTileImage(tile, frameState, x, y, w, h, gutter, transition) { const image = this.getTileImage(tile); if (!image) { return; } const uid = getUid(this); - const tileAlpha = transition ? tile.getAlpha(uid, frameState.time) : 1; - const alpha = opacity * tileAlpha; + const alpha = transition ? tile.getAlpha(uid, frameState.time) : 1; const alphaChanged = alpha !== this.context.globalAlpha; if (alphaChanged) { this.context.save(); @@ -495,7 +498,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { if (alphaChanged) { this.context.restore(); } - if (tileAlpha !== 1) { + if (alpha !== 1) { frameState.animate = true; } else if (transition) { tile.endTransition(uid); diff --git a/src/ol/renderer/canvas/VectorLayer.js b/src/ol/renderer/canvas/VectorLayer.js index 65e161bd93..a1aab7dd90 100644 --- a/src/ol/renderer/canvas/VectorLayer.js +++ b/src/ol/renderer/canvas/VectorLayer.js @@ -24,6 +24,7 @@ import { intersects as intersectsExtent, wrapX as wrapExtentX, } from '../../extent.js'; +import {cssOpacity} from '../../css.js'; import { defaultOrder as defaultRenderOrder, getTolerance as getRenderTolerance, @@ -301,10 +302,10 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { this.postRender(context, frameState); - const opacity = layerState.opacity; + const opacity = cssOpacity(layerState.opacity); const container = this.container; - if (opacity !== parseFloat(container.style.opacity)) { - container.style.opacity = opacity === 1 ? '' : String(opacity); + if (opacity !== container.style.opacity) { + container.style.opacity = opacity; } if (this.renderedRotation_ !== viewState.rotation) { diff --git a/test/node/ol/css.test.js b/test/node/ol/css.test.js index 90c51d572e..05d441ee98 100644 --- a/test/node/ol/css.test.js +++ b/test/node/ol/css.test.js @@ -1,7 +1,13 @@ import expect from '../expect.js'; -import {getFontParameters} from '../../../src/ol/css.js'; +import {cssOpacity, getFontParameters} from '../../../src/ol/css.js'; describe('ol.css', function () { + describe('cssOpacity()', function () { + it('converts number to string, 1 to ""', function () { + expect(cssOpacity(0.5)).to.eql('0.5'); + expect(cssOpacity(1)).to.eql(''); + }); + }); describe('getFontParameters()', function () { const cases = [ {