feat: 采集插件样式修改
This commit is contained in:
@@ -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)→ 收起
|
// 面板内 App(Esc)→ 收起;✕ 按钮已外置到宿主层(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();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user