ÐпÑимизаÑÐ¸Ñ canvas
ÐÐ»ÐµÐ¼ÐµÐ½Ñ <canvas> ÑвлÑеÑÑÑ Ð¾Ð´Ð½Ð¸Ð¼ из наиболее ÑиÑоко иÑполÑзÑемÑÑ
инÑÑÑÑменÑов Ð´Ð»Ñ ÑендеÑинга 2D-гÑаÑики в ÐнÑеÑнеÑе. Ðднако когда веб-ÑайÑÑ Ð¸ пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ÑполÑзÑÑÑ Canvas API на пÑеделе его возможноÑÑей, пÑоизводиÑелÑноÑÑÑ Ð½Ð°ÑÐ¸Ð½Ð°ÐµÑ ÑнижаÑÑÑÑ. Ð ÑÑой ÑÑаÑÑе пÑиводÑÑÑÑ Ð¿ÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ опÑимизаÑии иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑлеменÑа canvas Ð´Ð»Ñ Ð¾Ð±ÐµÑпеÑÐµÐ½Ð¸Ñ Ñ
оÑоÑей ÑабоÑÑ Ð³ÑаÑики.
СовеÑÑ Ð¿Ð¾ пÑоизводиÑелÑноÑÑи
Ðиже пÑиведÑн ÑбоÑник ÑовеÑов по ÑлÑÑÑÐµÐ½Ð¸Ñ Ð¿ÑоизводиÑелÑноÑÑи canvas.
ÐÑедваÑиÑелÑно оÑÑиÑÑйÑе Ð¿Ð¾Ñ Ð¾Ð¶Ð¸Ðµ пÑимиÑÐ¸Ð²Ñ Ð¸Ð»Ð¸ повÑоÑÑÑÑиеÑÑ Ð¾Ð±ÑекÑÑ Ð½Ð° offscreen canvas
ÐÑли Ð²Ñ Ð¿Ð¾Ð²ÑоÑÑеÑе одни и Ñе же опеÑаÑии ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð² каждом кадÑе анимаÑии, ÑаÑÑмоÑÑиÑе возможноÑÑÑ Ð¸Ñ Ð²ÑгÑÑзки на offscreen canvas. ÐаÑем Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе визÑализиÑоваÑÑ Ð·Ð°ÐºÐ°Ð´Ñовое изобÑажение на Ñвой оÑновной canvas Ñак ÑаÑÑо, как ÑÑо Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾, без Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи повÑоÑÑÑÑ Ñаги, Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ñе Ð´Ð»Ñ ÐµÐ³Ð¾ генеÑаÑии.
myCanvas.offscreenCanvas = document.createElement("canvas");
myCanvas.offscreenCanvas.width = myCanvas.width;
myCanvas.offscreenCanvas.height = myCanvas.height;
myCanvas.getContext("2d").drawImage(myCanvas.offScreenCanvas, 0, 0);
ÐзбегайÑе кооÑÐ´Ð¸Ð½Ð°Ñ Ñ Ð¿Ð»Ð°Ð²Ð°ÑÑей ÑоÑкой и иÑполÑзÑйÑе вмеÑÑо Ð½Ð¸Ñ ÑелÑе ÑиÑла
СÑбпикÑелÑнÑй ÑендеÑинг пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð¿Ñи ÑендеÑинге обÑекÑов на canvas без ÑелÑÑ Ð·Ð½Ð°Ñений.
ctx.drawImage(myImage, 0.3, 0.5);
ÐÑо заÑÑавлÑÐµÑ Ð±ÑаÑÐ·ÐµÑ Ð²ÑполнÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑÑÑекÑа ÑглаживаниÑ. ЧÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ ÑÑого, обÑзаÑелÑно окÑÑглиÑе вÑе кооÑдинаÑÑ, иÑполÑзÑемÑе в вÑзоваÑ
drawImage(), напÑимеÑ, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Math.floor().
Ðе маÑÑÑабиÑÑйÑе изобÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð² drawImage
ÐÑи загÑÑзке кеÑиÑÑйÑе изобÑÐ°Ð¶ÐµÐ½Ð¸Ñ ÑазнÑÑ
ÑазмеÑов на offscreen canvas, а не поÑÑоÑнно маÑÑÑабиÑÑйÑе иÑ
в drawImage().
ÐÑполÑзÑйÑе неÑколÑко ÑлоÑв canvas Ð´Ð»Ñ ÑложнÑÑ ÑÑен
ÐÑ Ð¼Ð¾Ð¶ÐµÑе обнаÑÑжиÑÑ, ÑÑо некоÑоÑÑе обÑекÑÑ Ð² ваÑем пÑиложении нÑжно ÑаÑÑо пеÑемеÑаÑÑ Ð¸Ð»Ð¸ менÑÑÑ, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº дÑÑгие оÑÑаÑÑÑÑ Ð¾ÑноÑиÑелÑно ÑÑаÑиÑнÑми. Ðозможной опÑимизаÑией в ÑÑой ÑиÑÑаÑии ÑвлÑеÑÑÑ Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ ваÑиÑ
ÑлеменÑов Ñ Ð¸ÑполÑзованием неÑколÑкиÑ
ÑлеменÑов <canvas>.
ÐапÑимеÑ, допÑÑÑим, Ñ Ð²Ð°Ñ ÐµÑÑÑ Ð¸Ð³Ñа Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑким инÑеÑÑейÑом навеÑÑ
Ñ, геймплеем в ÑеÑедине и ÑÑаÑиÑеÑким Ñоном внизÑ. Ð ÑÑом ÑлÑÑае Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе ÑазбиÑÑ ÑÐ²Ð¾Ñ Ð¸Ð³ÑÑ Ð½Ð° ÑÑи ÑÐ»Ð¾Ñ <canvas>. ÐолÑзоваÑелÑÑкий инÑеÑÑÐµÐ¹Ñ Ð±ÑÐ´ÐµÑ Ð¼ÐµÐ½ÑÑÑÑÑ ÑолÑко пÑи изменении полÑзоваÑелем, Ñлой Ñ Ð¸Ð³ÑовÑм пÑоÑеÑÑом бÑÐ´ÐµÑ Ð¼ÐµÐ½ÑÑÑÑÑ Ñ ÐºÐ°Ð¶Ð´Ñм новÑм кадÑом, а Ñон оÑÑанеÑÑÑ Ð² оÑновном неизменнÑм.
<div id="stage">
<canvas id="ui-layer" width="480" height="320"></canvas>
<canvas id="game-layer" width="480" height="320"></canvas>
<canvas id="background-layer" width="480" height="320"></canvas>
</div>
<style>
#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;
}
</style>
ÐÑполÑзÑйÑе пÑоÑÑой CSS Ð´Ð»Ñ Ð±Ð¾Ð»ÑÑÐ¸Ñ ÑоновÑÑ Ð¸Ð·Ð¾Ð±Ñажений
ÐÑли Ñ Ð²Ð°Ñ ÐµÑÑÑ ÑÑаÑиÑеÑкое Ñоновое изобÑажение, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе наÑиÑоваÑÑ ÐµÐ³Ð¾ на пÑоÑÑом ÑлеменÑе <div>, иÑполÑзÑÑ ÑвойÑÑво CSS background, и ÑаÑположиÑÑ ÐµÐ³Ð¾ под canvas. ÐÑо ÑведÑÑ Ð½Ð° Ð½ÐµÑ Ð½ÐµÐ¾Ð±Ñ
одимоÑÑÑ ÑендеÑинга Ñона на canvas на каждом Ñике.
ÐаÑÑÑабиÑование Ñ Ð¾Ð»ÑÑа Ñ Ð¸ÑполÑзованием CSS-пÑеобÑазований
CSS-пÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±ÑÑÑÑее, поÑколÑÐºÑ Ð¾Ð½Ð¸ иÑполÑзÑÑÑ Ð³ÑаÑиÑеÑкий пÑоÑеÑÑоÑ. Ридеале, не ÑÑÐ¾Ð¸Ñ Ð½Ðµ маÑÑÑабиÑоваÑÑ canvas, или можно иÑполÑзоваÑÑ Ð¼ÐµÐ½ÑÑий canvas и ÑвелиÑиваÑÑ ÐµÐ³Ð¾ пÑи Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи, но не ÑменÑÑаÑÑ.
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 + ")";
ÐÑклÑÑиÑе пÑозÑаÑноÑÑÑ
ÐÑли ваÑе пÑиложение иÑполÑзÑÐµÑ canvas и не нÑждаеÑÑÑ Ð² пÑозÑаÑном Ñоне, ÑÑÑановиÑе Ð´Ð»Ñ Ð¿Ð°ÑамеÑÑа alpha знаÑение false пÑи Ñоздании конÑекÑÑа ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ HTMLCanvasElement.getContext(). ÐÑа инÑоÑмаÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð±ÑаÑзеÑом Ð´Ð»Ñ Ð¾Ð¿ÑимизаÑии ÑендеÑинга.
var ctx = canvas.getContext("2d", { alpha: false });
ÐÑÑгие ÑовеÑÑ
- ÐбÑединÑйÑе запÑоÑÑ Ðº canvas. ÐапÑимеÑ, ÑиÑÑйÑе Ð¾Ð´Ð½Ñ Ð»Ð¾Ð¼Ð°Ð½Ð½ÑÑ Ð»Ð¸Ð½Ð¸Ñ Ð²Ð¼ÐµÑÑо неÑколÑÐºÐ¸Ñ Ð¾ÑделÑнÑÑ Ð»Ð¸Ð½Ð¸Ð¹.
- ÐзбегайÑе ненÑжнÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ ÑоÑÑоÑÐ½Ð¸Ñ canvas.
- ÐÑобÑажайÑе ÑолÑко Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑкÑана, а не заново пеÑеÑиÑовÑвайÑе.
- Ðо возможноÑÑи избегайÑе ÑвойÑÑва
shadowBlur. - ÐзбегайÑе ÑендеÑинга ÑекÑÑа, когда ÑÑо возможно.
- ÐопÑобÑйÑе ÑазнÑе ÑпоÑÐ¾Ð±Ñ Ð¾ÑиÑÑки canvas ((
clearRect(), илиfillRect(), или изменение ÑазмеÑа canvas). - С анимаÑиÑми иÑполÑзÑйÑе
window.requestAnimationFrame()вмеÑÑоwindow.setInterval(). - ÐÑдÑÑе оÑÑоÑÐ¾Ð¶Ð½Ñ Ñ ÑÑжÑлÑми ÑизиÑеÑкими библиоÑеками.