Files
tianshu-engine/docs/guide/UI_SCALING.md

68 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UI 屏幕适配方案
## 原则
**不做响应式布局,只做等比缩放。** 天书的 UI 是为 1920×1080 画布设计的,所有屏幕统一等比缩放,不发散断点。
## 实施方案:`transform: scale()`
### 入口处加 3 行
```html
<!-- 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>
```
```ts
// 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 基准