UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

136 lines (135 loc) 4.38 kB
import { Vector3, Matrix3, Triangle, Quaternion } from "../../../../_three@0.150.1@three/build/three.module.mjs"; import { CSS2DObject } from "../../../../_three@0.150.1@three/examples/jsm/renderers/CSS2DRenderer.mjs"; import { normalizeUnit } from "../styles/conversions.mjs"; import { parseExpressions } from "../styles/parsers.mjs"; /* @license * Copyright 2020 Google LLC. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the 'License'); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an 'AS IS' BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const a = new Vector3(); const b = new Vector3(); const c = new Vector3(); const mat = new Matrix3(); const triangle = new Triangle(); const quat = new Quaternion(); class Hotspot extends CSS2DObject { constructor(config) { super(document.createElement("div")); this.normal = new Vector3(0, 1, 0); this.initialized = false; this.referenceCount = 1; this.pivot = document.createElement("div"); this.slot = document.createElement("slot"); this.element.classList.add("annotation-wrapper"); this.slot.name = config.name; this.element.appendChild(this.pivot); this.pivot.appendChild(this.slot); this.updatePosition(config.position); this.updateNormal(config.normal); this.surface = config.surface; } get facingCamera() { return !this.element.classList.contains("hide"); } show() { if (!this.facingCamera || !this.initialized) { this.updateVisibility(true); } } hide() { if (this.facingCamera || !this.initialized) { this.updateVisibility(false); } } increment() { this.referenceCount++; } decrement() { if (this.referenceCount > 0) { --this.referenceCount; } return this.referenceCount === 0; } updatePosition(position) { if (position == null) return; const positionNodes = parseExpressions(position)[0].terms; for (let i = 0; i < 3; ++i) { this.position.setComponent(i, normalizeUnit(positionNodes[i]).number); } this.updateMatrixWorld(); } updateNormal(normal) { if (normal == null) return; const normalNodes = parseExpressions(normal)[0].terms; for (let i = 0; i < 3; ++i) { this.normal.setComponent(i, normalNodes[i].number); } } updateSurface(forceUpdate) { if (!forceUpdate && this.initialized) { return; } const { mesh, tri, bary } = this; if (mesh == null || tri == null || bary == null) { return; } mesh.getVertexPosition(tri.x, a); mesh.getVertexPosition(tri.y, b); mesh.getVertexPosition(tri.z, c); a.toArray(mat.elements, 0); b.toArray(mat.elements, 3); c.toArray(mat.elements, 6); this.position.copy(bary).applyMatrix3(mat); const target = this.parent; target.worldToLocal(mesh.localToWorld(this.position)); triangle.set(a, b, c); triangle.getNormal(this.normal).transformDirection(mesh.matrixWorld); const scene = target.parent; quat.setFromAxisAngle(a.set(0, 1, 0), -scene.yaw); this.normal.applyQuaternion(quat); } orient(radians) { this.pivot.style.transform = `rotate(${radians}rad)`; } updateVisibility(show) { if (show) { this.element.classList.remove("hide"); } else { this.element.classList.add("hide"); } this.slot.assignedNodes().forEach((node) => { if (node.nodeType !== Node.ELEMENT_NODE) { return; } const element = node; const visibilityAttribute = element.dataset.visibilityAttribute; if (visibilityAttribute != null) { const attributeName = `data-${visibilityAttribute}`; if (show) { element.setAttribute(attributeName, ""); } else { element.removeAttribute(attributeName); } } element.dispatchEvent(new CustomEvent("hotspot-visibility", { detail: { visible: show } })); }); this.initialized = true; } } export { Hotspot };