ìºë²ì¤(canvas)를 ì´ì©í ëí 그리기
ìì ìºë²ì¤ íê²½ ì¤ì (canvas environment)ì ìë£ íìë¤ë©´, ì´ì ì´ë»ê² ìºë²ì¤ì 그릴ì ìëì§ì ëíì¬ ìì¸íê² ììë´ ìë¤. ì´ ê¸ì ëë´ê³ ë í, ì¬ë¬ë¶ì ì´ë»ê² ì¬ê°í, ì¼ê°í, ì , ìì¹, 곡ì ë± ì 기본ì ì¸ ëíì 그릴ì ìëì§ ìµíì¤ ì ìì ê² ì ëë¤. ìºë²ì¤ ìì 물체를 그릴 ëìë path를 ì¬ì©íëê²ì´ íìì ì´ë¯ë¡ ì°ë¦¬ë ì´ê²ì´ ì´ë»ê² ì¬ì©ëëì§ ë³¼ ê²ì ëë¤.
그리ë
ëë¡ìì ìì í기ì ìì, ìºë²ì¤ 그리ë í¹ì ì¢íê³µê° (coordinate space) ì ëíì¬ ì´ì¼ê¸° í´ë³´ê² ìµëë¤. ì´ì íì´ì§ìì ì´ì¼ê¸° íë HTML 골격(skeleton)ë ê°ë¡ ì¸ë¡ ê°ê° 150 í½ì
ì ìºë²ì¤ ìì를 ê°ì§ê³ ììµëë¤. ì¤ë¥¸ìª½ì ë³´ìë©´, ìºë²ì¤ì 기본 그리ëê° ëì¸ê²ì ë³´ì¤ ì ììµëë¤. 기본ì ì¼ë¡ 그리ëì 1ë¨ìë ìºë²ì¤ì 1í½ì
ê³¼ ê°ìµëë¤. ì´ ê·¸ë¦¬ëì ìì ì ì¢ì¸¡ìë¨ì (0,0) ì
ëë¤. 모ë ììë¤ì ì´ ìì ì 기ì¤ì¼ë¡ ìì¹ë©ëë¤. ê·¸ë 기 ë문ì, íë ì¬ê°íì ì¢ì¸¡ìë¨ì ì¼ìª½ìì x í½ì
, ììì y í½ì
ë¨ì´ì§ ê²ì´ë¼ ë³¼ ì ìê³ , ì´ ì¬ê°íì ì¢íë (x,y)ê° ë©ëë¤. ì´ íí ë¦¬ì¼ íë°ë¶ìì ì´ë»ê² ìì ì ì´ëíë©°, 그리ë를 íì íê³ ê°ì ë¹ì¨ë¡ íë/ì¶ìí ì ìëì§ ì´í´ë³¼ ê²ì´ì§ë§, ì§ê¸ì 기본ì ì¶©ì¤íëë¡ í©ìë¤.
ì§ì¬ê°í 그리기
SVG ìë ë¤ë¥´ê², <canvas>ë ì¤ì§ íëì ììì ì¸ ëíë§ì ì ê³µí©ëë¤. ë°ë¡ ì§ì¬ê°í ì
ëë¤. ë¤ë¥¸ 모ë ëíë¤ì 무조건 íë í¹ì íë ì´ìì path ì ì¬ë¬ ì ì¼ë¡ ì´ì´ì§ ì ì¼ë¡ ë§ë¤ì´ì§ëë¤. ë¤ííë, ì°ë¦¬ë ì¬ë¬ path drawing í¨ì(function)ë¤ì íµí´ ì주 ì´ë ¤ì´ ëíë¤ë 그릴ì ììµëë¤.
첫ë²ì§¸ë¡, ì§ì¬ê°íì ë´ ìë¤. ìºë²ì¤ ìì ì§ì¬ê°íì 그리ëë°ìë ì¸ê°ì§ í¨ì(function)ê° ììµëë¤:
fillRect(x, y, width, height)-
ìì¹ ë ì§ì¬ê°íì 그립ëë¤.
strokeRect(x, y, width, height)-
ì§ì¬ê°í ì¤ê³½ì ì 그립ëë¤.
clearRect(x, y, width, height)-
í¹ì ë¶ë¶ì ì§ì°ë ì§ì¬ê°íì´ë©°, ì´ ì§ìì§ ë¶ë¶ì ìì í í¬ëª í´ì§ëë¤.
ê°ê°ì ì¸ í¨ìë 모ë ê°ì ë³ì를 ê°ì§ëë¤. xì yë ìºë²ì¤ì ì¢ì¸¡ìë¨ìì ì¬ê°íì (ìì ì¼ë¡ë¶í° ìëì ì¸) ìì¹ë¥¼ ë»íë©°, width ì heightë ì¬ê°íì í¬ê¸°ë¥¼ ë»íê² ë©ëë¤.
ì íì´ì§ìì ë³´ì¬ëë ¸ë draw() í¨ì(function)를 ì´ì©íì¬ ìì ì¸ê°ì§ í¨ì를 ìëì ìì ì ì ì©í´ ë³´ììµëë¤.
ì§ì¬ê°í ëí ìì
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillRect(25, 25, 100, 100);
ctx.clearRect(45, 45, 60, 60);
ctx.strokeRect(50, 50, 50, 50);
}
}
ì ìì ì ê²°ê³¼ë ë¤ìê³¼ ê°ìµëë¤.
fillRect() í¨ìë ê°ë¡ ì¸ë¡ 100 í½ì
ì¬ì´ì¦ì ê²ì ì¬ê°íì 그립ëë¤. ì´í clearRect() í¨ìê° 60x60 í½ì
ì ì¬ê°í í¬ê¸°ë¡ ëí ì¤ìì ì§ì°ê² ëê³ , strokeRect()ì ì´ ë¹ ì¬ê°í ê³µê° ìì 50x50 í½ì
ì¬ì´ì¦ì ì¤ê³½ì ë§ ìë ì¬ê°íì ë§ë¤ê² ë©ëë¤.
ë¤ì íì´ì§ìì, ì°ë¦¬ë clearRect()를 ëì íë ëê°ì í¨ìì ëí´ ì´í´ë³´ê³ , ë§ë¤ì´ì§ ëíì ìì´ë ì¤ê³½ì ì ì¤íì¼ì ë°ê¾¸ë ë°©ë²ë¤ì ëíì¬ ììë³´ëë¡ íê² ìµëë¤.
ì°ë¦¬ê° ë¤ì ì¹ì ìì ë³´ê²ë path í¨ìì ë¤ë¥´ê² ì¸ê°ì ì§ì¬ê°í í¨ìë ìºë²ì¤ì ë°ë¡ 그릴 ì ììµëë¤.
ê²½ë¡ ê·¸ë¦¬ê¸°
*ê²½ë¡(path)*ë ì§ì¬ê°í ì´ì¸ì ì ì¼í ììì ì¸(primitive) ëíì ëë¤. ê²½ë¡ë ì ë¤ì ì§í©ì´ë©°, ì ì í ë¶ë¶ì¼ë¡ ì°ê²°ëì´ ì¬ë¬ê°ì§ ëí, 곡ì ì ì´ë£¨ê³ ëê»ì ìì ëíë´ê² ë©ëë¤. ê²½ë¡ë íì ê²½ë¡(sub-path)ë ë«í ì ììµëë¤. ê²½ë¡ë¥¼ ì´ì©íì¬ ëíì ë§ë¤ ëìë ëªê°ì§ ì¶ê°ì ì¸ ë¨ê³ë¥¼ ê±°ì³ì¼ í©ëë¤:
- ê²½ë¡ë¥¼ ìì±í©ëë¤.
- 그리기 ëª ë ¹ì´ë¥¼ ì¬ì©íì¬ ê²½ë¡ìì 그립ëë¤.
- ê²½ë¡ê° íë² ë§ë¤ì´ì¡ë¤ë©´, ê²½ë¡ë¥¼ ë ëë§ í기 ìí´ì ì¤ê³½ì ì 그리거ë ëí ë´ë¶ë¥¼ ì±ì¸ì ììµëë¤.
ë¤ìì ìì ë¨ê³ë¤ì ì¤íí기 ìí´ ì¬ì©ëë í¨ìì ëë¤:
beginPath()-
ìë¡ì´ ê²½ë¡ë¥¼ ë§ëëë¤. ê²½ë¡ê° ìì±ë¬ë¤ë©´, ì´í 그리기 ëª ë ¹ë¤ì ê²½ë¡ë¥¼ 구ì±íê³ ë§ëëë° ì¬ì©íê² ë©ëë¤.
- Path ë©ìë (Path methods)
-
물체를 구ì±í ë íìí ì¬ë¬ ê²½ë¡ë¥¼ ì¤ì íëë° ì¬ì©íë í¨ìì ëë¤.
closePath()-
íì¬ íì ê²½ë¡ì ìì ë¶ë¶ê³¼ ì°ê²°ë ì§ì ì ì¶ê°í©ëë¤.
stroke()-
ì¤ê³½ì ì ì´ì©íì¬ ëíì 그립ëë¤.
fill()-
ê²½ë¡ì ë´ë¶ë¥¼ ì±ìì ë´ë¶ê° ì±ìì§ ëíì 그립ëë¤.
ê²½ë¡ë¥¼ ë§ë¤ê¸° ìí 첫ë²ì§¸ ë¨ê³ë beginPath() ë©ìë를 ì¬ì©íë ê² ì
ëë¤. ë´ë¶ì ì¼ë¡, ê²½ë¡ë ëíì ì´ë£¨ë íìê²½ë¡(ì , ìì¹ ë±)ë¤ì ì§í©ì¼ë¡ ì´ë£¨ì´ì ¸ììµëë¤. ì´ ë©ìëê° í¸ì¶ë ë ë§ë¤, íì ê²½ë¡ì 모ìì ì´ê¸°íëë©°, ì°ë¦¬ë ìë¡ì´ ëíì 그릴 ì ìê² ë©ëë¤.
ì°¸ê³ :
íì¬ ì´ë¦° pathê° ë¹ì´ìë ê²½ì° ( beginPath() ë©ìë를 ì¬ì©í ì§ í, í¹ììºë²ì¤ë¥¼ ìë¡ ìì±í ì§í), 첫 ê²½ë¡ ìì± ëª
ë ¹ì ì¤ì ëìì ìê´ ìì´ moveTo()ë¡ ì¬ê²¨ì§ê² ë©ëë¤. ê·¸ë 기 ë문ì ê²½ë¡ë¥¼ ì´ê¸°íí ì§íìë íì ëª
ííê² ìì ìì¹ë¥¼ ì¤ì í´ ëëê²ì´ ì¢ìµëë¤.
ëë²ì§¸ ë¨ê³ë ì¤ì ë¡ ê²½ë¡ê° ê·¸ë ¤ì§ë ìì¹ë¥¼ ì¤ì íë ë©ìë를 í¸ì¶íë ê² ì ëë¤. ì´ ë´ì©ì ëí´ìë ê³§ ë³´ì¤ì ììµëë¤.
ì¸ë²ì§¸ ë¨ê³ë ì íì¬íì¼ë¡ closePath() ë©ìë를 í¸ì¶íë ê² ì
ëë¤. ì´ ë©ìëë íì¬ ì ìì¹ì ììì ìì¹ë¥¼ ì§ì ì¼ë¡ ì´ì´ì ëíì ë«ìµëë¤. ì´ë¯¸ ëíì´ ë«íê±°ë í ì ë§ ì¡´ì¬íë¤ë©´, ì´ ë©ìëë ì무ê²ë íì§ ììµëë¤.
ì°¸ê³ :
fill() ë©ìë í¸ì¶ ì, ì´ë¦° ëíì ìëì¼ë¡ ë«íê² ëë¯ë¡ closePath()ë©ìë를 í¸ì¶íì§ ììë ë©ëë¤. ì´ê²ì stroke() ë©ìëìë ì ì©ëì§ ììµëë¤.
ì¼ê°í 그리기
ì를 ë¤ì´, ì¼ê°íì 그리기 ìí ì½ëë ë¤ìê³¼ ê°ìµëë¤:
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(75, 50);
ctx.lineTo(100, 75);
ctx.lineTo(100, 25);
ctx.fill();
}
}
ì ì½ëì ì¤í ê²°ê³¼ë ë¤ìê³¼ ê°ìµëë¤:
í(pen) ì´ëí기
ê°ì¥ ì ì©í í¨ìì¤ì ì¤ì ë¡ ì´ë¤ ê²ë ê·¸ë¦¬ì§ ìì§ë§ ììì ì¸ê¸í ê²½ë¡ì ì¼ë¶ê° ëë moveTo() í¨ìê° ììµëë¤. ì´ë íì´ë ì°íì ì¢
ì´ììì ë¤ì´ ìì¼ë¡ ì®ê¸°ëê²ì´ë¼ê³ ë³´ìë©´ ë©ëë¤.
moveTo(x, y)-
íì xì y ë¡ ì§ì ë ì¢íë¡ ì®ê¹ëë¤.
ìºë²ì¤ê° ì´ê¸°í ëìê±°ë beginPath() ë©ìëê° í¸ì¶ëìì ë, í¹ì ììì ì¤ì ì ìí´ moveTo() í¨ì를 ì¬ì©íëê²ì´ ì¢ìµëë¤. ëí moveTo() í¨ìë ì°ê²°ëì§ ìì ê²½ë¡ë¥¼ 그리ëë°ìë ì¬ì© í ì ììµëë¤. ìëì ì¤ë§ì¼ ìì´ì½ì ë´
ìë¤.
ì½ë snippetì ì¬ì©í´íì¬ ì§ì ìëíì¬ ë³´ì¸ì. ììì ë³´ìë draw() í¨ì(function)를 ë¶íë£ê¸° í´ ë³´ì¸ì.
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Outer circle
ctx.moveTo(110, 75);
ctx.arc(75, 75, 35, 0, Math.PI, false); // Mouth (clockwise)
ctx.moveTo(65, 65);
ctx.arc(60, 65, 5, 0, Math.PI * 2, true); // Left eye
ctx.moveTo(95, 65);
ctx.arc(90, 65, 5, 0, Math.PI * 2, true); // Right eye
ctx.stroke();
}
}
ê²°ê³¼ë ë¤ìê³¼ ê°ìµëë¤:
moveTo()를 ì¬ì©í ì½ëë¼ì¸ì ì§ì°ë©´ ì°ê²°ë ì ë¤ì íì¸ í ì ììµëë¤
ì°¸ê³ :
arc() functionì ëíì¬ ë ììë³´ê³ ì¶ë¤ë©´ ìëì Arcs 를 íì¸íì¸ì.
ì
ì§ì ì 그리기 ìí´ìë lineTo() ë©ìë를 ì¬ì©í ì ììµëë¤.
lineTo(x, y)-
íì¬ì ëë¡ì ìì¹ìì xì yë¡ ì§ì ë ìì¹ê¹ì§ ì ì 그립ëë¤.
ì´ ë©ìëë ì ì ëì ì ì¢íê° ëë xì yì ëê°ì ì¸ìê° íìí©ëë¤. ììì ì ì´ì ì ê·¸ë ¤ì§ ê²½ë¡ì ìí´ ê²°ì ëë©°, ì´ì ê²½ë¡ì ëì ì´ ë¤ì ê·¸ë ¤ì§ë ê²½ë¡ì ììì ì´ ë©ëë¤. ëí ììì ì moveTo() ë©ìë를 íµí´ ë³ê²½ë ì ììµëë¤.
ìëì ììë íëì ë ì¼ê°í (ì¤ê³½ì ì¼ê°í, ìì¹ ë ì¼ê°í)ì 그립ëë¤.
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
// Filled triangle
ctx.beginPath();
ctx.moveTo(25, 25);
ctx.lineTo(105, 25);
ctx.lineTo(25, 105);
ctx.fill();
// Stroked triangle
ctx.beginPath();
ctx.moveTo(125, 125);
ctx.lineTo(125, 45);
ctx.lineTo(45, 125);
ctx.closePath();
ctx.stroke();
}
}
ìë¡ì´ ê²½ë¡ë¥¼ ì§ì í기 ìí´ beginPath() ë©ìë를 먼ì ì¤íí©ëë¤. ê·¸ ë¤ì moveTo() ë©ìë를 ê°ì§ê³ ììì ì ìíë ìì¹ë¡ ìë¡ê² ì§ì í´ ì¤ëë¤. ë¤ìì, ëì ì ê·¸ì´ ì¼ê°íì ë ë©´ì ê·¸ë ¤ì¤ëë¤.
ì¬ë¬ë¶ì ì±ìì§ ì¼ê°íê³¼ ì¤ê³½ì ì¼ê°íì ì°¨ì´ë¥¼ íì¸ íì
¨ì ê²ëë¤. ìì ì¸ê¸íë ê² ì²ë¼, ê²½ë¡ê° ì±ìì§ê² ëë©´ ê·¸ ëíì ìëì¼ë¡ ë«íê² ëì§ë§ ì¤ê³½ì ì¼ê°íììë ê·¸ë ì§ ì기 ë문ì
ëë¤. ë§ì½ì closePath() ë©ìë를 ì¤ê³½ì ì¼ê°í ì½ëìì ì§ì´ë¤ë©´, ì¤ì§ ë ì ë§ ê·¸ë ¤ì§ê² ëë©° ìë²½í ì¼ê°íì¼ë¡ ë§ë¤ì´ì§ì§ ììµëë¤.
í¸(arc)
í¸ë ìì 그리기ìí´ìë arc() í¹ì arcTo() ë©ìë를 ì¬ì©í©ëë¤..
arc(x, y, radius, startAngle, endAngle, anticlockwise)-
(x, y) ìì¹ì ìì ì ëë©´ì, ë°ì§ë¦ rì ê°ì§ê³ , startAngle ìì ììíì¬ endAngle ìì ëëë©° 주ì´ì§ anticlockwise ë°©í¥ì¼ë¡ í¥íë (기본ê°ì ìê³ë°©í¥ íì ) í¸ë¥¼ ê·¸ë¦¬ê² ë©ëë¤.
arcTo(x1, y1, x2, y2, radius)-
주ì´ì§ ì ì´ì ë¤ê³¼ ë°ì§ë¦ì¼ë¡ í¸ë¥¼ ê·¸ë¦¬ê³ , ì´ì ì ê³¼ ì§ì ì¼ë¡ ì°ê²°í©ëë¤.
arc ë©ìëì ì¬ì¯ê°ì 매ê°ë³ìì ëíì¬ ì¢ ë ìì¸íê² ììë´
ìë¤: x ì yë í¸ë¥¼ 그릴 ë íìí ìì ì¢íì
ëë¤. ë°ì§ë¦(radius) ì ë§ ê·¸ëë¡ í¸ì ë°ì§ë¦ì ë»í©ëë¤. startAngle ë° endAngle ë§¤ê° ë³ìë ìì 커ë¸ë¥¼ ë°ë¼ í¸ì ììì ê³¼ ëì ì ë¼ëì ë¨ìë¡ ì ìí©ëë¤. ì´ ë³ìë¤ì xì¶ì 기ì¤ì¼ë¡ ê³ì°ë©ëë¤. Boolean ê°ì ê°ì§ë anticlockwise ë³ìë trueì¼ ë í¸ë¥¼ ë°ìê³ ë°©í¥ì¼ë¡ ê·¸ë¦¬ê² ëë©°, ê·¸ë ì§ ìì ê²½ì°ìë ìê³ ë°©í¥ì¼ë¡ ê·¸ë¦¬ê² ë©ëë¤.
ì°¸ê³ :
arc í¨ììì ê°ëë ê°ì´ ìë ë¼ëì ê°ì ì¬ì©í©ëë¤. ê°ë를 ë¼ëìì¼ë¡ ë°ê¾¸ë ¤ë©´ ë¤ìì JavaScript(JavaScript) ì½ë를 ì¬ì©íì¤ ì ììµëë¤: radians = (Math.PI/180)*degrees.
ë¤ìì ìì ë ì°ë¦¬ê° ì´ì ê» ë´ ìë ìì ë¤ ë³´ë¤ ì½ê° ë ë³µì¡í©ëë¤. ì´ ìì ë 12ê°ì§ì ë¤ìí ê°ëë¡ ì±ìì§ ê°ê¸° ë¤ë¥¸ í¸ë¥¼ 그립ëë¤.
ëê°ì for loopsì 루í를 íµí´ í¸(arc)ë¤ì íê³¼ ì´ì ì½ê¸° ìí´ ì¬ì©ëììµëë¤. beginPath()를 ì¬ì©í´ ê° í¸ì ìë¡ì´ ê²½ë¡ë¥¼ ë§ëëë¤. ì½ë ë´ìì, ê°ê°ì 매ê°ë³ìë¤ì ëª
ííê² ë³´ì¬ì£¼ê¸° ìí´ ë³ìë¡ ì ì íìì§ë§, ì¤ì ë¡ ì¬ì©í ë ê¼ íìí ê²ì ìëëë¤.
xì y ì¢íë ì¶©ë¶í ëª
ííê² í기ëì´ì¼ í©ëë¤. radius ì startAngleì ê³ ì ëì´ ììµëë¤. endAngleë ì²ì 180ë (ë°ì) ìì ììíê³ ì´í ë§¤ë² 90ëì© ì¦ê°íë¤ê° ë§ì§ë§ ì´ìì ìë²½í ìì 그립ëë¤.
clockwise ë§¤ê° ë³ì를 ì§ì í ê²°ê³¼ë¡ ì²«ë²ì§¸ì ì¸ë²ì§¸ ì¤ì ìê³ë°©í¥ì¼ë¡ ìí¸ë¤ì´ ê·¸ë ¤ì¡ê³ ëë²ì§¸ì ë¤ë²ì§¸ ì¤ìë ë°ìê³ë°©í¥ì ìí¸ë¤ì´ ê·¸ë ¤ì¡ìµëë¤. ë§ì§ë§ì¼ë¡ if 문ì ì ë°ìª½ì´ ì¤ê³½ì ì¼ë¡, ìë ë°ìª½ì´ ìì¼ë¡ ì±ìì§ í¸ë¤ì ë§ë¤ì´ ë
ëë¤.
ì°¸ê³ : ì´ ìì ë ë¤ë¥¸ ìì ë¤ ë³´ë¤ ë í°ì¬ì´ì¦ì ìºë²ì¤ê° íìí©ëë¤: 150 x 200 í½ì
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 3; j++) {
ctx.beginPath();
var x = 25 + j * 50; // x coordinate
var y = 25 + i * 50; // y coordinate
var radius = 20; // Arc radius
var startAngle = 0; // Starting point on circle
var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle
var anticlockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
if (i > 1) {
ctx.fill();
} else {
ctx.stroke();
}
}
}
}
}
ë² ì§ì´(Bezier) 곡ì ê³¼ ì´ì°¨(Quadratic )곡ì
ë¤ì ê²½ë¡ íì ì ë² ì§ì´ 곡ì (Bézier curves)ì¼ë¡, ì¼ì°¨(cubic)ì ì´ì°¨(quadric) ë³ìê° ëª¨ë ê°ë¥í©ëë¤. ì´ íì ì ëê² ë³µì¡í ì 기체ì íí (organic shape)를 그리ëë° ì¬ì©ë©ëë¤.
quadraticCurveTo(cp1x, cp1y, x, y)-
cp1xë°cp1yë¡ ì§ì ë ì ì´ì ì ì¬ì©íì¬ íì¬ íì ìì¹ììxìyë¡ ì§ì ë ëì ê¹ì§ ì´ì°¨ ë² ì§ì´ 곡ì ì 그립ëë¤. bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)-
(
cp1x,cp1y) ë° (cp2x, cp2y)ë¡ ì§ì ë ì ì´ì ì ì¬ì©íì¬ íì¬ í ìì¹ììxë°yë¡ ì§ì ë ëì ê¹ì§ ì¼ì°¨ ë² ì§ì´ 곡ì ì 그립ëë¤.
ì¤ë¥¸ìª½ì ì¬ì§ì ë 곡ì ì ì°¨ì´ë¥¼ ê°ì¥ ì ì¤ëª
í´ì£¼ê³ ììµëë¤. ì´ì°¨ ë² ì§ì 곡ì ì ììì ê³¼ ëì (íëì ì ) ê·¸ë¦¬ê³ íëì ì ì´ì (control point, ë¹¨ê° ì ì¼ë¡ íì)ì ê°ì§ê³ ìì§ë§, ì¼ì°¨ ë² ì§ì 곡ì ì ëê°ì ì ì´ì ì ì¬ì©íê³ ììµëë¤.
ë ë©ìëì 모ë ì¬ì©ëë xì y ë³ìë 모ë ëì ì ì¢í를 ëíë
ëë¤. 첫ë²ì§¸ ì ì´ì ì cp1x ì cp1y ì¢íë¡, ëë²ì§¸ ì ì´ì ì cp2x ì cp2y ì¢íë¡ íìëììµëë¤.
ì´ì°¨ ë° ì¼ì°¨ ë² ì§ì´ 곡ì ì ì¬ì©íë ê²ì ë§¤ì° ì´ë ¤ì¸ ì ììµëë¤. Adobe Illustratorì ê°ì ë²¡í° ëë¡ì ìíí¸ì¨ì´ìë ë¬ë¦¬, ì°ë¦¬ë íì¬ ìíì¤ì¸ ìì ì ëí´ ì§ì ì ì¸ ìê°ì í¼ëë°±ì ë°ì ì ì기 ë문ì ëë¤. ì´ë° ì ì ë³µì¡í 모ìì 그리기 ì´ë µëë¡ í©ëë¤. ë¤ì ìì ìì ì°ë¦¬ë ê°ë¨í ì 기체ì ííë§ ê·¸ë¦¬ëë¡ íê² ì§ë§, ì¬ë¬ë¶ì´ ì°ìµê³¼ ìê°ì í¬ì íì ë¤ë©´, ì´íì ëì± ë³µì¡í ëíì 그릴ì ìê² ë ê²ì ëë¤.
ì´ ìì ë ì주 ì´ë ¤ì´ ì ì ììµëë¤. ë ê²½ì° ëª¨ë ì°ìë 곡ì ì´ ê·¸ë ¤ì§ë©´ì ìµì¢ 모ìì´ ìì±ë©ëë¤.
ì´ì°¨ ë² ì§ì 곡ì (Quadratic Bezier curves)
ì´ ìì ë ì¬ë¬ê°ì ì´ì°¨ ë² ì§ì´ 곡ì ì ì´ì©í´ ë§íì ì ë§ë¤ì´ ë ëë¤.
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
// Quadratric curves example
ctx.beginPath();
ctx.moveTo(75, 25);
ctx.quadraticCurveTo(25, 25, 25, 62.5);
ctx.quadraticCurveTo(25, 100, 50, 100);
ctx.quadraticCurveTo(50, 120, 30, 125);
ctx.quadraticCurveTo(60, 120, 65, 100);
ctx.quadraticCurveTo(125, 100, 125, 62.5);
ctx.quadraticCurveTo(125, 25, 75, 25);
ctx.stroke();
}
}
ì¼ì°¨ ë² ì§ì´ 곡ì (Cubic Bezier curves)
ì´ ìì ë ì¼ì°¨ 곡ì ì ì´ì©íì¬ íí¸ë¥¼ 그립ëë¤.
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
// Cubic curves example
ctx.beginPath();
ctx.moveTo(75, 40);
ctx.bezierCurveTo(75, 37, 70, 25, 50, 25);
ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
ctx.bezierCurveTo(20, 80, 40, 102, 75, 120);
ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
ctx.bezierCurveTo(85, 25, 75, 37, 75, 40);
ctx.fill();
}
}
ì§ì¬ê°í
ì§ì¬ê°íì ìºë²ì¤ì ì§ì 그리ë ì§ì¬ê°í 그리기ìì 본 ì¸ ê°ì§ ë©ìë ì¸ì rect() ë©ìëë ììµëë¤. ì´ ë©ìëë íì¬ ì´ë¦° í¨ì¤ì ì§ì¬ê°í ê²½ë¡ë¥¼ ì¶ê°í©ëë¤.
rect(x, y, width, height)-
ì¢ì¸¡ìë¨ì´ (x, y)ì´ê³ íê³¼ ëì´ê°
widthìheightì¸ ì§ì¬ê°íì 그립ëë¤.
ì´ ë©ìëê° ì¤íë기 ì ì, (x,y) 매ê°ë³ì를 ê°ì§ moveTo() ë©ìëê° ìëì¼ë¡ í¸ì¶ë©ëë¤. ì¦, íì¬ì íìì¹ê° ìëì¼ë¡ 기본 ì¢íë¡ ì´ê¸°í ë©ëë¤.
ì¡°í©í기
ì´ì ê¹ì§ ì´ íì´ì§ì ìì ë¤ì ê°ê°ì ëíë§ë¤ íëì path í¨ì를 ê°ì§ê³ ìììµëë¤. íì§ë§ ëíì ë§ëëë°ì ì¬ì©ëë ê²½ë¡ì ì¢ ë¥ì ê°ìë ì íì´ ììµëë¤. ê·¸ë 기 ë문ì ì´ ë§ì§ë§ ìì ììë 모ë ê²½ë¡ í¨ì를 í©ì³ ì¬ë¬ ê²ì ìºë¦í°ë¤ì ê·¸ë ¤ë³´ëë¡ íê² ìµëë¤.
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
roundedRect(ctx, 12, 12, 150, 150, 15);
roundedRect(ctx, 19, 19, 150, 150, 9);
roundedRect(ctx, 53, 53, 49, 33, 10);
roundedRect(ctx, 53, 119, 49, 16, 6);
roundedRect(ctx, 135, 53, 49, 33, 10);
roundedRect(ctx, 135, 119, 25, 49, 10);
ctx.beginPath();
ctx.arc(37, 37, 13, Math.PI / 7, -Math.PI / 7, false);
ctx.lineTo(31, 37);
ctx.fill();
for (var i = 0; i < 8; i++) {
ctx.fillRect(51 + i * 16, 35, 4, 4);
}
for (i = 0; i < 6; i++) {
ctx.fillRect(115, 51 + i * 16, 4, 4);
}
for (i = 0; i < 8; i++) {
ctx.fillRect(51 + i * 16, 99, 4, 4);
}
ctx.beginPath();
ctx.moveTo(83, 116);
ctx.lineTo(83, 102);
ctx.bezierCurveTo(83, 94, 89, 88, 97, 88);
ctx.bezierCurveTo(105, 88, 111, 94, 111, 102);
ctx.lineTo(111, 116);
ctx.lineTo(106.333, 111.333);
ctx.lineTo(101.666, 116);
ctx.lineTo(97, 111.333);
ctx.lineTo(92.333, 116);
ctx.lineTo(87.666, 111.333);
ctx.lineTo(83, 116);
ctx.fill();
ctx.fillStyle = "white";
ctx.beginPath();
ctx.moveTo(91, 96);
ctx.bezierCurveTo(88, 96, 87, 99, 87, 101);
ctx.bezierCurveTo(87, 103, 88, 106, 91, 106);
ctx.bezierCurveTo(94, 106, 95, 103, 95, 101);
ctx.bezierCurveTo(95, 99, 94, 96, 91, 96);
ctx.moveTo(103, 96);
ctx.bezierCurveTo(100, 96, 99, 99, 99, 101);
ctx.bezierCurveTo(99, 103, 100, 106, 103, 106);
ctx.bezierCurveTo(106, 106, 107, 103, 107, 101);
ctx.bezierCurveTo(107, 99, 106, 96, 103, 96);
ctx.fill();
ctx.fillStyle = "black";
ctx.beginPath();
ctx.arc(101, 102, 2, 0, Math.PI * 2, true);
ctx.fill();
ctx.beginPath();
ctx.arc(89, 102, 2, 0, Math.PI * 2, true);
ctx.fill();
}
}
// A utility function to draw a rectangle with rounded corners.
function roundedRect(ctx, x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x, y + radius);
ctx.lineTo(x, y + height - radius);
ctx.arcTo(x, y + height, x + radius, y + height, radius);
ctx.lineTo(x + width - radius, y + height);
ctx.arcTo(x + width, y + height, x + width, y + height - radius, radius);
ctx.lineTo(x + width, y + radius);
ctx.arcTo(x + width, y, x + width - radius, y, radius);
ctx.lineTo(x + radius, y);
ctx.arcTo(x, y, x, y + radius, radius);
ctx.stroke();
}
ê²°ê³¼ ì´ë¯¸ì§ë ë¤ìê³¼ ê°ìµëë¤:
ì´ ìì ë ë³´ê¸°ë³´ë¤ ì주 ê°ë¨í기 ë문ì ìì¸í ì¤ëª
ì ìëµíê² ìµëë¤. ìì ëì´ì¼í ê°ì¥ ì¤ìí ë¶ë¶ì fillStyle ì½ëì ì¬ì©ë ì í¸ë¦¬í° í¨ì (roundedRect() ë¶ë¶) ì
ëë¤. ì í¸ë¦¬í° í¨ì를 ì¬ì©íê² ëë©´, ì¬ì©í´ì¼ í ì½ëì ìê³¼ ë³µì¡í¨ì ì¤ì¬ì£¼ëë° ëìì ì¤ëë¤.
ì´ íí 리ì¼ìì ëì¤ì fillStyleì ëíì¬ ì¡°ê¸ ë ìì¸íê² ììë³´ëë¡ íê² ì§ë§, ì§ê¸ì ê²½ë¡ì ì±ì°ë ìì 기본ê°(íë°±)ìì ë°ê¾¸ìë¤ê° ë¤ì 기본ê°ì¼ë¡ ë°ê¾¸ë ì ëë¡ë§ ì¬ì©íììµëë¤.
Path2D ì¤ë¸ì í¸ (Path2D objects)
ë§ì§ë§ ìì ìì ë³´ì ë¯ì´, ìºë²ì¤ì ê°ì²´ë¥¼ 그리ë ì¼ë ¨ì ê²½ë¡ì 그리기 ëª
ë ¹ì´ ìì ì ììµëë¤. ì½ë를 ë¨ìííê³ ì±ë¥ì í¥ììí¤ê¸° ìí´ ìµê·¼ ë²ì ì ë¸ë¼ì°ì ìì ì¬ì©í ììë Path2D ê°ì²´ë¥¼ ì¬ì©íì¬ ì´ë¬í ëë¡ì ëª
ë ¹ì ìºìíê±°ë ê¸°ë¡ í ì ììµëë¤. ì´ë¡ì¨ ì¬ë¬ë¶ì ê²½ë¡ë¥¼ ë¹ ë¥´ê² ë¤ì ì¤í ìí¬ ì ììµëë¤.
ì´ë»ê² Path2D object를 ìì± í ì ìëì§ íì¸í´ ë´
ìë¤:
Path2D()-
Path2D()ìì±ìë ìë¡ì´Path2Dê°ì²´ë¥¼ ë°íí©ëë¤. ì íì ì¼ë¡ ë¤ë¥¸ ê²½ë¡ë¥¼ ì¸ìë¡ ë°ê±°ë(ë³µì¬ë³¸ì ìì±), SVG ê²½ë¡ ë°ì´í°ë¡ 구ì±ë 문ìì´ì ë°ìì ê°ì²´ë¡ ë°íí©ëë¤.
new Path2D(); // empty path object
new Path2D(path); // copy from another Path2D object
new Path2D(d); // path from SVG path data
moveTo, rect, arc í¹ì quadraticCurveTo ë±ê³¼ ê°ì 모ë ê²½ë¡ ë©ìë (path methods)ë¤ì Path2D ê°ì²´ìì ì¬ì© ê°ë¥í©ëë¤.
Path2D APIë ëí addPath ë©ìë를 ì¬ì©íì¬ ê²½ë¡ë¥¼ ê²°í©íë ë°©ë²ì ì¶ê°í©ëë¤. ì를 ë¤ìë©´, ì¬ë¬ ìì를 ì¬ì©íë ì¤ë¸ì í¸ë¥¼ ë§ë¤ ë ì ì©íê² ì¬ì© ë ì ììµëë¤.
Path2D.addPath(path [, transform])-
ìµì ì¼ë¡ ë³í íë ¬(transformation matrix)ì ì¬ì©íì¬ íì¬ ê²½ë¡ì ê²½ë¡ë¥¼ ì¶ê°í©ëë¤.
Path2D ìì
ì´ ìì ììë, ì§ì¬ê°íê³¼ ìì ë§ë¤ì´ ë³¼ ê²ì
ëë¤. ëì¤ì ì¬ì©í ê²ì ê³ ë ¤íì¬, ë ëí 모ë Path2D objectë¡ ì ì¥ ë ê²ì
ëë¤. ìë¡ì´ ë²ì ì Path2D APIììë ì¬ë¬ ë©ìëë¤ì´ ì§ê¸ ì¬ì©íê³ ìë pathê° ìë Path2D object를 ìµì
ì¼ë¡ ì ííì¬ ì¬ì© í ì ìëë¡ ì
ë°ì´í¸ ëììµëë¤. ìëì ìì ìì ë³´ìë©´, stroke ì fill ë©ìëê° ì¤ë¸ì í¸ë¥¼ ìºë²ì¤ ìì 그리ëë¡ path ë³ìì í¨ê» ì¬ì©ëììµëë¤.
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var rectangle = new Path2D();
rectangle.rect(10, 10, 50, 50);
var circle = new Path2D();
circle.moveTo(125, 35);
circle.arc(100, 35, 25, 0, 2 * Math.PI);
ctx.stroke(rectangle);
ctx.fill(circle);
}
}
SVG paths ì¬ì©í기
ìë¡ì´ ìºë²ì¤ path2D API ëë¤ë¥¸ ê°ë ¥í í¹ì§ ì¤ íëë, ìºë²ì¤ì path를 ì´ê¸°í í기 ìí´ SVG path data를 ì¬ì©íë¤ë ê²ì ëë¤. ì´ë path ë°ì´í°ë¥¼ ì´ëìí¤ë©°, SVGì canvas ìì ì¬ì¬ì© í ì ìëë¡ í´ì¤ëë¤.
pathë (M10 10) ì ì¼ë¡ ì´ëí ë¤ì, ìííê² ì¤ë¥¸ìª½ì¼ë¡ ì¼ë¡ 80 í¬ì¸í¸ (h 80) ë§í¼ ì´ëí©ëë¤. ì´í ìì§ì¼ë¡ 80í¬ì¸í¸ (v 80) ë´ë ¤ê° ë¤ì, 80 í¬ì¸í¸ ì¼ìª½ì¼ë¡ (h -80) ìííê² ì´ëíê³ ë¤ì ììì (z)ì¼ë¡ ëìê°ëë¤. ììë ì´ê³³( Path2D constructor )ìì íì¸íì¤ ì ììµëë¤.
var p = new Path2D("M10 10 h 80 v 80 h -80 Z");