[패스트캠퍼스] 챌린 10일차 3. 1

2023. 3. 1. 22:07개발 일지/패스트캠퍼스\챌린지

Part2. Canvas 챕터 02 - 6 스파크 작업과 기타 꾸미기 강의 시작! 
 

강의 시작!

지난 강의에서는 꼬리가 올라오면서 점차 사라지고 꼬리가 사라진 자리에서 폭죽이 터지는 효과를 구현하는 방법에 대해서 알아봤다. 이번 강의에서는 지난 시간에 미리 준비해놨던 색 변경과 기타 꾸미기 작업까지 구현하는 방법에 대해 알아보는 시간이다.
우선 js 폴더에 Spark.js 파일을 생성하고 CanvasOption을 상속받는 Spark calss를 선언한다. 그리고 그 안에 constructor와 update, draw 함수를 선언하고 constructor가 받는 인자로 x, y, opacity를 설정해준다. 그리고 draw에서 반지름 2인 원을 그려주도록 구현하고 fillStyle을 'gold'로 설정한다.
그리고 Spark class를 본격적으로 사용하기 위해서 index.js에서 Canvas class의 constructor 안에서 sparks 배열 변수를 선언하고 폭죽이 터질 때, 스파크들이 따라 나오도록 frame 함수 안에서 동작하는 particles의 반복문 안에서 random 값을 활용하여 스파크가 생성되는 수가 어느 정도 조절하면서 생성되게 한다.
아래는 Spark class와 spark를 생성하는 코드이다.

import CanvasOption from "./CanvasOption.js";

export default class Spark extends CanvasOption{
    constructor(x, y, opacity){
        super();
        this.x = x;
        this.y = y;
        this.opacity = opacity;
    }

    update() {
        this.opacity -= 0.01;
    }

    draw() {
        this.ctx.beginPath();
        this.ctx.arc(this.x, this.y, 1, 0, Math.PI * 2);
        this.ctx.fillStyle = `gold`;
        this.ctx.fill();
        this.ctx.closePath();
    }
}
...
import Spark from "./js/Spark.js";

class Canvas extends CanvasOption {
    constructor() {
        ...
        this.sparks = [];
    }

	...

    render() {
    	...
        const frame = () => {
			...
            this.particles.forEach((particle, index) => {
            	...
                if(Math.random() < 0.05) this.sparks.push(new Spark(particle.x, particle.y, 0.3));
                ...
            });

            this.sparks.forEach((spark, index) =>  {
                spark.update();
                spark.draw();

                if(spark.opacity < 0) this.sparks.splice(index, 1);
            });
            ...
    }
}

이렇게 하면 일단은 폭죽 파티클이 터지면서 스파크 효과를 어색하지만 얻을 수 있게 된다. 다음으로는 흔들거리며 올라가긴 하지만 다소 밋밋한 느낌의 꼬리에 스파크 효과와 함께 색을 랜덤하게 주는 방법을 작업한다.
우선 임의의 색으로 변화를 주기 위해서는 색의 값을 랜덤하게 줘야 하는데 기존 rgb값을 랜덤하게 주는 방법도 있지만 좀 더 간단한 방법으로는 hsl 색상 표기법을 이용하는 것이다. hsl은 간략하게 설명하자면 Hue, Saturation, Lightness의 앞자를 따온것으로 색상, 채도, 밝기로 색을 표기하는 것이다. 여기서 우리가 조절할 값은 색상 값으로 0~360까지 색상을 표기할 수 있다. 그 후에 꼬리의 색상 표기법을 hsla로 변경하고 color 멤버 변수도 colorDeg로 변경해준다.
그리고 tails의 반복문 안에서 스파크가 꼬리를 따라 생성되도록 구현을 해주면 된다. 하지만 스파크가 꼬리를 따라 생성이 되기만 하기때문에 좀 더 효과를 주기 위해서 좌우로 흩어지면서 아래로 서서히 떨어지도록 구현을 해주고 투명도도 꼬리의 투명도를 따라갈 수 있도록 수정해주면서 꼬리의 색상과 스파크의 색상을 맞춰주면 스파크를 흩뿌리며 올라가는 꼬리의 모습을 확인할 수 있다. 이때, Spark class를 수정해줘야 하는데 construct가 vx, vy, colorDeg를 받도록 수정해줘야 한다.
아래는 수정한 Spark class와 Tail class, index.js 파일의 코드이다.

...
createTail() {
	...
    const colorDeg = randomNumBetween(0, 360);
    this.tails.push(new Tail(x, vy, colorDeg));
}
...
    this.tails.forEach((tail, index) => {
        tail.update();
        tail.draw();

        for(let i = 0; i < Math.round(-tail.vy * 0.5); i++){
            const vx = randomNumBetween(-5, 5) * 0.03;
            const vy = randomNumBetween(-5, 5) * 0.03;
            const opacity = Math.min(-tail.vy, 0.5);
            this.sparks.push(new Spark(tail.x, tail.y, vx, vy, opacity, tail.colorDeg))
        }

        if(tail.vy > -0.7){
            this.tails.splice(index, 1);
            this.createParticles(tail.x, tail.y, tail.colorDeg);
        }
    });
...
import CanvasOption from "./CanvasOption.js";

export default class Spark extends CanvasOption{
    constructor(x, y, vx, vy, opacity, colorDeg){
        super();
        this.x = x;
        this.y = y;
        this.vx = vx;
        this.vy = vy;
        this.opacity = opacity;
        this.colorDeg = colorDeg;
    }

    update() {
        this.opacity -= 0.01;

        this.x += this.vx;
        this.y += this.vy;
    }

    draw() {
        this.ctx.beginPath();
        this.ctx.arc(this.x, this.y, 1, 0, Math.PI * 2);
        this.ctx.fillStyle = `hsla(${this.colorDeg}, 100%, 65%, ${this.opacity})`;
        this.ctx.fill();
        this.ctx.closePath();
    }
}
...
export default class Tail extends CanvasOption  {
	...
    draw() {
        this.ctx.fillStyle = `hsla(${this.colorDeg}, 100%, 65%, ${this.opacity})`;
        ...
    }
}

그리고 파티클도 꼬리의 색상을 받아서 꼬리의 색과 비슷한 색으로 생성되도록 수정을 한다. 그리고 마지막으로 폭죽이 터질때 하늘이 번쩍이 듯이 화면이 번쩍일 수 있도록 화면의 색상이 폭죽이 터질때 마다 밝아지도록 수정을 하게 되면 불꽃놀이 파티클이 완성된다.
아래는 Particle class와 particle  생성 로직, 화면을 덧칠해주는 부분을 수정한 코드이다.

...
export default class Particle extends CanvasOption{
    constructor(x, y, vx, vy, opacity, colorDeg){
    	...
        this.colorDeg = colorDeg;
    }
    ...
    draw() {
        this.ctx.fillStyle = `hsla(${this.colorDeg}, 100%, 65%, ${this.opacity})`;
        ...
    }
}
...
class Canvas extends CanvasOption {
	...
    createParticles(x, y, colorDeg) {
        const PARTICLE_NUM = 400;
        for (let i = 0; i < PARTICLE_NUM; i++){
        	...
            const _colorDeg = randomNumBetween(-20, 20) + colorDeg
            this.particles.push(new Particle(x, y, vx, vy, opacity, _colorDeg));
        }
    }

    render() {
    	...
        const frame = () => {
        	...
            this.ctx.fillStyle = `rgba(255, 255, 255, ${this.particles.length / 10000})`;
            this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
			...
            this.tails.forEach((tail, index) => {
            	...
                if(tail.vy > -0.7){
                    this.tails.splice(index, 1);
                    this.createParticles(tail.x, tail.y, tail.colorDeg);
                }
            });
            ...
    }

}
...
강의 결과물


이렇게 폭죽 파티클을 완성했다. 길다면 길고 짧다면 짧은 시간이었지만 폭죽 터지는 효과를 보고 있으니 완성에 대한 축하를 받는거 같아서 뿌듯했다. 다음 강의 때도 완성된 결과물을 보고 뿌듯한 마음이 생길거 같아 기대가 된다.

강의 끝!


http://bit.ly/3Y34pE0

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.