You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Konva.js响应式画布图形比例失调问题求助

Konva.js 画布响应式适配(解决窗口缩放图形比例失调问题)

问题分析

当前实现的核心问题是窗口 resize 时对舞台进行了非等比缩放(分别设置 scaleX 和 scaleY),导致图形被拉伸或压缩。实际上无需单独更新图形的 X/Y 属性,只需保持舞台的等比缩放,并让舞台在容器中居中,即可确保图形比例正常。

解决方案

修改 fitStageIntoParentContainer 函数,采用等比缩放逻辑,同时将舞台居中对齐:

<!DOCTYPE html>
<html>

<head>
    <script src="https://unpkg.com/konva@9.3.14/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;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    </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');
            const containerWidth = container.offsetWidth;
            const containerHeight = container.offsetHeight;

            // 计算等比缩放比例,取较小值避免图形超出容器
            const scale = Math.min(containerWidth / sceneWidth, containerHeight / sceneHeight);
            
            // 更新舞台宽高与缩放比例
            stage.width(sceneWidth * scale);
            stage.height(sceneHeight * scale);
            stage.scale({ x: scale, y: scale });
            
            // 让舞台在容器中居中(CSS flex已实现,这里用Konva属性兜底)
            stage.position({
                x: (containerWidth - stage.width()) / 2,
                y: (containerHeight - stage.height()) / 2
            });
        }

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

</html>

关键修改说明

  • 等比缩放:用 Math.min(scaleX, scaleY) 获取统一缩放比例,彻底避免图形拉伸变形
  • 居中处理:通过 CSS flex 布局让舞台容器居中,同时用 Konva 的 position 属性做兜底保障
  • 无需调整图形属性:舞台的缩放会自动作用于所有子元素,不需要单独修改图形的 X/Y 坐标

内容的提问来源于stack exchange,提问作者user25478432

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:40:12