threejs 拖拽 画矩形

发布时间 2023-04-03 19:59:51作者: 虎虎生威啊
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

export function initThree() {
  THREE.Object3D.DefaultUp.set(0, 0, 1);

  var scene = new THREE.Scene();
  var camera = new THREE.PerspectiveCamera(
    60,
    window.innerWidth / window.innerHeight,
    1,
    1000000
  );
  camera.position.set(0, 0, 10);
  var renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setClearColor(0x999999);
  document.body.appendChild(renderer.domElement);

  var controls = new OrbitControls(camera, renderer.domElement);
  controls.mouseButtons = {
    LEFT: null as unknown as THREE.MOUSE,
    // LEFT: MOUSE.ROTATE,
    RIGHT: THREE.MOUSE.RIGHT,
    MIDDLE: THREE.MOUSE.MIDDLE,
  };

  var grid = new THREE.GridHelper(20, 40);
  grid.geometry.rotateX(Math.PI / 2);
  grid.position.set(0, 0.05, 0);
  scene.add(grid);

  var mouse = new THREE.Vector3();

  var started = false;

  var MAX_POINTS = 5;

  // geometry
  var geometry = new THREE.BufferGeometry();
  // attributes
  var positions = new Float32Array(MAX_POINTS * 3); // 3 vertices per point
  geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
  // geometry.setIndex()
  // draw range
  var drawCount = 3; // draw the first 2 points, only
  geometry.setDrawRange(0, drawCount);
  // material
  var material = new THREE.LineBasicMaterial({ color: 0xff0000 });
  // line
  var line = new THREE.Line(geometry, material);
  scene.add(line);

  var corePositions = line.geometry.attributes.position.array as any;

  var started = false;

  drawRect();

  function drawRect() {
    // geometry
    geometry = new THREE.BufferGeometry();
    // attributes
    positions = new Float32Array(MAX_POINTS * 3); // 3 vertices per point
    geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
    // draw range
    drawCount = 3; // draw the first 2 points, only
    geometry.setDrawRange(0, drawCount);

    // material
    material = new THREE.LineBasicMaterial({ color: 0xff0000 });
    // line
    line = new THREE.Line(geometry, material);
    scene.add(line);

    corePositions = line.geometry.attributes.position.array;
    // console.log(corePositions);

    window.addEventListener("mousedown", onMouseDown, false);
    window.addEventListener("mousemove", onMouseMove, false);
    window.addEventListener("mouseup", onMouseUp, false);
  }

  render();

  //Functions
  function onMouseDown(event: any) {
    if (!started) {
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
      mouse.z = 0;

      const raycaster = new THREE.Raycaster();
      var plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);

      raycaster.setFromCamera(mouse, camera);
      var intersects = new THREE.Vector3();
      let planeIntersect = raycaster.ray.intersectPlane(plane, intersects)!;

      console.log(planeIntersect);

      //Pt1
      corePositions[0] = planeIntersect.x;
      corePositions[1] = planeIntersect.y;
      corePositions[2] = 0;

      // console.log(corePositions)

      line.geometry.setDrawRange(1, drawCount++);
      line.geometry.attributes.position.needsUpdate = true;

      started = true;
    }
  }

  function onMouseMove(event: any) {
    if (started) {
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
      mouse.z = 0;

      const raycaster = new THREE.Raycaster();
      var plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);

      raycaster.setFromCamera(mouse, camera);
      var intersects = new THREE.Vector3();
      let planeIntersect = raycaster.ray.intersectPlane(plane, intersects)!;

      // console.log(planeIntersect)
      // console.log(corePositions);

      //Pt2
      corePositions[3] = planeIntersect.x;
      corePositions[4] = corePositions[1];
      corePositions[5] = 0;
      //Pt3
      corePositions[6] = planeIntersect.x;
      corePositions[7] = planeIntersect.y;
      corePositions[8] = 0;
      //Pt4
      corePositions[9] = corePositions[0];
      corePositions[10] = planeIntersect.y;
      corePositions[11] = 0;
      //Pt5
      corePositions[12] = corePositions[0];
      corePositions[13] = corePositions[1];
      corePositions[14] = 0;

      line.geometry.setDrawRange(0, 5);
      line.geometry.attributes.position.needsUpdate = true;
    }
  }

  function onMouseUp(event: any) {
    if (started) {
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
      mouse.z = 0;

      const raycaster = new THREE.Raycaster();
      var plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);

      raycaster.setFromCamera(mouse, camera);
      var intersects = new THREE.Vector3();
      let planeIntersect = raycaster.ray.intersectPlane(plane, intersects)!;

      console.log(corePositions);
      console.log(planeIntersect);

      // --------------------
      geometry = new THREE.BufferGeometry();
      geometry.attributes.position = new THREE.BufferAttribute(
        corePositions,
        3
      );

      geometry.setIndex([0, 1, 2, 2, 3, 0]);

      let mesh = new THREE.Mesh(
        geometry,
        new THREE.MeshBasicMaterial({
          color: 0xfefefe,
          side: THREE.DoubleSide,
          transparent: true,
          opacity: 0.1,
        })
      );

      scene.add(mesh);

      window.removeEventListener("mousemove", onMouseMove);
      window.removeEventListener("mousedown", onMouseDown);
      window.removeEventListener("mouseup", onMouseUp);

      started = false;
    }
  }

  function render() {
    requestAnimationFrame(render);
    renderer.render(scene, camera);
  }
}