How can a square track the mouse?

import * as THREE from 'three'
import { WEBGL } from './webgl'
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"

if (WEBGL.isWebGLAvailable()) {
  let markup = null;

  const markupMouse = new THREE.Vector2();
	const markupPoint = new THREE.Vector3();
	

  //장면
  const scene = new THREE.Scene();
  scene.background = new THREE.Color(0xffffff);
  //카메라
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.y = 1;
  camera.position.z = 2;
  //렌더러
  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  //OrbitControls 추가
  const controls = new OrbitControls(camera,renderer.domElement);
  controls.minDistance = 2;
  controls.update();
  //매쉬
  const geometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
  const material = new THREE.MeshStandardMaterial({
    color: 0x999999
  });
  const cube = new THREE.Mesh(geometry, material);
  cube.position.y = 0.5;
  scene.add(cube);

  //바닥
  const planeGeoMetry = new THREE.PlaneGeometry(20,20,1,1);
  const planeMaterial = new THREE.MeshStandardMaterial({color:0xffffff});
  const plane = new THREE.Mesh(planeGeoMetry,planeMaterial);
  plane.rotation.x = -0.5*Math.PI;
  plane.position.y = -0.2;
  scene.add(plane);

  //빛
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
  directionalLight.position.set(1, 1, 1);
  scene.add(directionalLight);
  function animate() {
    requestAnimationFrame( animate );
    controls.update();
    renderer.render( scene, camera );
  }
  animate();
  function render(time) {
    time *= 0.001;  // convert time to seconds

    cube.rotation.x = time;
    cube.rotation.y = time;

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);

  /**
	 * 마우스 포인터
	 * @param event
	 * @returns {Promise<void>}
	 */
	async function getMousePointer({event}){
		markupMouse.x = (event.clientX / window.innerWidth ) * 2 - 1;
		markupMouse.y = -( event.clientY / window.innerHeight ) * 2 + 1;
		markupPoint.set(markupMouse.x,markupMouse.y,0);
	}
  async function createRectangle({start,end,color}){
		const distance = camera.position.distanceTo( new THREE.Vector3(0,0,0) )-1;
		const points = [
			new THREE.Vector3( start.x, start.y, distance ) ,
			new THREE.Vector3( start.x, end.y, distance ) ,
			new THREE.Vector3( end.x, end.y, distance ) ,
			new THREE.Vector3( end.x, start.y, distance ),
			new THREE.Vector3( start.x, start.y, distance )
		];
		const geometry = new THREE.BufferGeometry().setFromPoints( points );
		const material = new THREE.LineBasicMaterial({
			color: color?color:"rgb(255,0,0)"
		});
		const line = new THREE.Line( geometry, material );
		line.quaternion.copy(camera.quaternion);
		scene.add(line);
		markup = line;

		const corner = new THREE.Vector2();
		const cornerPoint = new THREE.Vector3();
		let planePosition = controls.target;
		let normal = planePosition.clone().normalize()
		normal.sub( camera.position )

		const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, planePosition);
		const raycaster = new THREE.Raycaster();

		corner.set(0, 0); // NDC of the bottom-left corner
		raycaster.setFromCamera(corner, camera);
		raycaster.ray.intersectPlane(plane, cornerPoint);
		line.position.copy(cornerPoint);//.add(new Vector3(0, 0, 1));
	}
  window.addEventListener("mousemove", async (event) => {
    if(markup){
      scene.remove(markup);
    }
    await getMousePointer({event})
    let markupEndPoint = markupPoint.clone();
		markupEndPoint.set(markupPoint.x+0.1,markupPoint.y+0.1,0);
		await createRectangle({start:markupPoint,end:markupEndPoint});
  });
  
} else {
  var warning = WEBGL.getWebGLErrorMessage()
  document.body.appendChild(warning)
}


As you move toward the edge of the screen, the red square moves away from the mouse.

I want the red square exist to right behind the cursor.

Hi!
Why simply not make a div element follow the mouse cursor?

1 Like

For now it will follow the mouse but will markup

Just in case, the example of what I was talking about: https://codepen.io/prisoner849/pen/NWLVRyK

1 Like

This is the spot even if the camera perspective changes(or anothor bigger screen) . I want the markup to change as the camera view changes.

Is there any example or video, that demonstrates the desired effect?

Nice example, could potentially set the css of the target square…

pointer-events:none;
touch-action:none;

to accommodate mobile devices and not block orbit controls when touch is started from within the target (unless that was desired)

It’s difficult to tell what you’re trying to do, @prisoner849’s suggestion seems like the most reasonable solution to what’s been outlined as using a square in 3D space would come with pitfalls.

Essentially to do what has been suggested but in 3D space you could add the square to the camera (once, not to recreate it every mouse gesture) to ensure it always follows with the cameras transforms, set it deeper in z space as to ensure it’s seen by the camera and then unproject a vector at the desired z depth to attain world to screen space coordinates which the square can track to the mouse with…

Pitfall: the square in 3D space will always become distorted as it reaches the edges of the camera frustum due to fov foreshortening, in short, as the object reaches the edge of the screen it is being viewed from a greater oblique angle and will appear skewed, depending on the fov size this can be to the extreme point that the square visually seems no longer central to the mouse position when in actually it is… besides no longer being square…

1 Like

I want model markup like this vedio.

I’m afraid I still don’t follow the thing you want to achieve :thinking:
What specific part ot the video you refer to?

are you watch vedio

If you want to have frames, then I still stand for the option with div elements.
But you know better what you want, so I wish you luck with your project. :handshake: