import ol_interaction_Pointer from 'ol/interaction/Pointer.js'
/** Clip interaction to clip layers in a circle
* @constructor
* @extends {ol_interaction_Pointer}
* @param {ol_interaction_Clip.options} options flashlight param
* @param {number} options.radius radius of the clip, default 100
* @param {ol.layer|Array
} options.layers layers to clip
*/
var ol_interaction_Clip = class olinteractionClip extends ol_interaction_Pointer {
constructor(options) {
super({
handleDownEvent: function(e) { return this._setPosition(e) },
handleMoveEvent: function(e) { return this._setPosition(e) },
});
this.layers_ = [];
this.precomposeBind_ = this.precompose_.bind(this);
this.postcomposeBind_ = this.postcompose_.bind(this);
// Default options
options = options || {};
this.pos = false;
this.radius = (options.radius || 100);
if (options.layers) this.addLayer(options.layers);
this.setActive(true);
}
/** Set the map > start postcompose
*/
setMap(map) {
var i;
if (this.getMap()) {
for (i = 0; i < this.layers_.length; i++) {
this.layers_[i].un(['precompose', 'prerender'], this.precomposeBind_);
this.layers_[i].un(['postcompose', 'postrender'], this.postcomposeBind_);
}
try { this.getMap().renderSync(); } catch (e) { /* ok */ }
}
super.setMap(map);
if (map) {
for (i = 0; i < this.layers_.length; i++) {
this.layers_[i].on(['precompose', 'prerender'], this.precomposeBind_);
this.layers_[i].on(['postcompose', 'postrender'], this.postcomposeBind_);
}
try { map.renderSync(); } catch (e) { /* ok */ }
}
}
/** Set clip radius
* @param {integer} radius
*/
setRadius(radius) {
this.radius = radius;
if (this.getMap()) {
try { this.getMap().renderSync(); } catch (e) { /* ok */ }
}
}
/** Get clip radius
* @returns {integer} radius
*/
getRadius() {
return this.radius;
}
/** Add a layer to clip
* @param {ol.layer|Array} layer to clip
*/
addLayer(layers) {
if (!(layers instanceof Array))
layers = [layers];
for (var i = 0; i < layers.length; i++) {
if (this.getMap()) {
layers[i].on(['precompose', 'prerender'], this.precomposeBind_);
layers[i].on(['postcompose', 'postrender'], this.postcomposeBind_);
try { this.getMap().renderSync(); } catch (e) { /* ok */ }
}
this.layers_.push(layers[i]);
}
}
/** Remove all layers
*/
removeLayers() {
this.removeLayer(this.layers_);
}
/** Remove a layer to clip
* @param {ol.layer|Array} layer to clip
*/
removeLayer(layers) {
if (!(layers instanceof Array))
layers = [layers];
for (var i = 0; i < layers.length; i++) {
var k;
for (k = 0; k < this.layers_.length; k++) {
if (this.layers_[k] === layers[i]) {
break;
}
}
if (k != this.layers_.length && this.getMap()) {
this.layers_[k].un(['precompose', 'prerender'], this.precomposeBind_);
this.layers_[k].un(['postcompose', 'postrender'], this.postcomposeBind_);
this.layers_.splice(k, 1);
}
}
if (this.getMap()) {
try { this.getMap().renderSync(); } catch (e) { /* ok */ }
}
}
/** Set position of the clip
* @param {ol.coordinate} coord
*/
setPosition(coord) {
if (this.getMap()) {
this.pos = this.getMap().getPixelFromCoordinate(coord);
try { this.getMap().renderSync(); } catch (e) { /* ok */ }
}
}
/** Get position of the clip
* @returns {ol.coordinate}
*/
getPosition() {
if (this.pos)
return this.getMap().getCoordinateFromPixel(this.pos);
return null;
}
/** Set position of the clip
* @param {ol.Pixel} pixel
*/
setPixelPosition(pixel) {
this.pos = pixel;
if (this.getMap()) {
try { this.getMap().renderSync(); } catch (e) { /* ok */ }
}
}
/** Get position of the clip
* @returns {ol.Pixel} pixel
*/
getPixelPosition() {
return this.pos;
}
/** Set position of the clip
* @param {ol.MapBrowserEvent} e
* @privata
*/
_setPosition(e) {
if (e.type === 'pointermove' && this.get('action') === 'onclick'){
return;
}
if (e.pixel) {
this.pos = e.pixel;
}
if (this.getMap()) {
try { this.getMap().renderSync(); } catch (e) { /* ok */ }
}
}
/* @private
*/
precompose_(e) {
if (!this.getActive())
return;
var ctx = e.context;
var ratio = e.frameState.pixelRatio;
ctx.save();
ctx.beginPath();
var pt = [this.pos[0], this.pos[1]];
var radius = this.radius;
var tr = e.inversePixelTransform;
if (tr) {
// Transform pt
pt = [
(pt[0] * tr[0] - pt[1] * tr[1] + tr[4]),
(-pt[0] * tr[2] + pt[1] * tr[3] + tr[5])
];
// Get radius / transform
radius = pt[0] - ((this.pos[0] - radius) * tr[0] - this.pos[1] * tr[1] + tr[4]);
} else {
pt[0] *= ratio;
pt[1] *= ratio;
radius *= ratio;
}
ctx.arc(pt[0], pt[1], radius, 0, 2 * Math.PI);
ctx.clip();
}
/* @private
*/
postcompose_(e) {
if (!this.getActive())
return;
e.context.restore();
}
/**
* Activate or deactivate the interaction.
* @param {boolean} active Active.
* @observable
* @api
*/
setActive(b) {
if (b === this.getActive()) {
return;
}
super.setActive(b);
if (!this.layers_) return;
var i;
if (b) {
for (i = 0; i < this.layers_.length; i++) {
this.layers_[i].on(['precompose', 'prerender'], this.precomposeBind_);
this.layers_[i].on(['postcompose', 'postrender'], this.postcomposeBind_);
}
} else {
for (i = 0; i < this.layers_.length; i++) {
this.layers_[i].un(['precompose', 'prerender'], this.precomposeBind_);
this.layers_[i].un(['postcompose', 'postrender'], this.postcomposeBind_);
}
}
if (this.getMap()) {
try { this.getMap().renderSync(); } catch (e) { /* ok */ }
}
}
}
export default ol_interaction_Clip