Canvas 拉大后 WebGL 只画左下角,怎样同步 viewport 与 drawingBuffer

2026-10-24

调整 Canvas 的 WebGL 绘图缓冲尺寸后,按实际 drawingBufferWidth 与 drawingBufferHeight 更新 viewport。viewport 是独立的光栅状态,不能把 CSS 拉大或位图尺寸变化当作它已经同步。

用未覆盖区域定位状态差异

附件初始8×8,读取viewport为0、0、8、8,再把画布缓冲改成16×16。先用黑色清空整块缓冲,保留旧viewport画红三角形,在12、12取样仍黑;重设viewport覆盖16×16后,同一点变红。这个对照说明资源和着色器本身可用,局部未覆盖来自视口范围。

使用实际缓冲尺寸而非猜测

drawingBufferWidth与Height是WebGL实际绘图目标的尺寸,真实浏览器可能受能力或资源条件影响。resize处理应在更新缓冲后读取实际值,再设viewport;别把window.innerWidth直接当缓冲宽,也别忽略CSS尺寸与DPR带来的比例。若应用有多个子视口,则应按各自布局计算,并非每次都必须全画布。

viewport不等于所有裁剪状态

scissor测试也可能限制更新区域;改变viewport不自动替你重置scissor或相机投影矩阵。真实三维画面尺寸改变后,除了光栅范围,还应按渲染方案更新纵横比等条件。本题只使用一个覆盖视口的固定三角形,不涉及glTF坐标、镜头模型或多屏拼接,因此能把黑区原因限定到这一个状态。

2D与WebGL重置语义不同

Canvas2D改宽高会重置绘图状态,而此处WebGL的viewport保持旧值,不能把2D经验直接照搬。附件保留读回数值与像素,让差异可复跑。使用ANGLE SwiftShader只为了本地一致性,不测实体显卡帧率;目标大屏仍需在实际浏览器、驱动、分辨率与输出链路下检查尺寸和性能。

清屏范围不能证明绘制视口正确

gl.clear通常不按viewport裁剪,但会受启用的scissor等条件影响,所以整块缓冲能被清成黑色,不等于后续三角形会覆盖整块。附件先清全缓冲,再通过12、12处是否变红区分两者。若用“清屏看起来铺满”作为resize成功证据,会漏掉旧viewport问题。真实引擎应记录viewport和scissor状态,再结合实际几何绘制判断。

下载并复现

下载原创HTML夹具、独立验证程序、本次执行记录和依赖与运行说明,放在同一目录。安装Playwright 1.58.0及其Chromium后运行 python verify.py;程序使用两个随机本地端口,自动关闭浏览器与服务,不请求外网或业务接口。

本次实际环境为Python 3.12.4、Playwright 1.58.0、Chromium 145.0.7632.6。Canvas2D或WebGL1页面API与像素读取;非指针输入、非实体GPU性能测量。断言已通过;完整事件和数值保留在执行记录,不能把它改名后当目标展项测量。

Canvas题限定2D上下文,WebGL题限定WebGL1;启动使用ANGLE SwiftShader软件后端参数,实际renderer可见对应执行记录。软件后端的像素结果不代表实体显卡性能、驱动稳定性或跨浏览器一致性。

继续核查与一级出处

基础背景见把图片改成300DPI为何仍不清楚,怎样核对像素与物理尺寸。WebGL视口保持与2D状态重置的区别能避免错误套用经验,可继续用Canvas 改完 width 后颜色和变换都丢了,怎样验证上下文重置取证;相关工程入口在专题与产品对接说明。

需要展厅软硬件方案或定制开发?

加微信,把这一页发到你手机上

扫码加站长企业微信,会自动把这一页的链接发给你。问软件授权、报价,或者现场遇到问题,也可以直接聊。

去留微信

留言讨论

评论发布后会被人工复核,违规内容将被删除。

    还没有人评论,来说说你的看法

    如果发表没有反应,可以前往联系我们告诉我们。

    这个页面有问题?

    提交时会附带当前页面地址和浏览器信息,帮助我们定位问题。不填联系方式即为匿名。