diff --git a/preview-template/workbench/css/workbench.css b/preview-template/workbench/css/workbench.css index d68de63..0e28041 100644 --- a/preview-template/workbench/css/workbench.css +++ b/preview-template/workbench/css/workbench.css @@ -909,14 +909,14 @@ body { .pw-summary b { color: var(--pw-text); font-weight: 600; } .pw-pick-overlay { - position: fixed; + position: absolute; pointer-events: none; z-index: 99999; box-sizing: border-box; - background: rgba(46, 204, 113, 0.38); - border: 1px solid rgba(39, 174, 96, 0.95); - box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18); - border-radius: 1px; + background: rgba(46, 204, 113, 0.42); + border: 2px solid rgba(39, 174, 96, 1); + border-radius: 2px; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2), 0 0 14px rgba(46, 204, 113, 0.35); } .pw-pick-overlay[hidden] { diff --git a/preview-template/workbench/js/agent-pick.js b/preview-template/workbench/js/agent-pick.js index 91a980d..5474908 100644 --- a/preview-template/workbench/js/agent-pick.js +++ b/preview-template/workbench/js/agent-pick.js @@ -413,6 +413,24 @@ return this._hitTestDetailed(clientX, clientY).uuid || ''; }; + /** 取 UITransform(多种查找方式,与命中逻辑一致) */ + WorkbenchAgent.prototype._getUiTransform = function (node) { + var cc = this.cc; + if (!cc || !node || !node.getComponent) return null; + try { + var uit = (cc.UITransform && node.getComponent(cc.UITransform)) || + node.getComponent('cc.UITransform') || + node.getComponent('UITransform') || + null; + if (uit && uit.getBoundingBoxToWorld) return uit; + } catch (e) { /* */ } + var comps = node.components || []; + for (var i = 0; i < comps.length; i++) { + if (comps[i] && typeof comps[i].getBoundingBoxToWorld === 'function') return comps[i]; + } + return null; + }; + WorkbenchAgent.prototype._ensureOverlay = function () { var el = document.getElementById('pw-pick-overlay'); if (!el) { @@ -420,7 +438,10 @@ el.id = 'pw-pick-overlay'; el.className = 'pw-pick-overlay'; el.hidden = true; - (document.body || document.documentElement).appendChild(el); + // 挂到画布容器内,避免被设备壳/全局样式盖住 + var canvas = this._getCanvasEl(); + var host = (canvas && canvas.parentElement) || document.body || document.documentElement; + host.appendChild(el); } this._overlay = el; }; @@ -439,24 +460,46 @@ overlay.hidden = true; return; } + // 相对画布父容器定位(absolute),比 fixed 更稳 + var canvas = this._getCanvasEl(); + var parent = (canvas && canvas.parentElement) || overlay.parentNode; + var originLeft = 0; + var originTop = 0; + if (parent && parent.getBoundingClientRect) { + var pr = parent.getBoundingClientRect(); + originLeft = pr.left; + originTop = pr.top; + if (getComputedStyle(parent).position === 'static') { + parent.style.position = 'relative'; + } + } overlay.hidden = false; - overlay.style.position = 'fixed'; - overlay.style.left = box.left + 'px'; - overlay.style.top = box.top + 'px'; + overlay.style.position = 'absolute'; + overlay.style.left = (box.left - originLeft) + 'px'; + overlay.style.top = (box.top - originTop) + 'px'; overlay.style.width = box.width + 'px'; overlay.style.height = box.height + 'px'; overlay.style.zIndex = '99999'; + overlay.style.display = 'block'; }; WorkbenchAgent.prototype._nodeClientRect = function (node) { var cc = this.cc; var canvas = this._getCanvasEl(); - if (!cc || !canvas || !node || !node.isValid) return null; - var uit = node.getComponent && node.getComponent(cc.UITransform); + if (!cc || !canvas || !node) return null; + if (node.isValid === false) return null; + var uit = this._getUiTransform(node); if (!uit || !uit.getBoundingBoxToWorld) return null; var box = null; try { box = uit.getBoundingBoxToWorld(); } catch (e) { return null; } if (!box) return null; + var bx = Number(box.x); + var by = Number(box.y); + var bw = Number(box.width); + var bh = Number(box.height); + if (!isFinite(bx) || !isFinite(by) || !isFinite(bw) || !isFinite(bh)) return null; + if (bw < 0) { bx += bw; bw = -bw; } + if (bh < 0) { by += bh; bh = -bh; } var rect = canvas.getBoundingClientRect(); var cbox = this._canvasWorldBox(); @@ -474,10 +517,10 @@ oy = 0; } var corners = [ - { x: box.x, y: box.y }, - { x: box.x + box.width, y: box.y }, - { x: box.x + box.width, y: box.y + box.height }, - { x: box.x, y: box.y + box.height }, + { x: bx, y: by }, + { x: bx + bw, y: by }, + { x: bx + bw, y: by + bh }, + { x: bx, y: by + bh }, ]; var xs = []; var ys = []; @@ -502,6 +545,12 @@ }; WorkbenchAgent.prototype._getOverlayRect = function () { + // 优先读最新计算框,避免 style 尚未写入 + var node = this._findNode(this._selectedUuid); + if (node) { + var box = this._nodeClientRect(node); + if (box) return box; + } var overlay = this._overlay; if (!overlay || overlay.hidden) return null; return { diff --git a/preview-template/workbench/js/host.js b/preview-template/workbench/js/host.js index a477a70..8b750c0 100644 --- a/preview-template/workbench/js/host.js +++ b/preview-template/workbench/js/host.js @@ -139,13 +139,7 @@ cap.title = '检视:点击选取节点'; host.appendChild(cap); - // 选中节点绿色高亮(壳层,盖在预览上) - var hi = document.createElement('div'); - hi.id = 'pw-pick-highlight'; - hi.className = 'pw-pick-highlight pw-shell-only'; - hi.hidden = true; - host.appendChild(hi); - + // 选中高亮由游戏内 #pw-pick-overlay 绘制(壳层不再重复,避免坐标原点不一致) if (this.layout) this.layout.gameHost = host; }; @@ -337,6 +331,7 @@ document.getElementById('pw-mode-game').addEventListener('click', function () { self._inspectOn = false; self._setInspectCapture(false); + self._setPickHighlight(null); self.bridge.call('pick.setMode', { mode: 'game' }).catch(function () { /* */ }); document.getElementById('pw-mode-game').classList.add('active'); document.getElementById('pw-mode-inspect').classList.remove('active'); @@ -641,33 +636,11 @@ }; /** - * 预览区绿色半透明高亮(壳层,盖在游戏 iframe 上)。 - * @param {{left:number,top:number,width:number,height:number}|null} rect 游戏视口坐标 + * 选中高亮由游戏 iframe 内绘制;壳层仅清理遗留节点,避免双框/错位。 */ PreviewWorkbenchHost.prototype._setPickHighlight = function (rect) { var el = document.getElementById('pw-pick-highlight'); - if (!el) return; - if (!rect || !(rect.width > 0) || !(rect.height > 0)) { - el.hidden = true; - return; - } - var host = document.getElementById('pw-game-host'); - var ox = 0; - var oy = 0; - if (host) { - var hr = host.getBoundingClientRect(); - var iframe = this._iframe; - if (iframe) { - var ir = iframe.getBoundingClientRect(); - ox = ir.left - hr.left; - oy = ir.top - hr.top; - } - } - el.hidden = false; - el.style.left = (ox + (rect.left || 0)) + 'px'; - el.style.top = (oy + (rect.top || 0)) + 'px'; - el.style.width = Math.max(2, rect.width || 0) + 'px'; - el.style.height = Math.max(2, rect.height || 0) + 'px'; + if (el && el.parentNode) el.parentNode.removeChild(el); }; PreviewWorkbenchHost.prototype._setStatus = function (text, ok) {