ThreeJS로 육각형 그려서 마우스로 크기 바꾸기

 

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Three.js Cube Resize</title>
<style>
  body { margin:0; overflow:hidden; }
  .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/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="c"></canvas>

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

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

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

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

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
};

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

// ================= Cube =================
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0x00ffcc });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// light
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 10, 5);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.4));

// ================= Raycaster =================
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();

let resizing = false;
let lastX = 0;

// 마우스 위치 → Raycast
function updateMouse(e) {
  const rect = canvas.getBoundingClientRect();
  mouse.x = ((e.clientX - rect.left) / rect.width) * 2 - 1;
  mouse.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
}

// ================= Mouse Events =================

// 큐브 클릭 → 크기 조절 모드
canvas.addEventListener("mousedown", (e) => {
  if (e.button !== 0) return;

  updateMouse(e);
  raycaster.setFromCamera(mouse, camera);
  const intersects = raycaster.intersectObject(cube);

  if (intersects.length > 0) {
    resizing = true;
    controls.enabled = false;
    lastX = e.clientX;
  }
});

// 드래그 → 큐브 크기 변경
canvas.addEventListener("mousemove", (e) => {
  if (!resizing) return;

  const dx = e.clientX - lastX;
  lastX = e.clientX;

  const scaleDelta = dx * 0.01; // 민감도 조절

  cube.scale.x = Math.max(0.1, cube.scale.x + scaleDelta);
  cube.scale.y = Math.max(0.1, cube.scale.y + scaleDelta);
  cube.scale.z = Math.max(0.1, cube.scale.z + scaleDelta);
});

// 종료
canvas.addEventListener("mouseup", () => {
  resizing = 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