Mobile Development 18 min read

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.

Aotu Lab
Aotu Lab
Aotu Lab
How to Master Landscape Orientation for Mobile H5 Games: Rotation, Scaling, and Canvas Adaptation

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.
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

MobileCanvasscalingResponsivelandscape
Aotu Lab
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.