반응형

beginShape를 통해 하트 모양의 도형을 그린 후 빙글빙글 회전하면서 이동하는 예제입니다.

See the Pen p5.js Heart moving and rotates by myhappyman (@myhappyman) on CodePen.

 

해당 예제를 만들어보면서 발생했던 문제점과 해결방법을 공유해 봅니다.

x, y 값을 통해 기본도형(원, 사각형)등의 생성 위치를 변경하면서 이동하는 애니메이션을 처리 예제를 먼저 만들어봤었는데, 이때는 큰 문제가 없었습니다.

추가적으로 회전 기능을 추가하면서 문제가 발생했습니다.

중심점이 계속 변경되면서 깜빡거리는 현상이 발생하는데, 일반 도형의 경우 모드가 존재하여 rectMode(CENTER)를 처리 후 rotate()와 좌표 변경으로 애니메이션을 처리하였습니다.

 

하트모양을 만들기 위해 beginShape()를 통해 하트를 구성하고 그려냈는데, 중심점을 고정하는 메소드가 존재하지 않았습니다. 이상태에서 회전과 이동을 생성점을 통해 처리하게 되면 빙글빙글 돌면서 정상적으로 돌지 않는걸 볼 수 있습니다.

이런 현상을 방지하기 위해 중앙점을 고정으로 (0, 0) 처리하였고, 이동은 translate() 메소드를 통해 이동 좌표를 별개로 처리하여 해결하였습니다.

 

아래는 작성한 샘플소스이며 ES6 문법으로 작성되었습니다.

class Heart{
    constructor(){
        this.x = 0;
        this.y = 0;
        this.mx = random(0, width);
        this.my = random(0, height);
        this.speedRange = [-2,-1,1,2];
        this.xSpeed = random(this.speedRange);
        this.ySpeed = random(this.speedRange);
        this.size = random(55);
        this.degree = random(10);

        this.red = random(255);
        this.green = random(255);
        this.blue = random(255);
    }

    createHeart(){
        push();
        translate(this.mx, this.my);
        rotate(PI * this.degree);

        noStroke();
        noSmooth();
        fill(this.red, this.green, this.blue);
        beginShape();
        vertex(this.x, this.y);
        bezierVertex(this.x - this.size / 2, this.y - this.size / 2, this.x - this.size, this.y + this.size / 3, this.x, this.y + this.size);
        bezierVertex(this.x + this.size, this.y + this.size / 3, this.x + this.size / 2, this.y - this.size / 2, this.x, this.y);            
        endShape(CLOSE);
        pop();
    }

    move(){
        if(this.mx < 0 || this.mx > width){
            this.xSpeed *= -1;
        }
        if(this.my < 0 || this.my > height){
            this.ySpeed *= -1; 
        }

        this.mx += this.xSpeed;
        this.my += this.ySpeed;
        this.degree = this.degree + 0.01;
    }       
}

let heartArr = [];
function setup(){
    var w = window.innerWidth
    var h = window.innerHeight
    createCanvas(w, h);

    for(i=0; i<150; i++){
        heartArr.push(new Heart());
    }
}

function draw(){
    background(11);

    heartArr.forEach(function(r){
        r.createHeart();
        r.move();   
    });        
}

 

 

반응형