From 399537e08cdd8382cb211c9c8981db8a1b9111c6 Mon Sep 17 00:00:00 2001 From: howard Date: Sat, 3 Apr 2021 17:59:14 -0700 Subject: [PATCH] chkkpt --- src/sketcher/Sketch.js | 9 +- src/sketcher/drawDimension.js | 242 ++++++++++++---------------------- src/sketcher/drawEvents.js | 40 ++++-- src/sketcher/rect.js | 81 ++++++++++++ src/sketcher/threetest.js | 212 +++++++++++++++++++++++++++++ src/utils/mouseEvents.js | 67 ++++++---- src/utils/shared.js | 49 ++++--- 7 files changed, 483 insertions(+), 217 deletions(-) create mode 100644 src/sketcher/rect.js create mode 100644 src/sketcher/threetest.js diff --git a/src/sketcher/Sketch.js b/src/sketcher/Sketch.js index 153d001..2703fa2 100644 --- a/src/sketcher/Sketch.js +++ b/src/sketcher/Sketch.js @@ -9,7 +9,7 @@ import { get3PtArc } from './drawArc' import { _vec2, _vec3, raycaster, awaitPts } from '../utils/shared' import { replacer, reviver } from '../utils/mapJSONReplacer' import { AxesHelper } from '../utils/axes' -import { drawDimensionPre } from './drawDimension' +import { drawDimension } from './drawDimension'; @@ -107,9 +107,9 @@ class Sketch { this.drawOnClick1 = drawOnClick1.bind(this); this.drawPreClick2 = drawPreClick2.bind(this); this.drawOnClick2 = drawOnClick2.bind(this); + this.drawDimension = drawDimension.bind(this) this.awaitPts = awaitPts.bind(this); - this.drawDimensionPre = drawDimensionPre.bind(this); this.onHover = onHover.bind(this); this.onPick = onPick.bind(this); @@ -180,7 +180,8 @@ class Sketch { this.mode = "arc" break; case 'd': - this.drawDimensionPre() + this.drawDimension() + this.mode = "" break; case 'x': this.deleteSelected() @@ -310,7 +311,7 @@ class Sketch { raycaster.ray.intersectPlane(this.plane, _vec3).applyMatrix4(this.obj3d.inverse) - return _vec3.toArray() + return _vec3 } solve() { diff --git a/src/sketcher/drawDimension.js b/src/sketcher/drawDimension.js index 5aa0c73..bbceb21 100644 --- a/src/sketcher/drawDimension.js +++ b/src/sketcher/drawDimension.js @@ -1,162 +1,122 @@ import * as THREE from '../../node_modules/three/src/Three'; -import { ptObj, lineObj, awaitPts } from '../utils/shared' - -const color = { - hover: 0x00ff00, - lighting: 0xFFFFFF, - emissive: 0x072534, - d: 0xf5bc42, //datums: planes - p: 0x555555, //points - l: 0x555555, //lines - m: 0x156289, //mesh: extrude -} const lineMaterial = new THREE.LineBasicMaterial({ linewidth: 2, - color: color.l, + color: 0x156289, }) const pointMaterial = new THREE.PointsMaterial({ - color: color.p, + color: 0x156289, size: 4, }) -const DptObj = (n) => { - const ret = new THREE.Points( +export async function drawDimension() { + let pts; + // try { + + // pts = await this.awaitPts(2) + // } catch { + + // } + + pts = await this.awaitPts(2) + console.log('here', pts) + + + + + const p1 = new THREE.Vector2(...pts[0].geometry.attributes.position.array.slice(0, 2)) + const p2 = new THREE.Vector2(...pts[1].geometry.attributes.position.array.slice(0, 2)) + const p3 = new THREE.Vector2() + + const lineGeom = new THREE.Float32BufferAttribute(3 * 8, 3) + const line = new THREE.LineSegments( new THREE.BufferGeometry().setAttribute('position', - new THREE.Float32BufferAttribute(n || 3, 3) - ), - pointMaterial.clone() - ); - ret.name = 'p' + nid++ - - ret.matrixAutoUpdate = false; - ret.userData.constraints = [] - ret.userData.construction = true - - return ret -} - -const DlineObj = (n = 1) => { - const ret = new THREE.Line( - new THREE.BufferGeometry().setAttribute('position', - new THREE.Float32BufferAttribute(3 * (n + 1), 3) + lineGeom ), lineMaterial.clone() ); - ret.name = 'l' + nid++ - ret.matrixAutoUpdate = false; - ret.userData.constraints = [] - - return ret -} - - - -export async function drawDimensionPre() { - let [p1, p2] = await this.awaitPts(2) - - const lines = [ - DlineObj(), // 0: - DlineObj(), // 1: - DlineObj(), // 2: - ] - - const points = [ - p1, // 0: - DptObj(), // 1: | - DptObj(), // 2: | - DptObj(), // 3: | - DptObj(), // 4: | - DptObj(), // 5: | - DptObj(), // 6: | - p2, // 7: - ] - - this.constraints.set(++this.c_id, //??? - [ - 'pt_pt_distance', 10, - [p1.name, p2.name, -1, -1] - ] + const ptGeom = new THREE.Float32BufferAttribute(3, 3) + const point = new THREE.Points( + new THREE.BufferGeometry().setAttribute('position', + ptGeom + ), + pointMaterial.clone() ) - p1.userData.constraints.push(this.c_id) - p2.userData.constraints.push(this.c_id) - // this.updateOtherBuffers() - // console.log(points) - - const updatePoint = this.obj3d.children.length - for (let i = 1; i < points.length; i++) { - if (i % 2) { - this.constraints.set(++this.c_id, //??? increment investigation - [ - 'points_coincident', -1, - [points[i - 1].name, points[i].name, -1, -1] - ] - ) - points[i - 1].userData.constraints.push(this.c_id) - points[i].userData.constraints.push(this.c_id) + this.obj3d.children[0].add(line) + this.obj3d.children[0].add(point) - } else { // even + let dir, hyp, proj, perp, p1e, p2e, loc; + const onMove = (e) => { + loc = this.getLocation(e) + p3.set(loc.x, loc.y) - const toPush = [...points.slice(i - 1, i + 1), lines[i / 2 - 1]] + dir = p2.clone().sub(p1).normalize() + hyp = p3.clone().sub(p1) + proj = dir.multiplyScalar(hyp.dot(dir)) + perp = hyp.sub(proj) - this.linkedObjs.set(this.l_id, ['line', toPush.map(e => e.name)]) - for (let obj of toPush) { - obj.userData.l_id = this.l_id - } - this.l_id += 1 + p1e = p1.clone().add(perp).toArray() + p2e = p2.clone().add(perp).toArray() - if (i == 4 || i == 6) { - this.constraints.set(++this.c_id, //??? - [ - 'perpendicular', -1, - [-1, -1, lines[i / 2 - 2].name, lines[i / 2 - 1].name] - ] - ) - lines[i / 2 - 2].userData.constraints.push(this.c_id) - lines[i / 2 - 1].userData.constraints.push(this.c_id) - } + lineGeom.set(p1.toArray(), 0) + lineGeom.set(p1e, 3) - this.obj3d.add(...toPush) // not to be confused with this.topush + lineGeom.set(p1e, 6) + lineGeom.set(p2e, 9) + lineGeom.set(p2e, 12) + lineGeom.set(p2.toArray(), 15) - } + lineGeom.set(p1e, 18) + lineGeom.set(p3.toArray(), 21) - if (i<=3) { // move pts to their respective spots to spread them - points[i].geometry.attributes.position.set(p1.geometry.attributes.position.array) - } else { - points[i].geometry.attributes.position.set(p2.geometry.attributes.position.array) - } + ptGeom.set(p3.toArray()) + + line.geometry.attributes.position.needsUpdate = true; + point.geometry.attributes.position.needsUpdate = true; + sc.render() } - lines[0].userData.construction = true - lines[2].userData.construction = true + let onEnd, onKey; + + let ret = await new Promise((res, rej) => { + + onEnd = (e) => { + res(true) + this.updateOtherBuffers() + } + onKey = (e) => { + if (e.key == 'Escape') res(false) + } + this.canvas.addEventListener('pointermove', onMove) + this.canvas.addEventListener('pointerdown', onEnd) + window.addEventListener('keydown', onKey) + }) + console.log(ret, 'here') + this.canvas.removeEventListener('pointermove', onMove) + this.canvas.removeEventListener('pointerdown', onEnd) + this.canvas.removeEventListener('keydown', onKey) - this.updatePointsBuffer(updatePoint) - this.updateOtherBuffers() - - // line[1].geometry.attributes.position.set(p1.geometry.attributes.position.array) - // line[1].geometry.attributes.position.set(p1.geometry.attributes.position.array, 3) - - // line[0].geometry.attributes.position.set(p1.geometry.attributes.position.array) - // line[0].geometry.attributes.position.set(p2.geometry.attributes.position.array, 3) - - - // line[2].geometry.attributes.position.set(p2.geometry.attributes.position.array) - // line[2].geometry.attributes.position.set(p2.geometry.attributes.position.array, 3) - - + // this.constraints.set(++this.c_id, //??? + // [ + // 'pt_pt_distance', 10, + // [_p1.name, _p2.name, -1, -1] + // ] + // ) + // _p1.userData.constraints.push(this.c_id) + // _p2.userData.constraints.push(this.c_id) @@ -166,41 +126,3 @@ export async function drawDimensionPre() { return } -export function drawLine(mouseLoc) { - - - - - line.geometry.attributes.position.set(mouseLoc) - p1.geometry.attributes.position.set(mouseLoc) - - if (this.subsequent) { - - this.constraints.set(++this.c_id, - [ - 'points_coincident', -1, - [this.obj3d.children[this.obj3d.children.length - 2].name, p1.name, -1, -1] - ] - ) - - p1.userData.constraints.push(this.c_id) - this.obj3d.children[this.obj3d.children.length - 2].userData.constraints.push(this.c_id) - - } - - - - return [p1, p2, line]; -} - -export function drawLine2(mouseLoc, toPush) { - - const [p1, p2, line] = toPush - - p2.geometry.attributes.position.set(mouseLoc); - p2.geometry.attributes.position.needsUpdate = true; - p2.geometry.computeBoundingSphere(); - - line.geometry.attributes.position.set(mouseLoc, 3) - line.geometry.attributes.position.needsUpdate = true; -} \ No newline at end of file diff --git a/src/sketcher/drawEvents.js b/src/sketcher/drawEvents.js index 8a96b25..3d78ca8 100644 --- a/src/sketcher/drawEvents.js +++ b/src/sketcher/drawEvents.js @@ -1,34 +1,37 @@ import { drawArc, drawArc2 } from './drawArc' import { drawLine, drawLine2 } from './drawLine' +// import { drawDimension } from "./drawDimension"; export function drawOnClick1(e) { if (e.buttons !== 1) return this.canvas.removeEventListener('pointerdown', this.drawOnClick1) - const mouseLoc = this.getLocation(e); + this.canvas.addEventListener('pointermove', this.drawPreClick2) + this.canvas.addEventListener('pointerdown', this.drawOnClick2) + + const mouseLoc = this.getLocation(e).toArray(); if (this.mode == "line") { this.toPush = drawLine.call(this, mouseLoc) } else if (this.mode == "arc") { this.toPush = drawArc(mouseLoc) + } else if (this.mode == 'dim') { + this.curDimension = drawDimension.call(this) } this.updatePoint = this.obj3d.children.length this.obj3d.add(...this.toPush) - - this.linkedObjs.set(this.l_id, [this.mode, this.toPush.map(e=>e.name)]) + this.linkedObjs.set(this.l_id, [this.mode, this.toPush.map(e => e.name)]) for (let obj of this.toPush) { obj.userData.l_id = this.l_id } this.l_id += 1 - this.canvas.addEventListener('pointermove', this.drawPreClick2) - this.canvas.addEventListener('pointerdown', this.drawOnClick2) } export function drawPreClick2(e) { - const mouseLoc = this.getLocation(e); + const mouseLoc = this.getLocation(e).toArray(); if (this.mode == "line") { drawLine2(mouseLoc, this.toPush) @@ -36,7 +39,8 @@ export function drawPreClick2(e) { drawArc2(mouseLoc, this.toPush) } - this.obj3d.dispatchEvent({ type: 'change' }) + + sc.render() } export function drawOnClick2(e) { @@ -53,10 +57,29 @@ export function drawOnClick2(e) { this.drawOnClick1(e) } else if (this.mode == "arc") { - // this.canvas.addEventListener('pointermove', this.beforeClick_3) + this.toPush = [] + // this.canvas.addEventListener('pointermove', this.drawPreClick3) + // this.canvas.addEventListener('pointerdown', this.drawOnClick3) } + } + +export function drawPreClick3(e) { + const mouseLoc = this.getLocation(e).toArray(); + + sc.render() +} + + +export function drawOnClick3(e) { + if (e.buttons !== 1) return; + this.canvas.removeEventListener('pointermove', this.drawPreClick3); + this.canvas.removeEventListener('pointerdown', this.drawOnClick3); +} + + + export function drawClear() { if (this.mode == "") return @@ -69,5 +92,6 @@ export function drawClear() { this.obj3d.dispatchEvent({ type: 'change' }) this.subsequent = false + this.toPush = [] } } diff --git a/src/sketcher/rect.js b/src/sketcher/rect.js new file mode 100644 index 0000000..d5b8c96 --- /dev/null +++ b/src/sketcher/rect.js @@ -0,0 +1,81 @@ + const lines = [ + DlineObj(), // 0: + DlineObj(), // 1: + DlineObj(), // 2: + DlineObj(), // 2: + ] + + const points = [ + DptObj(), // 1: | + DptObj(), // 1: | + DptObj(), // 1: | + DptObj(), // 2: | + DptObj(), // 3: | + DptObj(), // 4: | + DptObj(), // 5: | + DptObj(), // 6: | + ] + + const updatePoint = this.obj3d.children.length + let prev = points[points.length - 1] + for (let i = 0, j = 0; i < points.length; i++) { + const cur = points[i] + if (i % 2 == 0) { + this.constraints.set(++this.c_id, //??? increment investigation + [ + 'points_coincident', -1, + [prev.name, cur.name, -1, -1] + ] + ) + cur.userData.constraints.push(this.c_id) + prev.userData.constraints.push(this.c_id) + } else { + const toPush = [prev, cur, lines[j]] + this.linkedObjs.set(this.l_id, ['line', toPush.map(e => e.name)]) + for (let obj of toPush) { + obj.userData.l_id = this.l_id + } + this.l_id += 1 + + if (j > 0) { + this.constraints.set(++this.c_id, //??? + [ + 'perpendicular', -1, + [-1, -1, lines[j - 1].name, lines[j].name] + ] + ) + lines[j - 1].userData.constraints.push(this.c_id) + lines[j].userData.constraints.push(this.c_id) + } + this.obj3d.add(...toPush) + + j += 1 + } + + if (i >= 3 && i <= 6) { + points[i].geometry.attributes.position.set(p2.geometry.attributes.position.array) + } else { + points[i].geometry.attributes.position.set(p1.geometry.attributes.position.array) + } + + prev = cur + } + + + this.constraints.set(++this.c_id, //??? increment investigation + [ + 'points_coincident', -1, + [p2.name, points[5].name, -1, -1] + ] + ) + points[5].userData.constraints.push(this.c_id) + p2.userData.constraints.push(this.c_id) + + this.constraints.set(++this.c_id, //??? increment investigation + [ + 'points_coincident', -1, + [p1.name, points[0].name, -1, -1] + ] + ) + points[0].userData.constraints.push(this.c_id) + p1.userData.constraints.push(this.c_id) \ No newline at end of file diff --git a/src/sketcher/threetest.js b/src/sketcher/threetest.js new file mode 100644 index 0000000..f33d7f9 --- /dev/null +++ b/src/sketcher/threetest.js @@ -0,0 +1,212 @@ + + + attribute float size; + attribute vec3 customColor; + + varying vec3 vColor; + + void main() { + + vColor = customColor; + + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); + + gl_PointSize = size * ( 300.0 / -mvPosition.z ); + + gl_Position = projectionMatrix * mvPosition; + + } + + + + + uniform vec3 color; + uniform sampler2D pointTexture; + + varying vec3 vColor; + + void main() { + + gl_FragColor = vec4( color * vColor, 1.0 ); + + gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord ); + + if ( gl_FragColor.a < ALPHATEST ) discard; + + } + + + + + + + + + import * as THREE from '../build/three.module.js'; + + import Stats from './jsm/libs/stats.module.js'; + + import { BufferGeometryUtils } from './jsm/utils/BufferGeometryUtils.js'; + + let renderer, scene, camera, stats; + + let particles; + + const PARTICLE_SIZE = 20; + + let raycaster, intersects; + let pointer, INTERSECTED; + + init(); + animate(); + + function init() { + + const container = document.getElementById( 'container' ); + + scene = new THREE.Scene(); + + camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 ); + camera.position.z = 250; + + // + + let boxGeometry = new THREE.BoxGeometry( 200, 200, 200, 16, 16, 16 ); + + // if normal and uv attributes are not removed, mergeVertices() can't consolidate indentical vertices with different normal/uv data + + boxGeometry.deleteAttribute( 'normal' ); + boxGeometry.deleteAttribute( 'uv' ); + + boxGeometry = BufferGeometryUtils.mergeVertices( boxGeometry ); + + // + + const positionAttribute = boxGeometry.getAttribute( 'position' ); + + const colors = []; + const sizes = []; + + const color = new THREE.Color(); + + for ( let i = 0, l = positionAttribute.count; i < l; i ++ ) { + + color.setHSL( 0.01 + 0.1 * ( i / l ), 1.0, 0.5 ); + color.toArray( colors, i * 3 ); + + sizes[ i ] = PARTICLE_SIZE * 0.5; + + } + + const geometry = new THREE.BufferGeometry(); + geometry.setAttribute( 'position', positionAttribute ); + geometry.setAttribute( 'customColor', new THREE.Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'size', new THREE.Float32BufferAttribute( sizes, 1 ) ); + + // + + const material = new THREE.ShaderMaterial( { + + uniforms: { + color: { value: new THREE.Color( 0xffffff ) }, + pointTexture: { value: new THREE.TextureLoader().load( 'textures/sprites/disc.png' ) } + }, + vertexShader: document.getElementById( 'vertexshader' ).textContent, + fragmentShader: document.getElementById( 'fragmentshader' ).textContent, + + alphaTest: 0.9 + + } ); + + // + + particles = new THREE.Points( geometry, material ); + scene.add( particles ); + + // + + renderer = new THREE.WebGLRenderer(); + renderer.setPixelRatio( window.devicePixelRatio ); + renderer.setSize( window.innerWidth, window.innerHeight ); + container.appendChild( renderer.domElement ); + + // + + raycaster = new THREE.Raycaster(); + pointer = new THREE.Vector2(); + + // + + stats = new Stats(); + container.appendChild( stats.dom ); + + // + + window.addEventListener( 'resize', onWindowResize ); + document.addEventListener( 'pointermove', onPointerMove ); + + } + + function onPointerMove( event ) { + + pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1; + pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1; + + } + + function onWindowResize() { + + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + + renderer.setSize( window.innerWidth, window.innerHeight ); + + } + + function animate() { + + requestAnimationFrame( animate ); + + render(); + stats.update(); + + } + + function render() { + + particles.rotation.x += 0.0005; + particles.rotation.y += 0.001; + + const geometry = particles.geometry; + const attributes = geometry.attributes; + + raycaster.setFromCamera( pointer, camera ); + + intersects = raycaster.intersectObject( particles ); + + if ( intersects.length > 0 ) { + + if ( INTERSECTED != intersects[ 0 ].index ) { + + attributes.size.array[ INTERSECTED ] = PARTICLE_SIZE; + + INTERSECTED = intersects[ 0 ].index; + + attributes.size.array[ INTERSECTED ] = PARTICLE_SIZE * 1.25; + attributes.size.needsUpdate = true; + + } + + } else if ( INTERSECTED !== null ) { + + attributes.size.array[ INTERSECTED ] = PARTICLE_SIZE; + attributes.size.needsUpdate = true; + INTERSECTED = null; + + } + + renderer.render( scene, camera ); + + } + + \ No newline at end of file diff --git a/src/utils/mouseEvents.js b/src/utils/mouseEvents.js index 2318a1e..79ade42 100644 --- a/src/utils/mouseEvents.js +++ b/src/utils/mouseEvents.js @@ -24,10 +24,10 @@ export function onHover(e) { let minDist = Infinity; for (let i = 0; i < hoverPts.length; i++) { if (!hoverPts[i].distanceToRay) continue; - if (hoverPts[i].distanceToRay < minDist) { + if (hoverPts[i].distanceToRay < minDist-0.0001) { minDist = hoverPts[i].distanceToRay idx = [i] - } else if (hoverPts[i].distanceToRay == minDist) { + } else if (Math.abs(hoverPts[i].distanceToRay - minDist) < 0.0001) { idx.push(i) } } @@ -38,17 +38,25 @@ export function onHover(e) { if (idx.length) { if (hoverPts[idx[0]].object != this.hovered[0]) { - const obj = this.hovered[this.hovered.length - 1] - if (obj && !this.selected.includes(obj)) { - obj.material.color.set(color[obj.name[0]]) + // const obj = this.hovered[this.hovered.length - 1] + // if (obj && !this.selected.includes(obj)) { + // obj.material.color.set(color[obj.name[0]]) + // } + + for (let x = 0; x < this.hovered.length; x++) { + const obj = this.hovered[x] + if (obj && !this.selected.includes(obj)) { + obj.material.color.set(color[obj.name[0]]) + } } + this.hovered = [] for (let x = 0; x < idx.length; x++) { - const i = idx[x] - this.hovered.push(hoverPts[i].object) + const obj = hoverPts[idx[x]].object + obj.material.color.set(color.hover) + this.hovered.push(obj) } - this.hovered[this.hovered.length - 1].material.color.set(color.hover) // console.log('render1') this.obj3d.dispatchEvent({ type: 'change' }) @@ -56,9 +64,17 @@ export function onHover(e) { } else { if (this.hovered.length) { - const obj = this.hovered[this.hovered.length - 1] - if (obj && !this.selected.includes(obj)) { - obj.material.color.set(color[obj.name[0]]) + // const obj = this.hovered[this.hovered.length - 1] + // if (obj && !this.selected.includes(obj)) { + // obj.material.color.set(color[obj.name[0]]) + // } + + for (let x = 0; x < this.hovered.length; x++) { + const obj = this.hovered[x] + // console.log(obj, 'here') + if (!this.selected.includes(obj)) { + obj.material.color.set(color[obj.name[0]]) + } } this.hovered = [] @@ -81,8 +97,8 @@ export function onPick(e) { this.canvas.addEventListener('pointerup', this.onRelease) } } else { - for (let obj of this.selected) { - // obj.material.color.set(0x555555) + for (let x = 0; x < this.selected.length; x++) { + const obj = this.selected[x] obj.material.color.set(color[obj.name[0]]) } this.obj3d.dispatchEvent({ type: 'change' }) @@ -91,21 +107,20 @@ export function onPick(e) { } export function onDrag(e) { - const mouseLoc = this.getLocation(e); - // for (let x = 0; x < this.hovered.length; x++) { - // const obj = this.hovered[x] - // this.ptsBuf.set( - // mouseLoc, - // this.objIdx.get(obj.name) * 3 - // ) - // } + // const obj = this.hovered[this.hovered.length-1] + // this.ptsBuf.set( + // this.getLocation(e).toArray(), + // this.objIdx.get(obj.name) * 3 + // ) - const obj = this.hovered[this.hovered.length-1] - this.ptsBuf.set( - mouseLoc, - this.objIdx.get(obj.name) * 3 - ) + for (let x = 0; x < this.hovered.length; x++) { + const obj = this.hovered[x] + this.ptsBuf.set( + this.getLocation(e).toArray(), + this.objIdx.get(obj.name) * 3 + ) + } this.solve() this.obj3d.dispatchEvent({ type: 'change' }) diff --git a/src/utils/shared.js b/src/utils/shared.js index 0e04b1b..eb681ea 100644 --- a/src/utils/shared.js +++ b/src/utils/shared.js @@ -59,30 +59,41 @@ const lineObj = (n = 1) => { async function awaitPts(n) { let references = this.selected.slice() - if (references.length == 0) { - while (references.length < n) { - let pt; - try { - pt = await new Promise((res, rej) => { - this.canvas.addEventListener('pointerdown', () => res(this.hovered[0]), { once: true }) - window.addEventListener('keydown', (e) => rej(e), { once: true }) - }) - - if (pt.name[0] == 'p') { - references.push(pt) - } else if (pt.name[0] == 'd') { - references = [pt] - break; + let end = false; + while (references.length < n && !end) { + let pt; + let onEnd, onKey; + try { + pt = await new Promise((res, rej) => { + onKey = (e) => { + if (e.key != 'Escape') return + console.log(e.key, 'key') + rej() + } + onEnd = (e) => { + res(this.hovered[0]) } - } catch (e) { - if (e.key == 'Escape') { - console.log('cancelled') - return; - } + this.canvas.addEventListener('pointerdown', onEnd) + window.addEventListener('keydown', onKey) + }) + + if (pt.name[0] == 'p') { + references.push(pt) + } else if (pt.name[0] == 'd') { + references = [pt] + end = true; } + + } catch (e) { + console.log('cancelled') + end = true; } + + window.removeEventListener('keydown', onKey) + this.canvas.removeEventListener('pointerdown', onEnd) } + return references }