@inweb/viewer-visualize
Version:
JavaScript library for rendering CAD and BIM files in a browser using VisualizeJS
119 lines (101 loc) • 4.07 kB
text/typescript
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
// All rights reserved.
//
// This software and its documentation and related materials are owned by
// the Alliance. The software may only be incorporated into application
// programs owned by members of the Alliance, subject to a signed
// Membership Agreement and Supplemental Software License Agreement with the
// Alliance. The structure and organization of this software are the valuable
// trade secrets of the Alliance and its suppliers. The software is also
// protected by copyright law and international treaty provisions. Application
// programs incorporating this software must include the following statement
// with their copyright notices:
//
// This application incorporates Open Design Alliance software pursuant to a
// license agreement with Open Design Alliance.
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
// All rights reserved.
//
// By use of this software, its documentation or related materials, you
// acknowledge and accept the above terms.
///////////////////////////////////////////////////////////////////////////////
import { Viewer } from "../Viewer";
import { Point3d } from "./Common/Geometry";
import { OdBaseDragger } from "./Common/OdBaseDragger";
export const MARKUP_ENTITY_TEXT = "$MarkupTempEntity_Text";
export class OdaTextDragger extends OdBaseDragger {
protected textRef: HTMLTextAreaElement;
protected m_center: Point3d;
protected entity: any;
protected readonly TEXT_HEIGHT_ALIGN = 24;
constructor(subject: Viewer) {
super(subject);
this.press = false;
}
override dispose(): void {
super.dispose();
this.textRef?.remove();
this.textRef = null;
}
private _finishInput(): void {
if (this.textRef && this.textRef.value.trimLeft()) {
this._updateFrame();
}
this.textRef?.remove();
this.textRef = null;
}
override start(x: number, y: number, absoluteX: number, absoluteY: number) {
if (!this.textRef) {
this.textRef = document.createElement("textarea");
this.textRef.style.zIndex = "9999";
this.textRef.style.position = "absolute";
this.textRef.style.display = "block";
this.textRef.style.top = absoluteY + "px";
this.textRef.style.left = absoluteX + "px";
this.textRef.onkeypress = (event) => {
if (event.key === "Enter") {
event.preventDefault();
this._finishInput();
}
};
document.body.appendChild(this.textRef);
this.press = true;
this.m_center = this.screenToWorld(x, y + this.TEXT_HEIGHT_ALIGN);
this.needInputText = true;
} else {
this._finishInput();
}
}
private _updateFrame(): void {
this.entity = this.getActiveMarkupEntity(MARKUP_ENTITY_TEXT);
const entityPtr = this.entity.openObject();
const view = this.getViewer().activeView;
const pos = this.toPoint(view.viewPosition);
const target = this.toPoint(view.viewTarget);
const eyeToWorld = view.eyeToWorldMatrix;
const eyeDir = pos.sub(target).asVector();
const xDir = this.toVector([1.0, 0.0, 0.0]);
const direction = xDir.transformBy(eyeToWorld);
const mtrx = this.createMatrix3d();
mtrx.setToWorldToPlane(this.toGeVector(eyeDir));
direction.transformBy(mtrx);
const angel = -Math.atan2(-direction.y, direction.x);
const textSize = 0.02;
let textScale = 1.0;
const projMtrx = view.projectionMatrix;
const mtrxNumber = projMtrx.get(1, 1);
const tol = 1.0e-6;
if (!(mtrxNumber < tol && mtrxNumber > -tol)) {
textScale = 1 / mtrxNumber;
}
const geomData = entityPtr.appendText(this.toGePoint(this.m_center), this.textRef.value.trimLeft());
const textPtr = geomData.openAsText();
textPtr.setNormal(this.toGeVector(eyeDir));
textPtr.setRotation(angel);
textPtr.setTextSize(textSize * textScale);
textPtr.delete();
geomData.delete();
entityPtr.delete();
}
}