响应式画布中的形状不成比例

问题描述 投票:0回答:1

我正在尝试学习 Konva.js 来构建游戏,我最重要的优先事项之一是画布应该在宽度和高度上响应。我已经成功实现了这一点,但是当我调整浏览器大小时,形状会不成比例地拉伸。我有一些猜测,当窗口调整大小时,我必须更新形状的 X 和 Y,但作为这个框架的新手,我不知道如何实现它。 这是我的代码-

<!DOCTYPE html>
<html>

<head>
    <script src="https://unpkg.com/[email protected]/konva.min.js"></script>
    <meta charset="utf-8" />
    <title>Konva Responsive Canvas Demo</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
            background-color: #f0f0f0;
            height: 100vh;
        }

        #stage-parent {
            width: 100%;
            height: 100vh;
        }
    </style>
</head>

<body>
    <div id="stage-parent">
        <div id="container"></div>
    </div>
    <script>
        let sceneWidth = 1000;
        let sceneHeight = 1000;

        let stage = new Konva.Stage({
            container: 'container',
            width: sceneWidth,
            height: sceneHeight,
        });

        let layer = new Konva.Layer();
        stage.add(layer);

        let circle = new Konva.Circle({
            radius: 50,
            fill: 'red',
            x: stage.width() / 2,
            y: stage.height() / 2,
        });
        layer.add(circle);

        let rect = new Konva.Rect({
            fill: 'green',
            x: stage.width() - 100,
            y: stage.height() - 100,
            width: 100,
            height: 100,
        });
        layer.add(rect);

        function fitStageIntoParentContainer() {
            const container = document.querySelector('#stage-parent');

            let containerWidth = container.offsetWidth;
            let containerHeight = container.offsetHeight

            let scaleX = containerWidth / sceneWidth;
            let scaleY = containerHeight / sceneHeight;

            stage.width(sceneWidth * scaleX);
            stage.height(sceneHeight * scaleY);
            stage.scale({ x: scaleX, y: scaleY });
        }

        fitStageIntoParentContainer();
        window.addEventListener('resize', fitStageIntoParentContainer);
    </script>
</body>

</html>
javascript html canvas konvajs konva
1个回答
0
投票

要在 Konva.js 中调整画布大小时保持形状的正确比例,请确保

scaleX
scaleY
值相同。这样,两个维度就会均匀缩放,从而防止扭曲。您还可以移动舞台以确保虚拟区域始终可见。

let sceneWidth = 1000;
        let sceneHeight = 1000;

        let stage = new Konva.Stage({
            container: 'container',
            width: sceneWidth,
            height: sceneHeight,
        });

        let layer = new Konva.Layer();
        stage.add(layer);

        let circle = new Konva.Circle({
            radius: 50,
            fill: 'red',
            x: sceneWidth / 2,
            y: sceneHeight / 2,
        });
        layer.add(circle);

        let rect = new Konva.Rect({
            fill: 'green',
            x: sceneWidth - 100,
            y: sceneHeight - 100,
            width: 100,
            height: 100,
        });
        layer.add(rect);

        function fitStageIntoParentContainer() {
            const container = document.querySelector('#stage-parent');

            let containerWidth = container.offsetWidth;
            let containerHeight = container.offsetHeight;

            let scale = Math.min(containerWidth / sceneWidth, containerHeight / sceneHeight);

            let newWidth = sceneWidth * scale;
            let newHeight = sceneHeight * scale;

            let x = (containerWidth - newWidth) / 2;
            let y = (containerHeight - newHeight) / 2;

            stage.width(containerWidth);
            stage.height(containerHeight);
            stage.scale({ x: scale, y: scale });
            stage.position({ x: x, y: y });
            stage.batchDraw();
        }

        fitStageIntoParentContainer();
        window.addEventListener('resize', fitStageIntoParentContainer);
body {
            margin: 0;
            padding: 0;
            overflow: hidden;
            background-color: #f0f0f0;
            height: 100vh;
        }

        #stage-parent {
            width: 100%;
            height: 100vh;
        }
<script src="https://unpkg.com/[email protected]/konva.min.js"></script>
<div id="stage-parent">
        <div id="container"></div>
    </div>

© www.soinside.com 2019 - 2024. All rights reserved.