Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

HTML5 Canvas 합성(Compositing) 완벽 가이드 – globalCompositeOperation 속성 활용법

HTML5 Canvas 합성(Compositing)이란?

HTML5 Canvas는 globalCompositeOperation 속성을 제공하며, 이 속성은 캔버스에서 이루어지는 모든 그리기 작업에 영향을 줍니다. 합성(컴포지팅) 기능을 활용하면 기존에 그려진 도형 뒤에 새로운 도형을 배치하거나, 특정 영역을 마스킹(masking) 처리하고, 캔버스의 일부를 지우는 등 다양한 시각 효과를 자유롭게 구현할 수 있습니다.

주요 합성 유형 살펴보기

globalCompositeOperation 속성에는 아래와 같은 값들을 설정할 수 있으며, 각 값에 따라 새로 그리는 도형(source)과 기존 도형(destination)이 결합되는 방식이 달라집니다.

  • source-over (기본값): 새 도형이 기존 도형 위에 그려집니다.
  • source-in: 두 도형이 겹치는 영역에만 새 도형이 표시됩니다.
  • source-out: 기존 도형과 겹치지 않는 부분에만 새 도형이 그려집니다.
  • source-atop: 기존 도형이 있는 영역 위에서만 새 도형이 그려집니다.
  • destination-over: 새 도형이 기존 도형 뒤에 그려집니다.
  • destination-in: 기존 도형 중 새 도형과 겹치는 부분만 남습니다.
  • destination-out: 기존 도형 중 새 도형과 겹치지 않는 부분만 남아 마스킹 효과를 냅니다.
  • destination-atop: 새 도형이 있는 영역 위에서만 기존 도형이 표시됩니다.
  • lighter: 두 도형의 색상 값이 더해져 더 밝은 색으로 표현됩니다.
  • darker: 두 도형의 색상 차이만큼 어두운 색으로 표현됩니다. (참고: 현재 대부분의 최신 브라우저에서는 지원되지 않습니다)
  • copy: 새 도형만 표시되고 기존 도형은 모두 사라집니다.
  • xor: 두 도형이 겹치는 부분은 투명하게 처리되고 나머지 부분만 표시됩니다.

실습 예제

다음 예제는 12가지 합성 유형을 각각의 캔버스에 적용하여 결과를 한눈에 비교할 수 있도록 만든 코드입니다. 먼저 분홍색(#FF3366) 사각형을 그린 후, globalCompositeOperation 속성을 설정하고 파란색(#0066FF) 원을 겹쳐 그리는 방식으로 동작합니다.

<!DOCTYPE HTML>
<html>
   <head>
      <script>
         var compositeTypes = [
            'source-over','source-in','source-out','source-atop',
            'destination-over','destination-in','destination-out',
            'destination-atop','lighter','darker','copy','xor'
         ];
         function drawShape(){
            for (i=0;i<compositeTypes.length;i++){
               var label = document.createTextNode(compositeTypes[i]);
               document.getElementById('lab'+i).appendChild(label);
               var ctx = document.getElementById('tut'+i).getContext('2d');
               
               // draw rectangle
               ctx.fillStyle = "#FF3366";
               ctx.fillRect(15,15,70,70);
               
               // set composite property
               ctx.globalCompositeOperation = compositeTypes[i];
               
               // draw circle
               ctx.fillStyle = "#0066FF";
               ctx.beginPath();
               ctx.arc(75,75,35,0,Math.PI*2,true);
               ctx.fill();
            }
         }
      </script>
   </head>
   <body onload="drawShape();">
      <table border="1" align="center">
         <tr>
            <td><canvas id="tut0" width="125" height="125"></canvas><br/>
               <label id="lab0"></label>
            </td>
            <td><canvas id="tut1" width="125" height="125"></canvas><br/>
               <label id="lab1"></label>
            </td>
            <td><canvas id="tut2" width="125" height="125"></canvas><br/>
               <label id="lab2"></label>
            </td>
         </tr>
         <tr>
            <td><canvas id="tut3" width="125" height="125"></canvas><br/>
               <label id="lab3"></label>
            </td>
               <td><canvas id="tut4" width="125" height="125"></canvas><br/>
                <label id="lab4"></label>
               </td>
               <td><canvas id="tut5" width="125" height="125"></canvas><br/>
                <label id="lab5"></label>
               </td>
         </tr>
         <tr>
            <td><canvas id="tut6" width="125" height="125"></canvas><br/>
               <label id="lab6"></label>
            </td>
            <td><canvas id="tut7" width="125" height="125"></canvas><br/>
               <label id="lab7"></label>
            </td>
            <td><canvas id="tut8" width="125" height="125"></canvas><br/>
               <label id="lab8"></label>
            </td>
         </tr>
         <tr>
            <td><canvas id="tut9" width="125" height="125"></canvas><br/>
               <label id="lab9"></label>
            </td>
            <td><canvas id="tut10" width="125" height="125"></canvas><br/>
               <label id="lab10"></label>
            </td>
            <td><canvas id="tut11" width="125" height="125"></canvas><br/>
               <label id="lab11"></label>
            </td>
         </tr>
      </table>
   </body>
</html>

예제 코드 동작 원리

코드의 핵심 흐름은 다음과 같습니다.

  1. 12개의 합성 유형 이름을 배열(compositeTypes)에 담습니다.
  2. 페이지가 로드되면 drawShape() 함수가 실행되어 각 캔버스마다 반복문을 돌며 작업을 수행합니다.
  3. 먼저 fillRect() 메서드로 분홍색 사각형을 그립니다.
  4. ctx.globalCompositeOperation에 해당 합성 유형을 설정합니다.
  5. arc() 메서드로 파란색 원을 그려 두 도형이 어떻게 합성되는지 확인합니다.

이처럼 globalCompositeOperation 속성 하나만 변경해도 도형이 겹치는 방식이 크게 달라지므로, 이미지 마스킹, 하이라이트 효과, 지우개 기능 구현 등 다양한 인터랙티브 그래픽 작업에 폭넓게 활용할 수 있습니다.