Handle canvas clip antialiasing during reprojection
This commit is contained in:
+38
-22
@@ -1,6 +1,8 @@
|
|||||||
goog.provide('ol.reproj');
|
goog.provide('ol.reproj');
|
||||||
|
|
||||||
goog.require('goog.array');
|
goog.require('goog.array');
|
||||||
|
goog.require('goog.labs.userAgent.browser');
|
||||||
|
goog.require('goog.labs.userAgent.platform');
|
||||||
goog.require('goog.math');
|
goog.require('goog.math');
|
||||||
goog.require('ol.dom');
|
goog.require('ol.dom');
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
@@ -58,6 +60,20 @@ ol.reproj.WrapXRendering_ = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need to employ more sophisticated solution
|
||||||
|
* if the web browser antialiases clipping edges on canvas.
|
||||||
|
*
|
||||||
|
* Currently only Chrome does not antialias the edges, but this is probably
|
||||||
|
* going to be "fixed" in the future: http://crbug.com/424291
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.reproj.browserAntialiasesClip_ = !goog.labs.userAgent.browser.isChrome() ||
|
||||||
|
goog.labs.userAgent.platform.isIos();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the source into the canvas based on the triangulation.
|
* Renders the source into the canvas based on the triangulation.
|
||||||
* @param {CanvasRenderingContext2D} context
|
* @param {CanvasRenderingContext2D} context
|
||||||
@@ -154,8 +170,6 @@ ol.reproj.renderTriangles = function(context,
|
|||||||
|
|
||||||
var targetTL = ol.extent.getTopLeft(targetExtent);
|
var targetTL = ol.extent.getTopLeft(targetExtent);
|
||||||
|
|
||||||
context.globalCompositeOperation = 'copy';
|
|
||||||
|
|
||||||
goog.array.forEach(triangulation.getTriangles(), function(tri, i, arr) {
|
goog.array.forEach(triangulation.getTriangles(), function(tri, i, arr) {
|
||||||
context.save();
|
context.save();
|
||||||
|
|
||||||
@@ -229,25 +243,29 @@ ol.reproj.renderTriangles = function(context,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var centroidX = (u0 + u1 + u2) / 3, centroidY = (v0 + v1 + v2) / 3;
|
|
||||||
var calcClipPoint = function(u, v) {
|
|
||||||
// Enlarges the triangle by 1 pixel to ensure overlap and rounds to whole
|
|
||||||
// pixels to ensure correct cross-browser behavior.
|
|
||||||
// Gecko does antialiasing differently than WebKit.
|
|
||||||
|
|
||||||
var dX = u - centroidX, dY = v - centroidY;
|
|
||||||
var distance = Math.sqrt(dX * dX + dY * dY);
|
|
||||||
return [Math.round(u + dX / distance), Math.round(v + dY / distance)];
|
|
||||||
};
|
|
||||||
|
|
||||||
var p0 = calcClipPoint(u0, v0);
|
|
||||||
var p1 = calcClipPoint(u1, v1);
|
|
||||||
var p2 = calcClipPoint(u2, v2);
|
|
||||||
|
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.moveTo(p0[0], p0[1]);
|
if (ol.reproj.browserAntialiasesClip_) {
|
||||||
context.lineTo(p1[0], p1[1]);
|
// Enlarge the clipping triangle by 1 pixel to ensure the edges overlap
|
||||||
context.lineTo(p2[0], p2[1]);
|
// in order to mask gaps caused by antialiasing.
|
||||||
|
var centroidX = (u0 + u1 + u2) / 3, centroidY = (v0 + v1 + v2) / 3;
|
||||||
|
var calcClipPoint = function(u, v) {
|
||||||
|
var dX = u - centroidX, dY = v - centroidY;
|
||||||
|
var distance = Math.sqrt(dX * dX + dY * dY);
|
||||||
|
return [Math.round(u + dX / distance), Math.round(v + dY / distance)];
|
||||||
|
};
|
||||||
|
|
||||||
|
var p0 = calcClipPoint(u0, v0);
|
||||||
|
var p1 = calcClipPoint(u1, v1);
|
||||||
|
var p2 = calcClipPoint(u2, v2);
|
||||||
|
|
||||||
|
context.moveTo(p0[0], p0[1]);
|
||||||
|
context.lineTo(p1[0], p1[1]);
|
||||||
|
context.lineTo(p2[0], p2[1]);
|
||||||
|
} else {
|
||||||
|
context.moveTo(u0, v0);
|
||||||
|
context.lineTo(u1, v1);
|
||||||
|
context.lineTo(u2, v2);
|
||||||
|
}
|
||||||
context.closePath();
|
context.closePath();
|
||||||
context.clip();
|
context.clip();
|
||||||
|
|
||||||
@@ -266,8 +284,6 @@ ol.reproj.renderTriangles = function(context,
|
|||||||
if (opt_renderEdges) {
|
if (opt_renderEdges) {
|
||||||
context.save();
|
context.save();
|
||||||
|
|
||||||
context.globalCompositeOperation = 'source-over';
|
|
||||||
|
|
||||||
context.strokeStyle = 'black';
|
context.strokeStyle = 'black';
|
||||||
context.lineWidth = 1;
|
context.lineWidth = 1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user