Compare commits

...

1 Commits

Author SHA1 Message Date
R524809 0e8fc4ebe0 feat: 采集插件样式修改 2026-08-26 17:38:18 +08:00
3 changed files with 44 additions and 9 deletions
+39 -2
View File
@@ -33,6 +33,32 @@ const STYLES = `
.fab:hover { transform: scale(1.08); } .fab:hover { transform: scale(1.08); }
.fab.hidden { display: none; } .fab.hidden { display: none; }
/* 收起按钮:骑在面板左上边缘(一半在面板外)。必须在 iframe 外渲染——
iframe 裁剪内容,iframe 内的元素永远溢不出面板边界 */
.panel-close {
position: fixed;
top: 20px;
right: min(880px, 100vw); /* 面板左边缘 = 视口右沿 - 面板宽度 */
transform: translateX(50%);
width: 28px;
height: 28px;
border-radius: 50%;
border: 1px solid rgba(0, 0, 0, 0.12);
background: #fff;
color: #555;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
z-index: 4;
opacity: 0;
pointer-events: none;
transition: opacity 0.25s ease, transform 0.15s ease;
}
.panel-close.visible { opacity: 1; pointer-events: auto; }
.panel-close:hover { color: #6d28d9; border-color: #6d28d9; transform: translateX(50%) scale(1.08); }
.panel { .panel {
position: fixed; position: fixed;
top: 0; top: 0;
@@ -92,23 +118,34 @@ export default defineContentScript({
const iframe = document.createElement('iframe'); const iframe = document.createElement('iframe');
iframe.title = '电商套图工作台'; iframe.title = '电商套图工作台';
panel.append(iframe); panel.append(iframe);
container.append(fab, panel);
// 外置收起按钮(骑在面板左上边缘,一半在面板外)
const closeBtn = document.createElement('button');
closeBtn.className = 'panel-close';
closeBtn.title = '收起面板(Esc';
closeBtn.innerHTML =
'<svg width="12" height="12" viewBox="0 0 12 12" fill="none">' +
'<path d="M2 2l8 8M10 2l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>';
container.append(fab, panel, closeBtn);
const open = () => { const open = () => {
if (!iframe.src) iframe.src = chrome.runtime.getURL('/sidepanel.html'); if (!iframe.src) iframe.src = chrome.runtime.getURL('/sidepanel.html');
panel.classList.add('open'); panel.classList.add('open');
closeBtn.classList.add('visible');
fab.classList.add('hidden'); fab.classList.add('hidden');
// 聚焦进面板,键盘操作(Esc 关闭 / 预览翻页)直接可用 // 聚焦进面板,键盘操作(Esc 关闭 / 预览翻页)直接可用
iframe.focus(); iframe.focus();
}; };
const close = () => { const close = () => {
panel.classList.remove('open'); panel.classList.remove('open');
closeBtn.classList.remove('visible');
if (isProductPage()) fab.classList.remove('hidden'); if (isProductPage()) fab.classList.remove('hidden');
}; };
fab.addEventListener('click', open); fab.addEventListener('click', open);
closeBtn.addEventListener('click', close);
// 面板内 App✕ / Esc)→ 收起 // 面板内 AppEsc)→ 收起;✕ 按钮已外置到宿主层(closeBtn)
window.addEventListener('message', (e) => { window.addEventListener('message', (e) => {
if (e.source === iframe.contentWindow && (e.data as any)?.type === PANEL_CLOSE_MSG) close(); if (e.source === iframe.contentWindow && (e.data as any)?.type === PANEL_CLOSE_MSG) close();
}); });
+3 -5
View File
@@ -11,7 +11,7 @@
import React, { useCallback, useEffect, useRef, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import { App as AntApp, ConfigProvider, Popover, Progress, Select } from 'antd'; import { App as AntApp, ConfigProvider, Popover, Progress, Select } from 'antd';
import { SettingOutlined, DownloadOutlined, ThunderboltOutlined, UploadOutlined, CloseOutlined } from '@ant-design/icons'; import { SettingOutlined, DownloadOutlined, ThunderboltOutlined, UploadOutlined } from '@ant-design/icons';
import type { ScanResult, ImageMaterial } from '../../src/collector/scan'; import type { ScanResult, ImageMaterial } from '../../src/collector/scan';
import { cleanFilename } from '../../src/collector/url'; import { cleanFilename } from '../../src/collector/url';
import { import {
@@ -671,11 +671,9 @@ const App: React.FC = () => {
return ( return (
<div className="page"> <div className="page">
{/* ── 顶栏 ── */} {/* ── 顶栏 ──(页内模式的收起 ✕ 按钮在宿主层渲染:要骑在面板边缘、一半在面板外,
iframe 会裁剪内容,按钮必须在 iframe 外;Esc 关闭仍走 closePanel */}
<div className="topbar"> <div className="topbar">
{IN_PAGE && (
<button className="icon-btn" title="收起面板(Esc" onClick={closePanel}><CloseOutlined /></button>
)}
<div className="logo"></div> <div className="logo"></div>
<div> <div>
<h1></h1> <h1></h1>
+2 -2
View File
@@ -18,8 +18,8 @@ from config import get_settings
log = logging.getLogger("suite.watermark") log = logging.getLogger("suite.watermark")
# 尺寸比例(与 ozonSeller app.js 常量一致 # 尺寸比例(BADGE_SCALE 在 ozonSeller 的 0.15 基础上缩小 30%:用户反馈偏大
BADGE_SCALE = 0.15 # 图片水印直径 / 图宽 BADGE_SCALE = 0.105 # 图片水印直径 / 图宽
BADGE_MARGIN = 0.01 # 图片水印边距 / 图宽(ozonSeller 固定 10px,按比例更稳) BADGE_MARGIN = 0.01 # 图片水印边距 / 图宽(ozonSeller 固定 10px,按比例更稳)
TEXT_SCALE = 0.06 # 文字字号 / 图宽 TEXT_SCALE = 0.06 # 文字字号 / 图宽
TEXT_MIN_SIZE = 12 TEXT_MIN_SIZE = 12