CanvasContext
画布的抽象层:负责 CSS 尺寸与绘制缓冲尺寸的对应、设备像素比、 自动缩放与位置跟踪,并返回可直接绘制的帧缓冲。
多数场景不用显式调用:在 luma.createDevice 时传入 createCanvasContext,设备会自动建好。
创建参数
| 参数 | 说明 |
|---|---|
canvas | 画布元素、元素 id 字符串,或 null 由设备新建 |
container | 新建画布时的父容器,省略时挂到 document.body |
width / height | 新建画布时的像素尺寸 |
useDevicePixels | 布尔值或固定像素比;为真时按 devicePixelRatio 放大绘制缓冲 |
autoResize | 是否用 ResizeObserver 跟踪容器尺寸 |
pixelSizeSource | exact 用浏览器的物理像素测量,css-dpr 用 CSS 尺寸乘像素比 |
colorFormat | 呈现纹理格式,仅 WebGPU;HDR 用 rgba16float |
alphaMode / colorSpace / toneMapping | 呈现相关设置,仅 WebGPU |
visible | 新建画布的可见性 |
trackPosition | 是否跟踪画布位置变化 |
成员
| 成员 | 说明 |
|---|---|
canvas | 画布元素,可能是 HTMLCanvasElement 或 OffscreenCanvas |
cssWidth / cssHeight | CSS 尺寸,由观察器维护 |
devicePixelWidth / devicePixelHeight | 设备像素尺寸 |
drawingBufferWidth / drawingBufferHeight | 实际绘制缓冲尺寸 |
devicePixelRatio | 当前生效的像素比 |
isInitialized | 上下文是否完成初始化 |
isVisible | 画布是否可见 |
props | 归一化后的创建参数 |
方法
| 方法 | 返回 | 说明 |
|---|---|---|
getCSSSize() | [number, number] | CSS 宽高 |
getDevicePixelSize() | [number, number] | 设备像素宽高 |
getDrawingBufferSize() | [number, number] | 绘制缓冲宽高 |
getMaxDrawingBufferSize() | [number, number] | 后端允许的最大绘制缓冲尺寸 |
getDevicePixelRatio() | number | 当前像素比 |
setDrawingBufferSize(width, height) | void | 手动设定绘制缓冲尺寸,关闭自动推导 |
cssToDevicePixels(cssPixel, yInvert?) | { x, y } | CSS 像素转设备像素,可选翻转 y 轴 |
getCurrentFramebuffer(options?) | Framebuffer | 取当前可绘制的画布帧缓冲 |
updatePosition() | void | 立即刷新记录的位置 |
setProps(props) | this | 运行期更新尺寸与像素比相关设置 |
destroy() | void | 停止观察并释放上下文 |
resize、getAspect、getPixelSize、cssToDeviceRatio
是旧接口,已标记废弃,新代码用上面的尺寸读取方法。
创建并读取尺寸
const device = await luma.luma.createDevice({
type: 'webgl',
adapters: [luma.webgl2Adapter],
createCanvasContext: {
canvas: 'map-canvas',
useDevicePixels: Math.min(window.devicePixelRatio, 2),
autoResize: true
}
});
const ctx = device.canvasContext;
console.log(ctx.getCSSSize()); // [800, 600]
console.log(ctx.getDrawingBufferSize()); // [1600, 1200],2 倍像素比
console.log(ctx.getDevicePixelRatio()); // 2
绘制缓冲比 CSS 尺寸大,画面才在高分屏上清晰。
useDevicePixels 传数字时固定该比例,传 true 时跟随系统,
传 false 时按 CSS 像素 1:1 绘制。
拾取鼠标位置
canvas.addEventListener('click', function (e) {
const rect = canvas.getBoundingClientRect();
const cssPixel = [e.clientX - rect.left, e.clientY - rect.top];
const devicePixel = ctx.cssToDevicePixels(cssPixel, true);
onPick(devicePixel.x, devicePixel.y);
});
设备像素比大于 1 时,CSS 坐标与纹理像素坐标不一致,
直接用鼠标坐标读像素会偏移。yInvert 让结果适配自下而上的纹理坐标系。
WebGL 只有一块画布
WebGL 后端的设备只能绑定一个画布上下文,再次调用
createCanvasContext 会抛错。需要第二个渲染目标时改用
Framebuffer;WebGPU 后端才允许同时存在多个画布。
自动缩放会与手动设置尺寸打架。
开启 autoResize 后,ResizeObserver 会覆盖
setDrawingBufferSize 的结果。做离屏截图时先关闭自动缩放,
或直接渲染到固定尺寸的帧缓冲。
经纬志(2026)。《CanvasContext》。https://www.jingweizhi.com/lumagl/api/canvas-context.html(访问日期 2026-11-03)。