[Canvas] Video

ChenΒ·2024λ…„ 6μ›” 6일
0

Canvas

λͺ©λ‘ 보기
5/11
post-thumbnail

μΊ”λ²„μŠ€μ—μ„œ video μ“°λŠ” 이유

μΊ”λ²„μŠ€λŠ” 기본적으둜 ν”½μ…€ λ‹¨μœ„λ‘œ μ‘°μž‘μ΄ κ°€λŠ₯ν•œλ°, λΉ„λ””μ˜€λ„ λ§ˆμ°¬κ°€μ§€λ‘œ κ·Έλž˜ν”½μ μœΌλ‘œ μ‘°μž‘ κ°€λŠ₯
( ex. ) λΉ„λ””μ˜€ ν”½μ…€λ‹¨μœ„λ‘œ μͺΌκ°œμ„œ λ’€μ„žκ±°λ‚˜.. λ“±

이미지 λŒ€μ‹ μ— λΉ„λ””μ˜€λ₯Ό κ·Έλ¦° κ±°λ‹€!! λ˜‘κ°™λ‹€

κ²°κ΅­ μΊ”λ²„μŠ€λŠ”

그리고 λ‹€ μ§€μš°κ³ 

그리고 또 λ‹€μ‹œ μ§€μš°κ³ 


1. Video Basic

drawImage() ν•  수 μžˆλŠ” 것

  1. 이미지
  2. λΉ„λ””μ˜€
  3. μΊ”λ²„μŠ€

canplaythrough 이벀트

μž¬μƒ μ€€λΉ„ 되면 탁! μž¬μƒν•˜λŠ”

html λΉ„λ””μ˜€ νƒœκ·ΈλŠ” 숨기기

video {
    position: absolute;
    width: 0;
    height: 0;
}
const canvas = document.querySelector('.canvas');
const ctx = canvas.getContext('2d');
let canPlayState = false;

ctx.textAlign = 'center';
ctx.fillText('λΉ„λ””μ˜€ λ‘œλ”© 쀑..', 300, 200);

const videoElem = document.querySelector('.video');
videoElem.addEventListener('canplaythrough', render);

function render() {
    ctx.drawImage(videoElem, 0, 0, 600, 400);
    requestAnimationFrame(render);
}

2. video μœ„ ν…μŠ€νŠΈ

currentTime

λΉ„λ””μ˜€μ˜ ν˜„μž¬ μž¬μƒμ‹œκ°„

for (let i = 0; i < messages.length; i++) {
  if (videoElem.currentTime > messages[i].time) {
    ctx.fillText(messages[i].message, messages[i].x, messages[i].y);
  }
}

const canvas = document.querySelector('.canvas');
const ctx = canvas.getContext('2d');
ctx.font = 'bold 50px serif';
ctx.fillStyle = 'red';

const videoElem = document.querySelector('.video');
videoElem.addEventListener('canplaythrough', render);

const messages = [
    { time: 1, message: '1 γ…‹γ…‹', x: 100, y: 100 },
    { time: 3, message: '2 γ…Žγ…Ž', x: 300, y: 300 },
    { time: 5, message: '3 γ…Šγ…Š', x: 400, y: 200 },
];

function render() {
    console.log(videoElem.currentTime);
    ctx.drawImage(videoElem, 0, 0, 600, 400);

    for (let i = 0; i < messages.length; i++) {
      if (videoElem.currentTime > messages[i].time) {
        ctx.fillText(messages[i].message, messages[i].x, messages[i].y);
      }
    }

    requestAnimationFrame(render);
}

3. video 색상 λ³€ν™˜

getImageData

μ•„ν•˜!! ν”½μ…€λ‹¨μœ„ 색상 μΆ”μΆœμ€ μ΄λ ‡κ²Œ ν•˜λ©΄ λ˜λŠ”κ΅¬λ‚˜

λ³΄μ΄μ‹œλŠ”κ°€! λ¬΄ν•œ λ Œλ”λ§!! 마 이게 λΉ„λ””μ˜€λ‹€
κ²°κ΅­ μΊ”λ²„μŠ€λŠ”
그리고 λ‹€ μ§€μš°κ³ 
그리고 또 λ‹€μ‹œ μ§€μš°κ³ 

getImageData.data

console.log(imageData.data);

// ..ㅁ...λ¨Έλ…Έ λ°°μ—΄μ›μ†Œ 9만 6천개

μ™œ 9만 6천개??

w: 600, h: 400, rgba라 4개
=> 24만 ν”½μ…€ * 4

  • μ—¬κΈ°μ„œλŠ” rgba의 μ•ŒνŒŒμ±„λ„(a)λŠ” λ‹€ λ§₯μ‹œλ©ˆμ΄λ‹ˆκΉŒ i * 4λŠ” 항상 255
console.log(imageData.data[0]);

// μ•„ν•˜!!

  • 각 i * 4 ν•œ 것듀은 λ‹€ 각각 r,g,b μƒ‰μƒλ“€μ˜ λ§₯μ‹œλ©ˆμœΌλ‘œ λŒμ–΄μ˜¬λ €μ£ΌλŠ” 것!

  • 즉, λ²„νŠΌμ„ λˆ„λ₯΄λ©΄ colorValue 값이 λ°”λ€Œλ„λ‘ μ„€μ •ν•΄μ•Ό 함!!


putImageData()

putImageData(imageData, dx, dy)
putImageData(imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)

MDN Docs

function render() {
    ctx.drawImage(videoElem, 0, 0, 600, 400);
    imageData = ctx.getImageData(0, 0, 600, 400);
    leng = imageData.data.length / 4;

    for (let i = 0; i < leng; i++) {
        switch (colorValue) {
            case 'red':
                imageData.data[i * 4 + 0] = 255;
                break;
            case 'green':
                imageData.data[i * 4 + 1] = 255;
                break;
            case 'blue':
                imageData.data[i * 4 + 2] = 255;
                break;
        }
    }

    ctx.putImageData(imageData, 0, 0);
    requestAnimationFrame(render);
}

❀️ rgbλŠ” μ™œ 256개라며!! μ™œ μ•„λ‹ˆλΌ 255일까?

λͺ…심해!!! μƒλŒ€λŠ” 컴퓨터닀!!

starts from the

0


λ²„νŠΌ colorValue μ„ΈνŒ… (feat. 이벀트 μœ„μž„)

  • 각 λ²„νŠΌμ€ data-color= "λ«„λ«„" 값을 κ°€μ§„λ‹€

이벀트 μœ„μž„

  • λͺ¨λ“  λ²„νŠΌμ— addEventListener 을 ν•˜μ§€ μ•Šκ³ , λΆ€λͺ¨ Elm인 div.btns에 이벀트 μœ„μž„
<div class="btns">
            <button class="btn" data-color="red">R</button>
            <button class="btn" data-color="green">G</button>
            <button class="btn" data-color="blue">B</button>
            <button class="btn" data-color="">Reset</button>
        </div>
const btnsElem = document.querySelector('.btns');
for (let i = 0; i < leng; i++) {
    switch (colorValue) {
        case 'red':
            imageData.data[i * 4 + 0] = 255;
            break;
        case 'green':
            imageData.data[i * 4 + 1] = 255;
            break;
        case 'blue':
            imageData.data[i * 4 + 2] = 255;
            break;
    }
}

    ctx.putImageData(imageData, 0, 0);
    requestAnimationFrame(render);
}

btnsElem.addEventListener('click', function (e) {
    colorValue = e.target.getAttribute('data-color');
});

1단계. 클릭된 λ²„νŠΌ(이벀트 μœ„μž„λ¨!!) 의 data-color을 κ°€μ Έμ˜¨λ‹€
2단계. colorValue 값을 λ³€κ²½ν•œλ‹€
3단계. render()λŠ” 계속 μΌμ–΄λ‚˜κ³  μžˆμœΌλ―€λ‘œ, ν΄λ¦­μ‹œ μƒˆλ‘œ λ³€κ²½λœ colorValue 값에 따라 switchλ¬Έ μž‘λ™
4단계. ν•΄λ‹Ή 색상 수치 λ§₯μ‹œλ©ˆμœΌλ‘œ 올렀주기

생각

  • ν”½μ…€ λ‹¨μœ„λ‘œ λ’€μ§‘μ–΄ μ„žμ–΄λ§žμΆ”κΈ°
  • ν”½μ…€ 날라가기 (x, y) λΌλ©΄μ›”λ“œμ»΅

전체 μ½”λ“œ

    // 색상 λ³€ν™˜
    const canvas = document.querySelector('.canvas');
    const ctx = canvas.getContext('2d');

    const videoElem = document.querySelector('.video');
    videoElem.addEventListener('canplaythrough', render);

    const btnsElem = document.querySelector('.btns');

    let imageData;
    const particles = [];
    let particle;
    let colorValue;
    let leng;

    function render() {
        ctx.drawImage(videoElem, 0, 0, 600, 400);
        imageData = ctx.getImageData(0, 0, 600, 400);
        leng = imageData.data.length / 4;

        console.log(imageData.data[0]);
for (let i = 0; i < leng; i++) {
            switch (colorValue) {
                case 'red':
                    imageData.data[i * 4 + 0] = 255;
                    break;
                case 'green':
                    imageData.data[i * 4 + 1] = 255;
                    break;
                case 'blue':
                    imageData.data[i * 4 + 2] = 255;
                    break;
            }
        }

        ctx.putImageData(imageData, 0, 0);
        requestAnimationFrame(render);
    }

    btnsElem.addEventListener('click', function (e) {
        colorValue = e.target.getAttribute('data-color');
    });
profile
ν˜„μ‹€μ μΈ λͺ½μƒκ°€

0개의 λŒ“κΈ€