UNPKG

ami.js

Version:

<p align="center"> <img src="https://cloud.githubusercontent.com/assets/214063/23213764/78ade038-f90c-11e6-8208-4fcade5f3832.png" width="60%"> </p>

472 lines (372 loc) 16.1 kB
import WidgetsBase from './widgets.base'; import WidgetsHandle from './widgets.handle'; import {Vector3} from 'three'; /** * @module widgets/handle * */ export default class WidgetsBiRuler extends WidgetsBase { constructor(targetMesh, controls, camera, container) { super(); this._targetMesh = targetMesh; this._controls = controls; this._camera = camera; this._container = container; this._active = true; this._initOrtho = false; this._worldPosition = new Vector3(); if (this._targetMesh !== null) { this._worldPosition = this._targetMesh.position; } // mesh stuff this._material = null; this._geometry = null; this._mesh = null; // dom stuff this._line = null; this._distance = null; // add handles this._handles = []; // first handle let firstHandle = new WidgetsHandle(this._targetMesh, this._controls, this._camera, this._container); firstHandle.worldPosition = this._worldPosition; firstHandle.hovered = true; this.add(firstHandle); this._handles.push(firstHandle); let secondHandle = new WidgetsHandle(this._targetMesh, this._controls, this._camera, this._container); secondHandle.worldPosition = this._worldPosition; secondHandle.hovered = true; // active and tracking might be redundant secondHandle.active = true; secondHandle.tracking = true; this.add(secondHandle); this._handles.push(secondHandle); // third handle let thirdHandle = new WidgetsHandle(this._targetMesh, this._controls, this._camera, this._container); thirdHandle.worldPosition = this._worldPosition; thirdHandle.hovered = true; this.add(thirdHandle); this._handles.push(thirdHandle); // fourth handle let fourthHandle = new WidgetsHandle(this._targetMesh, this._controls, this._camera, this._container); fourthHandle.worldPosition = this._worldPosition; fourthHandle.hovered = true; this.add(fourthHandle); this._handles.push(fourthHandle); // Create ruler this.create(); this.onMove = this.onMove.bind(this); this.addEventListeners(); this._orientation = null; this._slice = null; } addEventListeners() { this._container.addEventListener('mousewheel', this.onMove); this._container.addEventListener('DOMMouseScroll', this.onMove); } onMove(evt) { this._dragged = true; this._handles[0].onMove(evt); this._handles[1].onMove(evt); this._handles[2].onMove(evt); this._handles[3].onMove(evt); this._hovered = this._handles[0].hovered || this._handles[1].hovered || this._handles[2].hovered || this._handles[3].hovered; this.update(); } onStart(evt) { this._dragged = false; this._handles[0].onStart(evt); this._handles[1].onStart(evt); this._handles[2].onStart(evt); this._handles[3].onStart(evt); this._active = this._handles[0].active || this._handles[1].active || this._handles[2].active || this._handles[3].active; this.update(); } onEnd(evt) { // First Handle this._handles[0].onEnd(evt); this._handles[2].onEnd(evt); this._handles[3].onEnd(evt); window.console.log(this); // Second Handle if (this._dragged || !this._handles[1].tracking) { this._handles[1].tracking = false; this._handles[1].onEnd(evt); } else { this._handles[1].tracking = false; } // State of ruler widget this._active = this._handles[0].active || this._handles[1].active || this._handles[2].active || this._handles[3].active; this.update(); } create() { this.createMesh(); this.createDOM(); } hideDOM() { this._line.style.display = 'none'; this._distance.style.display = 'none'; this._line2.style.display = 'none'; this._distance2.style.display = 'none'; for (let index in this._handles) { this._handles[index].hideDOM(); } this._dashline.style.display = 'none'; } showDOM() { this._line.style.display = ''; this._distance.style.display = ''; this._line2.style.display = ''; this._distance2.style.display = ''; for (let index in this._handles) { this._handles[index].showDOM(); } this._dashline.style.display = ''; } hideMesh() { this._mesh.visible = false; this._mesh2.visible = false; this._handles[0].visible = false; this._handles[1].visible = false; this._handles[2].visible = false; this._handles[3].visible = false; } showMesh() { this._mesh.visible = true; this._mesh2.visible = true; this._handles[0].visible = true; this._handles[1].visible = true; this._handles[2].visible = true; this._handles[3].visible = true; } show() { this.showDOM(); this.showMesh(); } hide() { this.hideDOM(); this.hideMesh(); } update() { this.updateColor(); // mesh stuff this.updateMeshColor(); this.updateMeshPosition(); // DOM stuff this.updateDOMPosition(); this.updateDOMColor(); } createMesh() { // geometry this._geometry = new THREE.Geometry(); this._geometry.vertices.push(this._handles[0].worldPosition); this._geometry.vertices.push(this._handles[1].worldPosition); // geometry this._geometry2 = new THREE.Geometry(); this._geometry2.vertices.push(this._handles[2].worldPosition); this._geometry2.vertices.push(this._handles[3].worldPosition); // material this._material = new THREE.LineBasicMaterial(); this._material2 = new THREE.LineBasicMaterial(); this.updateMeshColor(); // mesh this._mesh = new THREE.Line(this._geometry, this._material); this._mesh.visible = true; this._mesh2 = new THREE.Line(this._geometry2, this._material2); this._mesh2.visible = true; // add it! this.add(this._mesh); this.add(this._mesh2); } updateMeshColor() { if (this._material) { this._material.color.set(this._color); } if (this._material2) { this._material2.color.set(this._color); } } updateMeshPosition() { if (this._geometry) { this._geometry.verticesNeedUpdate = true; } if (this._geometry2) { this._geometry2.verticesNeedUpdate = true; } } createDOM() { // add line! this._line = document.createElement('div'); this._line.setAttribute('class', 'widgets handle line'); this._line.style.position = 'absolute'; this._line.style.transformOrigin = '0 100%'; this._line.style.marginTop = '-1px'; this._line.style.height = '2px'; this._line.style.width = '3px'; this._container.appendChild(this._line); // add distance! this._distance = document.createElement('div'); this._distance.setAttribute('class', 'widgets handle distance'); this._distance.style.border = '2px solid'; this._distance.style.backgroundColor = '#F9F9F9'; // this._distance.style.opacity = '0.5'; this._distance.style.color = '#353535'; this._distance.style.padding = '4px'; this._distance.style.position = 'absolute'; this._distance.style.transformOrigin = '0 100%'; this._distance.innerHTML = 'Hello, world!'; this._container.appendChild(this._distance); // add line! this._line2 = document.createElement('div'); this._line2.setAttribute('class', 'widgets handle line'); this._line2.style.position = 'absolute'; this._line2.style.transformOrigin = '0 100%'; this._line2.style.marginTop = '-1px'; this._line2.style.height = '2px'; this._line2.style.width = '3px'; this._container.appendChild(this._line2); // add distance! this._distance2 = document.createElement('div'); this._distance2.setAttribute('class', 'widgets handle distance'); this._distance.style.border = '2px solid'; this._distance.style.backgroundColor = '#F9F9F9'; // this._distance2.style.opacity = '0.5'; this._distance2.style.color = '#353535'; this._distance2.style.padding = '4px'; this._distance2.style.position = 'absolute'; this._distance2.style.transformOrigin = '0 100%'; this._distance2.innerHTML = 'Hello, world!'; this._container.appendChild(this._distance2); // add dash line this._dashline = document.createElement('div'); this._dashline.setAttribute('class', 'widgets handle dashline'); this._dashline.style.position = 'absolute'; this._dashline.style.border = 'none'; this._dashline.style.borderTop = '2.5px dashed #F9F9F9'; this._dashline.style.transformOrigin = '0 100%'; this._dashline.style.height = '1px'; this._dashline.style.width = '50%'; this._container.appendChild(this._dashline); this.updateDOMColor(); } updateDOMPosition() { // update rulers lines and text! let x1 = this._handles[0].screenPosition.x; let y1 = this._handles[0].screenPosition.y; let x2 = this._handles[1].screenPosition.x; let y2 = this._handles[1].screenPosition.y; // let x0 = x1 + (x2 - x1)/2; // let y0 = y1 + (y2 - y1)/2; let x0 = x2; let y0 = y2; if (y1 >= y2) { y0 = y2 - 30; } else { y0 = y2 + 30; } let length = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); let angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; let posY = y1 - this._container.offsetHeight; // update line let transform = `translate3D(${x1}px,${posY}px, 0)`; transform += ` rotate(${angle}deg)`; this._line.style.transform = transform; this._line.style.width = length + 'px'; // update distance let w0 = this._handles[0].worldPosition; let w1 = this._handles[1].worldPosition; this._distance.innerHTML = `${Math.sqrt((w0.x-w1.x)*(w0.x-w1.x) + (w0.y-w1.y)*(w0.y-w1.y) + (w0.z-w1.z)*(w0.z-w1.z)).toFixed(2)} mm`; this._distanceValue = Math.sqrt((w0.x-w1.x)*(w0.x-w1.x) + (w0.y-w1.y)*(w0.y-w1.y) + (w0.z-w1.z)*(w0.z-w1.z)).toFixed(2); let posY0 = y0 - this._container.offsetHeight - this._distance.offsetHeight/2; x0 -= this._distance.offsetWidth/2; let transform2 = `translate3D(${Math.round(x0)}px,${Math.round(posY0)}px, 0)`; this._distance.style.transform = transform2; // update rulers lines 2 and text! let x3 = this._handles[2].screenPosition.x; let y3 = this._handles[2].screenPosition.y; let x4 = this._handles[3].screenPosition.x; let y4 = this._handles[3].screenPosition.y; // let x0 = x1 + (x2 - x1)/2; // let y0 = y1 + (y2 - y1)/2; let x02 = x4; let y02 = y4; if (y3 >= y4) { y02 = y4 - 30; } else { y02 = y4 + 30; } length = Math.sqrt((x3-x4)*(x3-x4) + (y3-y4)*(y3-y4)); angle = Math.atan2(y4 - y3, x4 - x3) * 180 / Math.PI; posY = y3 - this._container.offsetHeight; // update line transform = `translate3D(${x3}px,${posY}px, 0)`; transform += ` rotate(${angle}deg)`; this._line2.style.transform = transform; this._line2.style.width = length + 'px'; // update distance let w02 = this._handles[2].worldPosition; let w12 = this._handles[3].worldPosition; this._distance2.innerHTML = `${Math.sqrt((w02.x-w12.x)*(w02.x-w12.x) + (w02.y-w12.y)*(w02.y-w12.y) + (w02.z-w12.z)*(w02.z-w12.z)).toFixed(2)} mm`; this._distance2Value = Math.sqrt((w02.x-w12.x)*(w02.x-w12.x) + (w02.y-w12.y)*(w02.y-w12.y) + (w02.z-w12.z)*(w02.z-w12.z)).toFixed(2); let posY02 = y02 - this._container.offsetHeight - this._distance2.offsetHeight/2; x02 -= this._distance2.offsetWidth/2; transform2 = `translate3D(${Math.round(x02)}px,${Math.round(posY02)}px, 0)`; this._distance2.style.transform = transform2; // update dash line let l1center = this.getPointInBetweenByPerc(this._handles[0].worldPosition, this._handles[1].worldPosition, 0.5); let l2center = this.getPointInBetweenByPerc(this._handles[2].worldPosition, this._handles[3].worldPosition, 0.5); let screen1 = this._handles[0].worldToScreen(l1center, this._camera, this._container); let screen2 = this._handles[0].worldToScreen(l2center, this._camera, this._container); x1 = screen1.x; y1 = screen1.y; x2 = screen2.x; y2 = screen2.y; length = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; posY = y1 - this._container.offsetHeight; // update line transform = `translate3D(${x1}px,${posY}px, 0)`; transform += ` rotate(${angle}deg)`; this._dashline.style.transform = transform; this._dashline.style.width = length + 'px'; } updateDOMColor() { this._line.style.backgroundColor = `${this._color}`; this._distance.style.borderColor = `${this._color}`; this._line2.style.backgroundColor = `${this._color}`; this._distance2.style.borderColor = `${this._color}`; } getPointInBetweenByPerc(pointA, pointB, percentage) { let dir = pointB.clone().sub(pointA); let len = dir.length(); dir = dir.normalize().multiplyScalar(len*percentage); return pointA.clone().add(dir); } initOrtho() { this._initOrtho = true; let pcenter = this.getPointInBetweenByPerc(this._handles[0].worldPosition, this._handles[1].worldPosition, 0.5); this._handles[2].worldPosition = this.getPointInBetweenByPerc(this._handles[0].worldPosition, this._handles[1].worldPosition, 0.25); this._handles[3].worldPosition = this.getPointInBetweenByPerc(this._handles[0].worldPosition, this._handles[1].worldPosition, 0.75); this._handles[2].worldPosition.x = pcenter.x - Math.sqrt((pcenter.y - this._handles[2].worldPosition.y)*(pcenter.y - this._handles[2].worldPosition.y)); this._handles[2].worldPosition.y = pcenter.y + Math.sqrt((pcenter.x - this._handles[2].worldPosition.x)*(pcenter.x - this._handles[2].worldPosition.x)); this._handles[3].worldPosition.x = pcenter.x + Math.sqrt((pcenter.y - this._handles[2].worldPosition.y)*(pcenter.y - this._handles[2].worldPosition.y)); this._handles[3].worldPosition.y = pcenter.y - Math.sqrt((pcenter.x - this._handles[2].worldPosition.x)*(pcenter.x - this._handles[2].worldPosition.x)); } get worldPosition() { return this._worldPosition; } set worldPosition(worldPosition) { this._worldPosition = worldPosition; this._handles[0].worldPosition = this._worldPosition; this._handles[1].worldPosition = this._worldPosition; this._handles[2].worldPosition = this._worldPosition; this._handles[3].worldPosition = this._worldPosition; this.update(); } get shotestDistance() { return ((this._distanceValue < this._distance2Value) ? this._distanceValue : this._distance2Value); } get longestDistance() { return ((this._distanceValue > this._distance2Value) ? this._distanceValue : this._distance2Value); } }