Fix opacity handling for tile and vector layers

This commit is contained in:
Andreas Hocevar
2021-09-15 19:18:04 +02:00
parent cb6995d71a
commit 2f5e6906b9
5 changed files with 31 additions and 12 deletions

View File

@@ -114,3 +114,11 @@ export const getFontParameters = function (fontSpec) {
style.families = style.family.split(/,\s?/); style.families = style.family.split(/,\s?/);
return style; 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);
}

View File

@@ -17,6 +17,7 @@ import {
getTopRight, getTopRight,
} from '../../extent.js'; } from '../../extent.js';
import {createCanvasContext2D} from '../../dom.js'; import {createCanvasContext2D} from '../../dom.js';
import {cssOpacity} from '../../css.js';
/** /**
* @abstract * @abstract
@@ -88,7 +89,7 @@ class CanvasLayerRenderer extends LayerRenderer {
let container, context; let container, context;
if ( if (
target && target &&
target.style.opacity === '' && target.style.opacity === cssOpacity(opacity) &&
target.className === layerClassName target.className === layerClassName
) { ) {
const canvas = target.firstElementChild; const canvas = target.firstElementChild;

View File

@@ -16,6 +16,7 @@ import {
getIntersection, getIntersection,
getTopLeft, getTopLeft,
} from '../../extent.js'; } from '../../extent.js';
import {cssOpacity} from '../../css.js';
import {fromUserExtent} from '../../proj.js'; import {fromUserExtent} from '../../proj.js';
import {getUid} from '../../util.js'; import {getUid} from '../../util.js';
import {numberSafeCompareFunction} from '../../array.js'; import {numberSafeCompareFunction} from '../../array.js';
@@ -410,8 +411,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
w, w,
h, h,
tileGutter, tileGutter,
transition, transition
layerState.opacity
); );
if (clips && !inTransition) { if (clips && !inTransition) {
context.restore(); context.restore();
@@ -452,6 +452,11 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
if (canvasTransform !== canvas.style.transform) { if (canvasTransform !== canvas.style.transform) {
canvas.style.transform = canvasTransform; 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; return this.container;
} }
@@ -465,16 +470,14 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
* @param {number} h Height of the tile. * @param {number} h Height of the tile.
* @param {number} gutter Tile gutter. * @param {number} gutter Tile gutter.
* @param {boolean} transition Apply an alpha transition. * @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); const image = this.getTileImage(tile);
if (!image) { if (!image) {
return; return;
} }
const uid = getUid(this); const uid = getUid(this);
const tileAlpha = transition ? tile.getAlpha(uid, frameState.time) : 1; const alpha = transition ? tile.getAlpha(uid, frameState.time) : 1;
const alpha = opacity * tileAlpha;
const alphaChanged = alpha !== this.context.globalAlpha; const alphaChanged = alpha !== this.context.globalAlpha;
if (alphaChanged) { if (alphaChanged) {
this.context.save(); this.context.save();
@@ -495,7 +498,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
if (alphaChanged) { if (alphaChanged) {
this.context.restore(); this.context.restore();
} }
if (tileAlpha !== 1) { if (alpha !== 1) {
frameState.animate = true; frameState.animate = true;
} else if (transition) { } else if (transition) {
tile.endTransition(uid); tile.endTransition(uid);

View File

@@ -24,6 +24,7 @@ import {
intersects as intersectsExtent, intersects as intersectsExtent,
wrapX as wrapExtentX, wrapX as wrapExtentX,
} from '../../extent.js'; } from '../../extent.js';
import {cssOpacity} from '../../css.js';
import { import {
defaultOrder as defaultRenderOrder, defaultOrder as defaultRenderOrder,
getTolerance as getRenderTolerance, getTolerance as getRenderTolerance,
@@ -301,10 +302,10 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
this.postRender(context, frameState); this.postRender(context, frameState);
const opacity = layerState.opacity; const opacity = cssOpacity(layerState.opacity);
const container = this.container; const container = this.container;
if (opacity !== parseFloat(container.style.opacity)) { if (opacity !== container.style.opacity) {
container.style.opacity = opacity === 1 ? '' : String(opacity); container.style.opacity = opacity;
} }
if (this.renderedRotation_ !== viewState.rotation) { if (this.renderedRotation_ !== viewState.rotation) {

View File

@@ -1,7 +1,13 @@
import expect from '../expect.js'; 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('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 () { describe('getFontParameters()', function () {
const cases = [ const cases = [
{ {