aboutsummaryrefslogtreecommitdiff
path: root/files/ko/web/api/canvas_api/tutorial/basic_animations
diff options
context:
space:
mode:
authorFlorian Merz <me@fiji-flo.de>2021-02-11 14:48:24 +0100
committerFlorian Merz <me@fiji-flo.de>2021-02-11 14:48:24 +0100
commitee778d6eea54935fd05022e0ba8c49456003381a (patch)
tree151a4cef804d8823cc8fc753b8edc693b7078241 /files/ko/web/api/canvas_api/tutorial/basic_animations
parent8260a606c143e6b55a467edf017a56bdcd6cba7e (diff)
downloadtranslated-content-ee778d6eea54935fd05022e0ba8c49456003381a.tar.gz
translated-content-ee778d6eea54935fd05022e0ba8c49456003381a.tar.bz2
translated-content-ee778d6eea54935fd05022e0ba8c49456003381a.zip
unslug ko: move
Diffstat (limited to 'files/ko/web/api/canvas_api/tutorial/basic_animations')
-rw-r--r--files/ko/web/api/canvas_api/tutorial/basic_animations/index.html310
1 files changed, 310 insertions, 0 deletions
diff --git a/files/ko/web/api/canvas_api/tutorial/basic_animations/index.html b/files/ko/web/api/canvas_api/tutorial/basic_animations/index.html
new file mode 100644
index 0000000000..457d658172
--- /dev/null
+++ b/files/ko/web/api/canvas_api/tutorial/basic_animations/index.html
@@ -0,0 +1,310 @@
+---
+title: 기본 애니메이션
+slug: Web/HTML/Canvas/Tutorial/Basic_animations
+tags:
+ - HTML5
+ - 그래픽
+ - 캔버스
+translation_of: Web/API/Canvas_API/Tutorial/Basic_animations
+---
+<p>{{HTMLElement("canvas")}} 요소는 자바스크립트로 제어하는 것이므로, 애니메이션도 쉽게 만들 수 있습니다. 복잡한 애니메이션을 만드는 것은 추가 작업이 더 필요하고, 앞으로 그에 대한 페이지도 머지 않아 추가되기를 기대합니다.</p>
+<p>도형은 한번 만들어 놓으면 그 모습 그대로 있다는 것이 애니메이션을 만들 때의 가장 큰 제약일 것입니다. 그 도형을 움직이고자 하면 그 도형뿐만이 아니라 그 도형이 그려지기 전에 그려진 모든 것을 다시 그려야 합니다. 복잡한 장면을 다시 그리는 것은 시간도 많이 걸리며, 코드를 실행하는 컴퓨터의 능력에 따라 달라집니다.</p>
+<h2 id="Basic_animation_steps" name="Basic_animation_steps">기본 애니메이션 단계</h2>
+<p>한 장면을 그리려면 아래와 같은 단계를 밟습니다.</p>
+<ol>
+ <li><strong>캔버스를 비웁니다.</strong><br>
+ 그리려는 도형이 (배경 이미지를 만들 때처럼) 캔버스를 가득 채우는 것이 아니라면, 이전에 그려진 모든 도형을 지울 필요가 있습니다. 가장 쉬운 방법은 <code>clearRect()</code> 메소드를 사용하는 것입니다.</li>
+ <li><strong>캔버스 상태를 저장합니다.</strong><br>
+ 캔버스 상태에 영향을 주는 (스타일 변경, 모양 변형 등의) 설정값을 바꾸려고 하고, 바뀐 값을 각 장면마다 사용하려고 한다면, 원래 상태를 저장할 필요가 있습니다.</li>
+ <li><strong>애니메이션할 도형을 그립니다.</strong><br>
+ 실제 장면을 그리는 단계입니다.</li>
+ <li><strong>캔버스 상태를 복원합니다.</strong><br>
+ 새로운 장면을 그리기 전에 저장된 상태를 복원합니다.</li>
+</ol>
+<h2 id="Controlling_an_animation" name="Controlling_an_animation">애니메이션 제어하기</h2>
+<p>캔버스 메소드를 사용하거나 사용자 함수를 사용하여 캔버스에 도형들을 그립니다. 보통의 경우에서는, 코드 실행이 완료되면 캔버스에 나타나는 결과만을 보게 됩니다. 예를 들어,  <code>for</code> 반복문 안에서 애니메이션을 실행하는 것은 불가능합니다.</p>
+<p>그래서 정해진 시간마다 그리기 함수를 실행하는 방법이 필요한 것입니다. 아래와 같이 애니메이션을 제어하는 두 가지 방법이 있습니다.</p>
+<h3 id="예정된_변경">예정된 변경</h3>
+<p>정해진 시간마다 특정 함수를 부를 때 사용할 수 있는  {{domxref("window.setInterval()")}}과 {{domxref("window.setTimeout()")}} 함수가 있습니다.</p>
+<div class="note">
+ <p>알아둘 것: 현재는 애니메이션을 만드는 방법으로  {{domxref("window.requestAnimationFrame()")}} 메소드를 추천합니다. 이에 대한 튜토리얼은 곧 업데이트할 것입니다.</p>
+</div>
+<dl>
+ <dt>
+ <code>setInterval(<em>function</em>, <em>delay</em>)</code></dt>
+ <dd>
+ <code>delay</code> 밀리세컨드(1,000분의 1초)마다 <code>function</code> 함수 반복 실행을 시작합니다.</dd>
+ <dt>
+ <code>setTimeout(<em>function</em>, <em>delay</em>)</code></dt>
+ <dd>
+ <code>delay</code> 밀리세컨드(1,000분의 1초) 경과후, <code>function</code> 함수를 실행합니다.</dd>
+</dl>
+<p>사용자의 제어를  <strong>필요로 하지 않는</strong> 반복 실행에는  <code>setInterval()</code> 함수가 알맞을 것입니다.</p>
+<h3 id="사용자_상호_작용_변경">사용자 상호 작용 변경</h3>
+<p>애니메이션을 제어하는 두번째 방법은 사용자 입력입니다. 게임을 만들려고 한다면, 애니메이션을 제어하기 위해 키보드나 마우스 이벤트를 사용할 수 있을 것입니다.  {{domxref("EventListener")}}를 설정하여, 사용자와 상호 작용하여 애니메이션 함수를 실행합니다.</p>
+<p>사용자 상호 작용이 <strong>필요하다면</strong>, 우리가 만든 <a href="/en-US/docs/JavaScript/Timers/Daemons" title="/en-US/docs/JavaScript/Timers/Daemons">애니메이션용 프레임웍(framework)</a>의 <a href="/en-US/docs/DOM/window.setInterval#A_little_framework" title="/en-US/docs/DOM/window.setInterval#A_little_framework">최소 기능 버전</a> 또는 <a href="/en-US/docs/JavaScript/Timers/Daemons" title="/en-US/docs/JavaScript/Timers/Daemons">최대 기능 버전</a>을 사용할 수 있을 것입니다.</p>
+<pre>var myAnimation = new MiniDaemon(null, animateShape, 500, Infinity);</pre>
+<p>또는</p>
+<pre>var myAnimation = new Daemon(null, animateShape, 500, Infinity);</pre>
+<p>아래 예제에서는, 애니메이션을 제어하기 위해 {{domxref("window.setInterval()")}}을 사용할 것입니다. 페이지 제일 아래쪽에 {{domxref("window.setTimeout()")}}을 사용한 예제 링크도 있습니다.</p>
+<h4 id="태양계_애니메이션">태양계 애니메이션</h4>
+<p>이 예제에서는 달이 지구를 돌고 지구가 태양을 도는 애니메이션을 만듭니다.</p>
+<pre class="brush: js">var sun = new Image();
+var moon = new Image();
+var earth = new Image();
+function init(){
+ sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
+ moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
+ earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
+ setInterval(draw,100);
+}
+
+function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.clearRect(0,0,300,300); // 캔버스를 비운다
+
+ ctx.fillStyle = 'rgba(0,0,0,0.4)';
+ ctx.strokeStyle = 'rgba(0,153,255,0.4)';
+ ctx.save();
+ ctx.translate(150,150);
+
+ // 지구
+ var time = new Date();
+ ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
+ ctx.translate(105,0);
+ ctx.fillRect(0,-12,50,24); // Shadow
+ ctx.drawImage(earth,-12,-12);
+
+ // 달
+ ctx.save();
+ ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
+ ctx.translate(0,28.5);
+ ctx.drawImage(moon,-3.5,-3.5);
+ ctx.restore();
+
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.arc(150,150,105,0,Math.PI*2,false); // 지구 궤도
+ ctx.stroke();
+
+ ctx.drawImage(sun,0,0,300,300);
+}
+</pre>
+<div class="hidden">
+ <pre class="brush: html">&lt;canvas id="canvas" width="300" height="300"&gt;&lt;/canvas&gt;</pre>
+ <pre class="brush: js">init();</pre>
+</div>
+<p>{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}</p>
+<h4 id="시계_애니메이션">시계 애니메이션</h4>
+<p>이 예제에서는, 현재 시각을 보여주는 움직이는 시계를 만듭니다.</p>
+<pre class="brush: js">function init(){
+ clock();
+ setInterval(clock,1000);
+}
+
+function clock(){
+ var now = new Date();
+ var ctx = document.getElementById('canvas').getContext('2d');
+ ctx.save();
+ ctx.clearRect(0,0,150,150);
+ ctx.translate(75,75);
+ ctx.scale(0.4,0.4);
+ ctx.rotate(-Math.PI/2);
+ ctx.strokeStyle = "black";
+ ctx.fillStyle = "white";
+ ctx.lineWidth = 8;
+ ctx.lineCap = "round";
+
+ // 시계판 - 시
+ ctx.save();
+ for (var i=0;i&lt;12;i++){
+ ctx.beginPath();
+ ctx.rotate(Math.PI/6);
+ ctx.moveTo(100,0);
+ ctx.lineTo(120,0);
+ ctx.stroke();
+ }
+ ctx.restore();
+
+ // 시계판 - 분
+ ctx.save();
+ ctx.lineWidth = 5;
+ for (i=0;i&lt;60;i++){
+ if (i%5!=0) {
+ ctx.beginPath();
+ ctx.moveTo(117,0);
+ ctx.lineTo(120,0);
+ ctx.stroke();
+ }
+ ctx.rotate(Math.PI/30);
+ }
+ ctx.restore();
+
+ var sec = now.getSeconds();
+ var min = now.getMinutes();
+ var hr = now.getHours();
+ hr = hr&gt;=12 ? hr-12 : hr;
+
+ ctx.fillStyle = "black";
+
+ // 시간 표시 - 시
+ ctx.save();
+ ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
+ ctx.lineWidth = 14;
+ ctx.beginPath();
+ ctx.moveTo(-20,0);
+ ctx.lineTo(80,0);
+ ctx.stroke();
+ ctx.restore();
+
+ // 시간 표시 - 분
+ ctx.save();
+ ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(-28,0);
+ ctx.lineTo(112,0);
+ ctx.stroke();
+ ctx.restore();
+
+ // 시간 표시 - 초
+ ctx.save();
+ ctx.rotate(sec * Math.PI/30);
+ ctx.strokeStyle = "#D40000";
+ ctx.fillStyle = "#D40000";
+ ctx.lineWidth = 6;
+ ctx.beginPath();
+ ctx.moveTo(-30,0);
+ ctx.lineTo(83,0);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(0,0,10,0,Math.PI*2,true);
+ ctx.fill();
+ ctx.beginPath();
+ ctx.arc(95,0,10,0,Math.PI*2,true);
+ ctx.stroke();
+ ctx.fillStyle = "rgba(0,0,0,0)";
+ ctx.arc(0,0,3,0,Math.PI*2,true);
+ ctx.fill();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.lineWidth = 14;
+ ctx.strokeStyle = '#325FA2';
+ ctx.arc(0,0,142,0,Math.PI*2,true);
+ ctx.stroke();
+
+ ctx.restore();
+}</pre>
+<div class="hidden">
+ <pre class="brush: html">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+ <pre class="brush: js">init();</pre>
+</div>
+<p>{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}</p>
+<h4 id="움직이는_파노라마_사진">움직이는 파노라마 사진</h4>
+<p>이 예제에서는, 움직이는 파노라마 사진을 만듭니다. 사용할 그림은 위키피디어(Wikipedia)에서 구한 <a href="http://commons.wikimedia.org/wiki/File:Capitan_Meadows,_Yosemite_National_Park.jpg" title="http://commons.wikimedia.org/wiki/File:Capitan_Meadows,_Yosemite_National_Park.jpg">요세미티 국립공원</a>입니다. 캔버스보다 큰 그림을 사용할 수도 있습니다.</p>
+<pre class="brush: js">var img = new Image();
+
+// 변수
+// 스크롤될 이미지, 방향, 속도를 바꾸려면 변수값을 바꾼다.
+
+img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
+var CanvasXSize = 800;
+var CanvasYSize = 200;
+var speed = 30; // 값이 작을 수록 빨라진다
+var scale = 1.05;
+var y = -4.5; // 수직 옵셋
+
+// 주요 프로그램
+
+var dx = 0.75;
+var imgW;
+var imgH;
+var x = 0;
+var clearX;
+var clearY;
+var ctx;
+
+img.onload = function() {
+ imgW = img.width*scale;
+ imgH = img.height*scale;
+ if (imgW &gt; CanvasXSize) { x = CanvasXSize-imgW; } // 캔버스보다 큰 이미지
+ if (imgW &gt; CanvasXSize) { clearX = imgW; } // 캔버스보다 큰 이미지
+ else { clearX = CanvasXSize; }
+ if (imgH &gt; CanvasYSize) { clearY = imgH; } // 캔버스보다 큰 이미지
+ else { clearY = CanvasYSize; }
+ // 캔버스 요소 얻기
+ ctx = document.getElementById('canvas').getContext('2d');
+ // 새로 그리기 속도 설정
+ return setInterval(draw, speed);
+}
+
+function draw() {
+ // 캔버스를 비운다
+ ctx.clearRect(0,0,clearX,clearY);
+ // 이미지가 캔버스보다 작거나 같다면 (If image is &lt;= Canvas Size)
+ if (imgW &lt;= CanvasXSize) {
+ // 재설정, 처음부터 시작
+ if (x &gt; (CanvasXSize)) { x = 0; }
+ // 추가 이미지 그리기
+ if (x &gt; (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
+ }
+ // 이미지가 캔버스보다 크다면 (If image is &gt; Canvas Size)
+ else {
+ // 재설정, 처음부터 시작
+ if (x &gt; (CanvasXSize)) { x = CanvasXSize-imgW; }
+ // 추가 이미지 그리기
+ if (x &gt; (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
+ }
+ // 이미지 그리기
+ ctx.drawImage(img,x,y,imgW,imgH);
+ // 움직임 정도
+ x += dx;
+}
+</pre>
+<p>예제에 사용된 {{HTMLElement("canvas")}}의 크기는 아래와 같다. 캔버스의 너비가 변수 <code>CanvasXSize</code>값과 같고, 캔버스의 높이는 변수 <code>CanvasYSize</code>값과 같다는 것에 주목하라.</p>
+<pre class="brush: html">&lt;canvas id="canvas" width="800" height="200"&gt;&lt;/canvas&gt;</pre>
+<p><strong>Live sample</strong></p>
+<p>{{EmbedLiveSample("A_looping_panorama", "830", "230")}}</p>
+<h2 id="Other_examples" name="Other_examples">또 다른 예제들</h2>
+<dl>
+ <dt>
+ <a class="external" href="http://www.gartic.net/" title="http://www.gartic.net/">Gartic</a></dt>
+ <dd>
+ 다중 사용자 지원 그리기 놀이.</dd>
+ <dt>
+ <a class="external" href="http://www.abrahamjoffe.com.au/ben/canvascape/">Canvascape</a></dt>
+ <dd>
+ 3D 어드벤처 게임 (1인칭 슈팅).</dd>
+ <dt>
+ <a href="/en-US/docs/Web/Guide/HTML/A_basic_ray-caster" title="/en-US/docs/Web/Guide/HTML/A_basic_ray-caster">A basic ray-caster</a></dt>
+ <dd>
+ 키보드를 사용한 애니메이션 제어 방법에 대한 좋은 예제.</dd>
+ <dt>
+ <a class="external" href="http://andrewwooldridge.com/canvas/canvasgame001/canvasgame002.html">canvas adventure</a></dt>
+ <dd>
+ 키보드 제어를 사용하는 또다른 좋은 예제.</dd>
+ <dt>
+ <a class="external" href="http://www.blobsallad.se/">An interactive Blob</a></dt>
+ <dd>
+ 물방울 갖고 놀기.</dd>
+ <dt>
+ <a class="external" href="http://arapehlivanian.com/wp-content/uploads/2007/02/canvas.html">Flying through a starfield</a></dt>
+ <dd>
+ 별, 동그라미, 네모가 떠다니는 우주를 누벼라.</dd>
+ <dt>
+ <a class="external" href="http://igrapher.com/" title="http://igrapher.com/">iGrapher</a></dt>
+ <dd>
+ 주식 시장 자료 차트 예제.</dd>
+</dl>
+<h2 id="이것도_보세요">이것도 보세요</h2>
+<ul>
+ <li><a href="/en-US/docs/JavaScript/Timers" title="/en-US/docs/JavaScript/Timers">JavaScript timers</a></li>
+ <li><a href="/en-US/docs/DOM/window.setInterval#A_little_framework" title="/en-US/docs/DOM/window.setInterval#A_little_framework"><code>setInterval</code> – A little framework</a></li>
+ <li><a href="/en-US/docs/JavaScript/Timers/Daemons" title="/en-US/docs/JavaScript/Timers/Daemons">JavaScript Daemons Management</a></li>
+ <li><a href="/en-US/docs/DOM/HTMLCanvasElement" title="/en-US/docs/DOM/HTMLCanvasElement">HTMLCanvasElement</a></li>
+</ul>
+<p>{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Compositing", "Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas")}}</p>