canvas之ctx.scale

ctx.scale(x, y) 是 Canvas 2D 上下文的核心方法,作用是 对后续所有绘制操作进行「缩放变换」—— 简单说就是给画布设置一个「缩放比例」,之后绘制的所有元素(图形、文字、图片)都会按这个比例放大 / 缩小,核心用于 适配不同屏幕尺寸和高清屏。
结合我们的小程序海报场景,它的作用可以拆解为 2 个关键场景:
一、核心作用:高清屏适配(解决 “模糊” 问题)
手机屏幕大多是「视网膜屏(Retina)」,这类屏幕的 设备像素比(dpr)> 1(比如 iPhone 14 的 dpr=3,意味着 1 个逻辑像素 = 3 个物理像素)。
如果不做缩放:
你设置 Canvas 宽高为 375px × 667px(逻辑像素),但屏幕实际会用 375×dpr × 667×dpr 个物理像素显示;
绘制的图形 / 文字会被 “拉伸”,导致海报模糊、有锯齿。
ctx.scale(dpr, dpr) 的解决方案:
先把 Canvas 实际宽高设置为 逻辑宽高 × dpr(比如 375×3 × 667×3),预留足够的物理像素;
用 ctx.scale(dpr, dpr) 让后续绘制操作自动放大 dpr 倍;
你依然按「逻辑像素」写绘制代码(比如 ctx.fillRect(20, 30, 100, 50)),Canvas 会自动转为 20×dpr, 30×dpr, 100×dpr, 50×dpr 的物理像素,最终海报在高清屏上显示清晰无模糊。
二、次要作用:响应式适配(复用逻辑像素代码)
在我们的海报代码中,还叠加了「屏幕宽度适配」的 scale(比如小屏手机宽度 320px,大屏 428px),此时 ctx.scale 会结合两个比例:
javascript
运行
const dpr = systemInfo.pixelRatio; // 高清屏比例(如 2/3)
const scale = screenWidth / 375; // 响应式比例(如 428/375 ≈ 1.14)
ctx.scale(dpr * scale, dpr * scale); // 组合缩放
后续你写的所有绘制代码(比如 ctx.fillRect(20, 30, 100, 50)),会自动按 20×dpr×scale 计算实际位置和大小;
无需手动修改每一个绘制参数,就能让海报在「小屏手机、大屏手机、平板」上保持比例一致,同时保证高清。
三、关键细节:缩放的 “作用范围”
只影响后续绘制:ctx.scale 是「状态化操作」,只对执行后的绘制生效,之前的绘制不受影响;
可以嵌套使用:配合 ctx.save()(保存当前状态)和 ctx.restore()(恢复之前状态),可以对单个元素单独缩放(比如只放大某段文字);
缩放是 “乘法”:比如先 ctx.scale(2,2),再绘制 10px 的文字,实际显示为 20px;再执行一次 ctx.scale(1.5,1.5),后续文字会是 10×2×1.5=30px。
四、我们的海报代码中,ctx.scale 的具体用法
javascript
运行
const dpr = systemInfo.pixelRatio; // 高清屏比例(如 iPhone 14 是 3)
const scale = screenWidth / 375; // 响应式比例(如 428px 屏幕是 1.14)
ctx.scale(dpr * scale, dpr * scale); // 组合缩放
最终效果:你写的「逻辑像素代码」(比如 10px 圆角、16px 文字),会自动适配为「高清 + 响应式」的实际尺寸;
你不用关心不同手机的 dpr 和屏幕宽度,只需要按设计稿的逻辑像素写代码,ctx.scale 帮你搞定所有适配。
总结
ctx.scale(x, y) 的核心目的是 “用简单的逻辑像素代码,适配复杂的屏幕差异”:
解决高清屏模糊问题(主要);
简化响应式适配代码(次要);
让你不用手动计算每个元素的缩放后的尺寸,提高开发效率。
如果没有 ctx.scale,你需要手动把每一个绘制参数(位置、大小、字体、圆角)都乘以 dpr×scale,代码会变得极其繁琐且容易出错~

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容