Render transparent vector layers to an intermediate canvas
Until now, the features of transparent vector layers were rendered using the layer opacity. This caused colors to mix together and the opacities to stack up to an higher value than the expected layer opacity. With this commit, the features are rendered at 100% opacity to an intermediate canvas which ensures colors do not mix up even in the case of features using an array of styles. The intermediate canvas is then composed to the map canvas using the layer opacity. Transparent layers are automatically detected, non-transparent layers are not affected by the change.
This commit is contained in:
@@ -97,7 +97,9 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
|
||||
var drawOffsetX = 0;
|
||||
var drawOffsetY = 0;
|
||||
var replayContext;
|
||||
if (layer.hasListener(ol.render.EventType.RENDER)) {
|
||||
var transparentLayer = layerState.opacity !== 1;
|
||||
var hasRenderListeners = layer.hasListener(ol.render.EventType.RENDER);
|
||||
if (transparentLayer || hasRenderListeners) {
|
||||
var drawWidth = context.canvas.width;
|
||||
var drawHeight = context.canvas.height;
|
||||
if (rotation) {
|
||||
@@ -113,11 +115,15 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
|
||||
} else {
|
||||
replayContext = context;
|
||||
}
|
||||
// for performance reasons, context.save / context.restore is not used
|
||||
// to save and restore the transformation matrix and the opacity.
|
||||
// see http://jsperf.com/context-save-restore-versus-variable
|
||||
|
||||
var alpha = replayContext.globalAlpha;
|
||||
replayContext.globalAlpha = layerState.opacity;
|
||||
if (!transparentLayer) {
|
||||
// for performance reasons, context.save / context.restore is not used
|
||||
// to save and restore the transformation matrix and the opacity.
|
||||
// see http://jsperf.com/context-save-restore-versus-variable
|
||||
replayContext.globalAlpha = layerState.opacity;
|
||||
}
|
||||
|
||||
if (replayContext != context) {
|
||||
replayContext.translate(drawOffsetX, drawOffsetY);
|
||||
}
|
||||
@@ -159,11 +165,23 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
|
||||
width / 2, height / 2);
|
||||
|
||||
if (replayContext != context) {
|
||||
this.dispatchRenderEvent(replayContext, frameState, transform);
|
||||
context.drawImage(replayContext.canvas, -drawOffsetX, -drawOffsetY);
|
||||
if (hasRenderListeners) {
|
||||
this.dispatchRenderEvent(replayContext, frameState, transform);
|
||||
}
|
||||
if (transparentLayer) {
|
||||
var mainContextAlpha = context.globalAlpha;
|
||||
context.globalAlpha = layerState.opacity;
|
||||
context.drawImage(replayContext.canvas, -drawOffsetX, -drawOffsetY);
|
||||
context.globalAlpha = mainContextAlpha;
|
||||
} else {
|
||||
context.drawImage(replayContext.canvas, -drawOffsetX, -drawOffsetY);
|
||||
}
|
||||
replayContext.translate(-drawOffsetX, -drawOffsetY);
|
||||
}
|
||||
replayContext.globalAlpha = alpha;
|
||||
|
||||
if (!transparentLayer) {
|
||||
replayContext.globalAlpha = alpha;
|
||||
}
|
||||
}
|
||||
|
||||
if (clipped) {
|
||||
|
||||
Reference in New Issue
Block a user