본문으로 바로가기

CHAR 2. 캔버스에 그리기

category HTML5 Canvas 2012. 2. 22. 17:03

▼셀프제작데모: 눈내리기 효과 (2017.04.10 NAS2Dual 테스트용 페이지)


2.1 예제 기본 소스 템플릿


2.2 기본 사각형 그리기 메서드
    - fillRect (fillStyle), strokeRect(strokeStyle), clearRect
2.3 캔버스 상태정보★
    - 컨텍스트 상태 정보 스택에는 상태정보 데이터가 있다.        
  • 회전/이동에 대한 변환 행렬 정보
  • 현재의 영역 선택 정보
  • 캔버스 특성의 현재 값: globalAlpha, globalCompositeOperation, strokeStyle, textAlign/textBaseline, lineCap/lineJoin/lineWidth/miterLimit, fillStyle, font, shadowBlur/shadowColor, shadowOffsetX, shadowOffsetY 등등
    - 상태정보에 없는 정보: 현재 패스, 현재 비트맵(CHAR4) → 원하는 도형만 변환되도록 가능
    - 상태정보 저장/복구: context.save()/restore()

2.4 패스를 이용해서 선 그리기
- 그리기 상태 정보 저장시 패스정보는 빠지므로 나머지는 두고 패스만 변환할 수 있다.
- 상태정보의 변환 행렬은 모든 패스에 영향을 미친다.
- 영향 상태값: strokeStyle, lineWIdth, lineCap = 'square',
- 패스의 시작/끝: beginPath()/closePath()
- 패스그리기: moveTo(), lineTo()
- 패스 특성 설정: lineCap(라인끝 모양, butt|round|square), lineJoin(서브패스가 만나는 모서리 모양, "miter|bevel|round"
- 패스 유의사항: 패스는 시작픽셀 중심부터 x, y 방향으로 나간다. 따라서 lineWidth와 중심점에 유의
- 연습:) lineCap과 lineJoin 의 궁합 테스트해볼것!
// round 끝, bevel 조인
function drawPath() {
	context.strokeStyle = "black";
	context.lineWidth = 10;
	context.lineCap = "round";
	context.lineJoin = "bevel";
	context.beginPath();
	context.moveTo(10, 100);
	context.lineTo(35, 100);
	context.lineTo(35, 125);
	context.stroke();
	context.closePath();
}

2.5 고급 패스 메서드
2.5.1 원호
1) arc(x, y, radius, startAngle, endAngle, anticlockwise) 
    - 중심점 (x,y),  반지름(radius)
    - 원호의 시작각도/끝각도(startAngle/endAngle): 라디안값(=Math.PI/180*각도), 각도: 3시=0도
    - 속성설정: strokeStyle, lineWidth
function drawArc() {
	context.strokeStyle = "green";
	context.lineWidth = 5;
	context.arc(100, 100, 30, (Math.PI/180)*0, (Math.PI/180)*360, false);
	// 원 그리기
	context.stroke();
	context.closePath();
	// 원호가 채워진.
	//context.fillStyle = "silver";
	//context.fill(); }
2) arcTo(x1, y1, x2, y2, radius)
    - 중심점(현재위치)
    - 중심점~(x1, y1), 중심점~(x2, y2) 두 라인위의 점과 그릴때 거리가 radius인 원호
function drawArcTo()
 {	context.strokeStyle = "Lime";
	context.lineWidth = 5;
	context.moveTo(0,0);
	context.lineTo(100,200);
	context.arcTo(350, 350, 100, 100, 30);
	context.stroke();
	context.closePath();
}

2.5.2 베지어 곡선(Bezier curve)
▼  2차(quadratic): quadraticCurveTo(cp1x, cp1y, x, y)
     - 제어점(cp1x, cp1y) / 끝점(x, y)
     - 제어점:구부러질 위치
function drawCurveTo1()
 {	context.strokeStyle = "Teal";
	context.lineWidth = 5;
	context.moveTo(0, 0);
	context.quadraticCurveTo(100, 25, 0, 50);
	context.stroke();
	context.closePath();
}
▼  3차(cubic): bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
    - 제어점1(cp1x, cp1y) / 제어점2(cp2x, cp2y) / 끝점(x, y)
function drawCurveTo2()
 {
	context.strokeStyle = "Fuchsia";
	context.lineWidth = 5;
	context.moveTo(150, 0);
	context.bezierCurveTo(0, 125, 300, 175, 150, 300);
	context.stroke();
}
▼ 캔버스 영역 선택
- save(), restore(), 캔버스 영역 선택으로 그리는 영역 제한할 수 있다.(Mask)
- 그리기 영역 설정
  rect(x, y, width, height)
  또는 arc(float x, float y, float radius, float startAngle, float endAngle, boolean anticlockwise) 로 영역 지정
  한 후에 clip() 호출

2.6 겹치기 효과
- 투명도와 레이어 조절로 겹치기 효과를 결정
▼ globalAlpha: 알파값 설정, 0~1.0(불투명)
▼ globalCompositeOperation: 현재의 캔버스 비트맵 이미지 위에 어떻게 그릴것인가 결정 완벽이해할것!
    - 윗그림(source), 밑그림(destination)
    - copy: 겹치면 윗그림 출력
    - destination-atop: 윗밑 둘다 불투명☞밑그림, 윗(불투명)/밑(투명)-윗그림 출력
    - destination-in: 겹친 부분만 밑그림을 출력. 
    - destination-out: 겹치지 않는 부분만 밑그림
    - destination-over: 밑그림을 윗그림보다 위에 그린다.
    - lighter: 윗그림과 밑그림을 합친다.겹친 부분의 색상값은 최대가 1.0
    - source-atop: 윗그림은 겹친 부분만 출력(겹친 부분은 윗그림 겹치지 않는 부분은 밑그림만 출력)
    - source-in: 겹친 부분만 윗그림을 출력
    - source-out: 겹치지 않은 부분에서 윗그림만 출력
    - xor: 윗그림과 밑그림이 서로 겹치지 않는 부분만 출력(XOR)

<이미지 출처: http://www.html5rocks.com/en/tutorials/canvas/texteffects/ >


2.7 간단한 캔버스 변환
▼ 원점이동: translate(x, y)
    - 원점이 이동하면 도형을 그릴때 offset을 적용해야한다.
    - 도형의 중심점 찾기: 어떤 도형이든 중심 위치는 (x-.5*width, y-.5*height)
▼ 회전: rotate(angleInRadians)
▼ 스케일 변환: scale(x, y)  [x,y축에 대한 스케일값, 디폴트=1.0]
function drawScaleandRotate()
 {
	context.setTransform(1,0,0,1,0,0);
	var angleInRadians = 90 * Math.PI/180;
	var x = 100;
	var y = 100;
	var width = 100;
	var height = 50; // 직사각형
	context.translate(x+.5*width, y+.5*height);
	context.rotate(angleInRadians);
	context.scale(2,2); // x,y축 모두 2배
	context.fillStyle = "Aqua";
	context.fillRect(-.5*width, -5*height, width, height);
}
2.8 색상과 그레이디언트 넣기
▼ 색상채우기
    - context.fillStyle = {"red" | "#ff0000" | rgb(255,0,0) | rgba(255,0,0,1) | 그레이디언트객체}
    - context.strokeStyle = 상동
▼ 그레이디언트
    - 테두리에도 그레이디언트 효과 가능(strokeStyle = gr)
    ① 선형(lineal):
        - createLinearGradient(left, top, right, bottom/*그레이디언트 시작~끝 좌표*/) 
        - 수평(left=right), 수직(top=bottom), 대각선 스타일 / 색상 정지점(color stop) 설정
 
    function drawLinearGradient()
 {
	// 그레이디언트 객체 생성
	var gr = context.createLinearGradient(0, 0, 100, 0); // 수평
	//var gr = context.createLinearGradient(0, 0, 0, 100); // 수직
	//var gr = context.createLinearGradient(0, 0, 100, 100); // 대각선

	// 색상 정지점을 추가한다.
	gr.addColorStop(0, 'rgb(30,30,30)');
	gr.addColorStop(.4, 'rgb(220,220,220)');
	gr.addColorStop(.5, 'rgb(230,230,230)');
	gr.addColorStop(.6, 'rgb(220,220,220)');
	gr.addColorStop(1, 'rgb(30,30,30)');

	// fillStyle로 그레이디언트를 설정
        context.fillStyle = gr;
        context.fillRect(0, 0, 100, 100);
        //context.fillRect(0, 0, 200, 200); // 그레이디언트 영역만 적용된다.
}
    ② 방사형(radial)
        - createRadialGradient(x1, y1, radius1, x2, y2, radius2): 원 2개 설정
function drawRadialGradient()
 {
	var x1 = 13;
	var y1 = 12;
	var radius1 = 3;
	var x2 = 15;
	var y2 = 15;
	var radius2 = 10;
	var gr = context.createRadialGradient(x1, y1, radius1, x2, y2, radius2);

	// Add the color stops.
	gr.addColorStop(0,'rgba(255,205,222,1)');
	gr.addColorStop(.2,'rgba(255,205,222,.9)');
	gr.addColorStop(.5,'rgba(255,205,222,.6)');
	gr.addColorStop(.8,'rgba(255,205,222,.1)');
	gr.addColorStop(1,'rgba(255,205,222,.1)');

	// Use the gradient for the fillStyle.
	context.fillStyle = gr;
	context.fillRect(0, 0, x2+radius2, y2+radius2);
	context.arc(x2, y2, radius2, 0, Math.PI/180*360,false);
	context.fill();
	context.closePath();
/*
	// 참고: 그라디언트 두 원 그리기
	context.strokeStyle = "black";
	context.moveTo(x1+radius1,y1);
	context.arc(x1,y1,radius1,0*Math.PI/180,360*Math.PI/180,false);
	context.moveTo(x2+radius2,y2);
	context.arc(x2,y2,radius2,0*Math.PI/180,360*Math.PI/180,false);
	context.stroke();
	context.closePath();
*/}
2.9 도형에 패턴 채우기
▼ 이미지 패턴으로 도형 채우기
- createPattern(image, "repeat|repeat-x|repeat-y|no-repeat");
- image: Image 객체의 인스턴스, 반복 패턴
var fillImg = new Image();
fillImg.src = "https://t1.daumcdn.net/cfile/tistory/1246853D4F46428C08";
fillImg.onload = function()
 {
	var fillPattern = context.createPattern(fillImg, "repeat-y");
	context.fillStyle = fillPattern;
	context.fillRect(0, 0, 200, 200);
}


♣ API 정리 테이블 ▶ 구글Doc링크
♣ 참고
W3C HTML5 API ▶ http://dev.w3.org/html5/spec/Overview.html 
관련 ▶  http://www.veign.com > 하단의 Dev Center 메뉴


반응형

'HTML5 Canvas' 카테고리의 다른 글

CHAR 4. 캔버스에서의 이미지  (0) 2012.03.01
CHAR 3. HTML5 캔버스 문자 API  (6) 2012.02.29
HTML5 Canvas 관련 사이트  (0) 2012.02.27
CHAR 1. HTML5 캔버스 소개  (2) 2012.02.21
html5canvas 도서 스터디 시작(2/18-3/31)  (0) 2012.02.21