diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/api/canvas_api/tutorial/basic_animations | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/zh-cn/web/api/canvas_api/tutorial/basic_animations')
-rw-r--r-- | files/zh-cn/web/api/canvas_api/tutorial/basic_animations/index.html | 718 |
1 files changed, 718 insertions, 0 deletions
diff --git a/files/zh-cn/web/api/canvas_api/tutorial/basic_animations/index.html b/files/zh-cn/web/api/canvas_api/tutorial/basic_animations/index.html new file mode 100644 index 0000000000..531fef8cb1 --- /dev/null +++ b/files/zh-cn/web/api/canvas_api/tutorial/basic_animations/index.html @@ -0,0 +1,718 @@ +--- +title: 基本的动画 +slug: Web/API/Canvas_API/Tutorial/Basic_animations +tags: + - Canvas + - HTML5 + - 动画 + - 图像 + - 教程 + - 进阶 +translation_of: Web/API/Canvas_API/Tutorial/Basic_animations +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}</div> + +<div class="summary"> +<p>由于我们是用 JavaScript 去操控 {{HTMLElement("canvas")}} 对象,这样要实现一些交互动画也是相当容易的。在本章中,我们将看看如何做一些基本的动画。</p> +</div> + +<p>可能最大的限制就是图像一旦绘制出来,它就是一直保持那样了。如果需要移动它,我们不得不对所有东西(包括之前的)进行重绘。重绘是相当费时的,而且性能很依赖于电脑的速度。</p> + +<h2 id="Basic_animation_steps" name="Basic_animation_steps">动画的基本步骤</h2> + +<p>你可以通过以下的步骤来画出一帧:</p> + +<ol> + <li><strong>清空 canvas</strong><br> + 除非接下来要画的内容会完全充满 canvas (例如背景图),否则你需要清空所有。最简单的做法就是用 <code>clearRect</code> 方法。</li> + <li><strong>保存 canvas 状态</strong><br> + 如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。</li> + <li><strong>绘制动画图形(animated shapes)</strong><br> + 这一步才是重绘动画帧。</li> + <li><strong>恢复 canvas 状态</strong><br> + 如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。</li> +</ol> + +<h2 id="Controlling_an_animation" name="Controlling_an_animation">操控动画 Controlling an animation</h2> + +<p>在 canvas 上绘制内容是用 canvas 提供的或者自定义的方法,而通常,我们仅仅在脚本执行结束后才能看见结果,比如说,在 for 循环里面做完成动画是不太可能的。</p> + +<p>因此, 为了实现动画,我们需要一些可以定时执行重绘的方法。有两种方法可以实现这样的动画操控。首先可以通过 <code>setInterval</code> 和 <code>setTimeout</code> 方法来控制在设定的时间点上执行重绘。</p> + +<h3 id="有安排的更新画布_Scheduled_updates"><strong>有安排的更新画布 </strong>Scheduled updates</h3> + +<p>首先,可以用{{domxref("window.setInterval()")}}, {{domxref("window.setTimeout()")}},和{{domxref("window.requestAnimationFrame()")}}来设定定期执行一个指定函数。</p> + +<dl> + <dt>{{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}</dt> + <dd>当设定好间隔时间后,function会定期执行。</dd> + <dt>{{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}</dt> + <dt>在设定好的时间之后执行函数</dt> + <dd></dd> + <dt>{{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}</dt> + <dd>告诉浏览器你希望执行一个动画,并在重绘之前,请求浏览器执行一个特定的函数来更新动画。</dd> +</dl> + +<p>如果你并不需要与用户互动,你可以使用setInterval()方法,它就可以定期执行指定代码。如果我们需要做一个游戏,我们可以使用键盘或者鼠标事件配合上setTimeout()方法来实现。通过设置事件监听,我们可以捕捉用户的交互,并执行相应的动作。</p> + +<div class="note"> +<p>下面的例子,采用 {{domxref("window.requestAnimationFrame()")}}实现动画效果。这个方法提供了更加平缓并更加有效率的方式来执行动画,当系统准备好了重绘条件的时候,才调用绘制动画帧。一般每秒钟回调函数执行60次,也有可能会被降低。想要了解更多关于动画循环的信息,尤其是游戏,可以在<a href="https://developer.mozilla.org/zh-CN/docs/Games">Game development zone</a> 参考这篇文章 <a href="https://developer.mozilla.org/zh-CN/docs/Games/Anatomy">Anatomy of a video game</a>。</p> +</div> + +<h2 id="太阳系的动画">太阳系的动画</h2> + +<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'; + window.requestAnimationFrame(draw); +} + +function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + ctx.globalCompositeOperation = 'destination-over'; + ctx.clearRect(0,0,300,300); // clear canvas + + ctx.fillStyle = 'rgba(0,0,0,0.4)'; + ctx.strokeStyle = 'rgba(0,153,255,0.4)'; + ctx.save(); + ctx.translate(150,150); + + // Earth + 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); + + // Moon + 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); // Earth orbit + ctx.stroke(); + + ctx.drawImage(sun,0,0,300,300); + + window.requestAnimationFrame(draw); +} + +init(); +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="300" height="300"></canvas></pre> +</div> + +<p>{{EmbedLiveSample("太阳系的动画", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}</p> + +<h2 id="动画时钟">动画时钟</h2> + +<p>这个例子实现一个动态时钟, 可以显示当前时间。</p> + +<pre class="brush: js">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"; + + // Hour marks + ctx.save(); + for (var i=0;i<12;i++){ + ctx.beginPath(); + ctx.rotate(Math.PI/6); + ctx.moveTo(100,0); + ctx.lineTo(120,0); + ctx.stroke(); + } + ctx.restore(); + + // Minute marks + ctx.save(); + ctx.lineWidth = 5; + for (i=0;i<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>=12 ? hr-12 : hr; + + ctx.fillStyle = "black"; + + // write Hours + 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(); + + // write Minutes + 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(); + + // Write seconds + 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(); + + window.requestAnimationFrame(clock); +} + +window.requestAnimationFrame(clock); +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> +</div> + +<p>{{EmbedLiveSample("动画时钟", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}</p> + +<h2 id="循环全景照片">循环全景照片</h2> + +<p>在这个例子中,会有一个自左向右滑动的全景图。我们使用了在维基百科中找到的<a href="https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg">尤塞米提国家公园的图片</a>,当然你可以随意找一张任何尺寸大于canvas的图片。</p> + +<pre class="brush: js">var img = new Image(); + +// User Variables - customize these to change the image being scrolled, its +// direction, and the speed. + +img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg'; +var CanvasXSize = 800; +var CanvasYSize = 200; +var speed = 30; // lower is faster +var scale = 1.05; +var y = -4.5; // vertical offset + +// Main program + +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 > CanvasXSize) { + // image larger than canvas + x = CanvasXSize - imgW; + } + if (imgW > CanvasXSize) { + // image width larger than canvas + clearX = imgW; + } else { + clearX = CanvasXSize; + } + if (imgH > CanvasYSize) { + // image height larger than canvas + clearY = imgH; + } else { + clearY = CanvasYSize; + } + + // get canvas context + ctx = document.getElementById('canvas').getContext('2d'); + + // set refresh rate + return setInterval(draw, speed); +} + +function draw() { + ctx.clearRect(0, 0, clearX, clearY); // clear the canvas + + // if image is <= Canvas Size + if (imgW <= CanvasXSize) { + // reset, start from beginning + if (x > CanvasXSize) { + x = -imgW + x; + } + // draw additional image1 + if (x > 0) { + ctx.drawImage(img, -imgW + x, y, imgW, imgH); + } + // draw additional image2 + if (x - imgW > 0) { + ctx.drawImage(img, -imgW * 2 + x, y, imgW, imgH); + } + } + + // image is > Canvas Size + else { + // reset, start from beginning + if (x > (CanvasXSize)) { + x = CanvasXSize - imgW; + } + // draw aditional image + if (x > (CanvasXSize-imgW)) { + ctx.drawImage(img, x - imgW + 1, y, imgW, imgH); + } + } + // draw image + ctx.drawImage(img, x, y,imgW, imgH); + // amount to move + x += dx; +}</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="800" height="200"></canvas></pre> +</div> + +<p>下方就是是图片在其中滑动的 {{HTMLElement("canvas")}}。需要注意的是这里定义的width和height必须与JavaScript代码中的变量值<code>CanvasXZSize</code>和<code>CanvasYSize</code>保持一致。 </p> + +<pre><canvas id="canvas" width="800" height="200"></canvas></pre> + +<p>{{EmbedLiveSample("循环全景照片", "830", "230")}}</p> + +<h2 id="鼠标追踪动画">鼠标追踪动画</h2> + +<pre class="brush: html"><!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta http-equiv="X-UA-Compatible" content="ie=edge"> + <title>Document</title> + <script> + var cn; + //= document.getElementById('cw'); + var c; + var u = 10; + const m = { + x: innerWidth / 2, + y: innerHeight / 2 + }; + window.onmousemove = function(e) { + m.x = e.clientX; + m.y = e.clientY; + + } + function gc() { + var s = "0123456789ABCDEF"; + var c = "#"; + for (var i = 0; i < 6; i++) { + c += s[Math.ceil(Math.random() * 15)] + } + return c + } + var a = []; + window.onload = function myfunction() { + cn = document.getElementById('cw'); + c = cn.getContext('2d'); + + for (var i = 0; i < 10; i++) { + var r = 30; + var x = Math.random() * (innerWidth - 2 * r) + r; + var y = Math.random() * (innerHeight - 2 * r) + r; + var t = new ob(innerWidth / 2,innerHeight / 2,5,"red",Math.random() * 200 + 20,2); + a.push(t); + } + //cn.style.backgroundColor = "#700bc8"; + + c.lineWidth = "2"; + c.globalAlpha = 0.5; + resize(); + anim() + } + window.onresize = function() { + + resize(); + + } + function resize() { + cn.height = innerHeight; + cn.width = innerWidth; + for (var i = 0; i < 101; i++) { + var r = 30; + var x = Math.random() * (innerWidth - 2 * r) + r; + var y = Math.random() * (innerHeight - 2 * r) + r; + a[i] = new ob(innerWidth / 2,innerHeight / 2,4,gc(),Math.random() * 200 + 20,0.02); + + } + // a[0] = new ob(innerWidth / 2, innerHeight / 2, 40, "red", 0.05, 0.05); + //a[0].dr(); + } + function ob(x, y, r, cc, o, s) { + this.x = x; + this.y = y; + this.r = r; + this.cc = cc; + this.theta = Math.random() * Math.PI * 2; + this.s = s; + this.o = o; + this.t = Math.random() * 150; + + this.o = o; + this.dr = function() { + const ls = { + x: this.x, + y: this.y + }; + this.theta += this.s; + this.x = m.x + Math.cos(this.theta) * this.t; + this.y = m.y + Math.sin(this.theta) * this.t; + c.beginPath(); + c.lineWidth = this.r; + c.strokeStyle = this.cc; + c.moveTo(ls.x, ls.y); + c.lineTo(this.x, this.y); + c.stroke(); + c.closePath(); + + } + } + function anim() { + requestAnimationFrame(anim); + c.fillStyle = "rgba(0,0,0,0.05)"; + c.fillRect(0, 0, cn.width, cn.height); + a.forEach(function(e, i) { + e.dr(); + }); + + } + </script> + <style> + #cw { + position: fixed; + z-index: -1; + } + + body { + margin: 0; + padding: 0; + background-color: rgba(0,0,0,0.05); + } + </style> + </head> + <body> + <canvas id="cw"></canvas> + qwerewr + + </body> +</html> +</pre> + +<h5 id="OutPut">OutPut</h5> + +<table class="standard-table"> + <tbody> + <tr> + <td> + <p><a href="https://kunalverma94.github.io/gallery/gags/beyblade.html"><img alt="beyblade" src="https://kunalverma94.github.io/gallery/beyblade.jpg" style="height: 298px; width: 399px;"></a></p> + </td> + </tr> + </tbody> +</table> + +<h2 id="Snake_Game">Snake Game</h2> + +<pre class="brush: html"><!DOCTYPE html> +<html lang="en"> + +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width,initial-scale=1"> + <meta http-equiv="X-UA-Compatible" content="ie=edge"> + <title>Nokia 1100:snake..Member berries</title> +</head> + +<body> + <div class="keypress hide"> + <div class="up" onclick="emit(38)">&#8593;</div> + <div class="right" onclick="emit(39)">&#8594;</div> + <div class="left" onclick="emit(37)">&#8592;</div> + <div class="down" onclick="emit(40)">&#8595;</div> + </div> + <div class="banner" id="selector"> + <div> + Time :<span id="time">0</span> + </div> + <div>LousyGames ©</div> + <div> + Score :<span id="score">0</span> + </div> + <div class="touch off" onclick="touch(this)">touch</div> + </div> + <canvas id="main"></canvas> +</body> +<style> + body { + margin: 0; + overflow: hidden; + background: #000 + } + + .banner { + text-align: center; + color: #fff; + background: #3f51b5; + line-height: 29px; + position: fixed; + left: 0; + top: 0; + right: 0; + font-family: monospace; + height: 30px; + opacity: .4; + display: flex; + transition: .5s + } + + .banner:hover { + opacity: 1 + } + + div#selector>div { + flex-basis: 30% + } + + @keyframes diss { + from { + opacity: 1 + } + + to { + opacity: 0 + } + } + + .keypress>div { + border: dashed 3px #fff; + height: 48%; + width: 48%; + display: flex; + align-content: center; + justify-content: center; + align-self: center; + align-items: center; + font-size: -webkit-xxx-large; + font-weight: 900; + color: #fff; + transition: .5s; + opacity: .1; + border-radius: 7px + } + + .keypress { + position: fixed; + width: 100vw; + height: 100vh; + top: 0; + left: 0; + display: flex; + flex-wrap: wrap; + justify-content: space-around; + opacity: 1; + user-select: none + } + + .keypress>div:hover { + opacity: 1 + } + + .touch { + background: #8bc34a + } + + .off { + background: #f44336 + } + + .hide { + opacity: 0 + } +</style> +</html></pre> + +<p>Javascript</p> + +<pre class="brush: js">function tmz() { + var e = new Date(t), + i = new Date, + n = Math.abs(i.getMinutes() - e.getMinutes()), + o = Math.abs(i.getSeconds() - e.getSeconds()); + return n + " : " + o + } + + function coll(t, e) { + return t.x < e.x + e.w && t.x + t.w > e.x && t.y < e.y + e.h && t.h + t.y > e.y + } + + function snake() { + this.w = 15, this.h = 15, this.dx = 1, this.dy = 1, this.xf = 1, this.yf = 1, this.sn = []; + for (var t = { + x: w / 2, + y: h / 2 + }, e = 0; e < 5; e++) this.sn.push(Object.assign({}, t)), t.x += this.w; + this.draw = function () { + var t = d && d.search("Arrow") > -1, + e = -1; + if (t) { + var i = { + ...this.sn[0] + }; + if ("ArrowUp" == d && (i.y -= this.h), "ArrowDown" == d && (i.y += this.h), "ArrowLeft" == d && (i.x -= this.w), "ArrowRight" == d && (i.x += this.w), i.x >= w ? i.x = 0 : i.x < 0 && (i.x = w - this.w), i.y > h ? i.y = 0 : i.y < 0 && (i.y = h), e = fa.findIndex(t => coll({ + ...this.sn[0], + h: this.h, + w: this.w + }, t)), this.sn.unshift(i), -1 != e) return console.log(e), fa[e].renew(), void (document.getElementById("score").innerText = Number(document.getElementById("score").innerText) + 1); + this.sn.pop(), console.log(6) + } + this.sn.forEach((t, e, i) => { + if (0 == e || i.length - 1 == e) { + var n = c.createLinearGradient(t.x, t.y, t.x + this.w, t.y + this.h); + i.length - 1 == e ? (n.addColorStop(0, "black"), n.addColorStop(1, "#8BC34A")) : (n.addColorStop(0, "#8BC34A"), n.addColorStop(1, "white")), c.fillStyle = n + } else c.fillStyle = "#8BC34A"; + c.fillRect(t.x, t.y, this.w, this.h), c.strokeStyle = "#E91E63", c.font = "30px serif", c.strokeStyle = "#9E9E9E", i.length - 1 != e && 0 != e && c.strokeRect(t.x, t.y, this.w, this.h), 0 == e && (c.beginPath(), c.fillStyle = "#F44336", c.arc(t.x + 10, t.y + 2, 5, 360, 0), c.fill()), c.arc(t.x + 10, t.y + 2, 5, 360, 0), c.fill(), c.beginPath() + }) + } + } + + function gc() { + for (var t = "0123456789ABCDEF", e = "#", i = 0; i < 6; i++) e += t[Math.ceil(15 * Math.random())]; + return e + } + + function food() { + this.x = 0, this.y = 0, this.b = 10, this.w = this.b, this.h = this.b, this.color = gc(), this.renew = function () { + this.x = Math.floor(Math.random() * (w - 200) + 10), this.y = Math.floor(Math.random() * (h - 200) + 30), this.color = gc() + }, this.renew(), this.put = (() => { + c.fillStyle = this.color, c.arc(this.x, this.y, this.b - 5, 0, 2 * Math.PI), c.fill(), c.beginPath(), c.arc(this.x, this.y, this.b - 5, 0, Math.PI), c.strokeStyle = "green", c.lineWidth = 10, c.stroke(), c.beginPath(), c.lineWidth = 1 + }) + } + + function init() { + cc.height = h, cc.width = w, c.fillRect(0, 0, w, innerHeight); + for (var t = 0; t < 10; t++) fa.push(new food); + s = new snake(w / 2, h / 2, 400, 4, 4), anima() + } + + function anima() { + c.fillStyle = "rgba(0,0,0,0.11)", c.fillRect(0, 0, cc.width, cc.height), fa.forEach(t => t.put()), s.draw(), document.getElementById("time").innerText = tmz(), setTimeout(() => { + requestAnimationFrame(anima) + }, fw) + } + + function emit(t) { + key.keydown(t) + } + + function touch(t) { + t.classList.toggle("off"), document.getElementsByClassName("keypress")[0].classList.toggle("hide") + } + var t = new Date + "", + d = void 0, + cc = document.getElementsByTagName("canvas")[0], + c = cc.getContext("2d"); + key = {}, key.keydown = function (t) { + var e = document.createEvent("KeyboardEvent"); + Object.defineProperty(e, "keyCode", { + get: function () { + return this.keyCodeVal + } + }), Object.defineProperty(e, "key", { + get: function () { + return 37 == this.keyCodeVal ? "ArrowLeft" : 38 == this.keyCodeVal ? "ArrowUp" : 39 == this.keyCodeVal ? "ArrowRight" : "ArrowDown" + } + }), Object.defineProperty(e, "which", { + get: function () { + return this.keyCodeVal + } + }), e.initKeyboardEvent ? e.initKeyboardEvent("keydown", !0, !0, document.defaultView, !1, !1, !1, !1, t, t) : e.initKeyEvent("keydown", !0, !0, document.defaultView, !1, !1, !1, !1, t, 0), e.keyCodeVal = t, e.keyCode !== t && alert("keyCode mismatch " + e.keyCode + "(" + e.which + ")"), document.dispatchEvent(e) + }; + var o, s, h = innerHeight, + w = innerWidth, + fw = 60, + fa = []; + window.onkeydown = function (t) { + var e = t.key; + (e.search("Arrow") > -1 || "1" == e) && (d = t.key), "i" != e && "I" != e || (console.log("inc"), fw -= 10), "d" != e && "D" != e || (console.log("dec"), fw += 10) + }, init(); +</pre> + +<h5 id="Output">Output</h5> + +<table class="standard-table"> + <tbody> + <tr> + <td> + <h2 id="sect1"><a href="https://kunalverma94.github.io/pokemon/snake.html"><img alt="Snake game" src="https://kunalverma94.github.io/view/images/snake.jpg" style="height: 400px; width: 600px;"></a></h2> + </td> + </tr> + </tbody> +</table> + +<h2 id="Other_examples" name="Other_examples">其它例子</h2> + +<dl> + <dt><a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/A_basic_ray-caster" title="/zh-CN/docs/Web/Guide/HTML/A_basic_ray-caster">A basic ray-caster</a></dt> + <dd>一个关于如何使用键盘关联控制动画的优秀的案例。</dd> + <dt><a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Advanced_animations">Advanced animations</a></dt> + <dd>我们将在下一章看到一些先进的动画技术和物理现象。</dd> +</dl> + +<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}</p> |