반응형

3D 정육면체 박스 제어하기

P5.js 사용하여 면에 이미지를 넣고 회전을 시키며 마우스에 따라 회전되도록 제어해보겠습니다.

 

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="./p5.min.js"></script>
    <title>Document</title>
</head>
<body>
    <div class="controller">
        <div>
            W : <input type="range" name="width" value="120" step="10" min="10" max="250"><br/>
            H : <input type="range" name="height" value="120" step="10" min="10" max="250"><br/>
            D : <input type="range" name="depth" value="120" step="10" min="10" max="250"><br/>
        </div>
        <div>
            <button type="button" id="rotate">회전</button>
            <button type="button" id="stop">멈춤</button>
        </div>
    </div>
</body>
</html>

 

p5.js

 

var size = [];
var sizeName = ["width", "height", "depth"];
var img;
var rotate = true;
var rotateValue = 1;


window.onload = function(){
    sizeName.forEach(function(s, i){
        size[i] = document.querySelector("input[name="+s+"]").value;
        document.querySelector("input[name="+s+"]").addEventListener("change", function(){
            size[i] = this.value;
        });
    });

    document.getElementById("rotate").addEventListener("click", function(){
        rotate = true;
    });

    document.getElementById("stop").addEventListener("click", function(){
        rotate = false;
    });
}

function preload(){
    img = loadImage("image/ggome.jpg");
}

function setup(){
    createCanvas(710, 400, WEBGL);
    img.loadPixels();
}

function draw() {
    //배경색상
    background(50);

    //질감
    specularMaterial(183, 240, 177);

    //빛
    ambientLight(255, 255, 255);
    directionalLight(50, 50, 50, -frameCount, -frameCount, -1);
    noStroke();

    //마우스 컨트롤 - z축은 고정(Scroll 방지)
    orbitControl(1,1,0);    

    //박스 생성 및 회전
    push();
    if(rotate){
        rotateValue++;
        if(rotateValue > 10000000){
            rotateValue = 1;
        }
    }
    rotateX(rotateValue * 0.01);
    rotateY(rotateValue * 0.01);
    texture(img);
    box(size[0], size[1], size[2]);
    pop();
}

* 이미지 로드기능에서 교차출처(Cors) 오류가 발생하므로 서버에서 구동하셔야합니다.

 

range바에 따라 정육면체로 생성된 박스가 사이즈가 변경되는 모습을 볼 수 있고, 회전, 멈춤 버튼에 따라 회전이 멈추기도 재시작되기도 하는 모습을 볼 수 있습니다.

 

p5 메소드들이 워낙 잘 만들어져 있어서 간단하게 몇개의 메소드만으로 이러한 기능이 만들어지는 것을 볼 수 있습니다.

 

기능을 정리해보겠습니다.

  1. 먼저 3D형태의 박스를 생성하기 위해 캔버스 생성시 WEBGL을 추가합니다.
  2. 박스 겉면에 사진을 입히기 위해 이미지를 미리 로드합니다.(preload() 메소드에서 loadImage())
  3. draw메소드에서 background는 캔버스의 배경을 칠하기 위해 처리하였습니다.
  4. specularMaterial은 질감 표현인데, 이미지를 넣으면서 큰 차이가 없게 되었습니다.
  5. ambientLight는 빛의 밝기입니다 255, 255, 255는 가장 밝으면 0, 0, 0 가장 어둡기에 박스가 검은색으로 표현됩니다.
  6. directionalLight는 특정 방향으로 물체에 쬐는 빛의 색상 및 밝기 입니다.
  7. orbitControl은 마우스 회전등의 이벤트를 제어합니다 3번째 파라미터를 0으로 처리하여 스크롤이 동작하지 않도록 막았습니다.
  8. box(넓이, 높이, 깊이)를 통해 3D 형태의 박스가 생성됩니다.
  9. texture에 먼저 로드해온 이미지를 넣어 이미지를 입힙니다.
  10. 실시간 애니메이션 효과를 위해 rotateX, Y에 값을 처리하였습니다.

 

 

 

반응형