Canvas、SVG 与图形渲染

共 23 题
📑 题目列表 23 题
#
★★★

1. WebGL 的 Uniform Buffer Object 与 Transform Feedback 在批量渲染的取舍

WebGL 的 Uniform Buffer Object 与 Transform Feedback 在批量渲染中各有哪些取舍?

  • UBO 打包 uniform 减少状态切换
  • Transform Feedback 实现 GPU 内数据演化
  • std140 布局与回读同步代价

Uniform Buffer Object(UBO)把多个 uniform 打包进缓冲,按 block 一次性上传,减少 uniform 设置调用与状态切换,适合大量对象共享少量矩阵、材质参数的批量渲染;Transform Feedback 把顶点着色器输出捕获回缓冲(GPU 侧写回),避免 CPU 回读,适合粒子系统、骨骼动画等每帧由 GPU 更新数据的场景。取舍:UBO 要求着色器按 std140 布局对齐,数据排布需谨慎;Transform Feedback 增加管线复杂度(绑定反馈缓冲、处理容量与回读同步)。工程上常组合:UBO 管共享参数,TF 维护动态顶点数据,配合实例化绘制实现高性能批量渲染。

考察 WebGL 两类 GPU 数据管线的定位:UBO 优化参数上传与切换,Transform Feedback 实现 GPU 内数据演化;回答需对比适用场景、布局对齐与回读同步代价。

#
★★★

2. HTMLCanvasElement.toBlob 的 quality/type 参数在截图上传的现代取舍

HTMLCanvasElement.toBlob 的 quality/type 参数在截图上传中有哪些现代取舍?

  • type 与 quality 的作用域
  • canvas 污染与 SecurityError
  • 异步回调、体积控制与 Worker 化

toBlob(callback, type, quality) 把 canvas 内容编码为 Blob:type 支持 png、jpeg、webp 等,quality(0-1)只对 jpeg、webp 等有损格式生效,png 忽略 quality;回调异步返回 Blob,可预览或作为 FormData 上传。取舍:照片类用 jpeg/webp 减小体积,含透明的截图用 png/webp 保真,webp 体积与质量平衡通常优于 jpeg;quality 过低会出伪影,需按场景调参;toBlob 异步且旧浏览器缺失,可用 toDataURL 回退;截图前需确认 canvas 未被跨域图片污染。

考察 canvas 编码上传的工程细节:type 决定格式、quality 只对 jpeg/webp 生效、污染画布会抛 SecurityError;回答需覆盖 Blob 预览与上传、体积控制、toDataURL 回退与 Worker 化优化等落地手段。

canvas.toBlob(async (blob) => {
  const fd = new FormData();
  fd.append('file', blob, 'shot.webp');
  await fetch('/upload', { method: 'POST', body: fd });
}, 'image/webp', 0.85);
#
★★★

3. WebGL 扩展(OES_texture_float、EXT_color_buffer_float)

WebGL 扩展(OES_texture_float、EXT_color_buffer_float)的作用与启用方式是什么?

  • getExtension 按需启用
  • 浮点纹理与浮点渲染目标的组合
  • 线性滤波与移动端兼容降级

WebGL 扩展提供标准之外的 GPU 能力:OES_texture_float 允许创建浮点纹理(RGBA32F)作为采样数据源;EXT_color_buffer_float 允许把浮点纹理作为渲染目标(Framebuffer)写入,二者常配合实现 HDR、后处理、通用计算。启用方式:用 getExtension('OES_texture_float') 按需获取,返回 null 表示不支持;浮点纹理的线性滤波需 OES_texture_float_linear,移动端支持不稳定;EXT_color_buffer_half_float 是更轻量的折中。工程上应做能力矩阵检测,按支持情况选择管线。

考察 WebGL 扩展体系的用法:getExtension 按需启用、返回 null 表示不支持;浮点纹理与浮点渲染目标常需 OES_texture_float 与 EXT_color_buffer_float 组合,回答需覆盖线性滤波扩展与移动端兼容降级策略。

#
★★★

4. Canvas 2D、SVG 与 WebGL/WebGPU 的渲染模型差异

Canvas 2D、SVG 与 WebGL/WebGPU 的渲染模型差异是什么?如何选型?

  • 立即模式、保留模式与 GPU 可编程管线
  • 可访问性与命中测试差异
  • 按交互复杂度与数据量选型

Canvas 2D 是立即模式位图绘制:API 直接绘制像素,无场景图,重绘需重画全部;SVG 是保留模式矢量场景图:DOM 树描述图形,浏览器负责重绘与命中测试;WebGL/WebGPU 是 GPU 可编程管线:提交缓冲、着色器与绘制命令,控制力最强但复杂度最高。差异维度:可访问性(SVG 可被辅助技术读取,Canvas 不可读)、交互命中(SVG 天然按元素命中,Canvas 需自行计算)、性能(SVG 适合中等数量矢量,Canvas 适合高频重绘像素,WebGL 适合大量实例)。选型:图标、静态图表用 SVG,游戏、粒子用 WebGL,中等动态可视化用 Canvas 2D。

考察三大渲染模型的本质区别:Canvas 2D 立即模式、SVG 保留模式、WebGL/WebGPU 可编程管线;回答需从可访问性、命中测试、性能与实现复杂度四个维度给出选型依据,并说明混合使用场景。

#
★★★

5. Canvas 立即模式与 SVG 保留模式的命中测试、内存与可访问性

Canvas 立即模式与 SVG 保留模式在命中测试、内存与可访问性上有何差异?

  • SVG 自动命中与 Canvas 自行测试
  • 内存随元素数量的增长差异
  • 可访问性的本质区别与补偿

命中测试:SVG 保留模式由浏览器按元素几何自动命中(pointer-events 可控制),交互天然;Canvas 立即模式不保留图形对象,需自己记录图形数据并在 pointer 事件里做点包含测试,或用离屏颜色索引法反查对象。内存:SVG 的 DOM 节点随元素数量线性增长,数千节点以上内存与更新成本高;Canvas 只有一张位图加少量 JS 数据结构,图形多时内存更省。可访问性:SVG 是 DOM 语义,可加 title/desc 与 ARIA,能被屏幕阅读器读取;Canvas 输出只是像素,对辅助技术不可见,需 aria-label 补充。工程上:高交互低数量选 SVG,海量图形选 Canvas 并自行实现命中与无障碍补偿。

考察 Canvas 与 SVG 在三大维度的取舍:命中测试的实现方式、内存随元素数量的增长差异、可访问性的本质区别;回答体现按交互复杂度与图形数量选型的判断,并指出 Canvas 需自行补偿无障碍。

#
★★★

6. WebGL 上下文丢失(webglcontextlost/webglcontextrestored)的资源重建策略

WebGL 上下文丢失(webglcontextlost/webglcontextrestored)的资源重建策略是什么?

  • 上下文丢失的触发与 preventDefault
  • 恢复后全部资源重建
  • 资源管理器与统一重建入口

GPU 上下文可能因设备重置、驱动更新、内存压力等丢失:浏览器先派发 webglcontextlost,调用 preventDefault() 表示应用自行处理恢复;之后可能派发 webglcontextrestored 通知重建。丢失后所有 GL 资源(缓冲、纹理、着色器、程序)全部失效,必须重建。策略:在 webglcontextlost 中 preventDefault 并暂停渲染循环;在 webglcontextrestored 中重建全部资源并恢复渲染;实现资源管理器(记录创建参数,统一 rebuild 入口);恢复后重新设置视口与状态。

考察 WebGL 上下文生命周期的工程处理:preventDefault 开启可恢复,restored 后全部资源需重建;回答需给出资源管理器与统一重建入口的架构建议。

canvas.addEventListener('webglcontextlost', (e) => {
  e.preventDefault();
  stopLoop();
});
canvas.addEventListener('webglcontextrestored', () => {
  rebuildResources();
  startLoop();
});
#
★★★

7. Canvas 离屏渲染(OffscreenCanvas + transferControlToOffscreen)

Canvas 离屏渲染(OffscreenCanvas + transferControlToOffscreen)的原理与应用是什么?

  • OffscreenCanvas 在 Worker 中渲染
  • transferControlToOffscreen 转移控制权
  • ImageBitmap 位块传输与兼容回退

OffscreenCanvas 提供脱离 DOM 的画布:可在 Worker 中创建 2D/WebGL 上下文并渲染,用 transferToImageBitmap() 把结果转成 ImageBitmap 交给主线程,避免主线程承担渲染计算;transferControlToOffscreen() 把现有 canvas 的控制权转移给 Worker 端直接渲染。应用场景:复杂动画、粒子系统、图像处理流水线。注意:转移控制权后主线程画布失去绘制能力,需用 postMessage 通信;Worker 中的 WebGL 上下文与主线程互不共享;需兼容不支持 OffscreenCanvas 的浏览器。

考察离屏渲染的两种形态:Worker 内自建 OffscreenCanvas 与 transferControlToOffscreen 转移控制权;回答需覆盖位图传递、跨线程通信与兼容回退。

#
★★★

8. WebGL2 与 WebGPU 在 2D 渲染与图像处理管线的能力差异

WebGL2 与 WebGPU 在 2D 渲染与图像处理管线的能力差异是什么?

  • WebGL2 的状态机模型与扩展
  • WebGPU 的 Pipeline/BindGroup 模型
  • 计算着色器与图像处理

WebGL2 是 WebGL1 的升级:支持 3D 纹理、纹理数组、整数顶点属性、实例化、多渲染目标、统一缓冲对象等,管线仍是"固定渲染管线加着色器"模型;WebGPU 是新一代原生风格 API:以 Pipeline(渲染/计算)与 BindGroup 为组织单元,支持计算着色器、存储缓冲、显式资源管理与更少的状态切换。图像处理差异:WebGPU 可用计算着色器做卷积、直方图等通用算法;2D 渲染上 WebGPU 的实例化与统一缓冲更高效。工程取舍:WebGL2 兼容性广、生态成熟,WebGPU 性能与表达力强但仍在普及。

考察两代 GPU API 的管线模型差异:WebGL2 基于状态机加着色器,WebGPU 基于 Pipeline/BindGroup 且含计算管线;回答需落到图像处理与 2D 渲染的实际取舍。

#
★★★

9. OffscreenCanvas + Worker 的并行渲染限制

OffscreenCanvas + Worker 的并行渲染有哪些限制?

  • 上下文不可跨线程共享
  • 位图传递与消息通信成本
  • 无 DOM 环境与资源上限

OffscreenCanvas 让渲染脱离主线程,但存在多重限制:一是上下文不能跨线程共享——Worker 创建的 2D/WebGL 上下文只在 Worker 内有效,结果只能通过 ImageBitmap 位块传输或 postMessage 回传;二是转移控制权后主线程画布失去绘制能力,事件与交互数据必须消息通信,有延迟与序列化成本;三是 Worker 中无 DOM,无法使用 getBoundingClientRect 等 DOM API;四是每个 OffscreenCanvas 占用 GPU/内存资源,过多实例需池化复用;五是性能并不总是更优,应做基准测试。

考察 OffscreenCanvas 并行化的边界:上下文不可跨线程、控制权转移后的通信成本、无 DOM 环境与资源上限;回答需强调"并非总是更快,需基准测试"的工程判断。

#
★★★

10. SVG Symbol、 与 CSS 集成的复用模式

SVG Symbol、 与 CSS 如何集成实现图形复用?

  • symbol 定义与 use 实例化
  • currentColor 与 CSS 变量主题化
  • 影子树对 CSS 的限制与无障碍补充

定义可复用图形模板(不直接渲染), 在文档中实例化,实现"定义一次、多处引用",配合 组织渐变、滤镜、clipPath 等共享资源; 实例是影子树,可通过 CSS 继承与 currentColor 控制颜色,也可用 CSS 变量主题化。集成模式:图标系统——把所有图标收进隐藏 SVG sprite(symbol 集合),页面用 引用,减少请求与 DOM;样式控制——fill/stroke 用 CSS 或 currentColor 跟随文本颜色,hover 态用 CSS 变色;可访问性——给每个 use 配 title 与 aria-label。

考察 SVG sprite 与 CSS 的协作模式:symbol 定义、use 实例化、currentColor 与 CSS 变量驱动主题化;回答需点明影子树对 CSS 深入的限制与无障碍补充。

<svg style="display:none">
  <symbol id="icon-star" viewBox="0 0 24 24">
    <path d="M12 2l3 6 6 .5-4.5 4 1.5 6L12 15l-6 3.5 1.5-6L3 8.5 9 8z"/>
  </symbol>
</svg>
<svg class="icon"><use href="#icon-star"></use></svg>
#
★★★

11. WebGL 资源(Buffer、Texture、Framebuffer)

WebGL 资源(Buffer、Texture、Framebuffer)的生命周期与内存管理如何理解?

  • 显式创建与删除 API
  • 资源与 GC 分离的泄漏风险
  • 纹理附件与渲染目标的关系

WebGL 资源由 GPU 内存承载,创建与销毁通过显式 API:createBuffer/createTexture/createFramebuffer 分配,deleteBuffer/deleteTexture/deleteFramebuffer 释放;资源不随垃圾回收自动回收,忘记删除会泄漏显存。Buffer 用 bufferData 分配并上传数据,可指定 usage 提示优化;Texture 用 texImage2D 分配存储与上传像素,需管理尺寸、格式与纹理单元绑定;Framebuffer 是渲染目标组合,用 framebufferTexture2D 附加附件。工程要点:建立资源池与引用计数,场景切换时统一释放。

考察 WebGL 资源的显式生命周期:创建与销毁 API 与 GC 分离、usage 提示、纹理与 Framebuffer 的附件关系;回答需强调显存泄漏治理、资源池与引用计数,并说明场景切换时的统一释放。

#
★★★

12. WebGPU 与 WebGL 在着色器语言、计算管线与多线程上的代际差距

WebGPU 与 WebGL 在着色器语言、计算管线与多线程上有何代际差距?

  • WGSL 与 GLSL 的语言差异
  • 原生计算管线 vs 模拟 GPGPU
  • 多队列与显式同步

着色器语言:WebGL 用 GLSL ES(字符串编译,运行时错误难排查),WebGPU 用 WGSL(类型更安全、内存模型更明确)。计算管线:WebGL 无原生计算着色器,GPGPU 需用顶点/片元着色器模拟(纹理读写),WebGPU 原生支持 compute pass 与存储缓冲,适合通用计算、物理模拟、图像处理。多线程:WebGL 上下文单实例运行;WebGPU 支持多队列与显式同步原语,可构建并行流水线。工程差距:WebGPU 控制与性能上限更高,但学习成本高,生态与兼容性仍在追赶。

考察两代 GPU API 的代际差异:WGSL 与 GLSL 的语言差距、原生计算管线与模拟 GPGPU、多队列与显式同步 vs 单线程;回答需落到迁移成本、学习成本与渐进采用策略上。

#
★★

13. HTML5 元素的 2D 与 WebGL 上下文在大型图表渲染时的 GPU 加速差异

HTML5 元素的 2D 与 WebGL 上下文在大型图表渲染时的 GPU 加速差异是什么?

  • 2D 上下文的抽象层开销
  • WebGL 合并绘制调用与顶点缓冲
  • 按数据规模选型与降级

Canvas 2D 在现代浏览器由 GPU 加速合成,但每次绘制命令经 Canvas 渲染器的抽象层处理,复杂路径、阴影、大量绘制调用仍可能成为 CPU 瓶颈;WebGL 直接编程 GPU 管线,可把整个图表(数万点、网格、轴)合并为少量绘制调用,顶点缓冲与着色器在 GPU 侧处理,性能上限更高。差异场景:静态图表两者差别不大;数据量巨大、持续动画、缩放平移重绘时 WebGL 优势明显;2D 上下文易用且文本渲染开箱即用,WebGL 需自行处理文本与 DPR。工程取舍:中小图表用 Canvas 2D 或 SVG 足够,大型实时图表用 WebGL 库(regl、PixiJS 等),并做降级。

考察 Canvas 2D 与 WebGL 在图表场景的加速差异:绘制调用合并、顶点缓冲与 GPU 管线 vs 抽象层开销;回答需给出按数据规模选型与降级策略,并说明 WebGL 需自行处理文本与 DPR。

#
★★

14. WebGL 着色器(GLSL)在跨平台兼容性、调试与降级到软件渲染的工程挑战

WebGL 着色器(GLSL)在跨平台兼容性、调试与降级到软件渲染有哪些工程挑战?

  • 驱动差异与精度限定符
  • 无断点的着色器调试手段
  • 软件渲染的不可控性与降级

跨平台兼容性:GLSL 在不同 GPU 驱动上的编译精度、精度限定符(highp/mediump/lowp)支持、循环与分支限制、uniform 数量上限存在差异,移动端尤其明显;常见坑包括浮点精度不足导致渲染瑕疵、过大的循环被驱动拒绝编译。调试:着色器编译失败只返回日志,无法断点;常用手段是精简到最小复现、用 getShaderInfoLog 采集日志、把可疑输出写进颜色通道可视化。软件渲染降级:WebGL 不可用时软件渲染是否可用由浏览器决定,应用侧无法强制启用;工程上需能力检测并降级到 Canvas 2D 绘制或静态图片。

考察 GLSL 的工程化难题:驱动差异与精度问题、无断点的调试手段、软件渲染的不可控性;回答需给出最小复现、getShaderInfoLog 日志采集、颜色可视化输出与 Canvas 2D 降级方案。

#
★★

15. Canvas 2D 上下文 willReadFrequently 属性在频繁读写像素时的性能取舍

Canvas 2D 上下文 willReadFrequently 属性在频繁读写像素时有哪些性能取舍?

  • getImageData/putImageData 的回读成本
  • CPU 可读存储与 GPU 加速的权衡
  • 按用途拆分画布

getContext('2d', { willReadFrequently: true }) 提示浏览器该上下文将频繁调用 getImageData/putImageData 等像素读写,浏览器可能选择把画布存储在 CPU 可快速读取的内存布局,从而提升读取性能;默认 false 时画布倾向 GPU 加速合成,getImageData 需要从 GPU 回读,代价较高。取舍:开启后会牺牲 GPU 加速的绘制性能,适合像素级编辑、图像算法等高频读取场景;普通绘图与动画应保持默认。工程建议:按用途拆分画布——高频像素处理用 willReadFrequently 画布,展示与动画用 GPU 画布。

考察 Canvas 上下文选项的取舍:willReadFrequently 提示浏览器优先 CPU 可读存储以换取 getImageData 性能、同时牺牲 GPU 合成;回答需说明按用途拆分画布及浏览器可能忽略提示的边界。

#
★★

16.

内联 SVG 在样式继承、CSS 动画与可访问性( 、 )的取舍

内联 SVG 在样式继承、CSS 动画与可访问性( 、 )上有哪些取舍?

  • 内联 SVG 的 CSS 完全控制
  • CSS 动画与 SMIL 的并存
  • title/desc 与 aria-hidden 的规范

内联 SVG 是 DOM 的一部分,可被 CSS 完整控制:fill/stroke/opacity 等属性支持继承与 CSS 覆盖,可用 class 与 CSS 变量做主题化;CSS 动画与过渡可直接作用于 SVG 属性(transform、fill、stroke-dashoffset 等),比外链 SVG 灵活得多。可访问性: 提供短名称、<desc> 提供长描述,配合 role="img" 或 aria-labelledby 让屏幕阅读器朗读图形含义;内联时这些元素可直接被辅助技术读取。取舍:内联 SVG 增加 HTML 体积且不能缓存,适合少量图标与交互图形;大量图标用 sprite 或外链;纯装饰 SVG 应加 aria-hidden。</p>

考察内联 SVG 的三重优势与代价:CSS 完全控制、动画灵活、可访问性可标注;回答需覆盖体积与缓存取舍,以及 title、desc、aria-labelledby 与纯装饰 aria-hidden 的规范使用。

#
★★

17. Web Animations API 在 Canvas 与 SVG 元素动画的统一控制能力

Web Animations API 在 Canvas 与 SVG 元素动画上有何统一控制能力?

  • Animation 对象的统一控制
  • SVG 呈现属性的动画
  • Canvas 借时间驱动绘制逻辑

Web Animations API(WAAPI)把 CSS 动画、CSS 过渡与 JS 驱动的动画统一为 Animation 对象模型,可对任何 CSS 可样式化的元素(包括 SVG 元素)调用 element.animate() 创建动画,用 play/pause/cancel/reverse、currentTime、playbackRate 统一控制。对 SVG:可动画 fill、stroke、transform 等呈现属性,统一时间线与 JS 编排优于 SMIL;对 Canvas:WAAPI 不能直接动画画布位图,但可用同一套时间模型驱动绘制逻辑。工程价值:统一时间轴、暂停/倍速/倒放控制、与 CSS 动画同源。

考察 WAAPI 的统一时间模型:Animation 对象统一控制 CSS/SVG 动画,Canvas 需借时间驱动绘制逻辑;回答需对比 SMIL 与 rAF 方案,体现编排能力。

#
★★

18. crossorigin 属性在 文章配图 与 Canvas 污染(taint)跨域场景的处理

crossorigin 属性在 文章配图 与 Canvas 污染(taint)跨域场景如何处理?

  • CORS 模式加载与 taint 机制
  • crossorigin 的声明时机
  • 服务端头与代理兜底

Canvas 的 taint 机制:把跨域图片(或视频)绘制到 canvas 后,若资源未通过 CORS 合法获取,画布被标记为"污染",此后 getImageData/toDataURL/toBlob 抛 SecurityError。处理方式:img 加 crossorigin="anonymous" 且服务端返回 Access-Control-Allow-Origin,浏览器以 CORS 模式加载,成功加载后画布不污染;若资源不支持 CORS,则无法安全读取像素,只能展示或通过代理转发。要点:crossorigin 必须在设置 src 前声明;video 跨域同理;测 taint 可用 toDataURL 试读并捕获异常。

考察 Canvas 安全的 CORS 模型:跨域资源未获 CORS 即污染画布,crossorigin 属性配合服务端头才能安全读写;回答需覆盖声明时机、代理方案与异常捕获。

<img id="pic" crossorigin="anonymous" src="https://cdn.example.com/a.png">
#
★★

19. Canvas 与 WebGL 在 1px 模糊、HiDPI 渲染与设备像素比适配的常见坑

Canvas 与 WebGL 在 1px 模糊、HiDPI 渲染与设备像素比适配上有哪些常见坑?

  • 逻辑像素与物理像素的失配
  • dpr 缩放与像素网格对齐
  • dpr 动态变化与内存成本

1px 模糊的常见原因:canvas 逻辑尺寸(CSS 像素)与物理像素不匹配——未按 devicePixelRatio 放大画布时,浏览器把逻辑像素映射到物理像素产生半像素插值,线条发虚;绘制 1px 线时应使坐标对齐到像素网格(加 0.5 偏移)。HiDPI 适配标准做法:设置 canvas.width/height 为 CSS 尺寸乘以 dpr,再 ctx.scale(dpr, dpr) 绘制,最后用 CSS 尺寸展示;WebGL 同样需按 dpr 设置 drawingbuffer 尺寸或 viewport;dpr 变化(跨屏移动)需监听 matchMedia 重新适配。其他坑:阴影、缩放变换下线条宽度变化;图像素材按最大 dpr 提供或使用矢量。

考察像素密度适配的机制:画布物理像素与 CSS 像素的解耦、dpr 缩放与像素网格对齐;回答需覆盖 Canvas 2D 与 WebGL 两侧的适配做法及 dpr 动态变化的重新适配。

const dpr = window.devicePixelRatio || 1;
canvas.width = cssWidth * dpr;
canvas.height = cssHeight * dpr;
ctx.scale(dpr, dpr);
#
★★

20. Canvas 2D Path2D 对象在 SVG 路径解析复用与渲染性能的应用

Canvas 2D Path2D 对象在 SVG 路径解析复用与渲染性能上有哪些应用?

  • 从 SVG path 字符串构造
  • 一次解析多次绘制
  • isPointInPath 命中测试

Path2D 把路径封装为可复用对象:可从 SVG path 字符串构造(new Path2D('M0 0L10 10...')),实现"一份路径数据、多处绘制",同一 Path2D 可被 fill/stroke 多次使用或传递给 clip、isPointInPath 做命中测试。应用:SVG 路径复用——把设计师给出的 path d 字符串直接交给 Path2D,Canvas 与 SVG 共享数据源;性能——复杂路径只解析一次,重复绘制省去解析开销;命中测试——isPointInPath(path, x, y) 判断点是否落在路径内。

考察 Path2D 的复用与测试价值:SVG d 字符串直通构造、一次解析多次绘制、isPointInPath 命中测试;回答需点明 Path2D 仍属 CPU 侧数据、绘制瓶颈在光栅化的边界。

const heart = new Path2D('M12 21s-8-5.5-8-11a5 5 0 0 1 9-3 5 5 0 0 1 9 3c0 5.5-8 11-8 11z');
ctx.fill(heart);
ctx.isPointInPath(heart, x, y);
#

21. Canvas 的绘图状态管理,save/restore 与变换矩阵?

Canvas 的绘图状态管理(save/restore 与变换矩阵)如何理解?

  • 状态栈的入栈与出栈
  • 变换矩阵的组合与顺序
  • 状态泄漏与性能注意点

Canvas 2D 上下文维护一个状态栈:save() 把当前状态压栈(变换矩阵、样式、阴影、合成、裁剪区域等),restore() 弹栈恢复,用于隔离不同绘制单元的样式与变换;变换矩阵通过 translate/rotate/scale/transform/setTransform 操作,决定后续绘制的坐标映射。工程要点:成对使用 save/restore,在循环或函数内绘制后必须恢复,否则状态泄漏导致后续图形错位;变换矩阵是累积的,组合顺序影响结果;setTransform 直接覆盖矩阵。

考察 Canvas 状态栈与矩阵的协作:save/restore 隔离样式与变换、矩阵决定坐标映射、组合顺序影响结果;回答需覆盖状态泄漏、成对使用与高频循环避免频繁 save/restore 的性能要点。

ctx.save();
ctx.translate(100, 100);
ctx.rotate(Math.PI / 4);
ctx.fillRect(-25, -25, 50, 50);
ctx.restore();
#

22. SVG 与 Canvas 的选型,矢量 vs 位图、交互与性能?

SVG 与 Canvas 的选型:矢量 vs 位图、交互与性能如何权衡?

  • 矢量无损缩放与位图像素特性
  • DOM 交互 vs 自行命中
  • 节点数量与重绘模型

矢量 vs 位图:SVG 保存几何描述,任意缩放不失真,适合图标、图表、插画与高清输出场景;Canvas 是像素位图,缩放会失真,但渲染复杂场景时与元素数量解耦。交互:SVG 元素即 DOM,天然支持事件绑定、命中测试与 CSS 动画,适合大量可点击元素;Canvas 无图形对象,交互需自行命中与状态管理。性能:SVG 的渲染与更新成本随节点数增长,数千节点可能卡顿;Canvas 重绘整幅画布,适合高频动画、粒子、游戏;大数据量可视化与实时更新更适合 Canvas/WebGL。选型公式:数量少、交互多、要缩放清晰选 SVG;数量大、更新频繁、位图效果选 Canvas;两者可混合使用。

考察选型权衡的核心维度:矢量清晰度、DOM 交互能力、节点数量与重绘模型;回答需给出数量、交互、更新频率三因素决策框架,并说明两者按层混合使用的方案与可访问性考量。

#

23. Canvas 的高分屏适配,devicePixelRatio 与缩放?

Canvas 的高分屏适配:devicePixelRatio 与缩放如何实施?

  • 物理尺寸乘 dpr 与上下文缩放
  • dpr 动态变化监听
  • 小数 dpr 与内存上限

高分屏适配的核心是把画布的物理像素数提升到与设备像素密度匹配:const dpr = window.devicePixelRatio || 1; canvas.width = cssWidth * dpr; canvas.height = cssHeight * dpr; 然后 ctx.setTransform(dpr, 0, 0, dpr, 0, 0),使后续绘制按 CSS 逻辑坐标进行,最终用 CSS 宽高展示。要点:dpr 变化时要重新适配;dpr 可能是小数,直接乘法会出现非整数尺寸,可用 Math.round;大 dpr 下画布内存平方增长,超大画布考虑分块或限制上限;WebGL 同理设置 drawingbuffer 尺寸。

考察高分屏适配的完整流程:物理尺寸乘 dpr、上下文缩放、CSS 尺寸展示,以及 dpr 动态变化与内存成本;回答需覆盖小数 dpr 取整、超大画布限制上限与多倍图素材准备的策略。