CONFETTI ๋ฐœ์‚ฌ๐ŸŽ‡

๊น€์‚ฟ๊ฐ“์˜์‹ฑ์ž‰๋žฉยท2023๋…„ 8์›” 21์ผ
1

โœจ Vanilla JS ์ฝ˜ํŽ˜ํ‹ฐ ํšจ๊ณผ

vanilla JS ์ปดํฌ๋„ŒํŠธํ˜• ์›น๊ณผ WEBPACK ํ™˜๊ฒฝ์—์„œ ์ฝ˜ํŽ˜ํ‹ฐ ์ปดํฌ๋„ŒํŠธ ํšจ๊ณผ๋ฅผ ์จ๋ณด์ž!!

โœ… ์„ค์น˜ํ•ด์•ผ ํ•  ๊ฒƒ๋“ค

๋จผ์ € ์ฝ˜ํŽ˜ํ‹ฐ ํšจ๊ณผ๊ฐ€ Promise ๊ธฐ๋Šฅ์„ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฝ˜ํŽ˜ํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ž‘ promise ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด ๋ฐ›์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

$ npm install promise
$ npm install --save canvas-confetti

โœ… Webpack์— ์„ค์ •ํ•˜๊ธฐ

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด ๋ฐ›์•˜์œผ๋‹ˆ๊นŒ ๋นŒ๋“œ์‹œ์— ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์›นํŒฉ์นœ๊ตฌํ•œํ…Œ๋„ ์•Œ๋ ค์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ webpack.config.js ํŒŒ์ผ์— ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.

//webpack.config.js ํŒŒ์ผ ์ƒ๋‹จ์ž…๋‹ˆ๋‹ค!!
const path = require('path');
const confetti = require('canvas-confetti');
const MyPromise = require('some-promise-library');

//webpack.config.js ํŒŒ์ผ ํ•˜๋‹จ์— ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ ์–ธํ•ด๋†“์Šต๋‹ˆ๋‹ค.
...
        // loadash
        new LodashModuleReplacementPlugin(),
    ],
};
...
// ์ œ์ผ ํ•˜๋‹จ
confetti.Promise = MyPromise;

โœ… ์ฝ˜ํŽ˜ํ‹ฐ ํšจ๊ณผ๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ธฐ

import { Component } from '../core';
import confetti from 'canvas-confetti';

export default class Confetti extends Component {
    render() {
        
        this.el.innerHTML = /*html*/ `
            <canvas id="my-canvas"></canvas>
        `;
      	// ํ•ด๋‹น divํƒœ๊ทธ ์ˆจ๊ธฐ๊ธฐ
        this.el.style.position = 'fixed';
      	this.el.sylte.height = '0px';
      	
      	// ์บ”๋ฒ„์Šค ์ง€์ •ํ•˜๊ธฐ
      	const myCanvas = document.querySelector('canvas');
      	
      	// ์ฝ˜ํŽ˜ํ‹ฐ ์บ”๋ฒ„์Šค์— ์ง€์ •ํ•˜๊ธฐ
        const myConfetti = confetti.create(myCanvas, {
            resize: true,
            useWorker: true,
        });

      	// ์ฝ˜ํŽ˜ํ‹ฐ ํšจ๊ณผ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ
        myConfetti({
            particleCount: 100,
            spread: 160,
            zIndex: 5,
            origin: {
                y: 0.6,
            },
        });
    }
}

์ฝ˜ํŽ˜ํ‹ฐ ํšจ๊ณผ๋ฅผ ์‹คํ–‰ํ•  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

innerHTML์„ ํ™œ์šฉํ•˜์—ฌ canvas ํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

์ดํ›„ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ position ๊ฐ’์„ fixed๋กœ ๋‘์–ด์„œ canvas๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” div tag๋ฅผ ์ˆจ๊น๋‹ˆ๋‹ค (๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š” ๐Ÿ˜ฅ)

์ดํ›„ canvas์š”์†Œ์— ์ฝ˜ํŽ˜ํ‹ฐ๋ฅผ ๋ฐฐ์ •ํ•ด์ค๋‹ˆ๋‹ค.

์ฒซ๋ฒˆ์งธ parameter์—๋Š” canvas ์š”์†Œ๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

๋‘๋ฒˆ์งธ parameter์—๋Š” option ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

  • resize : viewport์˜ ๊ธธ์ด๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์บ”๋ฒ„์Šค์˜ ํฌ๊ธฐ๋ฅผ ์ž๋™์œผ๋กœ resizeํ•ด์ค๋‹ˆ๋‹ค.

  • useWorker : ํ•ด๋‹น ์ฝ˜ํŽ˜ํ‹ฐ ํšจ๊ณผ๊ฐ€ ํ•ญ์ƒ ๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์กฐ๊ธˆ ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๋ฉด ์›น์—์„œ ํŽ˜์ด์ง€๋ฅผ ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝํ•˜๋˜์ง€๊ฐ„์— ๊ทธ๋ƒฅ ํšจ๊ณผ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰ ํŽ˜์ด์ง€์˜ ๋™์ž‘์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๊ณ  ๋ฐฐ๊ฒฝํ™”๋ฉด์ฒ˜๋Ÿผ ์‹คํ–‰๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์˜ต์…˜์„ ์ง€์ •ํ•œ ์ฝ˜ํŽ˜ํ‹ฐํšจ๊ณผ๋ฅผ ์ด์ œ ๋ถˆ๋Ÿฌ ์˜ฌ ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค.

์ฝ˜ํŽ˜ํ‹ฐํšจ๊ณผ์— ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์†์„ฑ๋“ค์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
๋‹ค์–‘ํ•œ ํšจ๊ณผ๋“ค ๋ณด๊ธฐ

โœ… ์ฝ˜ํŽ˜ํ‹ฐ ํšจ๊ณผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

// ์›ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์ƒ๋‹จ์—์„œ ์ฝ˜ํŽ˜ํ‹ฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
import Confetti from '../components/Confetti.js';

// ์ดํ›„ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
this.el.append(new Confetti().el);

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ตฌํ˜„์ด ์™„์„ฑ๋ฉ๋‹ˆ๋‹ค!!
addEventListener์„ ํ™œ์šฉํ•ด์„œ append๋กœ ๋ถˆ๋Ÿฌ์™€์„œ ํšจ๊ณผ๋ฅผ ์ค„ ์ˆ˜ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค!! ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด์„œ ๊ฐ„๋‹จํ•œ ์ฝ˜ํŽ˜ํ‹ฐํšจ๊ณผ๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด์„ธ์š”!!

profile
์‹œ์Šคํ…œ ๊ฐœ๋ฐœ์— ์‹œ๊ฐ„์„ ์•„๋ผ์ง€ ๋ง์ž

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

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด