#instructions {
color: white;
position: absolute;
padding: 20px;
top: 10px;
font-family: monospace;
width: 100%;
height: 100px;
border-radius: 20px;
}
.measurementLabel {
font-family: monospace;
background-color: rgb(36, 35, 35);
color: rgb(255, 255, 255);
font-size:20px;
font-weight: 500;
padding: 2px;
font-family: "Roboto";
border-radius: 2px;
}
#button-click{
color:white;
background-color: red;
border-radius: 10px;
display: flex;
flex-direction: column;
justify-content: center;
top: 300px;
margin: 20px;
height: 40px;
}
.orientation-helper-in-scene {
position: fixed;
bottom: 50px;
right: 50px;
width: 300px;
height: 300px;
z-index: 0;
}
</style>
<script type="importmap">
{
"imports": {
"three": "./three.module.js"
}
}
</script>
</head>
<body id="container">
<div id="instructions">
Press CTRL + Left Mouse Click to start drawing a line. <br />Continue to hold CTRL and Left Mouse
Click again to mark the end of the line.
<button id="button-click" value="off">Measurements </button>
</div>
<script type="module">
import * as THREE from './three.module.js';
import { OrbitControls } from './OrbitControls.js';
import { GLTFLoader } from './GLTFLoader.js';
import { RGBELoader } from './RGBELoader.js';
import { CSS2DRenderer, CSS2DObject } from './CSS2DRenderer.js';
import { OrientationHelper } from './OrientationHelper.js';
// import { TransformControls } from './TransformControls.js';
const scene = new THREE.Scene()
var light = new THREE.SpotLight()
light.position.set(12.5, 12.5, 12.5)
light.castShadow = true
light.shadow.mapSize.width = 1024
light.shadow.mapSize.height = 1024
scene.add(light)
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.x = 15
camera.position.y = 15
camera.position.z = 15
const renderer = new THREE.WebGLRenderer()
renderer.physicallyCorrectLights = true;
renderer.shadowMap.enabled = true
renderer.outputEncoding = THREE.sRGBEncoding
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
const labelRenderer = new CSS2DRenderer()
labelRenderer.setSize(window.innerWidth, window.innerHeight)
labelRenderer.domElement.style.position = 'absolute'
labelRenderer.domElement.style.top = '0px'
labelRenderer.domElement.style.pointerEvents = 'none'
document.body.appendChild(labelRenderer.domElement)
const controls = new OrbitControls(camera, renderer.domElement)
controls.enabled=true
/* controls.touches = {
ONE: THREE.TOUCH.ROTATE,
TWO: THREE.TOUCH.DOLLY_PAN
}*/
const container=document.getElementById("container")
const pickableObjects = new Array()
const loader = new GLTFLoader()
loader.load(
'./ErgonomicTableScene_Nov_22_22.glb',
function (gltf) {
gltf.scene.traverse(function (child) {
if (child.isMesh) {
let m = child
switch (m.name) {
case 'Plane':
m.receiveShadow = true
break
default:
m.castShadow = true
}
pickableObjects.push(m)
}
})
scene.add(gltf.scene)
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
},
(error) => {
console.log(error)
}
)
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
labelRenderer.setSize(window.innerWidth, window.innerHeight)
render()
}
const axesHelper = new THREE.AxesHelper(0.5);
scene.add( axesHelper );
// orientation helper
const ohOptions = {
className: 'orientation-helper-in-scene'
},
ohLabels = {
px: 'East',
nx: 'West',
pz: 'South',
nz: 'North',
py: 'Sky',
ny: 'Ground'
};
let _lastCLick = Date.now();
let orientationHelper = new OrientationHelper( camera, controls, ohOptions, ohLabels );
orientationHelper.addEventListener( 'change', onOrientationHelperChange );
orientationHelper.addEventListener( 'click', onOrientationHelperClick );
document.body.appendChild(orientationHelper.domElement);
const raycaster = new THREE.Raycaster()
let intersects
const touchs= new THREE.Vector2()
let ctrlDown = false
let lineId = 0
let line
let drawingLine = false
let pickpoint=null
const measurementLabels = {}
let buttonClicks=document.getElementById("button-click")
buttonClicks.onclick=function(event){
if(buttonClicks.value==="off"){
console.log("Measurement Mode Active")
buttonClicks.value="on"
controls.enableRotate=false;
controls.enableZoom = true;
controls.enablePan = true;
buttonClicks.style.backgroundColor="green"
window.addEventListener('touchstart', touchon,false)
window.addEventListener('touchend', touchoff,false)
document.addEventListener('touchmove', onDocumentTouchMove,false)
renderer.domElement.addEventListener('pointerdown',onlyClick,false)
//document.addEventListener('mousemove', onDocumentMouseMove, false)
}else if(buttonClicks.value==="on"){
console.log("Measurement Mode Inactive")
controls.enabled=true
buttonClicks.value='off'
buttonClicks.style.backgroundColor="red"
scene.remove(line)
scene.remove(measurementLabels[lineId])
window.removeEventListener('touchstart', touchon,false)
window.removeEventListener('touchend', touchoff,false)
document.removeEventListener('touchmove', onDocumentTouchMove,false)
renderer.domElement.removeEventListener('pointerdown',onlyClick,false)
}
}
/* var mylatesttap;
function doubletap() {
var now = new Date().getTime();
var timesince = now - mylatesttap;
if((timesince < 600) && (timesince > 0)){
// double tap
console.log("double tap")
}else{
// too much time to be a doubletap
}
mylatesttap = new Date().getTime();
}*/
//var clickTimer=null
function touchon(e) {
//console.log("local co-ordinate",renderer.domElement.getBoundingClientRect())
// console.log("TouchPlaced :",'x: ' + event.touches[0].clientX + ', y: ' + event.touches[0].clientY)
// console.log("container co-ordinates :",geometry.domElement.getBoundingClientRect())
// console.log(document.body.appendChild(renderer.domElement));
console.log("Touch Start")
if(e.type==="touchstart"){
/* if (clickTimer == null) {
clickTimer = setTimeout(function () {
clickTimer = null;
// document.removeEventListener('touchmove', onDocumentTouchMove,false)
//renderer.domElement.removeEventListener('pointerdown',onlyClick,false)
}, 300)*/
ctrlDown=true;
controls.enableRotate=false;
controls.enableZoom = true;
controls.enablePan = true;
renderer.domElement.style.cursor = 'crosshair'
let rect= renderer.domElement.getBoundingClientRect();
let x9 = event.touches[0].clientX - rect.left;
let y9 = event.touches[0].clientY - rect.top;
console.log("Canvas Full Coordinates",rect.top, rect.left, rect.width, rect.height);
console.log("Canvas Screen Coordinations"," x: " + x9, " y: " + y9);
//console.log("Single Touch")
// var ndcX = (event.touches[0].screenX / window.innerWidth) * 2 - 1;
//var ndcY = -(event.touches[0].screenY / window.innerHeight) * 2 + 1;
//console.log("new cor",ndcX,ndcY)
//console.log(" Touch Start Screen Co-ordinates",touchs)
// console.log(e.touches.length)
// raycaster.setFromCamera(touchs, camera)
//console.log("raycaster")
//intersects = raycaster.intersectObjects(pickableObjects, false)
//console.log(intersects)
// Cast the ray and get the intersects array
/*raycaster.setFromCamera(touchs, camera);
intersects = raycaster.intersectObjects(pickableObjects,false);
// Get the first intersection point
const intersection = intersects[0];
// Get the UV coordinates of the intersection point
const uv = intersection.uv;
// Get the minimum and maximum UV coordinates
const minU = Math.min(0,uv.x);
const maxU = Math.max(uv.x);
const minV = Math.min(0,uv.y);
const maxV = Math.max(uv.y);
console.log("Min X",minU,"Min Y",minV)
console.log("Max X",maxU,"Max Y",maxV)*/
}
}
/* else {
clearTimeout(clickTimer);
clickTimer = null;
// document.removeEventListener('touchmove', onDocumentTouchMove,false)
//renderer.domElement.removeEventListener('pointerdown',onlyClick,false)
console.log("Double Touch")
}*/
function touchoff(event) {
// console.log("Touch End Screen Co-ordinates",touchs)
ctrlDown = false
//controls.enabled=true
// controls.enableZoom=true
renderer.domElement.style.cursor = 'pointer'
if (drawingLine) {
//delete the last line because it wasn't committed
// scene.remove(line)
//scene.remove(measurementLabels[lineId])
drawingLine = false
controls.enableRotate=false
event.preventDefault()
// let P = intersects[0].point
if(intersects.length>0){
raycaster.setFromCamera(touchs, camera)
intersects = raycaster.intersectObjects(pickableObjects, false)
console.log("TouchOff World Co-ordinates:",intersects[0].point)
}
console.log("Completed Drawing Line")
}
}
function onlyClick(event) {
touchs.x= (event.clientX / renderer.domElement.clientWidth) * 2 - 1;
touchs.y= -(event.clientY / renderer.domElement.clientHeight) * 2 + 1;
if (!ctrlDown) {
raycaster.setFromCamera(touchs, camera)
//console.log("raycaster")
intersects = raycaster.intersectObjects(pickableObjects, false)
if (intersects.length > 0) {
if (!drawingLine) {
//start the line
console.log("!Drawline")
const points = []
points.push(intersects[0].point)
points.push(intersects[0].point.clone())
const geometry = new THREE.BufferGeometry().setFromPoints(points)
line = new THREE.LineSegments(
geometry,
new THREE.LineBasicMaterial({
color: 0xff0000,
// transparent: true,
//opacity: 1,
linewidth:3,
// depthTest: false,
// depthWrite: true,
// dashed: false,
//alphaToCoverage: true,
})
)
event.preventDefault()
line.frustumCulled = false
scene.add(line)
const measurementDiv = document.createElement('div')
measurementDiv.className = 'measurementLabel'
measurementDiv.innerText = '0.0m'
const measurementLabel = new CSS2DObject(measurementDiv)
measurementLabel.position.copy(intersects[0].point)
measurementLabels[lineId] = measurementLabel
scene.add(measurementLabels[lineId])
// let P = intersects[0].point
// console.log("Touch Start World Co-ordinates",intersects[0].point)
let rect= renderer.domElement.getBoundingClientRect();
let x9 = event.clientX - rect.left;
let y9 = event.clientY - rect.top;
//console.log(rect.top, rect.left, rect.width, rect.height);
//console.log(" x: " + x9, " y: " + y9);
// Get the first intersection point
const intersection = intersects[0];
// Get the UV coordinates of the intersection point
const uv = intersection.uv;
console.log("Intersect UV Screen Coordinates",uv.x,uv.y)
//console.log("Intersect Length",intersects.length)
drawingLine = true
// console.log("raycaster-1")
} else {
//finish the line
const positions = line.geometry.attributes.position.array
positions[3] = intersects[0].point.x
positions[4] = intersects[0].point.y
positions[5] = intersects[0].point.z
line.geometry.attributes.position.needsUpdate = true
lineId++
drawingLine = false
//console.log("raycaster-2")
}
}
}
}
function onDocumentTouchMove(e) {
// console.log("Touch Move")
//event.preventDefault()
touchs.x= (event.targetTouches[0].clientX / renderer.domElement.clientWidth) * 2 - 1;
touchs.y= -(event.targetTouches[0].clientY / renderer.domElement.clientHeight) * 2 + 1;
/* if (event.targetTouches.length === 2) {
let hypo1 = Math.hypot((event.targetTouches[0].pageX - event.targetTouches[1].pageX),
(event.targetTouches[0].pageY - event.targetTouches[1].pageY));
if (hypo === undefined) {
hypo = hypo1;
}
}*/
if (drawingLine) {
raycaster.setFromCamera(touchs, camera)
intersects = raycaster.intersectObjects(pickableObjects, false)
if (intersects.length > 0) {
const positions = line.geometry.attributes.position.array
const v0 = new THREE.Vector3(positions[0], positions[1], positions[2])
const v1 = new THREE.Vector3( intersects[0].point.x, intersects[0].point.y, intersects[0].point.z )
positions[3] = intersects[0].point.x
positions[4] = intersects[0].point.y
positions[5] = intersects[0].point.z
line.geometry.attributes.position.needsUpdate = true
const distance = v0.distanceTo(v1)
measurementLabels[lineId].element.innerText = distance.toFixed(2) + 'm'
measurementLabels[lineId].position.lerpVectors(v0, v1, 0.5)
// console.log("Touchmove:", measurementLabels[lineId].element.innerText = distance.toFixed(2) + 'm')
}
}
}
//orbitcontrol helper
function onOrientationHelperChange( ev ) {
translateCamera( ev.direction );
}
function onOrientationHelperClick( ev ) {
// Simulate double-click (less than 250ms)
let nClick = Date.now();
if ( nClick - _lastCLick < 250 ) {
translateCamera( ev.normal );
}
_lastCLick = nClick;
}
function translateCamera( direction ) {
controls.enabled = false;
const dist = camera.position.distanceTo( controls.target ),
newCameraPos = controls.target.clone().add( direction.multiplyScalar( dist ) );
camera.position.set(newCameraPos.x, newCameraPos.y, newCameraPos.z);
controls.enabled = true;
}
var animate = function () {
requestAnimationFrame(animate)
controls.update()
render()
}
function render() {
labelRenderer.render(scene, camera)
renderer.render(scene, camera)
camera.updateMatrixWorld()
}
animate()
window.focus()
</script>
</body>

I am not getting room min and max x,y values .
body {
overflow: hidden;
margin: 0px;
}