UNPKG

@inweb/viewer-visualize

Version:

JavaScript library for rendering CAD and BIM files in a browser using VisualizeJS

254 lines (219 loc) 10.4 kB
/////////////////////////////////////////////////////////////////////////////// // 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 * as utils from "./MeasureUtils"; export class MeasureLineItem { protected htmlElemStartPoint: HTMLElement; protected htmlElemEndPoint: HTMLElement; protected htmlElemLine: HTMLElement; protected htmlElemTitle: HTMLElement; protected startPoint: number[]; protected endPoint: number[]; protected unit: string; protected scale: number; protected size: number; protected style: CSSStyleDeclaration; protected viewer: any; protected moduleInstance: any; protected targetElement: HTMLElement; protected isFinishDraw: boolean; public lineThickness: number; constructor(targetElement: HTMLElement, viewer: any, moduleInstance: any) { this.htmlElemStartPoint = null; this.htmlElemEndPoint = null; this.htmlElemLine = null; this.htmlElemTitle = null; this.startPoint = null; this.endPoint = null; this.unit = ""; this.scale = 1.0; this.size = 10.0; this.lineThickness = 2; this.style = { border: "2px solid #FFFFFF", background: "#009bff", color: "white", boxShadow: "0 0 10px rgba(0,0,0,0.5)", } as CSSStyleDeclaration; this.htmlElemStartPoint = utils.createHtmlElementIfNeed(this.htmlElemStartPoint, targetElement, "ruler-start"); this.htmlElemEndPoint = utils.createHtmlElementIfNeed(this.htmlElemEndPoint, targetElement, "ruler-end"); this.htmlElemLine = utils.createHtmlElementIfNeed(this.htmlElemLine, targetElement, "ruler-line"); this.htmlElemTitle = utils.createHtmlElementIfNeed(this.htmlElemTitle, targetElement, "ruler-value"); this.viewer = viewer; this.moduleInstance = moduleInstance; this.targetElement = targetElement; this.isFinishDraw = false; } drawMeasureLine(): void { const pointSize = this.size; const rect = this.moduleInstance.canvas.getBoundingClientRect(); // draw start point if (this.startPoint) { this.htmlElemStartPoint = utils.createHtmlElementIfNeed( this.htmlElemStartPoint, this.targetElement, "ruler-start" ); const pScreenStart = utils.worldToScreen(this.startPoint, this.moduleInstance, this.viewer); if (utils.isInsideRect(pScreenStart, rect.width, rect.height)) { this.htmlElemStartPoint.style.display = "block"; this.htmlElemStartPoint.style.cursor = "pointer"; this.htmlElemStartPoint.style.position = "absolute"; this.htmlElemStartPoint.style.top = `${pScreenStart.y - pointSize / 2}px`; this.htmlElemStartPoint.style.left = `${pScreenStart.x - pointSize / 2}px`; this.htmlElemStartPoint.style.borderRadius = `${pointSize}px`; this.htmlElemStartPoint.style.border = this.style.border; this.htmlElemStartPoint.style.background = this.style.background; this.htmlElemStartPoint.style.zIndex = "2"; this.htmlElemStartPoint.style.width = `${pointSize}px`; this.htmlElemStartPoint.style.height = `${pointSize}px`; this.htmlElemStartPoint.style.boxShadow = this.style.boxShadow; } else { this.htmlElemStartPoint.style.display = "none"; } } // draw end point if (this.endPoint && this.isFinishDraw) { this.htmlElemEndPoint = utils.createHtmlElementIfNeed(this.htmlElemEndPoint, this.targetElement, "ruler-end"); const pScreenEnd = utils.worldToScreen(this.endPoint, this.moduleInstance, this.viewer); if (utils.isInsideRect(pScreenEnd, rect.width, rect.height)) { this.htmlElemEndPoint.style.display = "block"; this.htmlElemEndPoint.style.cursor = "pointer"; this.htmlElemEndPoint.style.position = "absolute"; this.htmlElemEndPoint.style.top = `${pScreenEnd.y - pointSize / 2}px`; this.htmlElemEndPoint.style.left = `${pScreenEnd.x - pointSize / 2}px`; this.htmlElemEndPoint.style.borderRadius = `${pointSize}px`; this.htmlElemEndPoint.style.border = this.style.border; this.htmlElemEndPoint.style.background = this.style.background; this.htmlElemEndPoint.style.zIndex = "2"; this.htmlElemEndPoint.style.width = `${pointSize}px`; this.htmlElemEndPoint.style.height = `${pointSize}px`; this.htmlElemEndPoint.style.boxShadow = this.style.boxShadow; } else { this.htmlElemEndPoint.style.display = "none"; } } if (this.endPoint && this.startPoint) { const point1 = utils.worldToScreen(this.startPoint, this.moduleInstance, this.viewer); const point2 = utils.worldToScreen(this.endPoint, this.moduleInstance, this.viewer); const { p1, p2, angle, width } = utils.getDataForDrawLineWithFixed(point1, point2, rect.width, rect.height); const dx = p2.x - p1.x; const dy = p2.y - p1.y; const height = this.lineThickness; if (utils.isInsideRect(p1, rect.width, rect.height) && utils.isInsideRect(p2, rect.width, rect.height)) { this.htmlElemLine = utils.createHtmlElementIfNeed(this.htmlElemLine, this.targetElement, "ruler-line"); this.htmlElemLine.style.display = "block"; this.htmlElemLine.style.cursor = "pointer"; this.htmlElemLine.style.position = "absolute"; this.htmlElemLine.style.top = `${p1.y}px`; this.htmlElemLine.style.left = `${p1.x}px`; this.htmlElemLine.style.width = `${width}px`; this.htmlElemLine.style.transform = `rotate(${angle}deg)`; this.htmlElemLine.style.transformOrigin = `0px ${height / 2}px`; this.htmlElemLine.style.boxShadow = this.style.boxShadow; this.htmlElemLine.style.border = "none"; this.htmlElemLine.style.background = this.style.background; this.htmlElemLine.style.zIndex = "1"; this.htmlElemLine.style.height = `${height}px`; const distance = `${this.getDistance()} ${this.unit}`; const pX = p1.x + dx / 2; const pY = p1.y + dy / 2; const widthTitle = distance.length * 10; this.htmlElemTitle = utils.createHtmlElementIfNeed(this.htmlElemTitle, this.targetElement, "ruler-value"); this.htmlElemTitle.style.display = "block"; this.htmlElemTitle.style.cursor = "pointer"; this.htmlElemTitle.style.font = "10px"; this.htmlElemTitle.style.color = "white"; this.htmlElemTitle.style.position = "Absolute"; this.htmlElemTitle.style.top = `${pY}px`; this.htmlElemTitle.style.left = `${pX - widthTitle / 2}px`; this.htmlElemTitle.style.width = `${widthTitle}px`; this.htmlElemTitle.style.transformOrigin = "0px 0px"; this.htmlElemTitle.style.borderRadius = "5px"; this.htmlElemTitle.style.boxShadow = this.style.boxShadow; this.htmlElemTitle.style.border = "none"; this.htmlElemTitle.style.background = this.style.background; this.htmlElemTitle.style.zIndex = "3"; this.htmlElemTitle.style.padding = "2px"; this.htmlElemTitle.style.textAlign = "center"; this.htmlElemTitle.innerHTML = `${distance}`; } else { this.htmlElemLine.style.display = "none"; this.htmlElemTitle.style.display = "none"; } } } getDistance(): number { let distance = utils.getDistance(this.startPoint, this.endPoint, this.moduleInstance); if (Math.abs(this.scale - 1.0) > 10e-5) { distance = (distance / this.scale).toFixed(2); } return distance; } setStartPoint(gePoint: number[]): void { this.startPoint = gePoint; this.drawMeasureLine(); } setEndPoint(gePoint: number[], isFinish: boolean): void { this.isFinishDraw = isFinish === undefined ? true : isFinish; this.endPoint = gePoint; this.drawMeasureLine(); } update(): void { this.drawMeasureLine(); } setSize(size: number): void { this.size = size; this.drawMeasureLine(); } clear(): void { this.endPoint = null; this.startPoint = null; this.htmlElemStartPoint = utils.destroyHtmlElement(this.htmlElemStartPoint, this.targetElement); this.htmlElemEndPoint = utils.destroyHtmlElement(this.htmlElemEndPoint, this.targetElement); this.htmlElemLine = utils.destroyHtmlElement(this.htmlElemLine, this.targetElement); this.htmlElemTitle = utils.destroyHtmlElement(this.htmlElemTitle, this.targetElement); } setUnit(unit: string): void { this.unit = unit; this.drawMeasureLine(); } setConversionFactor(scale: number): void { this.scale = scale; this.drawMeasureLine(); } setStyle(style: CSSStyleDeclaration): void { this.style = style; this.drawMeasureLine(); } setSelectionReactor(reactor: any): void { utils.onSetCallback(this.htmlElemStartPoint, reactor ? reactor.onStartPoint : null); utils.onSetCallback(this.htmlElemEndPoint, reactor ? reactor.onEndPoint : null); utils.onSetCallback(this.htmlElemTitle, reactor ? reactor.onTitle : null); } setSelectability(enable: boolean): void { utils.onSetSelectivity(this.htmlElemStartPoint, enable); utils.onSetSelectivity(this.htmlElemEndPoint, enable); utils.onSetSelectivity(this.htmlElemLine, enable); utils.onSetSelectivity(this.htmlElemTitle, enable); } }