2.5 KiB
2.5 KiB
UI 屏幕适配方案
原则
不做响应式布局,只做等比缩放。 天书的 UI 是为 1920×1080 画布设计的,所有屏幕统一等比缩放,不发散断点。
实施方案:transform: scale()
入口处加 3 行
<!-- index.html / editor/index.html -->
<style>
html, body {
width: 100vw; height: 100vh; overflow: hidden;
}
#app {
width: 1920px; height: 1080px;
transform-origin: top left;
transform: scale(var(--scale));
}
</style>
// main.ts — app mount 前
const scale = Math.min(window.innerWidth / 1920, window.innerHeight / 1080)
document.documentElement.style.setProperty('--scale', String(scale))
// resize 时更新
window.addEventListener('resize', () => {
const s = Math.min(window.innerWidth / 1920, window.innerHeight / 1080)
document.documentElement.style.setProperty('--scale', String(s))
})
影响范围
| 影响的 | 说明 |
|---|---|
✅ 所有 px 值 |
等比缩放,按钮/字号/间距全部生效 |
| ✅ SVG / Canvas 内部坐标 | 天然缩放,无需换算 |
⚠️ position: fixed |
transform 非 none 的元素会创建新的坐标基准,fixed 定位可能"粘"在缩放容器内而非视口。解决: overlay 统一用 position: absolute,根容器设 position: relative |
兼容注意事项
| 属性 | 兼容性 |
|---|---|
backdrop-filter |
Chromium bug: transform 父容器内可能失效。把 backdrop-filter 放到 transform 容器外面(比如直接在 body 上) |
getBoundingClientRect() |
返回的是缩放前的逻辑坐标,需 ÷ scale 得到实际屏幕坐标 |
window.innerWidth/Height |
始终返回物理像素,用于计算 scale,内部逻辑坐标始终 = 设计尺寸 |
为什么不用 rem / clamp / media query
- 无断点布局需求 — 不是手机→平板→桌面三套排版,只是等比缩放一张画布
- 改动量 —
rem需要把 200+ 处px改为rem,收益为零 - 创作者 — 后续页面新增不需要考虑响应式,直接按 1920×1080 画布设计
新增页面的适配清单
当需要新增一个全屏页面(如新弹窗/面板)时:
- 所有尺寸使用
px(不要用vw/vh/rem) - 弹窗用
position: absolute(不用fixed) - 弹窗的父容器设
position: relative - 有
backdrop-filter时,确认它在非transform的父容器内 - 设计画布按 1920×1080 基准