How to Master Landscape Orientation for Mobile H5 Games: Rotation, Scaling, and Canvas Adaptation
This article explains how to force landscape mode for lightweight HTML5 mobile games, adapt DOM layouts by switching viewport units, choose appropriate canvas scaling strategies, and apply relocation and redraw techniques to ensure UI elements remain functional across diverse screen sizes and orientations.
Force Landscape Display
To guarantee landscape orientation regardless of device rotation, listen to the resize event and rotate the root container 90° counter‑clockwise when the screen is in portrait. The following JavaScript applies the appropriate CSS3 transform.
var detectOrient = function () {
var width = document.documentElement.clientWidth,
height = document.documentElement.clientHeight,
$wrapper = document.getElementById("J_wrapper"),
style = "";
if (width >= height) { // landscape
style += "width:" + width + "px;";
style += "height:" + height + "px;";
style += "-webkit-transform: rotate(0); transform: rotate(0);";
style += "-webkit-transform-origin: 0 0;";
style += "transform-origin: 0 0;";
} else { // portrait
style += "width:" + height + "px;";
style += "height:" + width + "px;";
style += "-webkit-transform: rotate(90deg); transform: rotate(90deg);";
style += "-webkit-transform-origin: " + width/2 + "px " + width/2 + "px;";
style += "transform-origin: " + width/2 + "px " + width/2 + "px;";
}
$wrapper.style.cssText = style;
};
window.onresize = detectOrient;
detectOrient();If the project uses CreateJS, rotating the canvas with CSS breaks event coordinates; instead rotate the CreateJS stage via its rotation property.
if (self.isPortrait) {
self.stage.x = self.canvasHeight;
self.stage.rotation = 90;
} else {
self.stage.x = 0;
self.stage.rotation = 0;
}Landscape Adaptation for DOM
Typical mobile layouts rely on a VW+REM scheme that works well in portrait but produces excessive whitespace or oversized text in landscape because sizes are calculated from screen width. Replacing VW with VH for landscape (or mixing both) resolves the issue.
$vw_base: 375;
$vw_fontsize: 20;
html {
font-size: 20px; /* fallback */
font-size: ($vw_fontsize / $vw_base) * 100vw;
}
@media screen and (orientation: landscape) {
html {
font-size: 20px;
font-size: ($vw_fontsize / $vw_base) * 100vh;
}
}Canvas Landscape Adaptation
Two mainstream solutions exist: maintaining two separate canvases for portrait and landscape, or applying a scaling transform to a single canvas. The latter is more flexible and is implemented through five scaling modes.
Scaling Modes
Contain : Scale uniformly so the entire game area fits inside the viewport; the smaller of width‑ratio or height‑ratio is used.
Cover : Scale uniformly until the viewport is completely covered; the larger ratio is used, possibly cropping edges.
Fill : Stretch the game area to fill the viewport, ignoring aspect ratio.
Fixed‑Width : Keep the design width constant, scale height proportionally, and redraw the canvas height.
Fixed‑Height : Keep the design height constant, scale width proportionally, and redraw the canvas width.
Example implementation of the Contain mode:
function CONTAIN() {
var self = this;
self.radioX = self.radioY = Math.min(self.winWidth / self.designWidth,
self.winHeight / self.designHeight);
self.canvasWidth = self.designWidth;
self.canvasHeight = self.designHeight;
}Similar functions exist for COVER, FILL, FIXED_WIDTH, and FIXED_HEIGHT.
Relocation and Redraw Strategies
When scaling crops or stretches edge elements, record their original top, left, right, bottom values and recompute positions after adaptation.
_adjustPosition: function (item) {
if (typeof item.top === "number") {
item.y = item.top + this.halfCutHeight;
}
if (typeof item.left === "number") {
item.x = item.left + this.halfCutWidth;
}
// similar handling for bottom and right …
},
adjustPosition: function (item) {
this._adjustPosition(item);
}For elements that depend on the canvas size (e.g., full‑screen backgrounds), redraw them after scaling:
_adjustFullSize: function (item) {
item.drawRect(0, 0, this.canvasWidth, this.canvasHeight);
},
adjustFullSize: function (item) {
this._adjustFullSize(item);
}Conclusion
Effective landscape support for H5 lightweight games requires (1) forcing landscape orientation via CSS3 rotation or CreateJS stage rotation, (2) adapting DOM layout by switching VW to VH, (3) choosing an appropriate canvas scaling mode, and (4) applying relocation and redraw strategies to keep edge UI elements visible.
All code samples are hosted on the author’s GitHub repository for reference.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Aotu Lab
Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
