표준화문서를기반으로하는지침서 속이깊은 HTML5 & CSS3 김명진지음 11 강 캔버스 Part-2 - 드로잉확장
학습목표 앞장에서캔버스에서드로잉작업에필요한기본적인내용들을살펴보았다. 이번장에서는기본드로잉기능에원및원호를그리는방법, 베지에곡선을그리는방법을학습한다. 그리고다양한색상으로도형을채울수있는그라데이션스타일, 와인딩에따른도형의다양한채우기스타일, 패턴에의한스타일, 그리고그림자스타일에대하여학습하도록한다. Section 1 원그리기 2 베지에곡선 3
01 원그리기 원 / 원호그리기 arc() 메서드 context.arc(x, y, radius, startangle, endangle [, anticlockwise ] ) 호를그린다. 3
01 원그리기 원 / 원호그리기 arc() 메서드 context.arc(x, y, radius, startangle, endangle [, anticlockwise ] ) 호를그린다. 예제 Canvas_11-01_Arc.html Script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 for (var i = 0; i < 2; i++) { for (var j = 0; j < 3; j++) { var x = 75 + j * 125; // 좌표 X var y = 75 + i * 125; // 좌표 Y var radius = 50; // 반지름 var startangle = 0; // 시작각도 var endangle = Math.PI + (Math.PI * j) / 2; // 종료각도 var anticlockwise = i % 2 == 0? false : true; // 그리는방향 } } context.linewidth = 4; context.arc(x, y, radius, startangle, endangle, anticlockwise); // 호를그린다 context.stroke(); 4
01 원그리기 원 / 원호그리기 arc() 메서드 context.arc(x, y, radius, startangle, endangle [, anticlockwise ] ) 호를그린다. 예제살펴보기 예제 Canvas_11-01_Arc.html Script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 for (var i = 0; i < 2; i++) { for (var j = 0; j < 3; j++) { var x = 75 + j * 125; // 좌표 X var y = 75 + i * 125; // 좌표 Y var radius = 50; // 반지름 var startangle = 0; // 시작각도 var endangle = Math.PI + (Math.PI * j) / 2; // 종료각도 var anticlockwise = i % 2 == 0? false : true; // 그리는방향 } } context.linewidth = 4; context.arc(x, y, radius, startangle, endangle, anticlockwise); // 호를그린다 context.stroke(); 5
01 원그리기 원 / 원호그리기 arc() 메서드 실습 Canvas_Study11-01_Arc.html Script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // 첫번째부채꼴을그린다 ---------------------------------------- context.moveto(120,120); context.arc(120,120,100,0,270*math.pi/180, true); context.closepath(); context.stroke(); // 두번째원의첫번째호를그린다 --------------------------------- context.arc(350,120,100,90*math.pi/180,360*math.pi/180,false); context.stroke(); // 두번째원의두번째채워진호를그린다 ----------------------------- context.arc(350,120,100,90*math.pi/180,360*math.pi/180,true); context.fill(); // 세번째원의첫번째부채꼴을그린다 -------------------------------- context.moveto(570,120); context.arc(570,120,100,90*math.pi/180,360*math.pi/180,false); context.closepath(); context.stroke(); // 세번째원의두번째채워진부채꼴을그린다 ---------------------------- context.moveto(580,130); context.arc(580,130,100,90*math.pi/180,360*math.pi/180,true); context.closepath(); context.fill(); 6
01 원그리기 직선과연결된원호그리기 arcto() 메서드 context.arcto(x1, y1, x2, y2, radius) 직선과연결된호를그린다. 현재경로에하나의지점이추가되고그지점은직선에의해직전지점에연결된다. 그리고현재경로에두번째지점이추가되고그지점은속성이인수에지정된호에의해직전지점에연결된다. 주어진반지름의크기가음수인경우, indexsizeerror 예외오류가발생한다. 7
01 원그리기 직선과연결된원호그리기 arcto() 메서드 arcto() vs. arc() 8
01 원그리기 직선과연결된원호그리기 arcto() 메서드 9
01 원그리기 직선과연결된원호그리기 arcto() 메서드 실습 Canvas_Study11-02_RoundRect.html Script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function roundrect(context, x, y, width, height, radius) { if(width < 1) return; context.moveto(x + radius, y); // 오른쪽상단모서리를그리기위한시작점으로이동 context.arcto((x+width), y, (x+width), (y+height), radius); // 오른쪽상단모서리 context.arcto((x+width), (y+height), x, (y+height), radius); // 오른쪽하단모서리 context.arcto(x, (y+height), x, y, radius); // 왼쪽하단모서리 context.arcto(x, y, (x+radius), y, radius); // 왼쪽상단모서리 context.stroke(); } function draw() { var canvas = document.getelementbyid("mycanvas"); var context = canvas.getcontext("2d"); } roundrect(context, 50, 50, 100, 100, 10); roundrect(context, 200, 50, 100, 100, 20); roundrect(context, 350, 50, 100, 100, 30); roundrect(context, 500, 50, 100, 100, 40); 10
02 베지에곡선 2 차베지에곡선 베지에곡선은 n 개의점으로부터얻어지는 (n-1) 차곡선을의미 베지에곡선은 2 차곡선과 3 차 ( 다항 ) 곡선으로이루어져있다. 2 차베지에곡선은 2 개의기준점 ( 시작점과종료점 ) 과한개의제어점을필요로한다. context.quadraticcurveto(cpx, cpy, endx, endy) 2 차베지어곡선을그린다. 주어진제어포인트와 2 차 (quadratic) 베지어곡선에연결되는현재의서브패스로지정된포인트를추가한다. 11
02 베지에곡선 2 차베지에곡선 Script 예제 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Canvas_11-02_quadraticCurve.html var X = 50, Y = 280; // 시작점의위치지정 var cpx = 100, cpy = 50; // 제어점의위치지정 var endx = 400, endy = 260; // 종료점의위치지정 // 2 차베지어곡선을그린다. context.linewidth = 10; // 곡선두께지정 context.strokestyle = "rgba(255, 0, 0, 0.5)"; // 선색지정 context.moveto(x, Y); // 시작점으로이동 context.quadraticcurveto(cpx, cpy, endx, endy); //2 차베지에곡선을그린다 context.stroke(); // 가상의보조선을그린다. context.linewidth = 1; // 보조선두께지정 context.strokestyle = "rgba(0, 0, 0, 0.5)"; context.moveto(x, Y); // 시작점으로이동 context.lineto(cpx, cpy); // 제어점까지연결선 context.lineto(endx, endy); // 종료점까지연결선 context.stroke(); // 시작점, 보조점, 종료점을표시한다 context.fillrect(x-3, Y-3, 6, 6); // 시작점표시 context.fillrect(cpx-3, cpy-3, 6, 6); // 제어점표시 context.fillrect(endx-3, endy-3, 6, 6); // 제어점표시 12
02 베지에곡선 2 차베지에곡선 실습 Canvas_Study11-03_quadraticCurve.html Script 1 2 3 4 5 6 7 8 9 context.linewidth = 5.0; context.strokestyle = "red" context.moveto(175, 25); // 시작점을중앙상단으로옮긴다 context.quadraticcurveto(325, 25, 325, 100); // 제어점 cp1 과종료점 (325,100) context.quadraticcurveto(325, 175, 175, 175); // 제어점 cp2 와종료점 (175,175) context.quadraticcurveto(25, 175, 25, 100); // 제어점 cp3 과종료점 (25,100) context.quadraticcurveto(25, 25, 175, 25); // 제어점 cp4 과종료점 (25,25) context.stroke(); 13
02 베지에곡선 3 차베지에곡선 베지에곡선은 n 개의점으로부터얻어지는 (n-1) 차곡선을의미 3 차베지에곡선은 2 개의기준점 ( 시작점, 종료점 ) 과 2 개의제어점으로정의된다. 4 개의점에서중간점 3 개를구하고, 중간점 3 개에서의중간점을 2 개를다시구한다. 마지막으로중간점 2 개에서마지막중간점을구하는식 context.beziercurveto(cp1x, cp1y, cp2x, cp2y, endx, endy) 3 차베지에곡선을그린다. 직선에의한이전포인트와연결된현재의서브패스로지정된포인트를추가한다. 14
02 베지에곡선 3 차베지에곡선 예제 Canvas_11-02_bezierCurve1.html Script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 var X = 100, Y = 320; // 시작점의위치지정 var cp1x = 60, cp1y = 50; // 제어점1의위치지정 var cp2x = 320, cp2y = 50; // 제어점1의위치지정 var endx = 400, endy = 280; // 종료점의위치지정 // 3차베지어곡선을그린다. context.linewidth = 10; // 곡선두께지정 context.strokestyle = "rgba(255, 0, 0, 0.5)"; // 선색지정 context.moveto(x, Y); // 시작점으로이동 context.beziercurveto(cp1x, cp1y, cp2x, cp2y, endx, endy); context.stroke(); // 가상의보조선과각지점을그린다. context.linewidth = 1; // 보조선두께지정 context.strokestyle = "rgba(0, 0, 0, 0.5)"; context.moveto(x, Y); context.lineto(cp1x, cp1y); context.lineto(cp2x, cp2y); context.lineto(endx, endy); context.stroke(); context.fillrect(x-3, Y-3, 6, 6); // 시작점의표시 context.fillrect(cp1x-3, cp1y-3, 6, 6); // 제어점1의표시 context.fillrect(cp2x-3, cp2y-3, 6, 6); // 제어점2의표시 context.fillrect(endx-3, endy-3, 6, 6); // 종료점의표시 15
02 베지에곡선 3 차베지에곡선 예제 Canvas_11-02_bezierCurve2.html Script 1 2 3 4 var X = 100, Y = 320; // 시작점의위치지정 var cp1x = 60, cp1y = 50; // 제어점1의위치지정 var cp2x = 320, cp2y = 50; // 제어점2의위치지정 var endx = 400, endy = 280; // 종료점의위치지정 16
채우기스타일 (Fill Style) 지정 context.fillstyle [ = value ] 도형을채우기위해사용되는현재의채우기스타일을반환한다. fillstyle 속성은도형내부에사용하는색상이나스타일을나타내는것으로지정한값 (value) 으로변경할수있다. 스타일은 CSS 색상을포함하는문자열이나 CanvasGradient 또는 CanvasPattern 객체가될수있으며, 잘못된값은무시된다. context.globalalpha [= value] 렌더링처리에적용하는현재의투명도값을반환한다. 전역 (global) 알파 (Alpha) 값을설정하는속성으로, 0( 완전투명 ) ~ 1.0( 완전불투명 ) 사이의값을지정할수있으며기본값은 1.0이다. rgba() 또는 hsla() 를이용하여투명도를지정할수있지만, 이속성을사용하면, 이후에계속해서그리게되는모든도형과이미지에이속성에지정된값이적용된다. 17
채우기스타일 (Fill Style) 지정 예제 Canvas_11-03_fillStyle.html Script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 context.linewidth = 10; context.strokestyle = "blue" polygon(context,125, 125, 100, 4, -Math.PI/2); // 사각형을그린다 context.fillstyle="rgba(227,11,93,0.75)"; context.fill(); context.stroke(); context.strokestyle = "green" polygon(context,350, 125, 100, 5, -Math.PI/2); // 오각형을그린다 context.fillstyle="rgba(51,128,255,0.75)"; context.fill(); context.stroke(); context.strokestyle = "red" polygon(context,550, 125, 100, 6, -Math.PI/2); // 육각형을그린다 context.fillstyle="rgba(11,227,93,0.75)"; context.fill(); context.stroke(); context.strokestyle = "black" polygon(context,750, 125, 100, 8, -Math.PI/2); // 팔각형을그린다 context.fillstyle="rgba(227,11,93,0.75)"; context.fill(); context.stroke(); 18
채우기스타일 (Fill Style) 지정 예제 Canvas_11-03_fillStyle.html Script 1 2 3 4 5 6 7 8 9 10 11 12 context.linewidth = 10; //context.globalalpha = 1; // 투명도를완전불투명하게지정 context.globalalpha = 0.5; // 투명도를 50% 투명하게지정 context.strokestyle = "blue" polygon(context,125, 125, 100, 4, -Math.PI/2); // 사각형을그린다 context.fillstyle="rgb(227,11,93)"; context.fill(); context.stroke(); 이하생략 ( 앞의예제참고 ) globalalpha = 1.0 globalalpha = 0.5 19
와인딩규칙 (Winding Rule) 현재패스가자기자신을통과하거나현재패스와교차하는여러개의서브패스가있을경우에, fill() 메서드는내부를어떻게채울까? 20
와인딩규칙 (Winding Rule) 컴퓨터그래픽에서의와인딩방식 21
와인딩규칙 (Winding Rule) 짝 - 홀와인딩 (even-odd winding) 어떤한지점이패스내부에있는지를확인하려면, 다음그림과같이다시한번그지점을통해서선을그려보면알수있다. 선을통과할때마다교차횟수를누적한다. 누적된교차횟수가짝수라면패스외부라고판단하고채우지않는다. 그러나, 교차횟수가홀수이면패스내부라고판단하고지정한스타일로채우게된다. 22
와인딩규칙 (Winding Rule) 넌제로와인딩 (non-zero winding) 패스의각부분에대한드로잉을하는방향 ( 시계방향및시계반대방향 ) 에의존하는방법 모든시계방향회전의경우에는 1 씩감소시키고, 모든시계반대방향회전의경우에는 1 씩증가시킨다. 마지막으로계산된카운터가 0 이아니면, 해당영역은패스안에존재한다고판단하여브라우저에서는 fill() 메서드를호출해서해당영역의내부를채운다. 그러나, 마지막카운터가 0 이라면해당영역은패스안에존재하지않는것으로판단하여브라우저에서는해당영역내부를채우지않는다. 23
와인딩규칙 (Winding Rule) 넌제로와인딩 (non-zero winding) 왼쪽그림 지점 1. Total = 1, 따라서내부라고판단하여내부를채운다. 지점 2. Total = 1 1( 시계방향 ) = 0, 따라서외부라고판단하여내부를채우지않는다. 지점 3. Total = 1 1( 시계방향 ) 1( 시계방향 ) = -1, 따라서내부라고판단하여내부를채운다. 오른쪽그림 지점 1. Total = 1, 따라서내부라고판단하여내부를채운다. 지점 2. Total = 1 + 1( 시계반대방향 ) = 2, 따라서내부라고판단하여내부를채운다. 지점 3. Total = 1 + 1( 시계반대방향 ) + 1( 시계반대방향 ) = 3, 따라서내부라고판단하여내부를채운다. 24
와인딩규칙 (Winding Rule) 수정된다각형그리기 //function polygon( 컨텍스트, 좌표 (x, y), 반지름, 면의수, 시작각도, 그리는방향 ) function polygon(context, x, y, radius, sides, startangle, anticlockwise) { 수정 if (sides < 3) return; //3 각형이하는그리지않도록한다. var degree = (Math.PI * 2)/sides; // 각면에대한각도를계산한다. degree = anticlockwise? -degree : degree; // 각도의방향을반대로계산하도록한다. 추가 } context.save(); // 드로잉상태를저정한다. context.translate(x,y); // 드로잉좌표공간을다각형중심좌표로이동한다. context.rotate(startangle); // 시작각도를중심으로그리도록하기위하여회전한다. context.moveto(radius,0); // 다각형의시작위치로이동한다. for (var i = 1; i < sides; i++) { // 면의수만큼루프를반복한다 // 다음꼭지점까지선을그린다. context.lineto(radius*math.cos(degree*i),radius*math.sin(degree*i)); } context.closepath(); // 패스를닫는다. context.restore(); // 기존드로잉상태를복구한다. 25
와인딩규칙 (Winding Rule) Script 수정된다각형그리기 예제 사각형 오각형 육각형 팔각형 Canvas_11-03_fillStyleWinding.html polygon(context,125, 125, 100, 4, -Math.PI/2, false); // 사각형외부를그린다 polygon(context,125, 125, 50, 4, -Math.PI/2, true); // 사각형내부를그린다 polygon(context,350, 125, 100, 5, -Math.PI/2, false); // 오각형외부를그린다 polygon(context,350, 125, 50, 5, -Math.PI/2, true); // 오각형내부를그린다 polygon(context,550, 125, 100, 6, -Math.PI/2, false); // 육각형외부를그린다 polygon(context,550, 125, 50, 6, -Math.PI/2, true); // 육각형내부를그린다 polygon(context,750, 125, 100, 8, -Math.PI/2, false); // 팔각형외부를그린다 polygon(context,750, 125, 50, 8, -Math.PI/2, false); // 팔각형내부를그린다 26
와인딩규칙 (Winding Rule) HTML Living Standard 명세서 enum CanvasFillRule { "nonzero", "evenodd" }; void fill(optional CanvasFillRule fillrule = "nonzero"); void fill(path2d path, optional CanvasFillRule fillrule = "nonzero"); 짝 - 홀와인딩 넌제로와인딩 context.fill("evenodd"); context.fill("nonzero"); 예제 Canvas_11-03_fillRule.html 27
그라데이션 (Gradient) 스타일지정 선형그라데이션 (Linear Gradient) 시작좌표 (x0, y0) 와종료좌표 (x1, y1) 를지정함으로써, 시작좌표와종료좌표간의위치에따라서색상변화가있는그라데이션효과 gradient = context.createlineargradient(x0, y0, x1, y1) 선형그라데이션객체를생성한다. 인수로표시되는좌표로지정된라인을따라서그리는선형그라데이션을나타내는 CanvasGradient 객체를반환한다. 만일, x0 = x1 그리고 y0 = y1 이면, 선형그라데이션은아무것도그리지않는다. 방사형그라데이션 (Radial Gradient) 원의중심좌표 (x0, y0), 원의반지름 (r0), 또다른원의중심좌표 (x1, y1), 또다른원의반지름 (r1) 을지정함으로써, 두개의가상의원이생성되고그두개의가상의원사이의위치에따라서색상변화가있는그라데이션으로효과 gradient = context.createradialgradient(x0, y0, r0, x1, y1, r1) 방사형그라데이션객체를생성한다. 인수로표시되는원에의해주어진원뿔을따라서그리는방사형그라데이션을나타내는 CanvasGradient 객체를반환한다. 지정된반지름 (r0, r1) 중에하나가음수일경우에는 IndexSizeError 예외오류가발생한다. 28
그라데이션 (Gradient) 스타일지정 변환점색 ( 경계색 ) 지정 두좌표간또는두가상의원사이의변환점색상을지정 context.addcolorstop(offset, color) 주어진오프셋위치에변환점색상 (color-stop) 을추가한다. 주어진오프셋 (offset) 위치에그라데이션의변환점색상을추가한다. 0.0 은한쪽끝의오프셋위치이고 1.0 은다른한쪽끝의오프셋위치에해당된다. 중간의변환점색상을지정하기위해서는소수점으로지정하면된다 ( 변환점색상은색상과색상사이의경계색을의미 ) 그라데이션적용방법 var 객체 = context.createlineargradient(x0, y0, x1, y1); // 또는 context.creatradialgradient(x0, y0, r0, x1, y1, r1); 객체.addColorStop( 시작지점오프셋, 시작색상 ); 객체.addColorStop( 끝지점오프셋, 색상 ); context.fillstyle = 객체 ; 29
그라데이션 (Gradient) 스타일지정 Script 예제 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Canvas_11-03_GradientLinear.html // 첫번째사각형을그린다. var rectstyle = context.createlineargradient(20,20,200,200); // 선형그라데이션객체생성 rectstyle.addcolorstop(0,"yellow"); // 시작노란색의옵셋을지정 rectstyle.addcolorstop(0.5,"red"); // 중간빨간색의옵셋을지정 rectstyle.addcolorstop(1,"blue"); // 종료파란색의옵셋을지정 context.fillstyle = rectstyle; // 그라데이션객체를채우기스타일로지정 context.fillrect(20,20,200,200); // 두번째사각형을그린다. rectstyle = context.createlineargradient(230,20,420,10); rectstyle.addcolorstop(0,"yellow"); // 시작노란색의옵셋을지정 rectstyle.addcolorstop(0.3,"red"); //30% 위치의빨간색상을지정 rectstyle.addcolorstop(1,"blue"); // 종료파란색의옵셋을지정 context.fillstyle = rectstyle; // 그라데이션객체를채우기스타일로지정 context.fillrect(230,20,200,200); // 세번째사각형을그린다. rectstyle = context.createlineargradient(450,20,430,210); rectstyle.addcolorstop(0,"yellow"); // 시작노란색의옵셋을지정 rectstyle.addcolorstop(0.7,"red"); //70% 위치의빨간색상을지정 rectstyle.addcolorstop(1,"blue"); // 종료파란색의옵셋을지정 context.fillstyle = rectstyle; // 그라데이션객체를채우기스타일로지정 context.fillrect(440,20,200,200); 30
그라데이션 (Gradient) 스타일지정 Script 예제 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Canvas_11-03_GradientRadial.html // 첫번째원을그린다. // 방사형그라데이션객체를만든다. var gradient = context.createradialgradient( 100, 100, 10, 100, 100, 90 ); gradient.addcolorstop(0, "yellow"); gradient.addcolorstop(1, "blue"); context.fillstyle = gradient; context.arc(100, 100, 90, 0, 360*Math.PI/180, true); context.fill(); // 두번째원을그린다. gradient = context.createradialgradient( 350, 100, 10, 300, 100, 90 ); gradient.addcolorstop(0, "yellow"); gradient.addcolorstop(1, "blue"); context.fillstyle = gradient; context.arc(300, 100, 90, 0, 360*Math.PI/180, true); context.fill(); // 세번째원을그린다. gradient = context.createradialgradient( 480, 120, 10, 510, 100, 90 ); gradient.addcolorstop(0, "yellow"); gradient.addcolorstop(1, "blue"); context.fillstyle = gradient; context.arc(510, 100, 90, 0, 360*Math.PI/180, true); context.fill(); 31
그라데이션 (Gradient) 스타일지정 실습 Canvas_Study11-04_LinearGradient.html HTML 1 <button id="mybutton"> 색상변경하기 </button> Script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 var gradarray = ["red","purple","blue","green","yellow","orange"]; var gradient; // 그라데이션을위한변수 document.getelementbyid("mybutton").addeventlistener("click", changecolor, false); dogradient(); // 처음지정된색상으로그라데이션효과를적용한다. // 배열 gradarray[] 에있는색상으로그라데이션효과를적용한다. function dogradient() { gradient = context.createlineargradient(0, 0, canvas.width, 0); // 그라데이션객체생성 gradient.addcolorstop("0", gradarray[0]); // 시작색상 gradient.addcolorstop(".20", gradarray[1]); //20% 지점의색상 gradient.addcolorstop(".40", gradarray[2]); //40% 지점의색상 gradient.addcolorstop(".60", gradarray[3]); //60% 지점의색상 gradient.addcolorstop(".80", gradarray[4]); //80% 지점의색상 gradient.addcolorstop("1.0", gradarray[5]); // 마지막색상 } context.fillstyle = gradient; // 채우기속성에그라데이션객체스타일을적용한다. context.fillrect(0, 0, 350, 150); // 그라데이션스타일로채워진첫번째사각형을그린다. context.fillrect(0, 155, 600, 10); // 그라데이션영역을비교하기위한사각형을그린다. context.fillrect(200, 170, 600, 150); // 그라데이션스타일로채워진두번째사각형을그린다. // 배열의첫번째색상을제거해서마지막색상으로이동시켜서배열의색상을변경하고그라데이션효과를적용한다. function changecolor() { var temp = gradarray.shift(); gradarray.push(temp); 32 dogradient(); // 변경된색상으로그라데이션효과를다시적용시킨다. }
그라데이션 (Gradient) 스타일지정 실습 Canvas_Study11-04_LinearGradient.html 33
패턴 (Pattern) 스타일지정 패턴은불투명한 CanvasPattern 인터페이스를구현하는객체로표현 pattern = context.createpattern(image, repetition) CanvasPattern 객체를반환한다. 첫 번째 인수 image 는 패턴으로 사용할 이미지를 지정한다. 이미지는 HTMLImageElement, HTMLCanvasElement, 그리고 HTMLVideoElement 중에서지정해야한다. 두번째인수 repetition는주어진 image의반복되는방향을나타낸다. 반복 (repetition) 으로지정될수있는값은다음과같으며, 그이외의값을지정하면 SyntaxError 예외 오류가 발생한다. 이 값이 생략되면 기본적으로 repeat 값이 된다. - repeat( 양방향 ), repeat-x( 수평방향만 ), repeat-y( 수직방향만 ), no-repeat( 반복안함 ) 패턴채우기적용과정 1. 이미지파일의 Image 객체를생성한다. 2. onload 이벤트처리기를사용하여이미지로드가완료되면 createpattern() 메서드를사용하여패턴객체를생성한다. 3. fillstyle 속성에패턴객체를지정한다. 4. 원하는도형등을그리면내부를패턴으로채울수있게된다. 34
패턴 (Pattern) 스타일지정 예제 Canvas_11-03_Pattern.html Script 1 2 3 4 5 6 7 8 9 10 11 12 13 var img = new Image(); // 이미지객체를만든다. img.src = "images/pattern.png"; // 이미지객체에이미지를지정한다. img.onload = function () { // 이미지가로드될때까지기다렸다가처리를계속한다. context.beginpath (); var pattern = context. createpattern (img, ""); // 이미지로패턴객체를생성한다. context.fillstyle = pattern; // 패턴객체를채우기스타일로지정한다. context.arc(100, 100, 70, 0, 2 * Math.PI, false); // 원을그린다. polygon(context, 270, 100, 70, 8, -Math.PI/2, false); // 팔각형외부를그린다 polygon(context, 270, 100, 40, 8, -Math.PI/2, true); // 팔각형내부를그린다 polygon(context, 440, 100, 70, 5, -Math.PI/2, false); // 오각형을그린다 context.fill (); // 원내부를채운다. } 35
패턴 (Pattern) 스타일지정 실습 Canvas_Study11-05_Pattern.html HTML Script 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <div> <img id="myimage" src="images/love.png" /> <p id="msg"> 이미지패턴이 repeat 으로지정되었습니다.</p> </div> <button onclick="draw('repeat')">repeat all</button> <button onclick="draw('repeat-x')">repeat-x</button> <button onclick="draw('repeat-y')">repeat-y</button> <button onclick="draw('no-repeat')">no-repeat</button><br /> var image, pattern, message; // 이미지와패턴, 메시지를위한객체를생성한다.. function draw(direction) { var canvas = document.getelementbyid("mycanvas"); var context = canvas.getcontext("2d"); } context.clearrect(0, 0, canvas.width, canvas.height); // 캔버스영역을지운다. pattern = context.createpattern(image, direction); // 패턴객체를생성한다. context.fillstyle = pattern; // 채우기스타일을패턴으로지정한다. context.fillrect(0, 0, canvas.width, canvas.height); // 캔버스영역을지운다. message.innerhtml = " 이미지패턴이 " + direction + " 으로지정되었습니다 "; message = document.getelementbyid("msg"); //P 요소의아이디를가져온다. image = document.getelementbyid("myimage"); // 이미지의아이디를가져온다. // 이미지리스너를통해이미지가로드되면, draw() 메서드를호출한다. image.addeventlistener("load", function () { draw("repeat"); // 초기 repeat 값으로패턴을채우도록 draw() 메서드를호출한다. }, false); 36
패턴 (Pattern) 스타일지정 실습 Canvas_Study11-05_Pattern.html 37
그림자스타일지정 어떤도형이나텍스트, 또는이미지등에입체감을주기위한방법 그림자를지정하면, 도형이나텍스트등이캔버스위에마치떠있는듯한느낌이들도록하는시각적효과를가진다 context.shadowcolor [= value] 현재그림자의색상을반환한다. CSS로지정할수있는값을사용하여그림자의색상을변경할수있다. CSS 색상으로구문분석할수없는값은무시된다. 기본값은완전히투명한검정 (rgba(0, 0, 0, 0)) 으로초기화된다. context.shadowoffsetx [= value] 현재그림자의수평 (X 좌표 ) 오프셋을반환한다. 도형이나텍스트로부터그림자까지의수평오프셋을픽셀단위로지정한다. 기본값은 0 으로초기화되며, 변환행렬의영향을받지않는다. context. shadowoffsety [= value] 현재그림자의수직 (Y 좌표 ) 오프셋을반환한다. 도형이나텍스트로부터그림자까지의수직오프셋을픽셀단위로지정한다. 기본값은 0 으로초기화되며, 변환행렬의영향을받지않는다. context.shadowblur [= value] 그림자의흐림정도 ( 크기또는범위 ) 를지정한다. 값을지정하여그림자의흐림정도를지정할수있다. 값이작을수록그림자는선명해진다. 컨텍스트가생성될때, shadowblur 속성은 0 으로초기화된다. 38
그림자스타일지정 예제 Canvas_11-03_Shadow.html Script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 context.shadowblur = 15; // 그림자의흐림정도를크게지정하여많이흐리게한다. context.shadowcolor = "rgb(0, 0, 0)"; // 그림자의색상을검은색으로지정한다. polygon(context, 125, 125, 100, 4, -Math.PI/2, false); // 사각형외부를그린다 polygon(context, 125, 125, 50, 4, -Math.PI/2, true); // 사각형내부를그린다 context.fillstyle="rgba(227,11,93,0.75)"; context.fill(); context.shadowblur = 0; // 그림자의흐림정도를주지않는다. context.shadowoffsetx = 6; // 그림자를도형의 6 픽셀만큼오른쪽으로위치시킨다. context.shadowoffsety = 6; // 그림자를도형의 6 픽셀만큼아래쪽으로위치시킨다. context.shadowcolor = "rgba(125, 125, 125, 0.5)"; // 그림자를 50% 투명하게지정한다. polygon(context, 350, 125, 100, 5, -Math.PI/2, false); // 오각형외부를그린다 polygon(context, 350, 125, 50, 5, -Math.PI/2, true); // 오각형내부를그린다 context.fillstyle="rgba(51,128,255,1.0)"; context.fill(); context.shadowblur = 10; context.shadowoffsetx = -10; // 그림자를도형의 10 픽셀만큼왼쪽으로위치시킨다. context.shadowoffsety = -10; // 그림자를도형의 10 픽셀만큼위쪽으로위치시킨다. context.shadowcolor = "rgba(227,11,93,0.75)"; // 그림자를 25% 투명하게지정한다. polygon(context, 550, 125, 100, 6, -Math.PI/2, false); // 육각형외부를그린다 polygon(context, 550, 125, 50, 6, -Math.PI/2, true); // 육각형내부를그린다 context.fillstyle="rgba(11,227,93,1.0)"; context.fill(); 39
그림자스타일지정 예제 Canvas_11-03_Shadow.html Script 29 30 31 32 33 34 35 36 37 context.shadowblur = 10; context.shadowoffsetx = 10; // 그림자를도형의 10 픽셀만큼오른쪽으로위치시킨다. context.shadowoffsety = 10; // 그림자를도형의 10 픽셀만큼아래쪽으로위치시킨다. context.shadowcolor = 'rgba(0,0,0,0.75)'; // 그림자의색상을 25% 투명한검은색으로지정한다. polygon(context, 750, 125, 100, 8, -Math.PI/2, false); // 팔각형외부를그린다 polygon(context, 750, 125, 50, 8, -Math.PI/2, true); // 팔각형내부를그린다 context.fillstyle="rgba(227,11,93,0.75)"; context.fill(); 40
다음학습 1 도형합성및변환 2 텍스트그리기 3 이미지처리하기 4 애니메이션 (Animation) 5 히트영역 (Hit Regions)