캔버스 ( html5 ) 그림 그리기2 > 개발자팁

개발자팁

개발과 관련된 유용한 정보를 공유하세요.
질문은 QA에서 해주시기 바랍니다.

캔버스 ( html5 ) 그림 그리기2 정보

JavaScript 캔버스 ( html5 ) 그림 그리기2

첨부파일

canvas.html (4.7K) 77회 다운로드 2014-02-14 06:34:11

본문

기본적인 마우스 움직임과 함께 선을 그리는 방법입니다
윗글에 썼듯이 자바스크립트를 기반으로 소스가 작동되기에 기본적인 함수를 몇개 넣겠습니다
 
 

<script type="text/javascript">
 /* 객체 아이디를 간단하게 하기 위한 함수 */
  function $(id){
      var element="";
      if(id==""){
         return false;
      }  
      else{
         element= document.getElementById(id);
         return element;
      }
  }
  //이벤트 등록
  function addEvent(obj,mouseEVT,fn){
     if(window.addEventListener){ // firefox
        if(mouseEVT){
           mouseEVT=mouseEVT.replace('on','');
           obj.addEventListener(mouseEVT , fn, false);
        return true;
        }
     } //end firefox IE8 이상
     else{ // IE8 이하
        mouseEVT=mouseEVT.replace('on','');                // 있다면 일단 지워준다
        mouseEVT=mouseEVT.replace(mouseEVT,'on'+mouseEVT); // 추가해줌
        obj.attachEvent(mouseEVT , fn);
     }//end IE8 이하
  }
  // 이벤트 삭제
  function removeEvent(obj,evt,func){
      if( /MSIE/.test(navigator.userAgent) ){/* IE */
         obj.detachEvent(evt , func);
      }else{
         evt=evt.replace('on','');
         obj.removeEventListener(evt , func, false);
      }
  }
  /* 온로드후 실행 함수 자주쓰기에 구분을 주기 위해 이벤트 함수를 똑 같이 하나 더 만듬*/
  function onLoad_Event(fucName){
     if(window.addEventListener){ // firefox
        window.addEventListener("load",fucName,false);
     } //end firefox
     else{ // IE
        window.attachEvent("onload",fucName);
     }  //end IE
  }
</script>
 
 
위의 4가지 함수는 자체적으로 만든 함수이기에 취향에 맞게 원칙적인 이벤트등록 함수를 사용하시거나 혹은 그대로 사용하시면 됩니다 다만 제이쿼리등과 충돌할 수도 있습니다
제이쿼리가 등장할 무렵 함수 네이밍의 간단함에 비슷하게 만들어 쓰다보니 저런 형태를 취했으므로
자신의 소스에 제이쿼리가 있다면 충돌할 소지가 있다는 것만 미리 말씀드립니다
 
function $(id) 함수는
document.getElementById(객체아이디); 를 일일이 적지 않고 $(객체아이디) 로 호출하기 위한 함수입니다
 
document.getElementById("canvas1");  => $("canvas1");  와 같이 쓰이며 달러 기호와 중괄호로 여닫는 문구가 있으면
아이디를 가진 객체를 호출하는 부분입니다
나머지 3개는 이벤트 등록과 관련된 함수입니다
 
 
 
 
아래부터가 캔버스에 들어가는 자바스크립트 소스입니다
 
 
이하소스
--------------------------------------------------------------------------------
 

<script type="text/javascript">
  onLoad_Event(startFUNC); // 온로드 후 startFUNC() 함수 실행

  var canvasTop =""; // 캔버스의 위치를 받아두는 변수
  var canvasLeft ="";
 
 /* 온로드시 필요한 실행 함수 등록 */
  function startFUNC(){
      addEvent(document.body,'mouseover',   function(){ //mousedown 스크롤 위치 파악
            if(self.pageYOffset>0){// 표준 브라우져
                scroll_x= self.pageXOffset;
                scroll_y= self.pageYOffset; 
            }
            else
            if(document.body){//IE8 이전 버전
                scroll_x = document.body.scrollLeft;
                scroll_y = document.body.scrollTop;
                scroll_x= self.pageXOffset; // 오류로 인해 변경
            }
            else
            if(document.documentElement &&document.documentElement.scrollTop){ //IE8 이전 버전
                scroll_x = document.documentElement.scrollLeft;
                scroll_y = document.documentElement.scrollTop;
            }
            canvasTop  = ( $("contentsLAYER").offsetTop  + $("canvasLAYER").offsetTop  +  $("canvas1").offsetTop)  - parseInt(scroll_y); // 캔버스의 위치
            canvasLeft = ( $("contentsLAYER").offsetLeft + $("canvasLAYER").offsetLeft +  $("canvas1").offsetLeft) - parseInt(scroll_x);
      });
  }
 
 
  function drowing(event,objType,objID){
      var jobCanvas   = document.getElementById("canvas1");
      var thisCanvas  = document.getElementById("canvas1");
      var ctx         = jobCanvas.getContext('2d');
      var dot   = 10;
      var color = "red";
      var x2="";
      var y2="";
 

      thisCanvas.onmousemove = function(event){
                 //캔버스 정점에서부터의 위치
                 var x=(parseInt(event.clientX) - canvasLeft);
                 var y=(parseInt(event.clientY) - canvasTop);

                 ctx.beginPath();
    ctx.moveTo( x, y );
    draw(event);
    x2=x; //위치 정보를 기록한다
          y2=y;
      }
  

      // 그리기
      this.draw=function(event){
          ctx.lineTo(x2,y2);
          ctx.lineWidth = dot;
          ctx.strokeStyle =color;
          ctx.lineCap = 'round';
          ctx.stroke();
      }
  }
 
</script>
 
 
 
--------------------------------------------------------------------------------
이상 소스
 
 
소스 설명
onLoad_Event(startFUNC); // 온로드 후 startFUNC() 함수 실행
주석에 써 놨듯이 캔버스가 들어간 페이지가 온로드 된후 필요한 함수들을 실행시켜서 그림을 그리거나 편집할 수 있는
상태로 만듭니다
 
간혹 온로드 함수로 고생하시는 분들이 있는데 이와 같이 온로드 함수를 따로 만들어 이벤트 등록을 하는게
함수 관리에 편합니다
직접 바디에 써줄수도 있고 window.onload=function(){} 과 같이 상황에 따라 표기해 줄수도 있지만
함수 실행 우선순위에 밀려 함수 호출이 되지 않아 고생하는데 이와 같이 하는것도 팁이 될수 있습니다
 
 
 
 

  var canvasTop =""; // 캔버스의 위치를 받아두는 변수
  var canvasLeft ="";
 
캔버스가 상단에서 좌측에서 얼마만큼 떨어져 위치해 있는지 받아두는 변수입니다
 
 
 
 /* 온로드시 필요한 실행 함수 등록 */
  function startFUNC(){
 
온로드 후 바로 실행하거나 혹은 기능 동작중에 필요한 부분이 있습니다 이를 따로 함수로 만들어 등록합니다
현재는 마우스의 포인터 위치만 넣어 두었습니다
후에 소스가 조금 추가될텐데 이 때  색상, 브러쉬 크기등을 설정할 때 필요한 부분을 넣을겁니다

      addEvent(document.body,'mouseover',   function(){ //mousedown 스크롤 위치 파악
 소스~~~~~
      });
 
 위의 부분은  startFUNC 함수 안에  제일 처음 미리 만들어 둔 이벤트 등록 함수인 addEvent란 함수를 담고 있습니다
 이는 마우스가 움직일 때 ( onmouseover 또는 mouseover ) 마우스의 현재 위치에 따른 좌표값이 필요한데
브라우저의 종류와 버젼에 따른 차이를 막기 위해 웹표준으로 값을 지정 받습니다
 
현재 객체의 마우스의 위치값을 받을 때는 다음의 조건이 좌우합니다
현재 객체의 위치 - 스크로바의 위치
 

            canvasTop  = ( $("contentsLAYER").offsetTop  + $("canvasLAYER").offsetTop  +  $("canvas1").offsetTop)  - parseInt(scroll_y); // 캔버스의 위치
            canvasLeft = ( $("contentsLAYER").offsetLeft + $("canvasLAYER").offsetLeft +  $("canvas1").offsetLeft) - parseInt(scroll_x);
 
 canvasTop  은 최상에서 현재 캔버스가 위치한 곳 까지의 높이이며 canvasLeft는 좌측에서 부터의 위치입니다
$("contentsLAYER").offsetTop  + $("canvasLAYER").offsetTop  +  $("canvas1").offsetTop)
 
캔버스가 담긴 div 인 contentsLAYER canvasLAYER 의 위치 그리고 캔버스인 canvas1의 위치를 다 더한 값이
비로소 canvas1의  좌측 상단 모서리 부부의 위치가 됩니다 그런데 스크롤이 생겨서 스크롤을 올리거나 내리거나 하면
값이 틀어지기에 여기에 스크롤의 위치값을 가감하게 됩니다
 
옵셉톱 (offsetTop )등을  사용시 위치값이 안 맞을 경우가 있습니다 이는 중간에 스타일 등으로 포지션 태그가 지정 되어 있거나 혹은 상위 태그등에서 마진, 패딩, 보더등이 덧붙여져서 틀어지는 경우입니다 하나 더 추가하면
문서 설정에 의한 도큐멘트 타입에 의해 틀어지게 됩니다
position : absolute ( 또는  realative ) 등을 써서 접근성을 확보합니다
 
 
  function drowing(event,objType,objID){ 소스~~~~~ }
 
 
드로윙에 관한 함수입니다
함수인수로 event,objType,objID등이 쓰였는데  event는 가감 없이 사용되어야 합니다
익스플러러와 기타 웹브라우저의 차이로 인해 이벤트가 일어났는지를 판단하는 부분이기에 함수에도 사용되어지고
호출부에서도 사용되어져야 합니다
 
위의 함수는  버튼으로 되어진 <input type="button" onclick="drowing(event)" value="그리기"> 에서 클릭을 함으로
함수 호출이 됩니다
 

      var jobCanvas   = document.getElementById("canvas1");
      var thisCanvas  = document.getElementById("canvas1");
      var ctx              =  jobCanvas.getContext('2d');
 
 캔버스를 변수로 등록합니다
 
 jobCanvas ,  thisCanvas 둘 다 canvas1을 지정해 뒀는데 후에 소스가 추가됩니다
두개를 지정한 이유는 후에 더 설명하겠지만 캔버스를 추가해서 사용해야 하는 일이 생깁니다
그럴때 현재 사용되어지는 캔버스와 작업이 되어야하는 작업 캔버스를 구분해야 되는데 그때 사용되어집니다
 
 var ctx   =  jobCanvas.getContext('2d');
 
제일 중요한 부분중 하나입니다 이부분이 명시가 되어야 비로서 캔버스가 2d 즉 그림을 그리고 편집할 준비를 하게됩니다
캔버스가 있어야 하며 위와 같이 캔버스를 사용하겠다는 명시를 해줘야 합니다
 
ctx란 변수에 jobCanvas를 [  document.getElementById("canvas1") ] 2d로 가져다 사용한다고 변수 처리를 해뒀습니다
 
ctx란 변수는 대부분의 사이트에서 canvas 활용 예제들이 70%이상 이와 같이 ctx란 문구로 사용되어 졌기에 후에 웹검색을 해서 사용하실 때 쓰시기 편하도록 그대로 사용했습니다
 
canvas , 캔버스, html5 캔버스, ctx등으로 검색시 아주 많은 양의 웹검색을 하실수 있습니다
 

      var dot   = 10;
      var color = "red";
      var x2="";
      var y2="";
 
 
 
dot 는 브러쉬의 크기입니다 포인트로 받지 않고 크기를 정수로 받기에 위와 같이 사용되며 크기는 해본 결과
1이하 소수점까지는 잘표현이 되지 않으므로 1부터 그 이상으로 생각하시면 됩니다
 color 는 브러쉬의 색입니다
x2,y2 는 마우스가 움직일때 현재의 위치를 받아두기 위한 마우스 위치용 변수입니다
 
 

      thisCanvas.onmousemove = function(event){
소스~~~~~~~~
      }
 
canvas1란 아이디를 가진 캔버스 위에서 마우스가 움직일때 마다 그림그리기를 호출합니다
위에 함수 중에 아래와 같이 정의한 부분이 있었습니다
      var jobCanvas   = document.getElementById("canvas1");
      var thisCanvas  = document.getElementById("canvas1");
 
위에서   thisCanvas.onmousemove 로 함수 호출을 시도한 이유는 다음과 같습니다
작업을 캔버스 위에서 하고 있는데 캔버스위에 다른 캔버스를 추가해 올려 놓아야 할 경우가 있습니다
( 포토샵의 레이어 추가와 같은 ) 이때  원본의 캔버스 혹은 작업으로 추가된 캔버스 ( 레이어 )를 선택해서
그림 그리기를 해야 하는데 그 사용성을 위해서 두가지로 나눴던 겁니다
즉 그림이 그려지는 실제 작업 캔버스와 마우스가 움직여서 위치를 전해주는 위에 올려진 레이어 캔버스로 생각하면 됩니다
 
 
 

                 //캔버스 정점에서부터의 위치
                 var x=(parseInt(event.clientX) - canvasLeft);
                 var y=(parseInt(event.clientY) - canvasTop);

                 ctx.beginPath();
                 ctx.moveTo( x, y );
                 draw(event);  // 그림 그리기 호출
                 x2=x; //위치 정보를 기록한다
                 y2=y;
 
 
x,y는 마우스가 움직일 때마다 현재의 좌표를 계산합니다
(parseInt(event.clientX) - canvasLeft);
parseInt(event.clientX) 브라우저에서  마우스가르키는 현재 좌측에서부터의 위치를 가르킵니다
여기에 canvasLeft ( 캔버스가 브라우저 좌측에서부터 얼마만큼 떨어져 있는지 )를 뺐습니다
 
계산에 의하면 캔버스 좌측에서부터 얼마만큼 떨어져 있는지가 나옵니다
 
마우스로 그림을 그릴때 필요한 부분은 캔버스의 좌측 상단 모서리에서부터 얼마만큼 떨어져 그림을 그리고 색을 입히는
지입니다
 
 ctx.beginPath();
그림을 그리겠다 선언을 해줍니다
패스 선언이 있으면 반대 선언도 있겠죠
아래는 닫음 패스입니다
 ctx.closePath();
 
ctx.moveTo( x, y );
마우스 이동 경로를 알려주는 canvas 지원 함수중 하나입니다
draw(event);  // 그림 그리기 호출
마우스가 이동한 곳에서 drow함수를 호출해 그림을 그려줍니다

x2=x; //위치 정보를 기록한다
y2=y;
 
마우스의 현재 위치를 기록해서  드로우 함수에서 활용합니다
 
 
 
      // 그리기
      this.draw=function(event){
          ctx.lineTo(x2,y2);
          ctx.lineWidth = dot;
          ctx.strokeStyle =color;
          ctx.lineCap = 'round';
          ctx.stroke();
      }
마우스 무브( 이동 )시 끊임없이 호출되어 위치를 계산하고 라인 혹은 색을 입혀주는 실제적인 함수입니다 
 
 ctx.lineTo(x2,y2);
마우스 무브에 의해 기록된 좌표를 받아서 라인을 그려주는 canvas 지원함수입니다
즉 이전 좌표에서 움직이고 난 후의 마지막 좌표까지 선으로 이어주기 위한 거리 계산 api입니다
계산을 했으니 어느정도 두께를 가지고 색을 입힌 선을 그어야겠죠
 
ctx.lineWidth = dot;(  canvas 지원함수입니다 )
라인의 넓이입니다 정수값으로 받고 위에서 dot 값을 정해줬으니 그 값의 넓이(크기)를 가진 선을 표현해줍니다
 
ctx.strokeStyle =color; ( canvas 지원함수입니다 )
선의 색을 표현합니다 컬러에 red를 써줬으니 빨간색으로 나옵니다
 
ctx.lineCap = 'round'; ( canvas 지원함수입니다 )
라인의 끝부분을 어떻게 처리할지를 말합니다 즉 끝부분을 둥그렇게 할지 단면으로 할지를 처리하는데
둥그렇게 처리를 합니다 종류가 몇가지 있느데 이부분은 생략합니다

ctx.stroke(); ( canvas 지원함수입니다 )
위에서 설정한 부분들을 스트로크란 지원함수를 이용해서 표현해줌으로 빨간색 선으로 이동거리만큼 그리게 됩니다
마우스를 끊임없이 움직이면 그에 맞게 계속 선을 긋게 되겠죠
 
위에 까지가 아주 기본적인 함수 사용법입니다
 
올려진 파일을 열어서 그림 그리기 단추를 누르면 마우스가 움직이는데로 선이 그어지는 것을 보실수 있을겁니다
여기에 마우스를 클릭후 움직였을때 마우스를 놓았을 때 기능정지, 전체 canvas 지우기 등을 다음 문서에 추가해보겠습니다
 
글이 길어지므로 오늘은 여기까지만 쓰겠습니다
 
- 덧붙여 -
해당 글들은 사정에 의해 또는 상황에 의해 수정되어질 수 있습니다
미리 준비된 강의 자료가 아닌 즉석에서 만들어서 올리는 것이기에 양해 바랍니다
 
 
 
 
 
 
 
 
 
 
추천
1

댓글 0개

전체 6
개발자팁 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1402호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT