mozilla

Revision 161851 of Drawing Graphics with Canvas

  • 리비전 슬러그: Drawing_Graphics_with_Canvas
  • 리비전 제목: Drawing Graphics with Canvas
  • 리비전 아이디: 161851
  • 제작일시:
  • 만든이: 행복한고니
  • 현재 리비전인가요? 아니오
  • 댓글 /* A Simple Example */

리비전 내용

소개

Firefox 1.5에서 Firefox는 프로그래밍이 가능한 새로운 HTML 요소를 포함합니다. <canvas>는 Apple이 Safari에 <canvas>를 구현할 때 기반이 되었던 WHATWG canvas 명세를 기반으로 하고 있습니다. 그래프를 그리거나, UI 요소, 그 외에도 클라이언트에서의 다른 여러 그래픽 작업에 사용될 수 있습니다.

<canvas> 는 고정된 크기의 한개이상의 rendering contexts를 가지는 그리기 영역을 만든다. 우리는 2D rendering context 를 주로 다룰 것이다(사실, 현재 정의된 rendering context는 그게 전부다). 앞으로는, 다른 context들이 서로 다른 형태의 렌더링을 지원하게 될 것이다. 예를 들어, 결국에는 OpenGL ES를 기반으로 한 3D context가 <canvas>에 추가될 것이다.

The 2D Rendering Context

간단한 예제

우선 두개의 겹치는 사각형을 그리는 간단한 예제부터 시작해보자. 하나의 사각형은 알파 투명도도 적용되어있다:

Example 1.

<html>
 <head>
  <script type="application/x-javascript">
function draw() {
 var canvas = document.getElementById("canvas");
 var ctx = canvas.getContext("2d");

 ctx.fillStyle = "rgb(200,0,0)";
 ctx.fillRect (10, 10, 50, 50);

 ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
 ctx.fillRect (30, 30, 50, 50);
}
  </script>
 </head>
 <body onload="draw()">
   <canvas id="canvas" width="300" height="300"></canvas>
 </body>
</html>

draw 함수는 canvas 요소를 얻고 거기서 2d context를 얻는다. ctx 객체는 캔버스를 실제로 렌더링하는데 사용되었다. 예제는 단순히 두개의 사각형을 색칠하는 것인데, 채우기 스타일(fillStyle)을 CSS 색상 명세에 따라 서로 다른 색으로 설정한 후 fillRect 메소드를 호출했다. 두번째 채우기 스타일은 rgba()를 사용해서 색상과 더불어 알파값을 지정했다.

fillRect, strokeRect, clearRect는 사각형 영역을 각각 채우고, 외각선을 그리고, 지운다. 조금 더 복잡한 그리기는 모양(shape)이나 경로(path)를 이용한다.

Using Paths

The beginPath function starts a new path, and moveTo, lineTo, arcTo, arc, and similar methods are used to add segments to the path. The path can be closed using closePath. Once a path is created, you can use fill or stroke to render the path to the canvas.

Example 2.

<html>
 <head>
  <script type="application/x-javascript">
function draw() {
  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");

  ctx.fillStyle = "red";

  ctx.beginPath();
  ctx.moveTo(30, 30);
  ctx.lineTo(150, 150);
  ctx.quadraticCurveTo(60, 70, 70, 150);
  ctx.lineTo(30, 30);
  ctx.fill();
}
   </script>
 </head>
 <body onload="draw()">
   <canvas id="canvas" width="300" height="300"></canvas>
 </body>
</html>

Calling fill() or stroke() causes the current path to be used. To be filled or stroked again, the path must be recreated.

Graphics State

Attributes of the context such as fillStyle, strokeStyle, lineWidth, and lineJoin are part of the current graphics state. The context provides two methods, save() and restore(), that can be used to move the current state to and from the state stack.

A More Complicated Example

Here's a little more complicated example, that uses paths, state, and also introduces the current transformation matrix. The context methods translate(), scale(), and rotate() all transform the current matrix. All rendered points are first transformed by this matrix.

Example 3.

 <html>
  <head>
   <script type="application/x-javascript">
 function drawBowtie(ctx, fillStyle) {
 
   ctx.fillStyle = "rgba(200,200,200,0.3)";
   ctx.fillRect(-30, -30, 60, 60);
 
   ctx.fillStyle = fillStyle;
   ctx.globalAlpha = 1.0;
   ctx.beginPath();
   ctx.moveTo(25, 25);
   ctx.lineTo(-25, -25);
   ctx.lineTo(25, -25);
   ctx.lineTo(-25, 25);
   ctx.closePath();
   ctx.fill();
 }
 
 function dot(ctx) {
   ctx.save();
   ctx.fillStyle = "black";
   ctx.fillRect(-2, -2, 4, 4);
   ctx.restore();
 }
 
 function draw() {
   var canvas = document.getElementById("canvas");
   var ctx = canvas.getContext("2d");

   // note that all other translates are relative to this
   // one
   ctx.translate(45, 45);

   ctx.save();
   //ctx.translate(0, 0); // unnecessary
   drawBowtie(ctx, "red");
   dot(ctx);
   ctx.restore();
 
   ctx.save();
   ctx.translate(85, 0);
   ctx.rotate(45 * Math.PI / 180);
   drawBowtie(ctx, "green");
   dot(ctx);
   ctx.restore();
 
   ctx.save();
   ctx.translate(0, 85);
   ctx.rotate(135 * Math.PI / 180);
   drawBowtie(ctx, "blue");
   dot(ctx);
   ctx.restore();
 
   ctx.save();
   ctx.translate(85, 85);
   ctx.rotate(90 * Math.PI / 180);
   drawBowtie(ctx, "yellow");
   dot(ctx);
   ctx.restore();
 }
    </script>
  </head>
  <body onload="draw()">
    <canvas id="canvas" width="300" height="300"></canvas>
  </body>
 </html>

This defines two methods, drawBowtie and dot, that are called 4 times. Before each call, translate() and rotate() are used to set up the current transformation matrix, which in turn positions the dot and the bowtie. dot renders a small black square centered at (0, 0). That dot is moved around by the transformation matrix. drawBowtie renders a simple bowtie path using the passed-in fill style.

As matrix operations are cumulative, save() and restore() are used around each set of calls to restore the original canvas state. One thing to watch out for is that rotation always occurs around the current origin; thus a translate() rotate() translate() sequence will yield different results than a translate() translate() rotate() series of calls.

Compatibility With Apple <canvas>

For the most part, <canvas> is compatible with Apple's and other implementations. There are, however, a few issues to be aware of, described here.

Required </canvas> tag

In the Apple Safari implementation, <canvas> is an element implemented in much the same way <img> is; it does not have an end tag. However, for <canvas> to have widespread use on the web, some facility for fallback content must be provided. Therefore, Mozilla's implementation has a required end tag.

If fallback content is not needed, a simple <canvas id="foo" ...></canvas> will be fully compatible with both Safari and Mozilla -- Safari will simply ignore the end tag.

If fallback content is desired, some CSS tricks must be employed to mask the fallback content from Safari (which should render just the canvas), and also to mask the CSS tricks themselves from IE (which should render the fallback content). Todo: get hixie to put the CSS bits in

Additional Features

Rendering Web Content Into A Canvas

This feature is only available for code running with Chrome privileges. It is not allowed in normal HTML pages.

Mozilla's canvas is extended with the drawWindow method. This method draws a snapshot of the contents of a DOM window into the canvas. For example,

ctx.drawWindow(window, 0, 0, 100, 200, "rgb(0,0,0)");

would draw the contents of the current window, in the rectangle (0,0,100,200) in pixels relative to the top-left of the viewport, on a black background, into the canvas. By specifying "rgba(0,0,0,0)" as the color, the contents would be drawn with a transparent background (which would be slower).

With this method, it is possible to fill a hidden IFRAME with arbitrary content (e.g., CSS-styled HTML text, or SVG) and draw it into a canvas. It will be scaled, rotated and so on according to the current transformation.

Ted Mielczarek's tab preview extension uses this technique in chrome to provide thumbnails of web pages, and the source is available for reference.

See also

{{ wiki.languages( { "fr": "fr/Dessiner_avec_canvas", "ja": "ja/Drawing_Graphics_with_Canvas", "ko": "ko/Drawing_Graphics_with_Canvas", "pl": "pl/Rysowanie_grafik_za_pomoc\u0105_Canvas" } ) }}

리비전 소스

<h3 name=".EC.86.8C.EA.B0.9C"> 소개 </h3>
<p><a href="ko/Firefox_1.5">Firefox 1.5</a>에서 Firefox는 프로그래밍이 가능한 새로운 HTML 요소를 포함합니다. <code>&lt;canvas&gt;</code>는 Apple이 Safari에 <code>&lt;canvas&gt;</code>를 구현할 때 기반이 되었던 <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/#scs-dynamic">WHATWG canvas 명세</a>를 기반으로 하고 있습니다. 그래프를 그리거나, UI 요소, 그 외에도 클라이언트에서의 다른 여러 그래픽 작업에 사용될 수 있습니다.
</p><p><code>&lt;canvas&gt;</code> 는 고정된 크기의 한개이상의 <i>rendering contexts</i>를 가지는 그리기 영역을 만든다. 우리는 2D rendering context 를 주로 다룰 것이다(사실, 현재 정의된 rendering context는 그게 전부다). 앞으로는, 다른 context들이 서로 다른 형태의 렌더링을 지원하게 될 것이다. 예를 들어, 결국에는 OpenGL ES를 기반으로 한 3D context가 <code>&lt;canvas&gt;</code>에 추가될 것이다.
</p>
<h3 name="The_2D_Rendering_Context"> The 2D Rendering Context </h3>
<h4 name=".EA.B0.84.EB.8B.A8.ED.95.9C_.EC.98.88.EC.A0.9C"> 간단한 예제 </h4>
<p>우선 두개의 겹치는 사각형을 그리는 간단한 예제부터 시작해보자. 하나의 사각형은 알파 투명도도 적용되어있다:
</p><p><img align="right" alt="Example 1." src="File:ko/Media_Gallery/Canvas_ex1.png">
</p>
<pre class="eval">&lt;html&gt;
 &lt;head&gt;
  &lt;script type="application/x-javascript"&gt;
function draw() {
 var canvas = document.getElementById("canvas");
 var ctx = canvas.getContext("2d");

 ctx.fillStyle = "rgb(200,0,0)";
 ctx.fillRect (10, 10, 50, 50);

 ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
 ctx.fillRect (30, 30, 50, 50);
}
  &lt;/script&gt;
 &lt;/head&gt;
 &lt;body onload="draw()"&gt;
   &lt;canvas id="canvas" width="300" height="300"&gt;&lt;/canvas&gt;
 &lt;/body&gt;
&lt;/html&gt;
</pre>
<p><code>draw</code> 함수는 <code>canvas</code> 요소를 얻고 거기서 <code>2d</code> context를 얻는다. <code>ctx</code> 객체는 캔버스를 실제로 렌더링하는데 사용되었다. 예제는 단순히 두개의 사각형을 색칠하는 것인데, 채우기 스타일(fillStyle)을 CSS 색상  명세에 따라 서로 다른 색으로 설정한 후 <code>fillRect</code> 메소드를 호출했다. 두번째 채우기 스타일은 <code>rgba()</code>를 사용해서 색상과 더불어 알파값을 지정했다.
</p><p><code>fillRect</code>, <code>strokeRect</code>, <code>clearRect</code>는 사각형 영역을 각각 채우고, 외각선을 그리고, 지운다. 조금 더 복잡한 그리기는 모양(shape)이나 경로(path)를 이용한다.
</p>
<h4 name="Using_Paths"> Using Paths </h4>
<p>The <code>beginPath</code> function starts a new path, and
<code>moveTo</code>, <code>lineTo</code>, <code>arcTo</code>, <code>arc</code>, and similar methods are used to add segments to the path.  The path can be
closed using <code>closePath</code>.  Once a path is created, you
can use <code>fill</code> or <code>stroke</code> to render the path
to the canvas.
</p><p><img align="right" alt="Example 2." src="File:ko/Media_Gallery/Canvas_ex2.png">
</p>
<pre class="eval">&lt;html&gt;
 &lt;head&gt;
  &lt;script type="application/x-javascript"&gt;
function draw() {
  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");

  ctx.fillStyle = "red";

  ctx.beginPath();
  ctx.moveTo(30, 30);
  ctx.lineTo(150, 150);
  ctx.quadraticCurveTo(60, 70, 70, 150);
  ctx.lineTo(30, 30);
  ctx.fill();
}
   &lt;/script&gt;
 &lt;/head&gt;
 &lt;body onload="draw()"&gt;
   &lt;canvas id="canvas" width="300" height="300"&gt;&lt;/canvas&gt;
 &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Calling <code>fill()</code> or <code>stroke()</code> causes the current path
to be used.  To be filled or stroked again, the path must be recreated.
</p>
<h4 name="Graphics_State"> Graphics State </h4>
<p>Attributes of the context such as <code>fillStyle</code>,
<code>strokeStyle</code>, <code>lineWidth</code>, and <code>lineJoin</code> are
part of the current <i>graphics state</i>.  The context provides two
methods, <code>save()</code> and <code>restore()</code>, that can be used to
move the current state to and from the state stack.
</p>
<h4 name="A_More_Complicated_Example"> A More Complicated Example </h4>
<p>Here's a little more complicated example, that uses paths, state, and
also introduces the current transformation matrix.  The context
methods <code>translate()</code>, <code>scale()</code>, and <code>rotate()</code>
all transform the current matrix.  All rendered points are first
transformed by this matrix.
</p><p><img align="right" alt="Example 3." src="File:ko/Media_Gallery/Canvas_ex3.png">
</p>
<pre> &lt;html&gt;
  &lt;head&gt;
   &lt;script type="application/x-javascript"&gt;
 function drawBowtie(ctx, fillStyle) {
 
   ctx.fillStyle = "rgba(200,200,200,0.3)";
   ctx.fillRect(-30, -30, 60, 60);
 
   ctx.fillStyle = fillStyle;
   ctx.globalAlpha = 1.0;
   ctx.beginPath();
   ctx.moveTo(25, 25);
   ctx.lineTo(-25, -25);
   ctx.lineTo(25, -25);
   ctx.lineTo(-25, 25);
   ctx.closePath();
   ctx.fill();
 }
 
 function dot(ctx) {
   ctx.save();
   ctx.fillStyle = "black";
   ctx.fillRect(-2, -2, 4, 4);
   ctx.restore();
 }
 
 function draw() {
   var canvas = document.getElementById("canvas");
   var ctx = canvas.getContext("2d");

   // note that all other translates are relative to this
   // one
   ctx.translate(45, 45);

   ctx.save();
   //ctx.translate(0, 0); // unnecessary
   drawBowtie(ctx, "red");
   dot(ctx);
   ctx.restore();
 
   ctx.save();
   ctx.translate(85, 0);
   ctx.rotate(45 * Math.PI / 180);
   drawBowtie(ctx, "green");
   dot(ctx);
   ctx.restore();
 
   ctx.save();
   ctx.translate(0, 85);
   ctx.rotate(135 * Math.PI / 180);
   drawBowtie(ctx, "blue");
   dot(ctx);
   ctx.restore();
 
   ctx.save();
   ctx.translate(85, 85);
   ctx.rotate(90 * Math.PI / 180);
   drawBowtie(ctx, "yellow");
   dot(ctx);
   ctx.restore();
 }
    &lt;/script&gt;
  &lt;/head&gt;
  &lt;body onload="draw()"&gt;
    &lt;canvas id="canvas" width="300" height="300"&gt;&lt;/canvas&gt;
  &lt;/body&gt;
 &lt;/html&gt;
</pre>
<p>This defines two methods, <code>drawBowtie</code> and <code>dot</code>, that
are called 4 times.  Before each call, <code>translate()</code> and
<code>rotate()</code> are used to set up the current transformation
matrix, which in turn positions the dot and the bowtie.  <code>dot</code>
renders a small black square centered at <code>(0, 0)</code>.  That dot is
moved around by the transformation matrix.  <code>drawBowtie</code>
renders a simple bowtie path using the passed-in fill style.
</p><p>As matrix operations are cumulative, <code>save()</code> and
<code>restore()</code> are used around each set of calls to restore the
original canvas state.  One thing to watch out for is that rotation
always occurs around the current origin; thus a <code>translate()
rotate() translate()</code> sequence will yield different results than a
<code>translate() translate() rotate()</code> series of calls.
</p>
<h3 name="Compatibility_With_Apple_.3Ccanvas.3E"> Compatibility With Apple &lt;canvas&gt; </h3>
<p>For the most part, <code>&lt;canvas&gt;</code> is compatible with Apple's and other implementations.  There are, however, a few issues to be aware of, described here.
</p>
<h4 name="Required_.3C.2Fcanvas.3E_tag"> Required <code>&lt;/canvas&gt;</code> tag </h4>
<p>In the Apple Safari implementation, <code>&lt;canvas&gt;</code> is an element implemented in much the same way <code>&lt;img&gt;</code> is; it does not have an end tag.  However, for <code>&lt;canvas&gt;</code> to have widespread use on the web, some facility for fallback content must be provided.  Therefore, Mozilla's implementation has a <i>required</i> end tag.
</p><p>If fallback content is not needed, a simple <code>&lt;canvas id="foo" ...&gt;&lt;/canvas&gt;</code> will be fully compatible with both Safari and Mozilla -- Safari will simply ignore the end tag.
</p><p>If fallback content is desired, some CSS tricks must be employed to mask the fallback content from Safari (which should render just the canvas), and also to mask the CSS tricks themselves from IE (which should render the fallback content).  <b>Todo: get hixie to put the CSS bits in</b>
</p>
<h3 name="Additional_Features"> Additional Features </h3>
<h4 name="Rendering_Web_Content_Into_A_Canvas"> Rendering Web Content Into A Canvas </h4>
<div class="note">This feature is only available for code running with Chrome privileges. It is not allowed in normal HTML pages.</div>
<p>Mozilla's <code>canvas</code> is extended with the <code>drawWindow</code>
method. This method draws a snapshot of the contents of a DOM <code>window</code> into the canvas. For example,
</p>
<pre class="eval">ctx.drawWindow(window, 0, 0, 100, 200, "rgb(0,0,0)");
</pre>
<p>would draw the contents of the current window, in the rectangle (0,0,100,200)
in pixels relative to the top-left of the viewport, on a black background,
into the canvas. By specifying "rgba(0,0,0,0)" as the color, the
contents would be drawn with a transparent background (which would be slower).
</p><p>With this method, it is possible to fill a hidden IFRAME with arbitrary content (e.g., CSS-styled HTML text, or SVG) and draw it into a canvas. It will be scaled, rotated and so on according to the current transformation.
</p><p>Ted Mielczarek's <a class="external" href="http://ted.mielczarek.org/code/mozilla/tabpreview/">tab preview</a> extension uses this technique in chrome to provide thumbnails of web pages, and the source is available for reference.
</p>
<h3 name="See_also"> See also </h3>
<ul><li> <a href="ko/Canvas_tutorial">Canvas tutorial</a>
</li><li> <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/#scs-dynamic">WHATWG specification</a>
</li><li> <a class="external" href="http://developer.apple.com/documentation/AppleApplications/Reference/SafariJSRef/Classes/Canvas.html">Apple Canvas Documentation</a>
</li><li> <a class="external" href="http://weblogs.mozillazine.org/roc/archives/2005/05/rendering_web_p.html">Rendering Web Page Thumbnails</a>
</li><li> Some <a href="Special:Tags?tag=Canvas_examples&amp;language=ko">examples</a>:
<ul><li> <a href="ko/A_Basic_RayCaster">A Basic RayCaster</a>
</li><li> <a class="external" href="http://awordlike.com/">The Lightweight Visual Thesaurus</a>
</li><li> <a class="external" href="http://caimansys.com/painter/">Canvas Painter</a>
</li></ul>
</li><li> <a href="Special:Tags?tag=HTML:Canvas&amp;language=ko">And more...</a>
</li></ul>
{{ wiki.languages( { "fr": "fr/Dessiner_avec_canvas", "ja": "ja/Drawing_Graphics_with_Canvas", "ko": "ko/Drawing_Graphics_with_Canvas", "pl": "pl/Rysowanie_grafik_za_pomoc\u0105_Canvas" } ) }}
현재 리비전 복원