ol-ext
Version:
A set of cool extensions for OpenLayers (ol) in node modules structure
145 lines (138 loc) • 4.13 kB
JavaScript
/* Copyright (c) 2016 Jean-Marc VIGLINO,
released under the CeCILL-B license (French BSD license)
(http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt).
*/
import ol_filter_Base from './Base.js'
/** Clip layer or map
* @constructor
* @requires ol.filter
* @extends {ol_filter_Base}
* @param {Object} [options]
* @param {Array<ol.Coordinate>} [options.coords]
* @param {ol.Extent} [options.extent]
* @param {string} [options.units] coords units percent (%) or pixel (px)
* @param {boolean} [options.keepAspectRatio] keep aspect ratio
* @param {string} [options.color] backgroundcolor
*/
var ol_filter_Clip = class olfilterClip extends ol_filter_Base {
constructor(options) {
options = options || {};
super(options);
this.set("coords", options.coords);
this.set("units", options.units);
this.set("keepAspectRatio", options.keepAspectRatio);
this.set("extent", options.extent || [0, 0, 1, 1]);
this.set("color", options.color);
if (!options.extent && options.units != "%" && options.coords) {
var xmin = Infinity;
var ymin = Infinity;
var xmax = -Infinity;
var ymax = -Infinity;
for (var i = 0, p; p = options.coords[i]; i++) {
if (xmin > p[0])
xmin = p[0];
if (xmax < p[0])
xmax = p[0];
if (ymin > p[1])
ymin = p[1];
if (ymax < p[1])
ymax = p[1];
}
options.extent = [xmin, ymin, xmax, ymax];
}
}
clipPath_(e) {
var ctx = e.context;
var size = e.frameState.size;
var coords = this.get("coords");
if (!coords)
return;
var ex = this.get('extent');
var scx = 1, scy = 1;
if (this.get("units") == "%") {
scx = size[0] / (ex[2] - ex[0]);
scy = size[1] / (ex[3] - ex[1]);
}
if (this.get("keepAspectRatio")) {
scx = scy = Math.min(scx, scy);
}
var pos = this.get('position');
var dx = 0, dy = 0;
if (/left/.test(pos)) {
dx = -ex[0] * scx;
} else if (/center/.test(pos)) {
dx = size[0] / 2 - (ex[2] - ex[0]) * scx / 2;
} else if (/right/.test(pos)) {
dx = size[0] - (ex[2] - ex[0]) * scx;
}
var fx = function (x) { return x * scx + dx; };
if (/top/.test(pos)) {
dy = -ex[1] * scy;
} else if (/middle/.test(pos)) {
dy = size[1] / 2 - (ex[3] - ex[1]) * scy / 2;
} else if (/bottom/.test(pos)) {
dy = size[1] - (ex[3] - ex[1]) * scy;
}
var fy = function (y) { return y * scy + dy; };
var pt = [fx(coords[0][0]), fy(coords[0][1])];
var tr = e.inversePixelTransform;
if (tr) {
pt = [
(pt[0] * tr[0] - pt[1] * tr[1] + tr[4]),
(-pt[0] * tr[2] + pt[1] * tr[3] + tr[5])
];
}
ctx.moveTo(pt[0], pt[1]);
for (var i = 1, p; p = coords[i]; i++) {
pt = [fx(p[0]), fy(p[1])];
if (tr) {
pt = [
(pt[0] * tr[0] - pt[1] * tr[1] + tr[4]),
(-pt[0] * tr[2] + pt[1] * tr[3] + tr[5])
];
}
ctx.lineTo(pt[0], pt[1]);
}
pt = [fx(coords[0][0]), fy(coords[0][1])];
if (tr) {
pt = [
(pt[0] * tr[0] - pt[1] * tr[1] + tr[4]),
(-pt[0] * tr[2] + pt[1] * tr[3] + tr[5])
];
}
ctx.moveTo(pt[0], pt[1]);
}
/**
* @private
*/
precompose(e) {
if (!this.get("color")) {
e.context.save();
e.context.beginPath();
this.clipPath_(e);
e.context.clip();
}
}
/**
* @private
*/
postcompose(e) {
if (this.get("color")) {
var ctx = e.context;
var canvas = e.context.canvas;
ctx.save();
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(0, canvas.height);
ctx.lineTo(canvas.width, canvas.height);
ctx.lineTo(canvas.width, canvas.height);
ctx.lineTo(canvas.width, 0);
ctx.lineTo(0, 0);
this.clipPath_(e);
ctx.fillStyle = this.get("color");
ctx.fill("evenodd");
}
e.context.restore();
}
}
export default ol_filter_Clip