aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/api/canvas_api/tutorial/optimizing_canvas
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
commit33058f2b292b3a581333bdfb21b8f671898c5060 (patch)
tree51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/api/canvas_api/tutorial/optimizing_canvas
parent8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff)
downloadtranslated-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/optimizing_canvas')
-rw-r--r--files/zh-cn/web/api/canvas_api/tutorial/optimizing_canvas/index.html115
1 files changed, 115 insertions, 0 deletions
diff --git a/files/zh-cn/web/api/canvas_api/tutorial/optimizing_canvas/index.html b/files/zh-cn/web/api/canvas_api/tutorial/optimizing_canvas/index.html
new file mode 100644
index 0000000000..cfa0a7250f
--- /dev/null
+++ b/files/zh-cn/web/api/canvas_api/tutorial/optimizing_canvas/index.html
@@ -0,0 +1,115 @@
+---
+title: canvas的优化
+slug: Web/API/Canvas_API/Tutorial/Optimizing_canvas
+tags:
+ - Advanced
+ - Canvas
+ - Tutorial
+translation_of: Web/API/Canvas_API/Tutorial/Optimizing_canvas
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility", "Web/API/Canvas_API/Tutorial/Finale")}}</div>
+
+<div>
+<p class="summary">{{HTMLElement("canvas")}}元素是众多广泛使用的网络2D图像渲染标准之一。它被广泛用于游戏及复杂的图像可视化中。然而,随着网站和应用将canvas画布推至极限,性能开始成为问题。此文目标是给使用canvas画布元素的优化带来建议,去保证你的网站或者应用表现卓越。</p>
+</div>
+
+<h2 id="性能贴士">性能贴士</h2>
+
+<p>下面是一些改善性能的建议</p>
+
+<h3 id="在离屏canvas上预渲染相似的图形或重复的对象">在离屏canvas上预渲染相似的图形或重复的对象</h3>
+
+<p>如果发现自己在每个动画帧上重复了一些相同的绘制操作,请考虑将其分流到屏幕外的画布上。 然后,您可以根据需要频繁地将屏幕外图像渲染到主画布上,而不必首先重复生成该图像的步骤。</p>
+
+<pre class="brush: js">myEntity.offscreenCanvas = document.createElement("canvas");
+myEntity.offscreenCanvas.width = myEntity.width;
+myEntity.offscreenCanvas.height = myEntity.height;
+myEntity.offscreenContext = myEntity.offscreenCanvas.getContext("2d");
+
+myEntity.render(myEntity.offscreenContext);
+</pre>
+
+<h3 id="避免浮点数的坐标点,用整数取而代之">避免浮点数的坐标点,用整数取而代之</h3>
+
+<p>当你画一个没有整数坐标点的对象时会发生子像素渲染。</p>
+
+<pre class="brush: js">ctx.drawImage(myImage, 0.3, 0.5);
+</pre>
+
+<p>浏览器为了达到抗锯齿的效果会做额外的运算。为了避免这种情况,请保证在你调用{{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}}函数时,用{{jsxref("Math.floor()")}}函数对所有的坐标点取整。</p>
+
+<h3 id="不要在用drawImage时缩放图像">不要在用<code>drawImage</code>时缩放图像</h3>
+
+<p>在离屏canvas中缓存图片的不同尺寸,而不要用{{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}}去缩放它们。</p>
+
+<h3 id="使用多层画布去画一个复杂的场景">使用多层画布去画一个复杂的场景</h3>
+
+<p>在您的应用程序中,您可能会发现某些对象需要经常移动或更改,而其他对象则保持相对静态。 在这种情况下,可能的优化是使用多个<code>&lt;canvas&gt;</code>元素对您的项目进行分层。</p>
+
+<p>例如,假设您有一个游戏,其UI位于顶部,中间是游戏性动作,底部是静态背景。 在这种情况下,您可以将游戏分成三个<code>&lt;canvas&gt;</code>层。 UI将仅在用户输入时发生变化,游戏层随每个新框架发生变化,并且背景通常保持不变。</p>
+
+<pre class="brush: html">&lt;div id="stage"&gt;
+ &lt;canvas id="ui-layer" width="480" height="320"&gt;&lt;/canvas&gt;
+ &lt;canvas id="game-layer" width="480" height="320"&gt;&lt;/canvas&gt;
+ &lt;canvas id="background-layer" width="480" height="320"&gt;&lt;/canvas&gt;
+&lt;/div&gt;
+
+&lt;style&gt;
+ #stage {
+ width: 480px;
+ height: 320px;
+ position: relative;
+ border: 2px solid black
+ }
+ canvas { position: absolute; }
+ #ui-layer { z-index: 3 }
+ #game-layer { z-index: 2 }
+ #background-layer { z-index: 1 }
+&lt;/style&gt;
+</pre>
+
+<h3 id="用CSS设置大的背景图">用CSS设置大的背景图</h3>
+
+<p>如果像大多数游戏那样,你有一张静态的背景图,用一个静态的{{HTMLElement("div")}}元素,结合{{cssxref("background")}} 特性,以及将它置于画布元素之后。这么做可以避免在每一帧在画布上绘制大图。</p>
+
+<h3 id="用CSS_transforms特性缩放画布">用CSS transforms特性缩放画布</h3>
+
+<p><a href="/en-US/docs/Web/Guide/CSS/Using_CSS_transforms">CSS transforms</a> 使用GPU,因此速度更快。 最好的情况是不直接缩放画布,或者具有较小的画布并按比例放大,而不是较大的画布并按比例缩小。</p>
+
+<pre class="brush: js">var scaleX = window.innerWidth / canvas.width;
+var scaleY = window.innerHeight / canvas.height;
+
+var scaleToFit = Math.min(scaleX, scaleY);
+var scaleToCover = Math.max(scaleX, scaleY);
+
+stage.style.transformOrigin = '0 0'; //scale from top left
+stage.style.transform = 'scale(' + scaleToFit + ')';
+</pre>
+
+<h3 id="关闭透明度">关闭透明度</h3>
+
+<p>如果你的游戏使用画布而且不需要透明,当使用 <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext" title="The HTMLCanvasElement.getContext() method returns a drawing context on the canvas, or null if the context identifier is not supported.">HTMLCanvasElement.getContext()</a></code> 创建一个绘图上下文时把 <code>alpha</code> 选项设置为 <code>false</code> 。这个选项可以帮助浏览器进行内部优化。</p>
+
+<pre class="brush: js">var ctx = canvas.getContext('2d', { alpha: false });</pre>
+
+<h3 id="更多的贴士">更多的贴士</h3>
+
+<ul>
+ <li>将画布的函数调用集合到一起(例如,画一条折线,而不要画多条分开的直线)</li>
+ <li>避免不必要的画布状态改变</li>
+ <li>渲染画布中的不同点,而非整个新状态</li>
+ <li>尽可能避免 {{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur")}}特性</li>
+ <li>尽可能避免<a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text">text rendering</a></li>
+ <li>尝试不同的方法来清除画布({{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}} vs. {{domxref("CanvasRenderingContext2D.fillRect", "fillRect()")}} vs. 调整canvas大小)</li>
+ <li> 有动画,请使用{{domxref("window.requestAnimationFrame()")}} 而非{{domxref("window.setInterval()")}}</li>
+ <li>请谨慎使用大型物理库</li>
+</ul>
+
+<h2 id="参见">参见</h2>
+
+<ul>
+ <li><a href="http://www.html5rocks.com/en/tutorials/canvas/performance/#toc-ref">Improving HTML5 Canvas Performance – HTML5 Rocks</a></li>
+ <li><a href="https://hacks.mozilla.org/2013/05/optimizing-your-javascript-game-for-firefox-os/">Optimizing your JavaScript game for Firefox OS – Mozilla Hacks</a></li>
+</ul>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility", "Web/API/Canvas_API/Tutorial/Finale")}}</p>