添加区域模式,优化提示
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(wc:*)"
|
||||
"Bash(wc:*)",
|
||||
"Bash(cat:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
138
content.css
138
content.css
@@ -10,59 +10,30 @@
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
/* 元素模式下的悬停效果 */
|
||||
body.blurtext-mode .blurtext-blurred:hover::after {
|
||||
content: '点击取消模糊' !important;
|
||||
position: absolute !important;
|
||||
top: 50% !important;
|
||||
left: 50% !important;
|
||||
transform: translate(-50%, -50%) !important;
|
||||
/* 元素模式下的悬停效果 - 移除伪元素方案,改用 JS 动态创建 */
|
||||
/* body.blurtext-mode .blurtext-blurred:hover::after 已移除 */
|
||||
|
||||
/* 元素模式悬停提示工具栏(JS 动态创建) */
|
||||
.blurtext-element-tooltip {
|
||||
position: fixed !important;
|
||||
background: rgba(102, 126, 234, 0.95) !important;
|
||||
color: white !important;
|
||||
padding: 4px 8px !important;
|
||||
border-radius: 4px !important;
|
||||
font-size: 12px !important;
|
||||
white-space: nowrap !important;
|
||||
z-index: 999999 !important;
|
||||
pointer-events: none !important;
|
||||
filter: none !important;
|
||||
}
|
||||
|
||||
/* 文本选择模式包裹的元素悬停效果 */
|
||||
.blurtext-selection-wrapped {
|
||||
transition: all 0.1s ease !important;
|
||||
}
|
||||
|
||||
.blurtext-selection-wrapped:hover {
|
||||
background-color: rgba(102, 126, 234, 0.2) !important;
|
||||
outline: 2px solid rgba(102, 126, 234, 0.5) !important;
|
||||
outline-offset: 2px !important;
|
||||
}
|
||||
|
||||
.blurtext-selection-wrapped:hover::after {
|
||||
content: '🔓 点击恢复' !important;
|
||||
position: absolute !important;
|
||||
top: 50% !important;
|
||||
left: 50% !important;
|
||||
transform: translate(-50%, -50%) !important;
|
||||
background: rgba(102, 126, 234, 0.98) !important;
|
||||
color: white !important;
|
||||
padding: 6px 12px !important;
|
||||
border-radius: 6px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
white-space: nowrap !important;
|
||||
z-index: 999999 !important;
|
||||
z-index: 2147483647 !important;
|
||||
pointer-events: none !important;
|
||||
filter: none !important;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
|
||||
animation: blurtext-tooltipPop 0.15s ease !important;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
|
||||
animation: blurtext-tooltipFadeIn 0.15s ease !important;
|
||||
}
|
||||
|
||||
@keyframes blurtext-tooltipPop {
|
||||
@keyframes blurtext-tooltipFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%) scale(0.8);
|
||||
transform: translate(-50%, -50%) scale(0.9);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
@@ -70,6 +41,42 @@ body.blurtext-mode .blurtext-blurred:hover::after {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 文本选择模式包裹的元素悬停效果 */
|
||||
.blurtext-selection-wrapped {
|
||||
display: inline !important;
|
||||
position: relative !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
/* 移除伪元素提示,改用 JS 动态创建(避免被模糊效果影响) */
|
||||
|
||||
/* 文本选择错误提示(显示在选区下方) */
|
||||
.blurtext-selection-error {
|
||||
background: #f44336 !important;
|
||||
color: white !important;
|
||||
padding: 8px 16px !important;
|
||||
border-radius: 6px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 500 !important;
|
||||
box-shadow: 0 2px 8px rgba(244, 67, 54, 0.4) !important;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
|
||||
animation: blurtext-errorPop 0.2s ease !important;
|
||||
pointer-events: none !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
@keyframes blurtext-errorPop {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateX(-50%) translateY(-5px) scale(0.9);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateX(-50%) translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* 模糊模式下的鼠标样式 */
|
||||
body.blurtext-mode * {
|
||||
cursor: crosshair !important;
|
||||
@@ -149,7 +156,52 @@ body.blurtext-mode * {
|
||||
}
|
||||
}
|
||||
|
||||
/* 文本选择模式包裹的元素 */
|
||||
.blurtext-selection-wrapped {
|
||||
display: inline !important;
|
||||
/* ========== 区域模式样式 ========== */
|
||||
|
||||
/* 绘制框(拖动时显示) */
|
||||
.blurtext-drawing-box {
|
||||
border: 2px dashed #667eea !important;
|
||||
background: rgba(102, 126, 234, 0.1) !important;
|
||||
pointer-events: none !important;
|
||||
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.5) !important;
|
||||
}
|
||||
|
||||
/* 区域覆盖层 */
|
||||
.blurtext-area-overlay {
|
||||
background: rgba(255, 255, 255, 0.1) !important;
|
||||
backdrop-filter: blur(var(--blur-intensity, 10px)) !important;
|
||||
-webkit-backdrop-filter: blur(var(--blur-intensity, 10px)) !important;
|
||||
border: none !important;
|
||||
box-sizing: border-box !important;
|
||||
transition: all 0.2s ease !important;
|
||||
user-select: none !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.blurtext-area-overlay:hover {
|
||||
outline: 2px solid rgba(102, 126, 234, 0.5) !important;
|
||||
outline-offset: -2px !important;
|
||||
background: rgba(255, 255, 255, 0.15) !important;
|
||||
}
|
||||
|
||||
/* 区域覆盖层悬停提示 */
|
||||
.blurtext-area-overlay:hover::after {
|
||||
content: '点击恢复此区域' !important;
|
||||
position: absolute !important;
|
||||
top: 50% !important;
|
||||
left: 50% !important;
|
||||
transform: translate(-50%, -50%) !important;
|
||||
background: rgba(102, 126, 234, 0.95) !important;
|
||||
color: white !important;
|
||||
padding: 6px 12px !important;
|
||||
border-radius: 6px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
white-space: nowrap !important;
|
||||
z-index: 999999 !important;
|
||||
pointer-events: none !important;
|
||||
backdrop-filter: none !important;
|
||||
-webkit-backdrop-filter: none !important;
|
||||
filter: none !important;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
|
||||
}
|
||||
|
||||
335
content.js
335
content.js
@@ -5,11 +5,19 @@
|
||||
console.log('[BlurText] Content script loaded');
|
||||
|
||||
let isBlurMode = false;
|
||||
let blurMode = 'element'; // 'element' or 'selection'
|
||||
let blurMode = 'element'; // 'element', 'selection', or 'area'
|
||||
let blurIntensity = 10;
|
||||
let blurredElements = new Set();
|
||||
let hintElement = null;
|
||||
let blurButton = null; // 浮动模糊按钮
|
||||
let elementTooltip = null; // 元素模式悬停提示
|
||||
|
||||
// 区域模式相关变量
|
||||
let isDrawing = false;
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let drawingBox = null;
|
||||
let areaOverlays = []; // 存储所有区域覆盖层
|
||||
|
||||
// 初始化:从存储中加载配置
|
||||
chrome.storage.local.get(['blurIntensity'], (result) => {
|
||||
@@ -53,7 +61,12 @@
|
||||
function enableBlurMode() {
|
||||
console.log('[BlurText] Enabling blur mode, mode:', blurMode);
|
||||
|
||||
const modeText = blurMode === 'selection' ? '文本选择模式 - 拖动选择文字后点击模糊按钮' : '元素模式 - 点击元素进行模糊';
|
||||
let modeText = '元素模式 - 点击元素进行模糊';
|
||||
if (blurMode === 'selection') {
|
||||
modeText = '文本选择模式 - 拖动选择文字后点击模糊按钮';
|
||||
} else if (blurMode === 'area') {
|
||||
modeText = '区域模式 - 拖动鼠标绘制模糊区域';
|
||||
}
|
||||
showHint(`模糊模式已开启 - ${modeText},按 ESC 退出`);
|
||||
|
||||
// 根据模式添加对应的样式和事件
|
||||
@@ -65,9 +78,15 @@
|
||||
} else if (blurMode === 'selection') {
|
||||
// 文本选择模式不需要 crosshair 光标
|
||||
document.addEventListener('mouseup', handleTextSelection, true);
|
||||
} else if (blurMode === 'area') {
|
||||
// 区域模式:使用 crosshair 光标并添加绘制事件
|
||||
document.body.classList.add('blurtext-mode');
|
||||
document.addEventListener('mousedown', handleAreaMouseDown, true);
|
||||
document.addEventListener('mousemove', handleAreaMouseMove, true);
|
||||
document.addEventListener('mouseup', handleAreaMouseUp, true);
|
||||
}
|
||||
|
||||
// 键盘事件对两种模式都需要
|
||||
// 键盘事件对所有模式都需要
|
||||
document.addEventListener('keydown', handleKeydown, true);
|
||||
|
||||
console.log('[BlurText] Event listeners attached');
|
||||
@@ -78,6 +97,8 @@
|
||||
document.body.classList.remove('blurtext-mode');
|
||||
hideHint();
|
||||
hideBlurButton();
|
||||
hideDrawingBox();
|
||||
hideElementTooltip();
|
||||
|
||||
// 移除所有事件监听
|
||||
document.removeEventListener('click', handleClick, true);
|
||||
@@ -85,6 +106,9 @@
|
||||
document.removeEventListener('mouseover', handleMouseOver, true);
|
||||
document.removeEventListener('mouseout', handleMouseOut, true);
|
||||
document.removeEventListener('mouseup', handleTextSelection, true);
|
||||
document.removeEventListener('mousedown', handleAreaMouseDown, true);
|
||||
document.removeEventListener('mousemove', handleAreaMouseMove, true);
|
||||
document.removeEventListener('mouseup', handleAreaMouseUp, true);
|
||||
|
||||
// 清除所有高亮和预览
|
||||
removeAllHighlights();
|
||||
@@ -102,10 +126,15 @@
|
||||
document.removeEventListener('mouseover', handleMouseOver, true);
|
||||
document.removeEventListener('mouseout', handleMouseOut, true);
|
||||
document.removeEventListener('mouseup', handleTextSelection, true);
|
||||
document.removeEventListener('mousedown', handleAreaMouseDown, true);
|
||||
document.removeEventListener('mousemove', handleAreaMouseMove, true);
|
||||
document.removeEventListener('mouseup', handleAreaMouseUp, true);
|
||||
|
||||
// 清除旧模式的UI元素
|
||||
hideBlurButton();
|
||||
removeAllHighlights();
|
||||
hideDrawingBox();
|
||||
hideElementTooltip();
|
||||
|
||||
// 根据新模式添加事件监听和样式
|
||||
if (blurMode === 'element') {
|
||||
@@ -118,6 +147,13 @@
|
||||
// 文本选择模式不需要 crosshair 光标
|
||||
document.addEventListener('mouseup', handleTextSelection, true);
|
||||
showHint('已切换到文本选择模式 - 拖动选择文字后点击模糊按钮', 3000);
|
||||
} else if (blurMode === 'area') {
|
||||
// 区域模式
|
||||
document.body.classList.add('blurtext-mode');
|
||||
document.addEventListener('mousedown', handleAreaMouseDown, true);
|
||||
document.addEventListener('mousemove', handleAreaMouseMove, true);
|
||||
document.addEventListener('mouseup', handleAreaMouseUp, true);
|
||||
showHint('已切换到区域模式 - 拖动鼠标绘制模糊区域', 3000);
|
||||
}
|
||||
|
||||
console.log('[BlurText] Mode switched successfully');
|
||||
@@ -222,6 +258,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 显示元素悬停提示
|
||||
function showElementTooltip(element, text) {
|
||||
// 移除旧提示
|
||||
hideElementTooltip();
|
||||
|
||||
// 获取元素位置
|
||||
const rect = element.getBoundingClientRect();
|
||||
|
||||
// 创建提示元素
|
||||
elementTooltip = document.createElement('div');
|
||||
elementTooltip.className = 'blurtext-element-tooltip';
|
||||
elementTooltip.textContent = text;
|
||||
elementTooltip.style.left = `${rect.left + rect.width / 2}px`;
|
||||
elementTooltip.style.top = `${rect.top + rect.height / 2}px`;
|
||||
elementTooltip.style.transform = 'translate(-50%, -50%)';
|
||||
|
||||
document.body.appendChild(elementTooltip);
|
||||
}
|
||||
|
||||
// 隐藏元素悬停提示
|
||||
function hideElementTooltip() {
|
||||
if (elementTooltip && elementTooltip.parentNode) {
|
||||
elementTooltip.parentNode.removeChild(elementTooltip);
|
||||
elementTooltip = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 模糊选中的文本
|
||||
function blurSelectedText() {
|
||||
const selection = window.getSelection();
|
||||
@@ -230,21 +293,76 @@
|
||||
try {
|
||||
const range = selection.getRangeAt(0);
|
||||
|
||||
// 获取选中的文本内容
|
||||
const selectedText = range.toString();
|
||||
|
||||
// 验证选区是否符合要求
|
||||
if (!selectedText.trim()) {
|
||||
console.log('[BlurText] No text selected');
|
||||
hideBlurButton();
|
||||
return;
|
||||
}
|
||||
|
||||
// 限制:不允许包含换行
|
||||
if (selectedText.includes('\n') || selectedText.includes('\r')) {
|
||||
console.log('[BlurText] Selection contains line breaks');
|
||||
showSelectionError(selection, '不支持跨行选择');
|
||||
hideBlurButton();
|
||||
return;
|
||||
}
|
||||
|
||||
// 限制:不允许包含多个空格(允许单个空格)
|
||||
if (/\s{2,}/.test(selectedText)) {
|
||||
console.log('[BlurText] Selection contains multiple spaces');
|
||||
showSelectionError(selection, '不支持多个连续空格');
|
||||
hideBlurButton();
|
||||
return;
|
||||
}
|
||||
|
||||
// 限制:检查是否跨越多个元素
|
||||
const startContainer = range.startContainer;
|
||||
const endContainer = range.endContainer;
|
||||
|
||||
// 如果起始和结束容器不同,则跨越了多个节点
|
||||
if (startContainer !== endContainer) {
|
||||
console.log('[BlurText] Selection spans multiple elements');
|
||||
showSelectionError(selection, '不支持跨元素选择');
|
||||
hideBlurButton();
|
||||
return;
|
||||
}
|
||||
|
||||
// 限制:只能选择文本节点
|
||||
if (startContainer.nodeType !== Node.TEXT_NODE) {
|
||||
console.log('[BlurText] Selection is not in a text node');
|
||||
showSelectionError(selection, '请选择纯文本内容');
|
||||
hideBlurButton();
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建 span 包裹选中的文本
|
||||
const span = document.createElement('span');
|
||||
span.className = 'blurtext-blurred blurtext-selection-wrapped';
|
||||
span.style.setProperty('--blur-intensity', `${blurIntensity}px`);
|
||||
span.style.cursor = 'pointer';
|
||||
span.title = '点击恢复此段文本';
|
||||
|
||||
// 添加鼠标悬停事件,显示恢复提示
|
||||
span.addEventListener('mouseenter', () => {
|
||||
showElementTooltip(span, '点击恢复此文本');
|
||||
});
|
||||
|
||||
span.addEventListener('mouseleave', () => {
|
||||
hideElementTooltip();
|
||||
});
|
||||
|
||||
// 添加点击事件,允许单独恢复
|
||||
span.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
hideElementTooltip(); // 点击后立即隐藏提示
|
||||
unblurSelectionSpan(span);
|
||||
});
|
||||
|
||||
// 包裹选中的内容
|
||||
// 使用 surroundContents(在严格限制下应该不会失败)
|
||||
range.surroundContents(span);
|
||||
|
||||
// 添加到模糊元素集合
|
||||
@@ -257,16 +375,43 @@
|
||||
|
||||
// 隐藏按钮
|
||||
hideBlurButton();
|
||||
|
||||
// 显示提示
|
||||
showHint('文本已模糊(点击可单独恢复)', 2000);
|
||||
} catch (error) {
|
||||
console.error('[BlurText] Error blurring selection:', error);
|
||||
showHint('无法模糊该选区(可能包含复杂的HTML结构)', 3000);
|
||||
showSelectionError(selection, '无法模糊该选区');
|
||||
hideBlurButton();
|
||||
}
|
||||
}
|
||||
|
||||
// 在选区位置显示错误提示
|
||||
function showSelectionError(selection, message) {
|
||||
if (!selection.rangeCount) return;
|
||||
|
||||
const range = selection.getRangeAt(0);
|
||||
const rect = range.getBoundingClientRect();
|
||||
|
||||
// 创建错误提示元素
|
||||
const errorTooltip = document.createElement('div');
|
||||
errorTooltip.className = 'blurtext-selection-error';
|
||||
errorTooltip.textContent = message;
|
||||
errorTooltip.style.position = 'fixed';
|
||||
errorTooltip.style.left = `${rect.left + rect.width / 2}px`;
|
||||
errorTooltip.style.top = `${rect.bottom + 10}px`;
|
||||
errorTooltip.style.transform = 'translateX(-50%)';
|
||||
errorTooltip.style.zIndex = '2147483647';
|
||||
|
||||
document.body.appendChild(errorTooltip);
|
||||
|
||||
// 清除选择
|
||||
selection.removeAllRanges();
|
||||
|
||||
// 2秒后自动移除
|
||||
setTimeout(() => {
|
||||
if (errorTooltip.parentNode) {
|
||||
errorTooltip.parentNode.removeChild(errorTooltip);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// 恢复单个选择模式的模糊段落
|
||||
function unblurSelectionSpan(span) {
|
||||
if (!span || !span.parentNode) return;
|
||||
@@ -276,7 +421,7 @@
|
||||
// 从集合中移除
|
||||
blurredElements.delete(span);
|
||||
|
||||
// 获取 span 的内容
|
||||
// 获取 span 的内容(保持子节点结构)
|
||||
const fragment = document.createDocumentFragment();
|
||||
while (span.firstChild) {
|
||||
fragment.appendChild(span.firstChild);
|
||||
@@ -285,9 +430,6 @@
|
||||
// 用原内容替换 span
|
||||
span.parentNode.replaceChild(fragment, span);
|
||||
|
||||
// 显示提示
|
||||
showHint('已恢复此段文本', 1500);
|
||||
|
||||
console.log('[BlurText] Selection span removed, remaining elements:', blurredElements.size);
|
||||
}
|
||||
|
||||
@@ -296,13 +438,20 @@
|
||||
if (!isBlurMode || blurMode !== 'element') return;
|
||||
|
||||
const target = e.target;
|
||||
if (target.classList.contains('blurtext-hint') ||
|
||||
target.classList.contains('blurtext-blurred')) {
|
||||
if (target.classList.contains('blurtext-hint')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 移除之前的高亮
|
||||
// 如果是已模糊的元素,显示恢复提示(不添加高亮)
|
||||
if (target.classList.contains('blurtext-blurred')) {
|
||||
removeAllHighlights(); // 移除其他高亮
|
||||
showElementTooltip(target, '点击取消模糊');
|
||||
return;
|
||||
}
|
||||
|
||||
// 移除之前的高亮和提示
|
||||
removeAllHighlights();
|
||||
hideElementTooltip();
|
||||
|
||||
// 直接高亮元素
|
||||
target.classList.add('blurtext-highlight');
|
||||
@@ -320,6 +469,9 @@
|
||||
function handleMouseOut(e) {
|
||||
if (!isBlurMode || blurMode !== 'element') return;
|
||||
|
||||
// 隐藏提示
|
||||
hideElementTooltip();
|
||||
|
||||
// 延迟移除,避免在元素间移动时闪烁
|
||||
setTimeout(() => {
|
||||
// 检查鼠标是否还在模糊模式下的元素上
|
||||
@@ -346,6 +498,9 @@
|
||||
element.classList.remove('blurtext-blurred');
|
||||
element.style.removeProperty('--blur-intensity');
|
||||
blurredElements.delete(element);
|
||||
|
||||
// 隐藏提示气泡(因为元素已不再模糊)
|
||||
hideElementTooltip();
|
||||
} else {
|
||||
// 添加模糊
|
||||
console.log('[BlurText] Adding blur to element, intensity:', blurIntensity);
|
||||
@@ -364,12 +519,160 @@
|
||||
});
|
||||
blurredElements.clear();
|
||||
|
||||
// 清除所有区域覆盖层
|
||||
areaOverlays.forEach(overlay => {
|
||||
if (overlay.parentNode) {
|
||||
overlay.parentNode.removeChild(overlay);
|
||||
}
|
||||
});
|
||||
areaOverlays = [];
|
||||
|
||||
// 如果在模糊模式下,显示提示
|
||||
if (isBlurMode) {
|
||||
showHint('已清除所有模糊效果', 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 区域模式相关函数 ==========
|
||||
|
||||
// 处理区域模式鼠标按下
|
||||
function handleAreaMouseDown(e) {
|
||||
if (!isBlurMode || blurMode !== 'area') return;
|
||||
|
||||
// 忽略提示元素和已有的区域覆盖层
|
||||
if (e.target.classList.contains('blurtext-hint') ||
|
||||
e.target.classList.contains('blurtext-area-overlay') ||
|
||||
e.target.classList.contains('blurtext-area-close')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否点击了关闭按钮
|
||||
if (e.target.classList.contains('blurtext-area-close')) {
|
||||
const overlay = e.target.parentElement;
|
||||
removeAreaOverlay(overlay);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
isDrawing = true;
|
||||
startX = e.pageX;
|
||||
startY = e.pageY;
|
||||
|
||||
// 创建绘制框
|
||||
drawingBox = document.createElement('div');
|
||||
drawingBox.className = 'blurtext-drawing-box';
|
||||
drawingBox.style.position = 'absolute';
|
||||
drawingBox.style.left = startX + 'px';
|
||||
drawingBox.style.top = startY + 'px';
|
||||
drawingBox.style.width = '0px';
|
||||
drawingBox.style.height = '0px';
|
||||
drawingBox.style.zIndex = '2147483646';
|
||||
document.body.appendChild(drawingBox);
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
// 处理区域模式鼠标移动
|
||||
function handleAreaMouseMove(e) {
|
||||
if (!isBlurMode || blurMode !== 'area' || !isDrawing || !drawingBox) return;
|
||||
|
||||
const currentX = e.pageX;
|
||||
const currentY = e.pageY;
|
||||
|
||||
const width = Math.abs(currentX - startX);
|
||||
const height = Math.abs(currentY - startY);
|
||||
const left = Math.min(currentX, startX);
|
||||
const top = Math.min(currentY, startY);
|
||||
|
||||
drawingBox.style.left = left + 'px';
|
||||
drawingBox.style.top = top + 'px';
|
||||
drawingBox.style.width = width + 'px';
|
||||
drawingBox.style.height = height + 'px';
|
||||
}
|
||||
|
||||
// 处理区域模式鼠标释放
|
||||
function handleAreaMouseUp(e) {
|
||||
if (!isBlurMode || blurMode !== 'area' || !isDrawing || !drawingBox) return;
|
||||
|
||||
isDrawing = false;
|
||||
|
||||
const width = parseInt(drawingBox.style.width);
|
||||
const height = parseInt(drawingBox.style.height);
|
||||
|
||||
// 只有当区域足够大时才创建模糊覆盖层(至少 20x20 像素)
|
||||
if (width > 20 && height > 20) {
|
||||
createAreaOverlay(
|
||||
parseInt(drawingBox.style.left),
|
||||
parseInt(drawingBox.style.top),
|
||||
width,
|
||||
height
|
||||
);
|
||||
}
|
||||
|
||||
// 移除绘制框
|
||||
if (drawingBox.parentNode) {
|
||||
drawingBox.parentNode.removeChild(drawingBox);
|
||||
}
|
||||
drawingBox = null;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
// 创建区域覆盖层
|
||||
function createAreaOverlay(left, top, width, height) {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'blurtext-area-overlay';
|
||||
overlay.style.position = 'absolute';
|
||||
overlay.style.left = left + 'px';
|
||||
overlay.style.top = top + 'px';
|
||||
overlay.style.width = width + 'px';
|
||||
overlay.style.height = height + 'px';
|
||||
overlay.style.setProperty('--blur-intensity', `${blurIntensity}px`);
|
||||
overlay.style.zIndex = '2147483645';
|
||||
|
||||
// 点击覆盖层恢复区域
|
||||
overlay.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
removeAreaOverlay(overlay);
|
||||
});
|
||||
|
||||
document.body.appendChild(overlay);
|
||||
areaOverlays.push(overlay);
|
||||
|
||||
// 添加到模糊元素集合(用于统一管理强度)
|
||||
blurredElements.add(overlay);
|
||||
|
||||
console.log('[BlurText] Area overlay created, total overlays:', areaOverlays.length);
|
||||
}
|
||||
|
||||
// 移除区域覆盖层
|
||||
function removeAreaOverlay(overlay) {
|
||||
const index = areaOverlays.indexOf(overlay);
|
||||
if (index > -1) {
|
||||
areaOverlays.splice(index, 1);
|
||||
}
|
||||
blurredElements.delete(overlay);
|
||||
if (overlay.parentNode) {
|
||||
overlay.parentNode.removeChild(overlay);
|
||||
}
|
||||
console.log('[BlurText] Area overlay removed, remaining:', areaOverlays.length);
|
||||
}
|
||||
|
||||
// 隐藏绘制框
|
||||
function hideDrawingBox() {
|
||||
if (drawingBox && drawingBox.parentNode) {
|
||||
drawingBox.parentNode.removeChild(drawingBox);
|
||||
drawingBox = null;
|
||||
}
|
||||
isDrawing = false;
|
||||
}
|
||||
|
||||
// ========== 区域模式函数结束 ==========
|
||||
|
||||
// 更新所有已模糊元素的强度
|
||||
function updateAllBlurIntensity() {
|
||||
blurredElements.forEach(element => {
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
|
||||
.mode-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
@@ -243,6 +243,10 @@
|
||||
<span class="mode-icon">📝</span>
|
||||
<span class="mode-label">文本选择</span>
|
||||
</button>
|
||||
<button class="mode-btn" id="modeArea" data-mode="area">
|
||||
<span class="mode-icon">🔲</span>
|
||||
<span class="mode-label">区域模式</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
13
popup.js
13
popup.js
@@ -13,6 +13,7 @@ const intensityValue = document.getElementById('intensityValue');
|
||||
const statusDiv = document.getElementById('status');
|
||||
const modeElementBtn = document.getElementById('modeElement');
|
||||
const modeSelectionBtn = document.getElementById('modeSelection');
|
||||
const modeAreaBtn = document.getElementById('modeArea');
|
||||
const usageTip = document.getElementById('usageTip');
|
||||
|
||||
// 从存储中加载模糊强度
|
||||
@@ -41,7 +42,7 @@ blurIntensitySlider.addEventListener('input', (e) => {
|
||||
});
|
||||
|
||||
// 模式切换
|
||||
[modeElementBtn, modeSelectionBtn].forEach(btn => {
|
||||
[modeElementBtn, modeSelectionBtn, modeAreaBtn].forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const mode = btn.dataset.mode;
|
||||
currentMode = mode;
|
||||
@@ -75,7 +76,7 @@ function updateUsageTip(mode) {
|
||||
3. 点击元素进行模糊<br>
|
||||
4. 再次点击取消模糊
|
||||
`;
|
||||
} else {
|
||||
} else if (mode === 'selection') {
|
||||
usageTip.innerHTML = `
|
||||
<strong>文本选择模式:</strong><br>
|
||||
1. 点击"开启模糊模式"<br>
|
||||
@@ -83,6 +84,14 @@ function updateUsageTip(mode) {
|
||||
3. 点击浮动按钮模糊文本<br>
|
||||
4. 可多次选择和模糊
|
||||
`;
|
||||
} else if (mode === 'area') {
|
||||
usageTip.innerHTML = `
|
||||
<strong>区域模式:</strong><br>
|
||||
1. 点击"开启模糊模式"<br>
|
||||
2. 拖动鼠标绘制矩形区域<br>
|
||||
3. 释放鼠标创建模糊区域<br>
|
||||
4. 点击区域恢复
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user