Canvas响应式需同步设置width/height属性与CSS尺寸,并用devicePixelRatio适配高清屏;用ResizeObserver监听父容器变化,结合ctx.scale缩放和分层重绘优化性能。

Canvas元素默认不会随父容器缩放,直接设置CSS宽高会导致绘制内容被拉伸变形。要实现真正的响应式自适应,关键在于同步调整canvas的width和height属性(即绘图上下文的逻辑像素尺寸),而非仅靠CSS控制显示尺寸。
保持设备像素比(DPR)清晰显示
在高清屏(如Retina屏)上,若只按CSS像素设置canvas尺寸,图形会模糊。需根据window.devicePixelRatio放大画布的内在分辨率,并用CSS缩回视觉尺寸:
- 获取父容器实际宽度(例如
container.clientWidth) - 乘以
devicePixelRatio得到canvas的width和height属性值 - 用CSS将canvas的
width和height设为100%或具体CSS像素值,使其填满容器 - 调用
ctx.scale(dpr, dpr),确保绘图坐标系与逻辑像素对齐
监听窗口或容器尺寸变化
不能只依赖window.onresize——它无法捕获父容器由Flex/Grid引起的动态缩放。推荐方案:
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
- 使用
ResizeObserver监听canvas父容器尺寸变化(现代浏览器支持良好) - 降级方案:定时检查容器
clientWidth/clientHeight是否变化(间隔约100–250ms) - 触发重设时,先保存当前绘图状态(如路径、样式),再清空、重设尺寸、重绘
重绘策略要轻量且可控
每次尺寸变更都全量重绘可能卡顿,尤其复杂场景。建议分层处理:
- 将不变内容(如背景、网格线)缓存到离屏canvas中,复用绘制
- 仅对动态区域(如移动的图形、实时数据点)做增量更新
- 使用
requestAnimationFrame节流重绘,避免连续触发导致丢帧 - 对简单图表类应用,可直接清空+重绘;对交互密集型应用,应记录缩放/平移状态并适配坐标转换
示例核心代码片段
以下为精简可行的初始化逻辑(无第三方库):
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const container = canvas.parentElement;
<p>function resizeCanvas() {
const dpr = window.devicePixelRatio || 1;
const rect = container.getBoundingClientRect();</p><p>canvas.width = rect.width <em> dpr;
canvas.height = rect.height </em> dpr;
canvas.style.width = rect.width + 'px';
canvas.style.height = rect.height + 'px';</p><p>ctx.scale(dpr, dpr);
// 此处调用你的重绘函数
redraw();
}</p><p>// 使用 ResizeObserver(推荐)
if (window.ResizeObserver) {
new ResizeObserver(resizeCanvas).observe(container);
} else {
window.addEventListener('resize', resizeCanvas);
}</p>前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










