画布设备方向缩放

5
我制作了一款赛车游戏。我正在尝试使其在移动设备上具有可伸缩性。
当设备方向为正常(垂直)时,我能够让其看起来很好:

![enter image description here

但是当我将设备旋转到横向视图时,会出现这种情况:(如何稍微缩小它)?

enter image description here

我该怎么做?我使用了display: none来隐藏图像。 非常感谢您的帮助。
编辑:我已经成功完成了这个操作,但是视图仍然太过缩放,有什么建议吗?
const width = 800;
const height = 600;
const pixelRatio = window.devicePixelRatio || 1;
canvas.width = width * pixelRatio;
canvas.height = height * pixelRatio;

canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;

// for sprites scaled up to retina resolution
canvas.mozImageSmoothingEnabled = false;
canvas.imageSmoothingEnabled = false;

c.scale(pixelRatio, pixelRatio);

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, height=device-height">

    <!-- <meta name="viewport" content="width=device-width, initial-scale=1"> -->
    <title>Canvas Story</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }
        canvas {

            display: block;
        }
        body {
            margin: 0;
        } 
        #container {
            margin: 0 auto;
            width: 800px;
            height: 600px;
            overflow: hidden;
            position: relative;
            border: 1px solid #000;
            border-radius: 10px;
            margin-top: 2px;
        } 
    </style>
</head>

<body>
    <br/>
    
    <img id="obstacle" src="obstacle.png" style="display: none;" />
        <img id="bonus" src="bonus.png" style="display: none;" />
        <img id="bullet" src="bullet.png" style="display: none;" />
        <img id="car" src="car.png" style="display: none;" />

    <div id="container">
        <canvas id="ltpcanvas"></canvas>
    </div>

    <div class="circleBase" id="rotateMode" style="margin:0 auto;">
        <button id="left" onmousedown="leftKeyPressed()" onmouseup="leftKeyReleased()" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-arrow-left"></span></button>
        <button id="right" onmousedown="rightKeyPressed()" onmouseup="rightKeyReleased()" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-arrow-right"></span></button>
        <button id="middle" onclick="bulletsPush()" class="btn btn-default btn-sm"><span class="glyphicon glyphicon glyphicon-record"></span></button>
        <button id="up" onmousedown="upKeyPressed()" onmouseup="upKeyReleased()" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-arrow-up"></span></button>
        <button id="down" onmousedown="downKeyPressed()" onmouseup="downKeyReleased()" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-arrow-down"></span></button>
    </div>
    
    
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="css.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="canvas.js"></script>

    

</body>

</html>

1
请看这里:https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html。即使是针对 WebGL 的解释,概念也是相同的。 - deblocker
从第二张图片来看,你的赛道的上部分似乎超出了浏览器的可见区域 - 那么你是如何在设备旋转时调整容器div / canvas的大小的?这在你发布的代码中并没有展示。 - obscure
4个回答

1

window对象的resize事件的回调函数中更新canvas大小或任何你需要的内容:

window.addEventListener('resize', function() {
    // canvas resize, etc.
}, false);

1
在标签中使用以下内容:
<meta name="viewport" content="width=device-width, initial-scale=1">

width=device-width部分将页面宽度设置为跟随设备的屏幕宽度(这将根据不同设备而变化)。

initial-scale=1.0部分在页面首次由浏览器加载时设置初始缩放级别。

并且在animate中添加以下内容:

            c.clearRect(0, 0, canvas.width, canvas.height);
            drawCanvas(boundaryLeftOffset - 2, 0,window.innerWidth, 
            window.innerHeight, 'grey');

我尝试了修改过的版本,但似乎仍然无法工作。也许是因为我的CSS的原因?我在div里面有canvas。感谢你正在努力帮助我。 - Simonsoft177
@Simonsoft177 我拿了你的整个代码在我的电脑上运行,甚至不能在大屏幕上运行。 - Nikhil S
尝试在您的画布中重新初始化并执行。曾经我用chart.js绘制了一个条形图,我重新初始化它,它起作用了,但现在我没有代码,也不会编写代码。 - Nikhil S
重新初始化画布是什么意思?清除画布?但是在哪里清除? - Simonsoft177
它不行 :( 当我缩小Web浏览器窗口时,画布无法适应,变形了。 - Simonsoft177
请使用 https://www.chartjs.org/docs/latest/general/responsive.html 这个链接。 - Nikhil S

0
如果``不起作用的话,你可能需要考虑一下@media查询。在过去,这对我帮助很大,我认为它会对你有所帮助,特别是如果你知道显示器/屏幕的分辨率。

我知道你想说什么,但我不知道这个问题的根源。当分辨率降低时,要更改哪些大小,因为我的画布应该是800x600。 - Simonsoft177

0

我认为你需要根据视口的大小设置画布的大小(如果视口大小发生变化(例如通过旋转屏幕),请务必这样做):

// Set canvas size (how many 'pixels' are on the canvas)
// NOTE CSS determines how large the canvas is, this determines
// the size of the things you draw on it.
const width = 800;
const height = 600;
const canvasAspectRatio = width / height;

// Also define the gap we want at the edges:
const edgeMargin = 10;

// Set the number of 'pixels' in the canvas.
canvas.width = width;
canvas.height = height;

// Sets the canvas size based on the window height and width
function setCanvasElementSize () {
  const windowWidth = window.innerWidth;
  const windowHeight = window.innerHeight;

  // Work out the orientation of the device.
  const isPortrait = window.innerHeight > window.innerWidth;

  if (isPortrait) {
    // We want to constrain the canvas by its width
    canvas.style.width = windowWidth - (2 * edgeMargin);
    // The height depends on the width to ensure we don't stretch pixels
    // on the canvas.
    canvas.style.height = canvas.style.width / canvasAspectRatio;
  } else {
    // constrain by height
    canvas.style.height = windowHeight - (2 * edgeMargin);
    canvas.style.width = canvas.style.height * canvasAspectRatio;
  }
}

// Call the function once initially to size the canvas
setCanvasElementSize();

// Also add a resize listener so we can ensure the canvas is 
// adjusted when the screen rotates.

// BONUS: Only do this once per animation frame.
let rafRequest = null;
window.addEventListener('resize', function () {
  if (rafRequest) {
    clearAnimationFrame(animationFrameReference);
  }

  let rafRequest = requestAnimationFrame(function () {
    rafRequest = null;
    setCanvasElementSize();
  });
});

注意事项:

  1. 我没有测试过这段代码,可能会有错别字!
  2. 一些移动浏览器在测量窗口大小时的行为与其他浏览器不同。例如,有些浏览器不考虑地址栏的大小或键盘是否可见。但这已经超出了问题的范围。如果您想进行调整,您需要进行更广泛的测试/研究,然后相应地增加或减少setCanvasElementSize()中画布的大小。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接