UNPKG

@shopware-ag/dive

Version:

Shopware Spatial Framework

126 lines (101 loc) 3.69 kB
import { Object3D, Vector3 } from 'three'; import { AxesColorBlue, AxesColorGreen, AxesColorRed, } from '../../constant/AxisHelperColors'; import { DIVEHoverable } from '../../interface/Hoverable'; import DIVEOrbitControls from '../../controls/OrbitControls'; import { DIVEScaleHandle } from '../handles/ScaleHandle'; import { DraggableEvent } from '../../toolbox/BaseTool'; import { DIVEGizmoAxis, DIVEGizmo } from '../Gizmo'; export class DIVEScaleGizmo extends Object3D implements DIVEHoverable { readonly isHoverable: true = true; public children: DIVEScaleHandle[]; private _controller: DIVEOrbitControls; public set debug(value: boolean) { this.children.forEach((child) => { child.debug = value; }); } private _startScale: Vector3 | null; constructor(controller: DIVEOrbitControls) { super(); this.name = 'DIVEScaleGizmo'; this.children = []; this._startScale = null; this._controller = controller; this.add( new DIVEScaleHandle('x', 1, new Vector3(1, 0, 0), AxesColorRed), ); this.add( new DIVEScaleHandle('y', 1, new Vector3(0, 1, 0), AxesColorGreen), ); this.add( new DIVEScaleHandle('z', 1, new Vector3(0, 0, 1), AxesColorBlue), ); } public reset(): void { this.children.forEach((child) => { child.reset(); }); } public update(scale: Vector3): void { this.children.forEach((child) => { child.update(scale); }); } private handleHighlight( axis: DIVEGizmoAxis, value: boolean, dragged: boolean, ): void { // Set highlight state for all handles. this.children.forEach((child) => { if (dragged) { // Dragging has priority when it comes to highlighting. child.highlight = child.axis === axis && dragged; } else { // If nothing is dragged, decide on hovered state. child.highlight = child.axis === axis && value; } }); } public onHoverAxis(handle: DIVEScaleHandle, value: boolean): void { // If _startScale is set, it means there is a drag operation in progress. // While dragging, we don't want to change the hover state. if (this._startScale) return; if (!this.parent) return; if (!this.parent.parent) return; (this.parent.parent as DIVEGizmo).onHover( 'translate', handle.axis, value, ); this.handleHighlight(handle.axis, value, false); } public onAxisDragStart(handle: DIVEScaleHandle): void { if (!this.parent) return; if (!this.parent.parent) return; const object = (this.parent.parent as DIVEGizmo).object; if (!object) return; this._startScale = object.scale.clone(); this.handleHighlight(handle.axis, true, true); } public onAxisDrag(axis: DIVEScaleHandle, e: DraggableEvent): void { if (!this._startScale) return; if (!this.parent) return; if (!this.parent.parent) return; if (!('onChange' in this.parent.parent)) return; const delta = e.dragDelta.clone().projectOnVector(axis.forwardVector); (this.parent.parent as DIVEGizmo).onChange( undefined, undefined, this._startScale.clone().add(delta), ); } public onAxisDragEnd(handle: DIVEScaleHandle): void { this._startScale = null; this.handleHighlight(handle.axis, false, false); } }