Support mix-blend-mode compositing in screenshots.
There are limitations to the current screenshot function.  If layers are
composited with mix-blend-mode, svg filters, or some other options,
these are not applied.  mix-blend-mode support is added here; other
limitations remain.
MODIFY
.travis.yml
.travis.yml
@@ -5,7 +5,7 @@ sudo: required
dist: xenial
node_js:
- - 14
+ - 12
addons:
# version 55.0 - 57.x have an issue with screenshots.

MODIFY
CHANGELOG.md
CHANGELOG.md
# Change Log
+## Unreleased
+
+### Improvements
+- Screenshots now handle mix-blend-mode settings on top level divs (#1074)
+
+### Bug Fixes
+- Fixed an issue with affine transforms and polygons (#1073)
+
## Version 0.20.0
### Features

MODIFY
src/map.js
src/map.js
@@ -1820,13 +1820,13 @@ var map = function (arg) {
if (layer.renderer() && layer.renderer().api() === 'webgl') {
layer.renderer()._renderFrame();
}
- drawLayerImageToContext(context, opacity, canvasElem, canvasElem[0]);
+ drawLayerImageToContext(context, opacity, canvasElem, canvasElem[0], layer.node().css('mix-blend-mode'));
});
});
if ((layer.node().children().not('canvas').length || !layer.node().children().length) && (!layer.renderer() || layer.renderer().api() !== 'webgl')) {
defer = defer.then(function () {
return util.htmlToImage(layer.node(), 1).done(function (img) {
- drawLayerImageToContext(context, 1, $([]), img);
+ drawLayerImageToContext(context, 1, $([]), img, layer.node().css('mix-blend-mode'));
});
});
}
@@ -1846,7 +1846,7 @@ var map = function (arg) {
var attrElem = $(this);
defer = defer.then(function () {
return util.htmlToImage(attrElem, 1).done(function (img) {
- drawLayerImageToContext(context, 1, $([]), img);
+ drawLayerImageToContext(context, 1, $([]), img, attrElem.css('mix-blend-mode'));
});
});
});
@@ -1963,10 +1963,14 @@ var map = function (arg) {
* @param {number} opacity The opacity in the range [0, 1].
* @param {object} elem A jQuery element that might have a transform.
* @param {HTMLImageObject} img The image or canvas to draw to the canvas.
+ * @param {string} [mixBlendMode] the mix-blend-mode used to add this layer.
* @private
*/
- function drawLayerImageToContext(context, opacity, elem, img) {
+ function drawLayerImageToContext(context, opacity, elem, img, mixBlendMode) {
context.globalAlpha = opacity;
+ if (mixBlendMode) {
+ context.globalCompositeOperation = mixBlendMode;
+ }
var transform = elem.css('transform');
// if the canvas is being transformed, apply the same transformation
if (transform && transform.substr(0, 7) === 'matrix(') {
@@ -1975,6 +1979,7 @@ var map = function (arg) {
context.setTransform(1, 0, 0, 1, 0, 0);
}
context.drawImage(img, 0, 0);
+ context.globalCompositeOperation = 'source-over';
}
/**

MODIFY
tests/cases/map.js
tests/cases/map.js
@@ -827,7 +827,6 @@ describe('geo.core.map', function () {
});
});
it('partial opacity', function (done) {
- // making a layer transparent is as good as not asking for it
layer2.opacity(0.5);
m.screenshot().then(function (result) {
expect(result).not.toEqual(ss.basic);
@@ -853,6 +852,23 @@ describe('geo.core.map', function () {
// These tests won't work in PhantomJS. See
// https://bugs.webkit.org/show_bug.cgi?id=17352, also 29305 and 129172.
if (!isPhantomJS()) {
+ it('mix-blend-mode multiply', function (done) {
+ layer2.node().css('mix-blend-mode', 'multiply');
+ m.screenshot().then(function (result) {
+ expect(result).not.toEqual(ss.basic);
+ expect(result).not.toEqual(ss.onelayer);
+ layer2.node().css('mix-blend-mode', 'initial');
+ done();
+ });
+ });
+ it('mix-blend-mode normal', function (done) {
+ layer2.node().css('mix-blend-mode', 'normal');
+ m.screenshot().then(function (result) {
+ expect(result).toEqual(ss.basic);
+ layer2.node().css('mix-blend-mode', 'initial');
+ done();
+ });
+ });
it('layer background', function (done) {
var layer3 = m.createLayer('ui');
layer3.node().css('background-image', 'url(/data/tilefancy.png)');

Support mix-blend-mode compositing in screenshots.

There are limitations to the current screenshot function.  If layers are
composited with mix-blend-mode, svg filters, or some other options,
these are not applied.  mix-blend-mode support is added here; other
limitations remain.