Wave Clone

Chenยท2024๋…„ 6์›” 6์ผ
1

Canvas

๋ชฉ๋ก ๋ณด๊ธฐ
6/11
post-thumbnail

sin๋Š” ์ฃผ๋กœ ํŒŒ๋„์˜ ๋†’์ด ํ‘œํ˜„, cos์€ ํŒŒ๋„์˜ ์‹œ์ž‘์ ์„ ํ‘œํ˜„ํ•˜๋Š” ๋ฐ์— ์ฃผ๋กœ ์‚ฌ์šฉ๋จ.

๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฑด, ๊ทธ๋ฆฌ๊ณ ์ž ํ•˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ขŒํ‘œ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ! ์ฆ‰, stageWidth, stageHeight ๊ต‰์žฅํžˆ ์ค‘์š”

์ข…๋ฏผ๋‹˜ ์›จ์ด๋ธŒ ํด๋ก !
์ด๊ฑด ๋”๋”๋”๋” ๊ณต๋ถ€ํ•ด์•ผ๊ฒ ๋‹ค
์–ด๋ ต๋‹ค! ๊ทผ๋ฐ ์žฌ๋ฐŒ๋‹ค
์ฝ”๋“œ๋Š” ๋˜ ๋ด์•ผ๊ฒ ๋‹ค


export class Point {
  constructor(x, y) {
    /*  ์›จ์ด๋ธŒ๋ฅผ ๊ทธ๋ฆฌ๋Š”๋ฐ ์ด์šฉ๋˜๋Š” ์ ๋“ค์€
            ์•„๋ž˜ ์œ„๋กœ ๋žœ๋คํ•˜๊ฒŒ offset ๊ฐ’์„ ๊ฐ€์ง
        */
    this.x = x;
    this.y = y;
    this.fixedY = y; // ๊ธฐ๋ณธ Y ์ค‘์‹ฌ
    this.speed = 0.1;
    this.cur = 0;
    this.max = Math.random() * 100 + 150;
  }

  update() {
    this.cur += this.speed;

    this.y = this.fixedY + Math.sin(this.cur) * this.max;
  }
}

โœจ ๊ถ๊ธˆ์ฆ ํ•ด๊ฒฐ

1. max ๋ฒ”์œ„ ์ง€์ •

this.max = Math.random() * 100 + 150;


this.y = this.fixedY + Math.sin(this.cur) * this.max;

2. point์˜ ๊ฐ„๊ฒฉ

๋จผ์ €, totalPoints๋ฅผ ๋„˜๊ฒจ์ค˜์„œ ๋ช‡๊ฐœ์˜ ํฌ์ธํŠธ๋ฅผ ์ƒ์„ฑํ•  ๊ฒƒ์ธ์ง€ ๊ฐ๊ฐ Wave ๋งˆ๋‹ค ์ •์˜ํ•ด์ฃผ๊ธฐ

๊ฐ„๊ฒฉ = ์ด stageWidth์—์„œ totalPoints ๋ฅผ ๋‚˜๋ˆˆ๊ฐ’

this.pointGap = this.stageWidth / (this.totalPoints - 1);

๊ฐ„๊ฒฉ๋งŒํผ, ๊ฐ„๊ฒฉ์— ๋งž์ถฐ์„œ point๋ฅผ ํ™”๋ฉด์— ๊ทธ๋ ค์ฃผ๊ธฐ

init ํ•จ์ˆ˜ ์žฌ์„ค์ •

๊ธฐ์กด ver.

 // init() ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œ์ผœ Point ์ƒ์„ฑ
    init() {
        // ์ƒ์„ฑ๋œ point์—๋Š” ์œ„ resize ํ•จ์ˆ˜์—์„œ ์ •์˜ํ•œ ํ™”๋ฉด์ค‘์•™์— ๋‚˜ํƒ€๋‚˜๋„๋ก
        this.point = new Point(this.centerX, this.centerY);
    }

์žฌ์„ค์ • ver.

init() {
    this.points = [];

    for(let i = 0; i < this.totalPoints; i++){
        const point = new Point(
            this.index + i,
            this.pointGap * i,
            this.centerY,
        );
        this.points[i] = point;
    }
}

์—…๋ฐ์ดํŠธ๋œ point๊ฐœ์ˆ˜์— ๋งž์ถ”์–ด drawํ•จ์ˆ˜๋„ ์—…๋ฐ์ดํŠธ

๊ธฐ์กด ver.

// ์•„๊นŒ ์˜ˆ์‹œ๋กœ ๋นจ๊ฐ„ ๊ณต 

draw(ctx) {
    ctx.beginPath();
    ctx.fillStyle = '#ff0000';

    this.point.update();

    ctx.arc(this.point.x, this.point.y, 30, 0, Math.PI * 2);
    ctx.fill();
}

์—…๋ฐ์ดํŠธ ver.

draw(ctx) {
        ctx.beginPath();
        ctx.fillStyle = this.color; // ํ˜„์žฌ wave color๋กœ

        let prevX = this.points[0].x;
        let prevY = this.points[0].y;

        ctx.moveTo(prevX, prevY);

        for (let i = 0; i < this.totalPoints; i++) {
            if (i < this.totalPoints - 1) {
                this.points[i].update();
            }

            const cx = (prevX + this.points[i].x) / 2;
            const cy = (prevY + this.points[i].y) / 2;

            ctx.lineTo(cx, cy);

            prevX = this.points[i].x;
            prevY = this.points[i].y;
        }

        ctx.lineTo(prevX, prevY); // ์ค‘๊ฐ„๊ฐ’
        ctx.lineTo(this.stageWidth, this.stageHeight);
        ctx.lineTo(this.points[0].x, this.stageHeight);
        ctx.fill();
        ctx.closePath();
    }
ctx.lineTo(cx, cy);


ctx.quadraticCurveTo(prevX, prevY, cx, cy);

profile
ํ˜„์‹ค์ ์ธ ๋ชฝ์ƒ๊ฐ€

0๊ฐœ์˜ ๋Œ“๊ธ€