fix(web): 图片缩放 load 即量基准尺寸 + 双击复位提示 + bump 0.12.12
- _captureBase:图片加载完即量贴合尺寸做基准,避免首次缩放时还没渲染量到 0px 把图片塌成 0;量不到则本次跳过不破坏。 - 双击复位徽标显式提示「已复位 · 100%」(停留 1.4s)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
12171a4bdf
commit
eb1027b040
|
|
@ -21,6 +21,11 @@
|
|||
|
||||
## 已完成关键能力
|
||||
|
||||
### 2026-06-15 / 文件预览缩放加固 + 双击复位提示
|
||||
|
||||
- 图片 load 完即量基准尺寸(`_captureBase`,免首次缩放时还没渲染量到 0px 导致塌成 0);基准未量到时本次缩放跳过不破坏;双击复位时徽标显式提示「已复位 · 100%」(停留 1.4s)。bump 0.12.11 → 0.12.12。
|
||||
- 排查提示:左栏底部版本号 = `core/__init__.py __version__`,用户报"缩放完全没动静"且本地 8765 无服务 → 多半是**远端实例未 pull/重启**,版本号对不上即旧代码。
|
||||
|
||||
### 2026-06-15 / 文件预览缩放改显式 px:修 CSS zoom 放不大
|
||||
|
||||
- 接上一条:CSS `zoom` 对带 `max-width/height:100%` 的 flex item 不生效 —— zoom 放大后被百分比 max 约束重新夹回,视觉无变化(用户实测"还是不能放大")。
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
||||
# 改版本只动这一行。
|
||||
__version__ = "0.12.11"
|
||||
__version__ = "0.12.12"
|
||||
|
|
|
|||
|
|
@ -67,7 +67,16 @@ let _fpCurrentRel = null;
|
|||
// 缩放目标用 _zoomState 记录,避免每次预览重复 addEventListener 泄漏。
|
||||
const _zoomState = new WeakMap(); // bodyEl -> { img, scale, badge, timer }
|
||||
|
||||
function _applyZoom(z) {
|
||||
function _captureBase(z) {
|
||||
const img = z.img;
|
||||
if (!z.baseW) {
|
||||
z.baseW = img.clientWidth || img.naturalWidth || 0;
|
||||
z.baseH = img.clientHeight || img.naturalHeight || 0;
|
||||
}
|
||||
return z.baseW > 0;
|
||||
}
|
||||
|
||||
function _applyZoom(z, hint) {
|
||||
const img = z.img;
|
||||
if (z.scale === 1) {
|
||||
// 复位:还原 CSS 里的 max-width/height:100% 自适应贴合
|
||||
|
|
@ -80,20 +89,17 @@ function _applyZoom(z) {
|
|||
// 以 scale=1 时的"贴合显示"尺寸为基准,给显式像素尺寸。
|
||||
// 不用 CSS zoom:图片是带 max-width/height:100% 的 flex item,zoom 放大后会被
|
||||
// 百分比 max 约束重新夹回 → 视觉不变;显式 px + max:none 才真正撑大并让 body 出滚动条。
|
||||
if (!z.baseW) {
|
||||
z.baseW = img.clientWidth || img.naturalWidth;
|
||||
z.baseH = img.clientHeight || img.naturalHeight;
|
||||
}
|
||||
if (!_captureBase(z)) return; // 图片还没量到尺寸(未加载完),本次跳过,下次再缩
|
||||
img.style.maxWidth = "none";
|
||||
img.style.maxHeight = "none";
|
||||
img.style.width = Math.round(z.baseW * z.scale) + "px";
|
||||
img.style.height = Math.round(z.baseH * z.scale) + "px";
|
||||
img.style.cursor = "zoom-out";
|
||||
}
|
||||
z.badge.textContent = Math.round(z.scale * 100) + "%";
|
||||
z.badge.textContent = hint || (Math.round(z.scale * 100) + "%");
|
||||
z.badge.classList.add("show");
|
||||
if (z.timer) clearTimeout(z.timer);
|
||||
z.timer = setTimeout(() => z.badge.classList.remove("show"), 1000);
|
||||
z.timer = setTimeout(() => z.badge.classList.remove("show"), hint ? 1400 : 1000);
|
||||
}
|
||||
|
||||
// 给某 body 内的图片接上 Ctrl+滚轮缩放(badge + 双击复位),记录到 _zoomState。
|
||||
|
|
@ -106,7 +112,14 @@ function _makeImageZoomable(bodyEl, img) {
|
|||
const z = { img, scale: 1, badge, timer: null, baseW: 0, baseH: 0 };
|
||||
_zoomState.set(bodyEl, z);
|
||||
img.style.cursor = "zoom-in";
|
||||
img.addEventListener("dblclick", () => { z.scale = 1; _applyZoom(z); });
|
||||
// 图片一加载完就量好贴合尺寸做基准,避免首次缩放时还没渲染量到 0
|
||||
if (img.complete) _captureBase(z);
|
||||
else img.addEventListener("load", () => _captureBase(z), { once: true });
|
||||
img.addEventListener("dblclick", () => {
|
||||
if (z.scale === 1) return; // 本来就 100%,无需提示
|
||||
z.scale = 1;
|
||||
_applyZoom(z, "已复位 · 100%");
|
||||
});
|
||||
}
|
||||
|
||||
function _clearZoom(bodyEl) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue