diff --git a/assets/app.js b/assets/app.js index 37bb10c..efa5184 100644 --- a/assets/app.js +++ b/assets/app.js @@ -847,17 +847,58 @@ // ---- 打开 / 关闭 ---- function openPanel() { panel.hidden = false; - // 面板可能超出视口底部,翻到上方 - var r = trigger.getBoundingClientRect(); - panel.classList.remove('cp-up'); - var need = panel.offsetHeight + 8; - if (r.bottom + need > window.innerHeight && r.top > need) { - panel.classList.add('cp-up'); - } drawSV(); moveCursor(); + positionPanel(); } + + /* 色板是 position:fixed,位置必须自己算。 + * + * 🔴 为什么不用 absolute 贴按钮:后台这个表单在 + *
里,那个容器有 overflow:hidden, + * absolute 会被裁掉下半部分 —— 色相条正好在底部,连带看不见, + * 用户就以为"色板只有蓝色"。fixed 不受任何祖先 overflow 影响。 + * + * 定位规则: + * ① 默认贴在触发按钮下方,左边缘对齐按钮 + * ② 右边超出视口就往左挪 + * ③ 下方空间不够就翻到按钮上方 + * ④ 都放不下(屏幕太矮)就贴住视口上下边,保证能看全 */ + function positionPanel() { + if (panel.hidden) { return; } + var r = trigger.getBoundingClientRect(); + var pw = panel.offsetWidth; + var ph = panel.offsetHeight; + var vw = window.innerWidth; + var vh = window.innerHeight; + var gap = 8; + var margin = 10; + + // 水平:默认左对齐按钮 + var left = r.left; + if (left + pw + margin > vw) { left = vw - pw - margin; } + if (left < margin) { left = margin; } + + // 垂直:优先下方 + var top = r.bottom + gap; + if (top + ph + margin > vh) { + var above = r.top - gap - ph; + if (above >= margin) { + top = above; // 放上面 + } else { + top = Math.max(margin, vh - ph - margin); // 都放不下:贴住底部 + } + } + + panel.style.left = Math.round(left) + 'px'; + panel.style.top = Math.round(top) + 'px'; + } + function closePanel() { panel.hidden = true; } + // 窗口尺寸变化 / 滚动时重新定位,避免色板"漂走" + window.addEventListener('resize', positionPanel); + window.addEventListener('scroll', positionPanel, true); + trigger.addEventListener('click', function (e) { e.stopPropagation(); if (panel.hidden) { openPanel(); } else { closePanel(); } diff --git a/assets/style.css b/assets/style.css index e74346e..107233a 100644 --- a/assets/style.css +++ b/assets/style.css @@ -389,7 +389,12 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh} /* ---------- 自绘色板 ---------- * 用户 2026-11-04:「需要一个完整的色板,右侧那些默认颜色就不要了。」 - * ⇒ 面板做大(宽 372),色板画布 340×200;右侧预设圆点已删除。 */ + * + * 🔴 色板必须 position:fixed —— 后台这个表单在
+ * 里面,而它有 overflow:hidden。用 absolute 会被裁掉下半部分, + * 连带色相条一起看不见,用户就以为"只有蓝色"(只能看到当前色相)。 + * fixed 直接相对视口定位,任何祖先的 overflow 都管不到它。 + * 位置由 JS 按触发按钮的坐标算出来写进 style。 */ .color-trigger{ display:inline-flex; align-items:center; gap:9px; padding:5px 12px 5px 6px; height:34px; @@ -408,13 +413,12 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh} .color-trigger-caret{font-size:10px; color:var(--muted); margin-left:1px} .cp{ - position:absolute; top:calc(100% + 8px); left:0; z-index:80; + position:fixed; z-index:9999; width:372px; padding:14px; background:var(--card); border:1px solid var(--line-strong); - border-radius:14px; box-shadow:0 12px 36px rgba(16,24,40,.20); + border-radius:14px; box-shadow:0 12px 36px rgba(16,24,40,.24); user-select:none; box-sizing:border-box; } -.cp.cp-up{top:auto; bottom:calc(100% + 8px)} .cp-hd{ font-size:12.5px; font-weight:700; color:var(--muted); letter-spacing:.3px; margin:0 0 10px; @@ -430,11 +434,15 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh} border:2px solid #fff; border-radius:50%; pointer-events:none; box-shadow:0 0 0 1px rgba(0,0,0,.4), 0 1px 3px rgba(0,0,0,.3); } -/* 两条滑条:色相 + 明度 */ -.cp-slider{margin:11px 0 0} +/* 两条滑条:色相 + 明度 + * 🔴 色相条必须**看得出是光谱** —— 用户反馈「好像只有蓝色」, + * 是因为之前色相条被 overflow 裁掉了,只看到上面那片蓝色的 HSV 板。 + * 所以这里把色相条做高(18px)、加圆角描边,一眼就知道"能选所有颜色"。 */ +.cp-slider{margin:12px 0 0} .cp-slider input[type=range]{ - -webkit-appearance:none; appearance:none; width:100%; height:14px; border-radius:7px; + -webkit-appearance:none; appearance:none; width:100%; height:18px; border-radius:9px; outline:none; cursor:pointer; display:block; + box-shadow:inset 0 0 0 1px rgba(0,0,0,.10); } .cp-hue input[type=range]{ background:linear-gradient(to right, @@ -442,13 +450,13 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh} } .cp-val input[type=range]{background:linear-gradient(to right, #000, #fff)} .cp-slider input[type=range]::-webkit-slider-thumb{ - -webkit-appearance:none; width:18px; height:18px; border-radius:50%; + -webkit-appearance:none; width:20px; height:20px; border-radius:50%; background:#fff; border:2px solid #fff; - box-shadow:0 0 0 1px rgba(0,0,0,.35), 0 1px 4px rgba(0,0,0,.25); cursor:pointer; + box-shadow:0 0 0 1px rgba(0,0,0,.45), 0 1px 4px rgba(0,0,0,.3); cursor:pointer; } .cp-slider input[type=range]::-moz-range-thumb{ - width:16px; height:16px; border-radius:50%; background:#fff; - border:2px solid #fff; box-shadow:0 0 0 1px rgba(0,0,0,.35); cursor:pointer; + width:18px; height:18px; border-radius:50%; background:#fff; + border:2px solid #fff; box-shadow:0 0 0 1px rgba(0,0,0,.45); cursor:pointer; } .cp-foot{display:flex; align-items:center; gap:8px; margin-top:13px} .cp-preview{ diff --git a/lib/bootstrap.php b/lib/bootstrap.php index f3a4993..585c494 100644 --- a/lib/bootstrap.php +++ b/lib/bootstrap.php @@ -8,7 +8,7 @@ if (!defined('FB_ROOT')) { define('FB_ROOT', dirname(__DIR__)); // 静态资源版本号:改 assets/ 下的 css/js 后把这个数字 +1, // 让浏览器与 CDN 缓存失效。全站只此一处,别再往页面里写死数字。 - if (!defined('FB_ASSET_V')) { define('FB_ASSET_V', 43); } + if (!defined('FB_ASSET_V')) { define('FB_ASSET_V', 45); } } /* ------------------------------------------------------------------