An adaptive solution HTML5 canvas mobile phone screen size

First, the final results

In order not to waste everybody's time, to show the final results, we need to see is not the solution:

Complete Project Address: https://github.com/zxf20180725/canvas_auto-adapted

Standard resolution:

Other resolutions adaptation of the situation:

Second, demand

1.canvas content can all be displayed on the screen

2. Try to ensure that the image is not deformed

3. Draw Text can adaptively

Third, the solution

1. We need to specify a standard resolution gameW and gameH

2. We need to get the actual screen resolution:

screenW=document.documentElement.clientWidth

screenH=document.documentElement.clientHeight

3. Set the canvas width and height as big as the screen

4. Calculate the screen width and standard width ratio:

kW=screenW/gameW

5. After drawing area may be smaller than the screen height adapted to the height, it will appear black bars. So we need to calculate the height of the black side:

= dY (screenH - gameH kW *) / 2 ; // black region height (distance from the top and the top of the screen violet region)

Note that, when the dY is less than 0, the drawing area will be off the screen, requiring a high degree of compression drawing area (in this case, the screen will be deformed and unavoidable thing):

    //我们先根据宽度比例适配
    let dY = (screenH - gameH * kW) / 2;    //黑色区域的高度(紫色区域顶部与屏幕顶部的距离)
    //当dY小于0时,我们不得不把画面给纵向压缩了。不然部分内容就会到屏幕外面去了
    if (dY<0){
        dY=0;
        kH=screenH/gameH;
    }

    let scaleH = kW;    //高度缩放率,默认以宽度比例
    if (kH!==1){
        scaleH=kH;
    }

Finally, there is an important issue, adaptive font size. I think the easiest way is to use double buffering mechanism, we are drawing, draw text takes place on another cushion canvas, finally scaled according scaleH, the contents of the buffer canvas to draw to the screen canvas.

Fourth, the complete code

Complete Project Address: https://github.com/zxf20180725/canvas_auto-adapted

Core code:

    let canvas = document.getElementById("main");
    let ctx = canvas.getContext("2d");
    let screenW = document.documentElement.clientWidth;     //屏幕宽度
    let screenH = document.documentElement.clientHeight;    //屏幕高度
    let gameW = 640, gameH = 1280;   //标准分辨率,也就是你开发时的分辨率 TODO:这里可以自行修改

    let kW = screenW / gameW;       //屏幕宽度与标准宽度的比值
    let kH = 1;                   //屏幕高度与标准高度的比值

    //我们先根据宽度比例适配
    let dY = (screenH - gameH * kW) / 2;    //黑色区域的高度(紫色区域顶部与屏幕顶部的距离)
    //当dY小于0时,我们不得不把画面给纵向压缩了。不然部分内容就会到屏幕外面去了
    if (dY < 0) {
        dY = 0;
        kH = screenH / gameH;
    }

    let scaleH = kW;    //高度缩放率,默认以宽度比例
    if (kH !== 1) {
        scaleH = kH;
    }

    //设置canvas的绝对大小与屏幕一致
    canvas.width = screenW;
    canvas.height = screenH;

    //缓冲区
    let canvasBuffer = document.createElement("canvas");
    let ctxBuffer = canvasBuffer.getContext("2d");
    //缓冲区使用标准分辨率
    canvasBuffer.width = gameW;
    canvasBuffer.height = gameH;

    let timer = setInterval(mainLoop, 32);      //60FPS
    let testImg = NewImage('./test.png', 200, 250); //测试图片

    //游戏主循环
    function mainLoop() {
        drawFillRect(ctx, '#000', 0, 0, canvas.width, canvas.height);   //给canvas刷上一层黑色背景~
        drawFillRect(ctxBuffer, '#FF00FF', 0, 0, gameW, gameH);     //给游戏区域刷上一层紫色背景~
        drawText(ctxBuffer, '#FFF', 25, '窗口width:' + screenW, 0, 0);
        drawText(ctxBuffer, '#FFF', 25, '窗口height:' + screenH, 0, 30);
        drawText(ctxBuffer, '#FFF', 25, 'kW:' + kW, 0, 60);
        drawText(ctxBuffer, '#FFF', 25, 'kH:' + kH, 0, 90);
        drawText(ctxBuffer, '#FFF', 25, 'dY:' + dY, 0, 120);

        drawSrcImg(ctxBuffer, testImg, 100, 100);
        drawText(ctxBuffer, '#000', 32, '柳逐霓', 150, 350);

        drawSrcImg(ctxBuffer, testImg, 270, 100);
        drawText(ctxBuffer, '#000', 32, '柳逐霓', 320, 350);

        drawSrcImg(ctxBuffer, testImg, 530, 100);
        drawText(ctxBuffer, '#000', 32, '柳逐霓', 580, 350);

        drawSrcImg(ctxBuffer, testImg, 100, 400);
        drawText(ctxBuffer, '#000', 32, '柳逐霓', 150, 650);

        drawSrcImg(ctxBuffer, testImg, 100, 700);
        drawText(ctxBuffer, '#000', 32, '柳逐霓', 150, 950);

        drawSrcImg(ctxBuffer, testImg, 100, 1000);
        drawText(ctxBuffer, '#000', 32, '柳逐霓', 150, 1250);

        //双缓冲
        ctx.drawImage(canvasBuffer, 0, 0, gameW, gameH, 0, dY, screenW, gameH * scaleH);
    }

 

发布了40 篇原创文章 · 获赞 99 · 访问量 12万+

Guess you like

Origin blog.csdn.net/qq_39687901/article/details/104071957