Support panning in rects view

Implement rects view panning through mouse drag and drop.

Fix: b/258605234
Test: npm run build:all && npm run test:all
Change-Id: I0345e5d10d9076f66a2de36e4914b641aecded91
This commit is contained in:
Kean Mariotti
2022-12-21 10:05:02 +00:00
parent 69a16f877a
commit a8d7d1e2d1
4 changed files with 68 additions and 20 deletions

View File

@@ -16,7 +16,6 @@
import {Rectangle} from "viewers/common/rectangle";
import * as THREE from "three";
import {CSS2DObject, CSS2DRenderer} from "three/examples/jsm/renderers/CSS2DRenderer";
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";
import {ViewerEvents} from "viewers/common/viewer_events";
import {Circle3D, ColorType, Label3D, Point3D, Rect3D, Scene3D, Transform3D} from "./types3d";
@@ -58,16 +57,22 @@ export class Canvas {
widthAspectRatioAdjustFactor = 1;
}
const cameraWidth = Canvas.TARGET_SCENE_DIAGONAL * widthAspectRatioAdjustFactor;
const cameraHeight = Canvas.TARGET_SCENE_DIAGONAL * heightAspectRatioAdjustFactor;
const panFactorX = scene.camera.panScreenDistance.dx / this.canvasRects.clientWidth;
const panFactorY = scene.camera.panScreenDistance.dy / this.canvasRects.clientHeight;
this.scene = new THREE.Scene();
const scaleFactor = Canvas.TARGET_SCENE_DIAGONAL / scene.boundingBox.diagonal * scene.camera.zoomFactor;
this.scene.scale.set(scaleFactor, -scaleFactor, scaleFactor);
this.scene.translateX(scaleFactor * -scene.boundingBox.center.x);
this.scene.translateY(scaleFactor * scene.boundingBox.center.y);
this.scene.translateX(scaleFactor * -scene.boundingBox.center.x + cameraWidth * panFactorX);
this.scene.translateY(scaleFactor * scene.boundingBox.center.y - cameraHeight * panFactorY);
this.scene.translateZ(scaleFactor * -scene.boundingBox.center.z);
this.camera = new THREE.OrthographicCamera(
-Canvas.TARGET_SCENE_DIAGONAL / 2 * widthAspectRatioAdjustFactor, Canvas.TARGET_SCENE_DIAGONAL / 2 * widthAspectRatioAdjustFactor,
Canvas.TARGET_SCENE_DIAGONAL / 2 * heightAspectRatioAdjustFactor, -Canvas.TARGET_SCENE_DIAGONAL / 2 * heightAspectRatioAdjustFactor,
- cameraWidth / 2, cameraWidth / 2,
cameraHeight / 2, - cameraHeight / 2,
0, 100,
);

View File

@@ -15,7 +15,16 @@
*/
import {Rectangle} from "viewers/common/rectangle";
import {Box3D, ColorType, Label3D, Point3D, Rect3D, Scene3D, Transform3D} from "./types3d";
import {
Box3D,
ColorType,
Distance2D,
Label3D,
Point3D,
Rect3D,
Scene3D,
Transform3D
} from "./types3d";
class Mapper3D {
private static readonly CAMERA_ROTATION_FACTOR_INIT = 1;
@@ -34,6 +43,7 @@ class Mapper3D {
private cameraRotationFactor = Mapper3D.CAMERA_ROTATION_FACTOR_INIT;
private zSpacingFactor = Mapper3D.Z_SPACING_FACTOR_INIT;
private zoomFactor = Mapper3D.ZOOM_FACTOR_INIT;
private panScreenDistance: Distance2D = new Distance2D(0, 0);
private showOnlyVisibleMode = false; // by default show all
private showVirtualMode = false; // by default don't show virtual displays
private currentDisplayId = 0; // default stack id is usually 0
@@ -72,10 +82,17 @@ class Mapper3D {
this.zoomFactor = Math.max(this.zoomFactor, Mapper3D.ZOOM_FACTOR_MIN);
}
addPanScreenDistance(distance: Distance2D) {
this.panScreenDistance.dx += distance.dx;
this.panScreenDistance.dy += distance.dy;
}
resetCamera() {
this.cameraRotationFactor = Mapper3D.CAMERA_ROTATION_FACTOR_INIT;
this.zSpacingFactor = Mapper3D.Z_SPACING_FACTOR_INIT;
this.zoomFactor = Mapper3D.ZOOM_FACTOR_INIT;
this.panScreenDistance.dx = 0;
this.panScreenDistance.dy = 0;
}
getShowOnlyVisibleMode(): boolean {
@@ -112,7 +129,8 @@ class Mapper3D {
boundingBox: boundingBox,
camera: {
rotationFactor: this.cameraRotationFactor,
zoomFactor: this.zoomFactor
zoomFactor: this.zoomFactor,
panScreenDistance: this.panScreenDistance,
},
rects: rects3d,
labels: labels3d

View File

@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Component, Input, OnDestroy, Inject, ElementRef, SimpleChanges, OnInit, HostListener} from "@angular/core";
import {Rectangle} from "viewers/common/rectangle";
import {Component, Input, OnDestroy, Inject, ElementRef, OnInit, HostListener} from "@angular/core";
import {Rectangle, Point} from "viewers/common/rectangle";
import {Canvas} from "./canvas";
import {ViewerEvents} from "viewers/common/viewer_events";
import {Mapper3D} from "./mapper3d";
import {Distance2D} from "./types3d";
@Component({
selector: "rects-view",
@@ -204,6 +205,8 @@ export class RectsComponent implements OnInit, OnDestroy {
private resizeObserver: ResizeObserver;
private canvasRects?: HTMLCanvasElement;
private canvasLabels?: HTMLElement;
private mouseMoveListener = (event: MouseEvent) => this.onMouseMove(event);
private mouseUpListener = (event: MouseEvent) => this.onMouseUp(event);
constructor(
@Inject(ElementRef) private elementRef: ElementRef,
@@ -222,6 +225,8 @@ export class RectsComponent implements OnInit, OnDestroy {
this.canvasLabels = canvasContainer.querySelector(".canvas-labels");
this.canvas = new Canvas(this.canvasRects, this.canvasLabels!);
this.canvasRects.addEventListener("mousedown", event => this.onCanvasMouseDown(event));
this.mapper3d.setCurrentDisplayId(this.internalDisplayIds[0] ?? 0);
this.drawScene();
}
@@ -254,6 +259,22 @@ export class RectsComponent implements OnInit, OnDestroy {
}
}
public onCanvasMouseDown(event: MouseEvent) {
document.addEventListener("mousemove", this.mouseMoveListener);
document.addEventListener("mouseup", this.mouseUpListener);
}
public onMouseMove(event: MouseEvent) {
const distance = new Distance2D(event.movementX, event.movementY);
this.mapper3d.addPanScreenDistance(distance);
this.drawScene();
}
public onMouseUp(event: MouseEvent) {
document.removeEventListener("mousemove", this.mouseMoveListener);
document.removeEventListener("mouseup", this.mouseUpListener);
}
public onZoomInClick() {
this.doZoomIn();
}

View File

@@ -14,13 +14,18 @@
* limitations under the License.
*/
enum ColorType {
export enum ColorType {
VISIBLE,
NOT_VISIBLE,
HIGHLIGHTED
}
interface Box3D {
export class Distance2D{
constructor(public dx: number, public dy: number) {
}
}
export interface Box3D {
width: number,
height: number,
depth: number,
@@ -28,7 +33,7 @@ interface Box3D {
diagonal: number;
}
interface Rect3D {
export interface Rect3D {
id: number;
center: Point3D;
width: number;
@@ -39,7 +44,7 @@ interface Rect3D {
transform: Transform3D;
}
interface Transform3D {
export interface Transform3D {
dsdx: number;
dsdy: number;
tx: number;
@@ -48,13 +53,13 @@ interface Transform3D {
ty: number;
}
interface Point3D {
export interface Point3D {
x: number;
y: number;
z: number;
}
interface Label3D {
export interface Label3D {
circle: Circle3D;
linePoints: Point3D[];
textCenter: Point3D;
@@ -63,21 +68,20 @@ interface Label3D {
rectId: number;
}
interface Circle3D {
export interface Circle3D {
radius: number;
center: Point3D;
}
interface Scene3D {
export interface Scene3D {
boundingBox: Box3D;
camera: Camera;
rects: Rect3D[];
labels: Label3D[];
}
interface Camera {
export interface Camera {
rotationFactor: number;
zoomFactor: number;
panScreenDistance: Distance2D;
}
export {Box3D, Circle3D, ColorType, Label3D, Point3D, Rect3D, Scene3D, Transform3D};