UNPKG

ol-ext

Version:

A set of cool extensions for OpenLayers (ol) in node modules structure

94 lines (87 loc) 3.38 kB
/* Copyright (c) 2017 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' import {asString as ol_color_asString} from 'ol/color.js' import {toHSL as ol_color_toHSL} from '../util/color.js' /** Make a map or layer look like made of a set of Lego bricks. * @constructor * @requires ol_filter * @extends {ol_filter_Base} * @param {Object} [options] * @param {string} [options.channel] RGB channels: 'r', 'g' or 'b', default use intensity * @param {ol.colorlike} [options.color] color, default black * @param {number} [options.size] point size, default 30 * @param {null | string | undefined} [options.crossOrigin] crossOrigin attribute for loaded images. */ var ol_filter_Halftone = class olfilterHalftone extends ol_filter_Base { constructor(options) { options = options || {}; super(options); this.internal_ = document.createElement('canvas'); this.setSize(options.size); this.set('channel', options.channel); } /** Set the current size * @param {number} width the pattern width, default 30 */ setSize(size) { size = Number(size) || 30; this.set("size", size); } /** Postcompose operation */ postcompose(e) { var ctx = e.context; var canvas = ctx.canvas; var ratio = e.frameState.pixelRatio; // ol v6+ if (e.type === 'postrender') { ratio = 1; } ctx.save(); // resize var step = this.get('size') * ratio; var p = e.frameState.extent; var res = e.frameState.viewState.resolution / ratio; var offset = [-Math.round((p[0] / res) % step), Math.round((p[1] / res) % step)]; var ctx2 = this.internal_.getContext("2d"); var w = this.internal_.width = canvas.width; var h = this.internal_.height = canvas.height; // No smoothing please ctx2.webkitImageSmoothingEnabled = ctx2.mozImageSmoothingEnabled = ctx2.msImageSmoothingEnabled = ctx2.imageSmoothingEnabled = false; var w2 = Math.floor((w - offset[0]) / step); var h2 = Math.floor((h - offset[1]) / step); ctx2.drawImage(canvas, offset[0], offset[1], w2 * step, h2 * step, 0, 0, w2, h2); var data = ctx2.getImageData(0, 0, w2, h2).data; // Draw tone ctx.clearRect(0, 0, w, h); ctx.fillStyle = ol_color_asString(this.get('color') || '#000'); for (var x = 0; x < w2; x++) for (var y = 0; y < h2; y++) if (data[x * 4 + 3 + y * w2 * 4]) { var pix; switch (this.get('channel')) { case 'r': pix = data[x * 4 + y * w2 * 4] / 2.55; break; case 'g': pix = data[x * 4 + 1 + y * w2 * 4] / 2.55; break; case 'b': pix = data[x * 4 + 2 + y * w2 * 4] / 2.55; break; default: pix = ol_color_toHSL([data[x * 4 + y * w2 * 4], data[x * 4 + 1 + y * w2 * 4], data[x * 4 + 2 + y * w2 * 4]]); pix = pix[2]; break; } var l = (100 - pix) / 140; if (l) { ctx.beginPath(); ctx.arc(offset[0] + step / 2 + x * step, offset[1] + step / 2 + y * step, step * l, 0, 2 * Math.PI); ctx.closePath(); ctx.fill(); } } ctx.restore(); } } export default ol_filter_Halftone