From 052d1c901e78ff7c10c387baedecf6c1a94a4823 Mon Sep 17 00:00:00 2001 From: Reaosen Date: Tue, 1 Sep 2026 11:14:18 +0800 Subject: [PATCH] =?UTF-8?q?Add=20plugin=20=E8=81=9A=E5=85=89=E7=81=AF=20v1?= =?UTF-8?q?.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add plugin spotlight v1.0.0 - feat: spotlight 功能声明 mainHide 进入时自动隐藏主窗口 - fix: 聚光灯开启后重进主窗口时恢复设置页显示,避免残留黑色区域 - feat: 聚光灯退出后自动 outPlugin,重开 ZTools 回到搜索页 --- plugins/spotlight/.gitignore | 7 + plugins/spotlight/CHANGELOG.md | 15 ++ plugins/spotlight/README.md | 77 ++++++ plugins/spotlight/app.js | 427 +++++++++++++++++++++++++++++++++ plugins/spotlight/index.html | 236 ++++++++++++++++++ plugins/spotlight/logo.png | Bin 0 -> 65648 bytes plugins/spotlight/overlay.html | 55 +++++ plugins/spotlight/overlay.js | 221 +++++++++++++++++ plugins/spotlight/plugin.json | 23 ++ plugins/spotlight/preload.js | 13 + 10 files changed, 1074 insertions(+) create mode 100644 plugins/spotlight/.gitignore create mode 100644 plugins/spotlight/CHANGELOG.md create mode 100644 plugins/spotlight/README.md create mode 100644 plugins/spotlight/app.js create mode 100644 plugins/spotlight/index.html create mode 100644 plugins/spotlight/logo.png create mode 100644 plugins/spotlight/overlay.html create mode 100644 plugins/spotlight/overlay.js create mode 100644 plugins/spotlight/plugin.json create mode 100644 plugins/spotlight/preload.js diff --git a/plugins/spotlight/.gitignore b/plugins/spotlight/.gitignore new file mode 100644 index 00000000..03de1200 --- /dev/null +++ b/plugins/spotlight/.gitignore @@ -0,0 +1,7 @@ +node_modules/ +dist/ +.env +.env.* +.DS_Store +Thumbs.db +*.log diff --git a/plugins/spotlight/CHANGELOG.md b/plugins/spotlight/CHANGELOG.md new file mode 100644 index 00000000..6ac32560 --- /dev/null +++ b/plugins/spotlight/CHANGELOG.md @@ -0,0 +1,15 @@ +# Changelog + +## 1.0.0 + +### Added + +- 聚光灯核心效果:全屏变暗,圆形亮区跟随鼠标指针平滑移动(rAF 插值 + 合成器位移) +- 入场动画:黑幕从屏幕四角向鼠标位置收拢,退出时淡出 +- 多显示器支持:每块屏幕独立遮罩窗口,光圈跨屏平滑跟随,兼容不同分辨率 / DPI 缩放 +- 设置页:光圈大小(60–600px)、背景暗度(30%–95%)、边缘柔化(0–150px)实时预览调节 +- 开关项:点击屏幕任意处退出、多屏覆盖 +- 快捷键引导:一键跳转 ZTools 全局快捷键设置页(redirectHotKeySetting) +- 退出方式:Esc / 点击 / 切换窗口(Alt+Tab)自动退出,多窗口 localStorage 令牌联动 +- 显示器诊断:设置页展示检测到的屏幕数量、分辨率、坐标与缩放比 +- macOS 适配:遮罩窗口在所有桌面 Space 及全屏 App 之上可见 diff --git a/plugins/spotlight/README.md b/plugins/spotlight/README.md new file mode 100644 index 00000000..04b6a263 --- /dev/null +++ b/plugins/spotlight/README.md @@ -0,0 +1,77 @@ +# 聚光灯 (Spotlight) + +一款 ZTools 插件:按下快捷键,全屏瞬间变暗,只有鼠标指针周围的一圈保持明亮,并跟随鼠标平滑移动。适用于演示讲解、录屏教学、远程协作时指示光标位置,让观众的视线聚焦在你想表达的地方。 + +## 功能特性 + +- 🔦 **一键聚光**:全屏变暗,圆形光圈实时跟随鼠标指针 +- 🌊 **平滑跟随**:基于 `requestAnimationFrame` 的插值动画,光圈移动顺滑无卡顿 +- 🖥️ **多显示器支持**:遮罩窗口精确覆盖鼠标所在的屏幕 +- ⚙️ **可视化设置页**:光圈大小、背景暗度、边缘柔化自由调节,内置实时预览 +- ⌨️ **自定义快捷键**:设置页录制组合键,配合 ZTools 全局快捷键全局唤起 +- 💾 **设置自动保存**:所有配置通过 `dbStorage` 持久化,即时生效 + +## 安装 + +1. 下载或克隆本仓库 +2. 打开 ZTools → 插件中心 → 开发者模式(本地插件) +3. 添加本插件所在目录(包含 `plugin.json` 的目录) + +## 使用 + +| 操作 | 方式 | +| --- | --- | +| 开启聚光灯 | 搜索框输入 `聚光灯` / `spotlight` / `jgd`,或使用绑定的全局快捷键 | +| 打开设置页 | 搜索框输入 `聚光灯设置` / `聚光灯配置` | +| 退出聚光灯 | 按 `Esc`、点击屏幕任意处(可在设置中关闭)、或切换窗口(Alt+Tab) | + +### 绑定全局快捷键 + +点击设置页的「去绑定全局快捷键」按钮(自动跳转 ZTools 快捷键设置页),为本插件的「聚光灯」功能录入组合键(如 `Ctrl + Alt + S`)即可。 + +## 设置项 + +| 设置 | 范围 | 默认值 | 说明 | +| --- | --- | --- | --- | +| 光圈大小 | 60 – 600 px | 180 px | 亮圆区域的半径 | +| 背景暗度 | 30% – 95% | 75% | 光圈之外区域的压暗程度 | +| 边缘柔化 | 0 – 150 px | 60 px | 光圈边缘的羽化过渡宽度 | +| 点击退出 | 开 / 关 | 开 | 开启后点击屏幕任意处退出聚光灯 | +| 多屏覆盖 | 开 / 关 | 开 | 开启后黑幕横跨所有显示器,光圈跨屏跟随鼠标 | + +## 技术实现 + +- 纯 HTML / CSS / JavaScript,无构建步骤,无第三方依赖 +- 遮罩窗口由 `ztools.createBrowserWindow` 创建:全屏、透明、无边框、置顶、跳过任务栏 +- 多屏支持:每块显示器创建一个独立遮罩窗口,各自精确覆盖自身 bounds(规避混合 DPI / 不同分辨率下单窗口跨屏被系统裁剪的问题);窗口间通过 localStorage 会话令牌联动退出,通过焦点心跳识别用户切走 +- 光圈渲染:圆形元素 + 超大扩散 `box-shadow`(`0 0 {柔化}px 300vmax rgba(0,0,0,{暗度})`),圆外遮暗、圆内透亮 +- 位置跟踪:遮罩窗口 `mousemove` 事件为主通道,`ztools.getCursorScreenPoint()` 轮询为兜底 +- 平滑算法:每帧 `pos += (target - pos) × 0.3` 线性插值,位移仅更新 `transform`,由浏览器合成器处理 + +## 文件结构 + +``` +spotlight/ +├── plugin.json 插件配置(功能入口定义) +├── index.html 设置页面(UI) +├── app.js 主页面逻辑:设置存取 + 聚光灯激活控制 +├── overlay.html 全屏遮罩窗口页面 +├── overlay.js 遮罩窗口逻辑:光圈渲染 + 平滑跟随 + 退出 +├── preload.js preload 脚本(补充原生信息) +└── logo.png 插件图标 +``` + +## 发布 + +本插件符合 ZTools 插件规范(preload 未压缩混淆)。发布流程: + +```bash +git init && git add . && git commit -m "Add plugin spotlight v1.0.0" +ztools publish +``` + +详见 [ZTools 开发者文档](https://ztoolscenter.github.io/ZTools-doc/getting-started.html)。 + +## License + +MIT diff --git a/plugins/spotlight/app.js b/plugins/spotlight/app.js new file mode 100644 index 00000000..7062a1e1 --- /dev/null +++ b/plugins/spotlight/app.js @@ -0,0 +1,427 @@ +/** + * 聚光灯插件 - 主页面逻辑(设置页 + 聚光灯激活控制) + * + * 两个功能入口(plugin.json features): + * - spotlight → 直接开启聚光灯(隐藏主窗口,创建全屏遮罩窗口) + * - spotlight-settings → 打开本设置页 + */ + +(function () { + 'use strict'; + + var SETTINGS_KEY = 'spotlight-settings'; + + var DEFAULTS = { + radius: 180, // 光圈半径 px + opacity: 75, // 背景暗度 % + softness: 60, // 边缘柔化 px + clickExit: true, // 点击退出 + allScreens: true // 多屏覆盖(每块屏幕一个遮罩窗口) + }; + + var spotWins = []; // 当前聚光灯遮罩窗口(多屏时每块屏幕一个) + var monitorTimer = null; // 遮罩窗口存活监视器 + var lastActivateAt = 0; // 上次激活时间(用于去重,onPluginEnter/onPluginReady 可能重复触发) + + /* ---------------- 设置存取 ---------------- */ + + function loadSettings() { + var saved = null; + try { + saved = window.ztools && window.ztools.dbStorage.getItem(SETTINGS_KEY); + } catch (e) { /* ignore */ } + var s = {}; + for (var k in DEFAULTS) s[k] = DEFAULTS[k]; + if (saved && typeof saved === 'object') { + for (var k2 in DEFAULTS) { + if (saved[k2] !== undefined) s[k2] = saved[k2]; + } + } + return s; + } + + function saveSettings(s) { + try { + window.ztools && window.ztools.dbStorage.setItem(SETTINGS_KEY, s); + } catch (e) { /* ignore */ } + } + + /* ---------------- 开启聚光灯 ---------------- */ + + function activateSpotlight() { + if (!window.ztools) return; + + // 去重:onPluginEnter / onPluginReady 可能先后触发同一进入事件 + var now = Date.now(); + if (now - lastActivateAt < 800) return; + lastActivateAt = now; + + var s = loadSettings(); + + // 已开启则先关闭旧的(重复按快捷键 = 重新开启/刷新) + if (spotWins.length) { + destroyAllOverlays(); + } + + // 取鼠标当前位置,找到所在显示器 + var point = null; + try { point = window.ztools.getCursorScreenPoint(); } catch (e) {} + var display = null; + try { + display = point + ? window.ztools.getDisplayNearestPoint(point) + : window.ztools.getPrimaryDisplay(); + } catch (e) {} + var primaryBounds = (display && display.bounds) || { x: 0, y: 0, width: screen.width, height: screen.height }; + + // 确定要覆盖的显示器列表: + // - 多屏覆盖开启 → 所有显示器(每块屏幕一个独立遮罩窗口,各自精确覆盖自身 bounds, + // 避免混合 DPI / 不同分辨率下单个大窗口被系统裁剪的问题) + // - 关闭 → 仅鼠标所在显示器 + var boundsList = []; + if (s.allScreens) { + try { + var displays = window.ztools.getAllDisplays(); + if (displays && displays.length) { + displays.forEach(function (d) { if (d && d.bounds) boundsList.push(d.bounds); }); + } + } catch (e) { /* 获取失败时退回单屏 */ } + } + if (!boundsList.length) boundsList.push(primaryBounds); + + // 本次会话 ID:多窗口之间通过 localStorage 令牌联动退出 + var sid = 's' + Date.now(); + + function createOverlays() { + var cursorWin = null; + var failCount = 0; + + boundsList.forEach(function (b) { + // 通过 URL query 把初始参数交给遮罩窗口(窗口坐标原点 + 设置项 + 会话 ID) + var isCursorScreen = point && + point.x >= b.x && point.x < b.x + b.width && + point.y >= b.y && point.y < b.y + b.height; + var q = 'ox=' + b.x + '&oy=' + b.y + + '&r=' + s.radius + '&o=' + s.opacity + '&soft=' + s.softness + + '&ce=' + (s.clickExit ? 1 : 0) + + '&sid=' + sid + + (isCursorScreen ? '&tip=1' : '') + + (point ? '&cx=' + point.x + '&cy=' + point.y : ''); + + var win = null; + try { + win = window.ztools.createBrowserWindow('overlay.html?' + q, { + x: b.x, + y: b.y, + width: b.width, + height: b.height, + frame: false, + transparent: true, + resizable: false, + movable: false, + minimizable: false, + maximizable: false, + fullscreenable: false, + alwaysOnTop: true, + skipTaskbar: true, + show: false, + backgroundColor: '#00000000', + webPreferences: { + preload: 'preload.js', + backgroundThrottling: false + } + }); + } catch (e) { win = null; } + + // createBrowserWindow 失败时可能返回 null 或 Error 对象 + if (!win || typeof win.show !== 'function') { + failCount++; + return; + } + spotWins.push(win); + + // 注意:不使用创建回调来显示窗口。 + // ZTools 主进程通过 window.ztools.__event__.createBrowserWindowCallback 单一全局槽位 + // 触发回调,连续创建多个窗口时回调会相互覆盖,只有最后一个生效。 + // 窗口背景是透明的,立即显示不会有视觉闪烁。 + try { + if (typeof win.showInactive === 'function') win.showInactive(); + else win.show(); + } catch (e) { try { win.show(); } catch (e2) {} } + try { win.setAlwaysOnTop(true, 'screen-saver'); } catch (e) {} + // macOS:让遮罩在所有桌面 Space 及全屏 App 之上可见(Windows 下为无操作) + try { + if (typeof win.setVisibleOnAllWorkspaces === 'function') { + win.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); + } + } catch (e) {} + + if (isCursorScreen) cursorWin = win; + }); + + // 最后统一聚焦鼠标所在屏幕的窗口,确保 Esc 退出立即可用 + if (cursorWin) { + try { cursorWin.focus(); } catch (e) {} + } + + if (!spotWins.length) { + try { window.ztools.showNotification('聚光灯窗口创建失败'); } catch (e) {} + return; + } + if (failCount > 0) { + try { + window.ztools.showNotification('有 ' + failCount + ' 块屏幕的遮罩创建失败(共 ' + boundsList.length + ' 块)'); + } catch (e) {} + } + + // 监视遮罩窗口:任何一个被外部关闭时,兜底销毁其余窗口; + // 全部关闭后退出插件到后台——下次打开 ZTools 回到搜索页,而不是停留在本插件页面 + monitorTimer = setInterval(function () { + if (!spotWins.length) { clearInterval(monitorTimer); return; } + var alive = 0; + var anyGone = false; + spotWins.forEach(function (w) { + try { + if (w.isDestroyed()) anyGone = true; + else alive++; + } catch (e) { alive++; /* 代理不支持时视为存活 */ } + }); + if (anyGone && alive > 0) destroyAllOverlays(); + if (alive === 0 || anyGone) { + spotWins = []; + clearInterval(monitorTimer); + try { window.ztools.outPlugin(); } catch (e) {} + } + }, 500); + } + + // 关键顺序:先隐藏主窗口,再创建遮罩窗口。 + // 避免遮罩加载期间 ZTools 主窗口停留在屏幕上造成"先弹出再关闭"的闪烁感。 + var hideResult = null; + try { hideResult = window.ztools.hideMainWindow(); } catch (e) {} + if (hideResult && typeof hideResult.then === 'function') { + hideResult.then(createOverlays, createOverlays); + } else { + createOverlays(); + } + } + + function destroyAllOverlays() { + spotWins.forEach(function (w) { + try { w.destroy(); } catch (e) { try { w.close(); } catch (e2) {} } + }); + spotWins = []; + } + + /* ---------------- 进入插件 ---------------- */ + + function handleEnter(param) { + var code = param && param.code; + if (code === 'spotlight') { + document.body.classList.add('activating'); + activateSpotlight(); + } else { + // 设置页:务必移除 activating 隐藏类—— + // 插件页面在开启聚光灯后仍在后台存活,类名会残留导致设置页显示为空白 + document.body.classList.remove('activating'); + refreshDisplayInfo(); // 每次进入设置页刷新显示器诊断(函数声明会提升,此处可安全调用) + } + } + + if (window.ztools) { + window.ztools.onPluginEnter(handleEnter); + if (window.ztools.onPluginReady) window.ztools.onPluginReady(handleEnter); + } else { + // 非 ZTools 环境(如直接浏览器打开调试)也保证设置页可见 + document.body.classList.remove('activating'); + } + + // 聚光灯开启后插件页在后台存活,activating 隐藏类会残留; + // 当 ZTools 主窗口重新显示、本页面重新获得焦点/可见时,恢复设置页显示 + function restorePage() { + document.body.classList.remove('activating'); + } + window.addEventListener('focus', restorePage); + document.addEventListener('visibilitychange', function () { + if (!document.hidden) restorePage(); + }); + + /* ---------------- 设置页 UI ---------------- */ + + var settings = loadSettings(); + + var $ = function (id) { return document.getElementById(id); }; + var toastTimer = null; + function toast() { + var el = $('toast'); + el.classList.add('show'); + clearTimeout(toastTimer); + toastTimer = setTimeout(function () { el.classList.remove('show'); }, 900); + } + function persist() { + saveSettings(settings); + toast(); + } + + function paintRange(input) { + var p = (input.value - input.min) / (input.max - input.min) * 100; + input.style.setProperty('--p', p + '%'); + } + + // --- 滑杆 --- + function bindSlider(id, valId, key, fmt) { + var input = $(id), val = $(valId); + input.value = settings[key]; + val.textContent = fmt(settings[key]); + paintRange(input); + input.addEventListener('input', function () { + settings[key] = parseInt(input.value, 10); + val.textContent = fmt(settings[key]); + paintRange(input); + persist(); + }); + } + bindSlider('radius', 'radiusVal', 'radius', function (v) { return v + ' px'; }); + bindSlider('opacity', 'opacityVal', 'opacity', function (v) { return v + '%'; }); + bindSlider('softness', 'softnessVal', 'softness', function (v) { return v + ' px'; }); + + // --- 开关 --- + function bindSwitch(id, key) { + var el = $(id); + el.checked = !!settings[key]; + el.addEventListener('change', function () { + settings[key] = el.checked; + persist(); + }); + } + bindSwitch('clickExit', 'clickExit'); + bindSwitch('allScreens', 'allScreens'); + + // --- 立即开启 --- + $('testBtn').addEventListener('click', activateSpotlight); + + // --- 跳转 ZTools 全局快捷键设置 --- + $('bindBtn').addEventListener('click', function () { + try { + if (window.ztools && window.ztools.redirectHotKeySetting) { + window.ztools.redirectHotKeySetting('聚光灯', true); + } else { + window.ztools && window.ztools.showNotification('当前 ZTools 版本不支持自动跳转,请手动到 设置 → 全局快捷键 绑定'); + } + } catch (e) {} + }); + + // --- 显示器诊断 --- + function refreshDisplayInfo() { + var el = $('displayInfo'); + if (!el) return; + if (!window.ztools || !window.ztools.getAllDisplays) { + el.textContent = '当前环境不支持显示器检测'; + return; + } + try { + var displays = window.ztools.getAllDisplays() || []; + if (!displays.length) { + el.textContent = '未检测到任何显示器(getAllDisplays 返回空)'; + return; + } + var lines = displays.map(function (d, i) { + var b = d.bounds || {}; + return '屏 ' + (i + 1) + ':' + b.width + '×' + b.height + + ' @ (' + b.x + ', ' + b.y + ')' + + (d.scaleFactor ? ' · 缩放 ' + d.scaleFactor + 'x' : ''); + }); + el.textContent = '共检测到 ' + displays.length + ' 块显示器 — ' + lines.join(' | '); + } catch (e) { + el.textContent = '显示器检测出错:' + e.message; + } + } + refreshDisplayInfo(); + + /* ---------------- 实时预览 ---------------- */ + + var preview = $('preview'); + var pSpot = $('pSpot'); + var pTarget = { x: 160, y: 120 }; + var pPos = { x: 160, y: 120 }; + + function applyPreviewSpot() { + var r = settings.radius; + var op = settings.opacity / 100; + var soft = settings.softness; + pSpot.style.width = r * 2 + 'px'; + pSpot.style.height = r * 2 + 'px'; + // 大扩散 box-shadow 形成“圆形亮区 + 四周变暗”,blur 提供柔化边缘 + pSpot.style.boxShadow = '0 0 ' + soft + 'px 3000px rgba(0, 0, 0, ' + op + ')'; + } + + preview.addEventListener('mousemove', function (e) { + var rect = preview.getBoundingClientRect(); + pTarget.x = e.clientX - rect.left; + pTarget.y = e.clientY - rect.top; + }); + + // 鼠标进入预览区时,重播“黑幕从四角向鼠标收拢”的入场动画 + var OPEN_MS = 300; + var pOpenStart = null; + preview.addEventListener('mouseenter', function (e) { + var rect = preview.getBoundingClientRect(); + pTarget.x = e.clientX - rect.left; + pTarget.y = e.clientY - rect.top; + pPos.x = pTarget.x; + pPos.y = pTarget.y; + pOpenStart = performance.now(); + }); + + function easeOutCubic(t) { return 1 - Math.pow(1 - t, 3); } + + function farthestCornerDist(x, y, w, h) { + return Math.max( + Math.sqrt(x * x + y * y), + Math.sqrt((w - x) * (w - x) + y * y), + Math.sqrt(x * x + (h - y) * (h - y)), + Math.sqrt((w - x) * (w - x) + (h - y) * (h - y)) + ); + } + + (function previewLoop() { + // 与真实遮罩相同的平滑跟随算法(线性插值) + pPos.x += (pTarget.x - pPos.x) * 0.28; + pPos.y += (pTarget.y - pPos.y) * 0.28; + + // 入场收拢:亮洞半径从“覆盖整个预览区”收缩到设定半径 + var rEff = settings.radius; + if (pOpenStart !== null) { + var t = (performance.now() - pOpenStart) / OPEN_MS; + if (t >= 1) { + pOpenStart = null; + } else { + var rect = preview.getBoundingClientRect(); + var extra = farthestCornerDist(pPos.x, pPos.y, rect.width, rect.height) + settings.softness; + rEff = settings.radius + (1 - easeOutCubic(t)) * extra; + } + } + + pSpot.style.width = rEff * 2 + 'px'; + pSpot.style.height = rEff * 2 + 'px'; + pSpot.style.transform = 'translate3d(' + (pPos.x - rEff) + 'px, ' + (pPos.y - rEff) + 'px, 0)'; + requestAnimationFrame(previewLoop); + })(); + + applyPreviewSpot(); + ['radius', 'opacity', 'softness'].forEach(function (id) { + $(id).addEventListener('input', applyPreviewSpot); + }); + + // 兜底:若 600ms 内未收到任何进入事件(非常规打开方式),恢复设置页可见 + setTimeout(function () { + if (Date.now() - lastActivateAt > 800) { + document.body.classList.remove('activating'); + } + }, 600); + + // 主窗口高度适配 + if (window.ztools) { + try { window.ztools.setExpendHeight(770); } catch (e) {} + } +})(); diff --git a/plugins/spotlight/index.html b/plugins/spotlight/index.html new file mode 100644 index 00000000..c6228c90 --- /dev/null +++ b/plugins/spotlight/index.html @@ -0,0 +1,236 @@ + + + + + + +聚光灯设置 + + + +
+
+ 聚光灯 +
+

聚光灯

+

全屏变暗,光圈跟随鼠标指针,随时聚焦注意力

+
+
+ +
+

快捷键

+
+ + +
+

+ 点击「去绑定全局快捷键」跳转 ZTools 快捷键设置页,为本插件的「聚光灯」功能录入组合键(如 + Ctrl+Alt+S)即可全局唤起。 + 开启聚光灯后,按 Esc 或点击屏幕任意处退出。 +

+
+ +
+

光圈与明暗

+
+ + + 180 px +
+
+ + + 75% +
+
+ + + 60 px +
+
+ 点击屏幕任意处退出聚光灯 + +
+
+ 多屏覆盖(黑幕横跨所有显示器,光圈跨屏跟随) + +
+
+ +
+

实时预览

+
+
+
+
+
+
+
+
+
+
移动鼠标预览效果
+
+
+ +
+

显示器诊断

+

读取中…

+
+ +
+ 所有设置自动保存并即时生效
+ 在 ZTools 搜索框输入「聚光灯」或绑定全局快捷键开启 +
+
+ +
已保存
+ + + + diff --git a/plugins/spotlight/logo.png b/plugins/spotlight/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7a7a419f0db37255d3c682e77c6cbe23699e975f GIT binary patch literal 65648 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 ?h`B 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 z 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 literal 0 HcmV?d00001 diff --git a/plugins/spotlight/overlay.html b/plugins/spotlight/overlay.html new file mode 100644 index 00000000..9e4380e9 --- /dev/null +++ b/plugins/spotlight/overlay.html @@ -0,0 +1,55 @@ + + + + + +spotlight-overlay + + + +

+ + + diff --git a/plugins/spotlight/overlay.js b/plugins/spotlight/overlay.js new file mode 100644 index 00000000..9eb56f7e --- /dev/null +++ b/plugins/spotlight/overlay.js @@ -0,0 +1,221 @@ +/** + * 聚光灯遮罩窗口逻辑(多屏版:每块屏幕一个独立遮罩窗口) + * + * 本窗口由插件主页面通过 ztools.createBrowserWindow 创建, + * 初始参数经 URL query 传入: + * ox, oy - 窗口左上角在屏幕中的 DIP 坐标(用于把全局鼠标坐标换算为窗口内坐标) + * r - 光圈半径 px + * o - 背景暗度 0-100 + * soft - 边缘柔化 px + * ce - 1/0 是否允许点击退出 + * cx, cy - 开启瞬间的鼠标屏幕坐标(可选) + * sid - 本次聚光灯会话 ID(多窗口联动退出用) + * tip - 1 时在本窗口显示底部提示条(仅鼠标所在屏幕) + * + * 多窗口联动(localStorage 令牌): + * - 任意窗口退出时写入 spotlight-close:{sid},其余窗口轮询到后跟随关闭 + * - 聚焦窗口持续写焦点心跳 spotlight-fhb:{sid};某窗口失焦 300ms 后 + * 若全局焦点心跳已停(用户 Alt+Tab 离开),则触发整体退出。 + * 窗口间焦点转移时心跳不断,不会误退出。 + */ + +(function () { + 'use strict'; + + var params = new URLSearchParams(location.search); + function num(key, def) { + var v = parseFloat(params.get(key)); + return isNaN(v) ? def : v; + } + + var ORIGIN = { x: num('ox', 0), y: num('oy', 0) }; + var RADIUS = Math.max(20, num('r', 180)); + var OPACITY = Math.min(0.98, Math.max(0, num('o', 75) / 100)); + var SOFTNESS = Math.max(0, num('soft', 60)); + var CLICK_EXIT = params.get('ce') !== '0'; + var SID = params.get('sid') || 'default'; + var SHOW_TIP = params.get('tip') === '1'; + + var CLOSE_KEY = 'spotlight-close:' + SID; + var FOCUS_KEY = 'spotlight-fhb:' + SID; + + function lsGet(key) { + try { return localStorage.getItem(key); } catch (e) { return null; } + } + function lsSet(key, value) { + try { localStorage.setItem(key, value); } catch (e) {} + } + + var spot = document.getElementById('spot'); + var tip = document.getElementById('tip'); + + /* ---------- 光圈外观 ---------- */ + + spot.style.width = RADIUS * 2 + 'px'; + spot.style.height = RADIUS * 2 + 'px'; + // 300vmax 的扩散足以覆盖任意尺寸的屏幕 + spot.style.boxShadow = '0 0 ' + SOFTNESS + 'px 300vmax rgba(0, 0, 0, ' + OPACITY + ')'; + + /* ---------- 位置跟踪(全局坐标轮询为主,鼠标事件为辅) ---------- */ + + // target 是本窗口内的坐标;鼠标不在本屏时为负值或超出窗口尺寸, + // 光圈会平滑地从边缘滑出,本屏保持全暗 + var target = { x: window.innerWidth / 2, y: window.innerHeight / 2 }; + var pos = { x: target.x, y: target.y }; + + // 初始位置:优先使用父窗口传来的开启瞬间鼠标坐标 + if (params.get('cx') !== null && params.get('cy') !== null) { + target.x = num('cx', target.x) - ORIGIN.x; + target.y = num('cy', target.y) - ORIGIN.y; + pos.x = target.x; + pos.y = target.y; + } + + // 通道一:轮询全局鼠标坐标(跨屏跟踪的关键,ZTools 会向创建的窗口注入 ztools) + var canPoll = !!(window.ztools && window.ztools.getCursorScreenPoint); + function pollCursor() { + if (!canPoll) return; + try { + var p = window.ztools.getCursorScreenPoint(); + if (p && typeof p.x === 'number') { + target.x = p.x - ORIGIN.x; + target.y = p.y - ORIGIN.y; + + // 焦点跟随鼠标:光标进入本屏且聚光灯仍持有焦点(焦点心跳新鲜)时, + // 让本窗口获得焦点,保证 Esc 在任意屏幕都能退出; + // 心跳已停说明用户切走了,不抢焦点(由失焦逻辑统一退出) + var inside = + target.x >= 0 && target.x < window.innerWidth && + target.y >= 0 && target.y < window.innerHeight; + if (inside && !(document.hasFocus && document.hasFocus())) { + var lastBeat = parseInt(lsGet(FOCUS_KEY) || '0', 10); + if (Date.now() - lastBeat < 600) { + try { window.focus(); } catch (e) {} + } + } + } + } catch (e) { /* 忽略单次失败 */ } + } + + // 通道二:本窗口捕获的鼠标事件(事件驱动,更顺滑;仅光标在本屏时触发) + document.addEventListener('mousemove', function (e) { + target.x = e.clientX; + target.y = e.clientY; + }); + + /* ---------- 平滑跟随渲染循环 ---------- */ + + var LERP = 0.3; // 每帧向目标靠近 30%,形成顺滑的跟随感 + + /* + * 入场动画:黑幕从四角向鼠标位置收拢。 + * 原理:亮洞(光斑 div)的半径从“足以覆盖全屏”收缩到设定半径, + * box-shadow 的暗色边缘便从屏幕四角向光标处收拢。 + * 鼠标不在本屏的窗口:亮洞收缩到屏幕外,最终整屏变暗。 + */ + var OPEN_MS = 300; + var openStart = null; + + function easeOutCubic(t) { return 1 - Math.pow(1 - t, 3); } + + // 当前光斑中心到窗口四角的距离最大值(保证动画开始时阴影完全在屏幕外) + function farthestCornerDist(x, y) { + var w = window.innerWidth, h = window.innerHeight; + return Math.max( + Math.sqrt(x * x + y * y), + Math.sqrt((w - x) * (w - x) + y * y), + Math.sqrt(x * x + (h - y) * (h - y)), + Math.sqrt((w - x) * (w - x) + (h - y) * (h - y)) + ); + } + + function frame() { + pollCursor(); + pos.x += (target.x - pos.x) * LERP; + pos.y += (target.y - pos.y) * LERP; + + var rEff = RADIUS; + if (openStart !== null) { + var t = (performance.now() - openStart) / OPEN_MS; + if (t >= 1) { + openStart = null; + spot.style.width = RADIUS * 2 + 'px'; + spot.style.height = RADIUS * 2 + 'px'; + } else { + var extra = farthestCornerDist(pos.x, pos.y) + SOFTNESS + 20; + rEff = RADIUS + (1 - easeOutCubic(t)) * extra; + spot.style.width = rEff * 2 + 'px'; + spot.style.height = rEff * 2 + 'px'; + } + } + + spot.style.transform = + 'translate3d(' + (pos.x - rEff) + 'px, ' + (pos.y - rEff) + 'px, 0)'; + requestAnimationFrame(frame); + } + requestAnimationFrame(frame); + + // 入场:启动收拢动画 + 短暂显示提示条(仅鼠标所在屏幕) + requestAnimationFrame(function () { + openStart = performance.now(); + if (SHOW_TIP) { + tip.classList.add('show'); + setTimeout(function () { tip.classList.remove('show'); }, 2600); + } + }); + + /* ---------- 多窗口联动与退出 ---------- */ + + var closed = false; + var bornAt = Date.now(); + + function closeSpotlight(broadcast) { + if (closed) return; + closed = true; + if (broadcast) lsSet(CLOSE_KEY, String(Date.now())); // 通知其余遮罩窗口一起退出 + // 通知父窗口(若环境支持) + try { + if (window.ztools && window.ztools.sendToParent) { + window.ztools.sendToParent('spotlight:close'); + } + } catch (e) {} + // 黑幕淡出后关闭窗口 + spot.style.transition = 'opacity 120ms ease'; + spot.style.opacity = '0'; + tip.classList.remove('show'); + clearInterval(cascadeTimer); + clearInterval(focusBeatTimer); + setTimeout(function () { window.close(); }, 120); + } + + // 联动:其余窗口关闭时跟随关闭 + var cascadeTimer = setInterval(function () { + if (lsGet(CLOSE_KEY) !== null) closeSpotlight(false); + }, 200); + + // 焦点心跳:聚焦窗口每 200ms 上报一次;失焦窗口据此判断用户是否已离开聚光灯 + var focusBeatTimer = setInterval(function () { + if (document.hasFocus && document.hasFocus()) { + lsSet(FOCUS_KEY, String(Date.now())); + } + }, 200); + + window.addEventListener('blur', function () { + // 启动初期窗口间焦点交接属正常,宽限 800ms + if (Date.now() - bornAt < 800) return; + setTimeout(function () { + if (closed) return; + var lastBeat = parseInt(lsGet(FOCUS_KEY) || '0', 10); + // 没有任何遮罩窗口持有焦点(用户 Alt+Tab 离开)→ 整体退出 + if (Date.now() - lastBeat > 500) closeSpotlight(true); + }, 300); + }); + + document.addEventListener('keydown', function (e) { + if (e.key === 'Escape') closeSpotlight(true); + }); + + if (CLICK_EXIT) { + document.addEventListener('mousedown', function () { closeSpotlight(true); }); + } +})(); diff --git a/plugins/spotlight/plugin.json b/plugins/spotlight/plugin.json new file mode 100644 index 00000000..75fe0751 --- /dev/null +++ b/plugins/spotlight/plugin.json @@ -0,0 +1,23 @@ +{ + "name": "spotlight", + "title": "聚光灯", + "description": "屏幕聚光灯:一键全屏变暗,光圈平滑跟随鼠标,演示录屏时聚焦视线", + "author": "Reaosen", + "version": "1.0.0", + "main": "index.html", + "logo": "logo.png", + "preload": "preload.js", + "features": [ + { + "code": "spotlight", + "explain": "开启聚光灯(全屏变暗,光圈跟随鼠标)", + "cmds": ["聚光灯", "spotlight", "jgd"], + "mainHide": true + }, + { + "code": "spotlight-settings", + "explain": "聚光灯设置(快捷键 / 光圈大小 / 明暗 / 柔化)", + "cmds": ["聚光灯设置", "spotlight设置", "聚光灯配置", "jgd设置"] + } + ] +} diff --git a/plugins/spotlight/preload.js b/plugins/spotlight/preload.js new file mode 100644 index 00000000..0277f987 --- /dev/null +++ b/plugins/spotlight/preload.js @@ -0,0 +1,13 @@ +/** + * 聚光灯插件 preload + * ZTools 会自动向页面注入 window.ztools,这里只补充少量原生信息。 + * 注意:本文件遵循 ZTools 规范,保持清晰可读,不做压缩混淆。 + */ + +window.spotlightPreload = { + platform: process.platform, + versions: { + electron: process.versions.electron, + node: process.versions.node + } +};