<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - animation - groups</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
<script type="importmap">
{
"imports": {
"three": "../build/three.module.js",
"three/addons/": "./jsm/"
}
}
</script>
<button type="button" id="draw-line" style="position: absolute;top:0;left:0;">draw line</button>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
let isDraw = false;
let startPoint = null;
let line = null;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
scene.add( new THREE.AxesHelper( 20 ) );
scene.background = new THREE.Color( "#ffffff" );
document.body.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
camera.position.set( 0, 0, 5 );
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
animate();
function createStrokeGeometry({start,end,linewidth}){
let direction = new THREE.Vector3().subVectors(end, start).normalize();
let leftDirection = new THREE.Vector3(-direction.y, direction.x, 0);
let halfThickness = linewidth / 2;
let points = [
new THREE.Vector3().addScaledVector(leftDirection, halfThickness).add(start),
new THREE.Vector3().addScaledVector(leftDirection, -halfThickness).add(start),
new THREE.Vector3().addScaledVector(leftDirection, -halfThickness).add(end),
new THREE.Vector3().addScaledVector(leftDirection, halfThickness).add(end)
];
let geometry = new THREE.BufferGeometry();
let vertices = new Float32Array([
points[0].x, points[0].y, points[0].z,
points[1].x, points[1].y, points[1].z,
points[2].x, points[2].y, points[2].z,
points[3].x, points[3].y, points[3].z,
]);
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
let indices = new Uint16Array([
0, 1, 2,
0, 2, 3,
]);
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
return geometry;
}
function createStroke({start,end,linewidth}){
if(line){
scene.remove(line);
}
line = new THREE.Mesh( createStrokeGeometry({start,end,linewidth}), new THREE.MeshBasicMaterial( { color: "#FF0000", side: THREE.DoubleSide } ) );
scene.add(line);
}
function getMousePosition(clientX, clientY) {
const rect = renderer.domElement.getBoundingClientRect();
const x = ((clientX - rect.left) / rect.width) * 2 - 1;
const y = -((clientY - rect.top) / rect.height) * 2 + 1;
const mouseVector = new THREE.Vector3(x, y, 0.5);
mouseVector.unproject(camera);
return mouseVector;
}
window.addEventListener('mousedown', ()=>{
startPoint = getMousePosition(event.clientX, event.clientY);
createStroke({start:startPoint.clone(),end:startPoint.clone(),linewidth:0.06});
});
window.addEventListener('mouseup', ()=>{
startPoint = null;
});
window.addEventListener('mousemove', ()=>{
if (isDraw===true&&startPoint) {
const endPoint = getMousePosition(event.clientX, event.clientY);
createStroke({start:startPoint.clone(),end:endPoint.clone(),linewidth:0.06});
}
});
document.getElementById("draw-line").addEventListener("click",()=>{
isDraw = !isDraw;
controls.enabled = !isDraw;
if(isDraw===true){
document.getElementById("draw-line").innerText="end draw";
}else{
document.getElementById("draw-line").innerText="draw line";
}
});
</script>
</body>
</html>
I want to draw a straight line, but when I move the mouse, the axis of the line looks slightly off.
How can I fix it? The one above is my code.