src/extras/MarqueePicker/MarqueePickerMouseControl.js
import {Component} from "../../viewer/scene/Component.js";
import {MarqueePicker} from "./MarqueePicker.js";
/**
* Controls a {@link MarqueePicker} with mouse input.
*
* See {@link MarqueePicker} for usage example.
*
* When the MarqueePickerMouseControl is active:
*
* * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s.
* * Drag left-to-right to pick Entities that intersect the box.
* * Drag right-to-left to pick Entities that are fully inside the box.
* * On release, the MarqueePicker will fire a "picked" event with IDs of the picked Entities , if any.
*/
export class MarqueePickerMouseControl extends Component {
/**
* Creates a new MarqueePickerMouseControl.
*
* @param {*} cfg Configuration
* @param {MarqueePicker} cfg.marqueePicker The MarqueePicker to control.
*/
constructor(cfg) {
super(cfg.marqueePicker, cfg);
const marqueePicker = cfg.marqueePicker;
const scene = marqueePicker.viewer.scene;
const canvas = scene.canvas.canvas;
let pageStartX;
let pageStartY;
let pageEndX;
let pageEndY;
let canvasStartX;
let canvasStartY;
let canvasEndX;
let canvasEndY;
let isMouseDragging = false;
let isMouseDown = false;
let mouseWasUpOffCanvas = false;
let mouseDownTimer;
canvas.addEventListener("mousedown", (e) => {
if (!this.getActive()) {
return;
}
if (e.button !== 0) { // Left button only
return;
}
mouseDownTimer = setTimeout(function () {
const input = marqueePicker.viewer.scene.input;
if (!input.keyDown[input.KEY_CTRL]) { // Clear selection unless CTRL down
marqueePicker.clear();
}
pageStartX = e.pageX;
pageStartY = e.pageY;
canvasStartX = e.offsetX;
canvasStartY = e.offsetY;
marqueePicker.setMarqueeCorner1([pageStartX, pageStartY]);
isMouseDragging = true;
marqueePicker.viewer.cameraControl.pointerEnabled = false; // Disable camera rotation
marqueePicker.setMarqueeVisible(true);
canvas.style.cursor = "crosshair";
}, 400);
isMouseDown = true;
});
canvas.addEventListener("mouseup", (e) => {
if (!this.getActive()) {
return;
}
if (!isMouseDragging && !mouseWasUpOffCanvas) {
return
}
if (e.button !== 0) {
return;
}
clearTimeout(mouseDownTimer);
pageEndX = e.pageX;
pageEndY = e.pageY;
const width = Math.abs(pageEndX - pageStartX);
const height = Math.abs(pageEndY - pageStartY);
isMouseDragging = false;
marqueePicker.viewer.cameraControl.pointerEnabled = true; // Enable camera rotation
if (mouseWasUpOffCanvas) {
mouseWasUpOffCanvas = false;
}
if (width > 3 || height > 3) { // Marquee pick if rectangle big enough
marqueePicker.pick();
}
}); // Bubbling
document.addEventListener("mouseup", (e) => {
if (!this.getActive()) {
return;
}
if (e.button !== 0) { // check if left button was clicked
return;
}
clearTimeout(mouseDownTimer);
if (!isMouseDragging) {
return
}
marqueePicker.setMarqueeVisible(false);
isMouseDragging = false;
isMouseDown = false;
mouseWasUpOffCanvas = true;
marqueePicker.viewer.cameraControl.pointerEnabled = true;
}, true); // Capturing
canvas.addEventListener("mousemove", (e) => {
if (!this.getActive()) {
return;
}
if (e.button !== 0) { // check if left button was clicked
return;
}
if (!isMouseDown) {
return;
}
clearTimeout(mouseDownTimer);
if (!isMouseDragging) {
return
}
pageEndX = e.pageX;
pageEndY = e.pageY;
canvasEndX = e.offsetX;
canvasEndY = e.offsetY;
marqueePicker.setMarqueeVisible(true);
marqueePicker.setMarqueeCorner2([pageEndX, pageEndY]);
marqueePicker.setPickMode((canvasStartX < canvasEndX) ? MarqueePicker.PICK_MODE_INSIDE : MarqueePicker.PICK_MODE_INTERSECTS);
});
}
/**
* Activates or deactivates this MarqueePickerMouseControl.
*
* @param {boolean} active Whether or not to activate.
*/
setActive(active) {
if (this._active === active) {
return;
}
this._active = active;
this.fire("active", this._active);
}
/**
* Gets if this MarqueePickerMouseControl is active.
*
* @returns {boolean}
*/
getActive() {
return this._active;
}
/**
*
*/
destroy() {
}
}