Warning, /firebird/firebird-ng/src/app/components/tool-panel/tool-panel.component.ts is written in an unsupported language. File is not indexed.
0001 import { Component, Output, EventEmitter } from '@angular/core';
0002 import { NgIf } from '@angular/common';
0003 import { MatIcon } from '@angular/material/icon';
0004 import { ViewOptionsComponent } from '../view-options/view-options.component';
0005 import { ThreeService } from '../../services/three.service';
0006 import {MatIconButton} from "@angular/material/button";
0007 import {MatTooltip} from "@angular/material/tooltip";
0008 import * as THREE from 'three';
0009
0010
0011 @Component({
0012 selector: 'app-tool-panel',
0013 imports: [
0014 NgIf,
0015 MatIcon,
0016 ViewOptionsComponent,
0017 MatIconButton,
0018 MatTooltip,
0019
0020 ],
0021 templateUrl: './tool-panel.component.html',
0022 styleUrls: ['./tool-panel.component.scss']
0023 })
0024 export class ToolPanelComponent {
0025 @Output() cameraControlsToggle = new EventEmitter<void>();
0026
0027 isCollapsed = false;
0028
0029 /** Factor to zoom by. */
0030 private zoomFactor = 1.1;
0031 /** Whether camera is orthographic or perspective. */
0032 private orthographicView = false;
0033
0034 constructor(
0035 private threeService: ThreeService // no more EventDisplayService
0036 ) {}
0037
0038 /**
0039 * Zoom in or out around the orbit controls target.
0040 * Use OrbitControls or direct camera logic from threeService.
0041 */
0042 private zoomTo(factor: number): void {
0043 const controls = this.threeService.controls;
0044 const cam = this.threeService.camera as THREE.Camera;
0045
0046 // Ensure matrices are up to date
0047 cam.updateMatrixWorld(true);
0048
0049 const target = controls.target;
0050
0051 if ((cam as any).isOrthographicCamera) {
0052 const ortho = cam as THREE.OrthographicCamera;
0053 const newZoom = ortho.zoom / Math.max(1e-6, factor);
0054
0055 ortho.zoom = THREE.MathUtils.clamp(newZoom, 0.01, 1e5);
0056 ortho.updateProjectionMatrix();
0057
0058 } else if ((cam as any).isPerspectiveCamera) {
0059 const persp = cam as THREE.PerspectiveCamera;
0060
0061 const dir = new THREE.Vector3().subVectors(persp.position, target).normalize();
0062 const dist = persp.position.distanceTo(target);
0063
0064 let newDist = dist * factor;
0065
0066 const minD = (controls as any).minDistance ?? 0.001;
0067 const maxD = (controls as any).maxDistance ?? Infinity;
0068 newDist = THREE.MathUtils.clamp(newDist, minD, maxD);
0069
0070 const newPos = new THREE.Vector3().copy(target).addScaledVector(dir, newDist);
0071 persp.position.copy(newPos);
0072
0073 persp.lookAt(target);
0074 }
0075
0076 controls.update();
0077 }
0078
0079 onLeftClick(event: MouseEvent, action: string) {
0080 // Only respond to left-button
0081 if (event.button === 0) {
0082 if (action === 'zoomIn') {
0083 this.zoomIn();
0084 } else if (action === 'zoomOut') {
0085 this.zoomOut();
0086 }
0087 }
0088 }
0089
0090 zoomIn() {
0091 this.zoomTo(1 / this.zoomFactor);
0092 }
0093
0094 zoomOut() {
0095 this.zoomTo(this.zoomFactor);
0096 }
0097
0098 clearZoom() {
0099 // If you had logic for continuous zoom while mouse is held, you can clear it here
0100 }
0101
0102 togglePanel() {
0103 this.isCollapsed = !this.isCollapsed;
0104 }
0105
0106 /**
0107 * Switch between orthographic and perspective camera.
0108 * You can define a method in ThreeService to do the actual swap or toggling.
0109 */
0110 switchMainView() {
0111 this.orthographicView = !this.orthographicView;
0112 this.threeService.toggleOrthographicView(this.orthographicView);
0113 }
0114
0115 onCameraControlsToggle() {
0116 this.cameraControlsToggle.emit();
0117 }
0118 }