본문으로 바로가기

CHAR 3. HTML5 캔버스 문자 API

category HTML5 Canvas 2012. 2. 29. 10:26
♣ 소스: ch3.zip

• 챕터 목표
1) 캔버스 문자API의 기능과 API간 상호 연관성을 알아보자.
2) 현재 브라우저가 어디까지 지원하는지 알아보자.
3) 그린 문자가 브라우저에 따라 어떻게 다르게 출력되는지 알아보자.
4) 아래 이미지는 챕터의 최종 결과물


3.1 문자 출력의 기본
3.1.1 기본 문자 출력
- CSS폰트 스타일에 값 설정후 context.font 스타일을 설정
context.font = "30px serif";
context.fillStyle = "#ff0000";
context.fillText("Hello World", 50, 80);

3.1.2 Text Arranger에서의 기본적인 문자 출력
- 사용자가 입력한 문자열(msg) 출력

   context.fillStyle = “#ff0000”;
   context.fillText(msg, 100, 80);
- keyup event 처리
- HTML <form> <input> 태그 사용
   <form>
       Text: <input id = “textBox” placeholder = “your text”/> <!-- 호환: placeholder대신 value 사용 -->
   </form>

3.1.3 HTML 폼과 캔버스의 연결
- form 엘리먼트에 이벤트 핸들러 지정하기
   var form = document.getElementById(“textBox”);
   form.addEventListner(“keyup”, eventTextBoxChanged, false);
- eventTextBoxChanged 이벤트 핸들러 작성
   function eventTextBoxChanged(e) {

       var target = e.target;
       msg = target.value;
       drawScreen();
   }

3.1.4 measureText 사용하기
- measureText(msg) : msg에 대한 TextMetrics 객체 리턴
- TextMetrics 객체에는 문자열(msg)의 컨텍스트 설정(폰트 모양, 크기 등)에 대한 속성을 갖는다.
- 현재는 width속성만 지원→ 가운데 정렬에 이용
- 캔버스 가운데 정렬하기
   var metrics = context.measureText(msg);
   var textWidth = metrics.width;
   var xPos = (theCanvas.width/2) - (textWidth/2);
- 문자열의 높이 처리: TextMetrics가 height를 미지원 → 영역의 중간
- 폰트의 기준선(baseline)이 middle(기본값)이라는 가정하면
   var yPos = (theCanvas.height/2);

3.1.5 fillText와 strokeText
- fillText
   context.fillColor = “#990000”;
   context.font = “30px serif”
   fillText(text, x, y, maxWidth);
   #text: 캔버스에 그릴 문자열
   #x, y: 캔버스에서 문자열의 x,y 위치
   #maxWidth: 캔버스에 그릴 문자열의 최대 폭(지원여부 체크)

- strokeText
   context.strokeColor = “blue”;
   context.font = “30px serif”;
   context.strokeText(text, x, y, maxWidth);
   #maxWidth: 지원여부 체크 필요

- TextArranger 에 FillOrStroke 옵션선택 추가
   * HTML
   <select id = “fillOrStroke”>
       <option value = “fill”>fill</option>
       <option value= “stroke”>stroke</option>
       <option value=”both”>both</option>
   </select>
   * JavaScript
   var fillOrStroke = “fill”; // 기본값
   form = document.getElementById(“fillOrStroke”);
   form.addEventListner(“change”, fillOrStrokeChanged, false);

   function fillOrStrokeChanged(e) {
       var target = e.target;
       fillOrStroke = target.value;
       drawScreen();
   }

3.2 문자 폰트 설정
3.2.1 폰트 스타일, 두께, 크기, 종류 의 기본
- context.font = “[style][weight][size][face]”;
- 예:)
context.font = “italic bold 24px serif”;
context.font = “normal lighter 50px cursive”;

3.2.2 Text Arranger에서 폰트 크기와 종류 설정하기
- 표준 폰트 옵션만 사용(대부분 브라우저에서 지원하도록)
① 사용 가능한 폰트 스타일: normal | italic | oblique[영단어:비스듬한, 기울어진] | inherit(미지원)
② 사용 가능한 폰트 두께: normal | bold | bolder | ligher | 100 | 200 | 300 | .. | 900 | inherit | auto
                                (지원: normal | bold | bolder | ligher)
③ 일반적인 폰트 모양(CSS 명세에서 일반적인 폰트라 정의): serif | sans-serif | cursive | fantasy | monospace
④ 폰트 크기와 HTML5 range 컨트롤: 지정한 범위의 숫자를 선택하게 하는 슬라이더(<input> 타입중 하나)
 <input type=”range” id=”textSize” min=”0” max=”200” step=”1” value=”50”/>
   min: 최소값/ max: 최대값 / step: 슬라이더 눈금 단위 / value: 기본값
   ※ 브라우저가 지원하지 않을시 텍스트 박스로 처리된다.

3.2.3 폰트 색상
⑤ 폰트 색상
// 문자색
context.fillStyle = “#ff0000”;
// 문자 테두리색
context.strokeStyle = “#ff00ff”;
▼ JSColor 색성 선택 폼(http://jscolor.com)
   - HTML5 <input> 의 color type 대체(∵현재는 Opera만 지원)
   - 선택한 색상에 대 ‘FF0000’같은 문자를 리턴(앞에 ‘#’이 붙지 않는다)
   - Usage:
* import library
<script type=”text/javascript” src=”jscolor/jscolor.js”></sciprt>
* HTML
<input class=”color” id=”textFillColor” value=”FF0000”/>

3.2.4 폰트 기준선과 정렬
- HTML5 캔버스의 문자졍렬 개념: 문자열의 left, top, right, bottom을 감싸는 보이지 않는 박스에 대한 정렬
- 폰트 기준선(baseline): 폰트 외곽선으로 사용되는 그리드 박스(em square)안에서 세로로 정렬할 때 쓰는 기준선
- 디센더(descender): ‘p’, ‘y’ 같은 활자에서 기준선 밑으로 내려가는 부분
⑥ 세로 정렬: context.textBaseline = “top | hanging | middle | alphabetic | ideographic | bottom”;
   - top: 그리드 박스(em square)의 맨 위 또는 폰트 모양에서 가장 높은 위치가 기준(폰트가 기준선 아래로 내려감)
   - hanging: top 기준선보다 약간 아래(폰트가 걸쳐 있는 것처럼 보이는 위치의 가로선)
   - middle: 세로로 정중앙 기준선
   - alphabetic: 아라비아어, 라틴어, 히브리어 같은 활자의 아래 기준선
   - ideographic: 한글, 가타카나, 히라가나 같은 활자의 아래 기준선
   - bottom: 그리드 박스의 맨 아래 기준, 문자열의 가장 낮은 y 위치가 기준선이 되므로 폰트가 가장 높은 위치로 올라간다.
⑦ 가로 정렬: context.textAlign = “center | start | end | left | right”;
   - center: 가로로 정중앙 위치를 기준
   - start: 문자열의 x 위치 바로 로 출력
   - end: 문자열의 x 위치 바로 으로 출력
   - left: x 위치에 문자열의 가장 왼쪽이 오도록 출력(=start)
   - right: x 위치에 문자열의 가장 오른쪽이 오도록 출력(=end)
   - textAlign 설정 다른 방법: document.canvas.dir = “rtl(right to left) | ltr(left to right)”;
▼ Text Arranger 에서 문자의 기준선과 정렬
   var xPos = (theCanvas.width/2) - (textWidth/2);
                   ||
   var xPos = (theCanvas.width/2);
   context.textAlign = “center”;

3.2.5 Text Arranger 버젼 2.0
3.3 문자와 캔버스 컨텍스트
3.3.1 문자에 투명도 설정하기
- context.globalAlpha = 1.00 ~ 0.00
- 알파값 설정 순서와 횟수 결정시 투명도는 캔버스 전체에 영향을 미친다는 점에 유의한다.

3.3.2 그림자 설정하기
context.shadowColor = “#FF0000”;
context.shadowOffsetX = 5;
context.shadowOffsetY = 5;
context.shadowBlur = 2;
context.shadow();

3.4 문자에 패턴과 그레이디언트 넣기
- fillColor / strokeColor
- 그레이디언트: 선형/방사형/이미지 패턴

3.4.1 선형 그레이디언트와 문자
- 문자열의 시작점~문자열의 폭이 끝점인 선형 그레이디언트
- syntax:
   var gr = contetxt.createLinearGradient(x1, y1, x2, y2);
   gr.addColorStop([offset],[color]);
   (x1, y1): 선의 시작점 ~ (x2, y2): 선의 끝점
   offset: 그레이디언트 선에서 색상이 시작하는 오프셋(0.0~1.0으로 퍼센트를 표현)
- ex:
   var matrics = context.measureText(msg);
   var textWidth = metrics.width;
   var gr = contetxt.createLinearGradient(100, 100, textWidth, 100);
   gr.addColorStop(0, “#000000”);
   gr.addColorStop(.5, “#FF0000”);
- addColorStop()으로 색상-색상 정지점-을 추가하지 않으면 투명하게 그려진다.

3.4.2 방사형 그레이디언트와 문자
- 원뿔대 오양 그레이디언트
- syntax:
   var gr = context.createRadialGradient(x1, y1, radius1, x2, y2, radius2);
   두 원의 중심점과 반지름(시작원,끝 원)
- ex:
   var gr = context.createRidialGradient(100, 100, 20, 200, 100, 5);
   gr.addColorStop(0, “#000000”);
   gr.addColorStop(.5, “#000000”);

3.4.3 이미지 패턴과 문자
- 이미지 패턴 만들기
- syntax:
   var pattern = context.createPattern([image], [repetitation]);
   image: 이미지, 비디오, 다른 <canvas>도 가능
   repetition: 이미지를 타일 형식으로 채우는 방식 (‘repeat | repeat-x | repeat-y | no-repeat’)
- ex:

var patternImg = new Image();
patternImg.src = "texture.jpg";
patternImg.onload = function() {
var pattern = context.createPattern(patternImg, "repeat");
context.fillStyle = pattern;
...
}

3.4.4 Text Arranger에서 그레이디언트와 패턴 처리하기
- eventWindowLoaded()에 이미지가 로딩되었는지 체크 추가
- var fillType: 문자 채울 방식 [색상, 선형 그레이디언트, 방사형 그레이디언트, 이미지 패턴]
- var textFillColor2: 그레이디언트의 색상정지점용 칼라값
- var pattern = new Image(): 이미지 패턴용으로 로드된 이미지 인스턴스

- canvasApp()에 이벤트 리스너 추가
- 이벤트 핸들러 함수 추가
- drawScreen() 추가된 기능 적용 코드 추가
- 그레이디언트 영역 너비: measureText().width 로 너비 구하기

<그레이디언트 기능>
▼ 선형
   - 문자열 시작 위치(가운데 정렬 = xPos - textWidth/2) ~ 끝 위치(textWidth)까지
   - 색상 정지점: 0%(textFillColor), 60%(textFillColor2)
▼ 방사형 (원뿔형)
   - 시작원: 중심점 - 문자열 중간 위치, 반지름 - 폰트 크기
   - 끝원: 중심점 -  문자열 중간 위치, 반지름 - 1  
▼ 패턴
   - 가로/세로 방향으로 반복하는 타일 모양 패턴(repeat)

3.5 폭, 높이, 스케일, toDataURL() 다시 보기
3.5.1 동적으로 캔버스 크기 조절하기
▼ 캔버스 크기 변환이 필요한 때?
   - 로드된 비디오 객체의 크기로 캔버스 크기를 바꿀 때
   - 페이지가 로드된 후 캔버스에 동적으로 애니메이션 효과를 넣으려고 할 때
   - 기타

▼ 캔버스의 크기 변환( ≠ scaling)
canvas.width = 600;
canvas.height = 500;
drawScreen();
※ 크기를 바꾸면 캔버스가 모두 지워진다.

▼ Text Arranger에 캔버스 크기 변환 기능 추가
① width, height 컨트롤 추가
Canvas Width:
<input type=”range” id=”canvasWidth” min=”0” max=”1000” step=”1” value=”500”/><br/>
Canvas Height:
<input type=”range” id=”canvasHeight” min=”0” max=”1000” step=”1” value=”500”/><br/>
② 이벤트 리스너 추가

form = document.getElementById(“canvasWidth”);
form.addEventListner(“change”, canvasWidthChanged, false);

form = document.getElementById(“canvasHeight”);
form.addEventListner(“change”, canvasHeightChanged, false);

③ 이벤트 핸들러 함수 추가
function canvasWidthChanged(e) {
   var target = e.target;
   theCanvas.width = target.value;
   drawScreen();
}

function canvasHeightChanged(e) {
   var target = e.target;
   theCanvas.height = target.value;
   drawScreen();
}

③ 배경 그리기(∵다시그리기) - 배경색/테두리
context.fillStyle = “#ffffaa”;
context.fillRect(0, 0, theCanvas.width, theCanvas.height);

context.strokeStyle = “black”;
context.strokeRect(5, 5, theCanvas.width-10, theCanvas.height-10);

3.5.2 동적으로 캔버스 스케일하기
- 캔버스 크기변환은 canvas.width, canvas.height / 스케일은: css style 사용
style = “width: 400px; height: 400px”;


▼ Text Arranger에 스케일 추가
① 입력폼 추가
Canvas Style Width: <input type=”range” id=”canvasStyleWidth” min=”0” max=”1000” step=”1” value=”500”/>
Canvas Style Height: <input type=”range” id=”canvasStyleHeight” min=”0” max=”1000” step=”1” value=”500”/>

② 이벤트 리스너
form = document.getElementById(“canvasStyleWidth”);
form.addEventListner(“change”, canvasStyleSizeChanged, flase);

form = document.getElementById(“canvasStyleHeight”);
form.addEventListner(“change”, canvasStyleSizeChanged, flase);

③ 이벤트 해들러 함수
function canvasStyleSizeChanged(e) {
   var styleWidth = document.getElementById(“canvasStyleWidth”);
   var styleHeight = document.getElementById(“canvasStyleHeight”);
   var styleValue = “width:”+styleWidth.value+”px; height:”+styleHeight.value+”px;”;
   theCanvas.setAttribute(“style”, styleValue);
   drawScreen();
}
- css style 스케일은 canvas 크기에 영향을 미친다.

3.5.3 toDataURL() 메서드
- toDataURL(imagetype, ziplevel): 캔버스의 이미지 데이터를 나타내는 문자열을 리턴
- toDataURL(‘image/png’(default) | {‘image/jpg’, 압축레벨.0~1.0 }
▼ 이미지 데이터 만들기 기능 추가
① 폼 추가
<input type=”button” id=”createImageData” value=”Create Image Data”></input>
<br/><br/>
// 이미지의 문자열 데이터를 출력
<textarea id=”imageDataDisplay” rows=10 cols=30></textarea>

② 이벤트 리스너
form = document.getElementById(“createImageData”);
form.addEventListner(“click”, createImageDataPressed, false);

③ 이벤트 핸들러
function createImageDataPressed(e) {
   var imageDataDisplay = document.getElementById(“createImageData”);
   imageDataDisplay.value = theCanvas.getDataURL(); // theCanvas.getDataURL(“image/jpg”, .5);
   window.open(imageDataDisplay.value, “canvasImage”,
“left=0, top=0, width=”+theCanvas.width+”,height=”+theCanvas.height+”,toolbar=0,resizable=0”);
}

※ SECURITY_ERR: DOM Exception 18
- 구글 크롬이나 몇몇 웹 브라우저에서 캔버스 이미지를 브라우저의 새 창으로 내보낼때(또는 패턴에 비디오를 사용할 때) 이 에러가 발생.
- 브라우저가 파일시스템으로부터 웹 페이지를 로드할 때 주로 발생
- 원격 웹 서버나 로컬 컴퓨터의 웹 서버로부터 HTML 페이지를 로드하면 에러 발생 안함.

3.6 Text Arranger 최종버젼 (3.0)
▼ 주의사항
- 그림자는 패턴이나 그레이디언트가 들어가지 않는다.
- 캔버스 크기의 패턴을 갖는 문자열의 크기가 증가하면 문자열 속의 패턴 모양이 변한다(캔버스 크기의 패턴이 바탕이고 위에 문자 모양으로 뚫린 창문 또는 마스크가 커지는 것처럼 보임)
♠ 해보기: Text Arranger 3.0 작성해보기 (예제3-3)




Text [http://www.w3schools.com/html5/html5_ref_canvas.asp]
Attribute Value Description
font fontproperties Specifies font properties used for writing on the canvas
textAlign start
end
left
right
center
The alignment of the text, "start" is default
textBaseline alphabetic
bottom
hanging
ideographic
middle
top
The vertical alignment of the text, "alphabetic" is default
Method Description
fillText(text,x,y,maxWidth) Draws text on the canvas, and fills it with the color set by the fillStyle attribute
strokeText(text,x,y,maxWidth) Draws text on the canvas, without filling, using the color set by the strokeStyle attribute.
measureText(text).width Measures the given text string, returns the result in pixels

반응형