마우스로 선 그리기 예제이다.

 

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Three.js Line Drawing (importmap)</title>
<style>
  body { margin:0; overflow:hidden; }
  #threeCanvas { display:block; }
  .info {
    position: fixed;
    top: 10px;
    left: 10px;
    background: rgba(0,0,0,0.6);
    color: white;
    padding: 8px 12px;
    font-size: 13px;
    border-radius: 6px;
  }
</style>
<script type="importmap">
{
  "imports": {
    "three": "https://unpkg.com/three@0.160.0/build/three.module.js",
    "three/examples/jsm/": "https://unpkg.com/three@0.160.0/examples/jsm/"
  }
}
</script>
</head>
<body>

<div class="info">
  좌클릭 드래그: 선 그리기<br>
  우클릭 드래그: 화면 회전<br>
  휠: 줌
</div>

<canvas id="threeCanvas"></canvas>

<script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

const canvas = document.getElementById("threeCanvas");

// ================= Scene =================
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x202020);

const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.set(5, 5, 10);

const renderer = new THREE.WebGLRenderer({ canvas, antialias:true });
renderer.setSize(window.innerWidth, window.innerHeight);

// ================= Controls =================
const controls = new OrbitControls(camera, canvas);
controls.enableDamping = true;
controls.mouseButtons = {
  LEFT: null,
  MIDDLE: THREE.MOUSE.DOLLY,
  RIGHT: THREE.MOUSE.ROTATE
};

// ================= Grid =================
scene.add(new THREE.GridHelper(20, 20));
scene.add(new THREE.AxesHelper(5));

// ================= Line Drawing =================
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);

let drawing = false;
let line;
let points = [];

function getMousePoint(event) {
  const rect = canvas.getBoundingClientRect();
  mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
  mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);
  const pos = new THREE.Vector3();
  raycaster.ray.intersectPlane(plane, pos);
  return pos;
}

canvas.addEventListener("mousedown", (e) => {
  if (e.button !== 0) return;

  drawing = true;
  controls.enabled = false;

  points = [];
  const start = getMousePoint(e);
  points.push(start.clone());

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

canvas.addEventListener("mousemove", (e) => {
  if (!drawing) return;

  const pos = getMousePoint(e);
  if (points.length === 1) points.push(pos.clone());
  else points[1] = pos.clone();

  line.geometry.setFromPoints(points);
});

canvas.addEventListener("mouseup", (e) => {
  if (e.button !== 0) return;
  drawing = false;
  controls.enabled = true;
});

// ================= Resize =================
window.addEventListener("resize", () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

// ================= Render =================
function animate() {
  requestAnimationFrame(animate);
  controls.update();
  renderer.render(scene, camera);
}
animate();
</script>
</body>
</html>

 

728x90

+ Recent posts