拖拽图片进行以图搜图,可自定义四个方向的搜索引擎
// ==UserScript==
// @name 拖拽搜图
// @namespace http://tampermonkey.net/
// @version 0.2
// @description 拖拽图片进行以图搜图,可自定义四个方向的搜索引擎
// @author PaulW47
// @match *://*/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @license MIT
// ==/UserScript==
(function() {
'use strict';
let isDragging = false;
let initialMouseX = 0;
let initialMouseY = 0;
// 搜索引擎URL模板
const searchEngines = {
google: "https://lens.google.com/uploadbyurl?url=",
baidu: "https://graph.baidu.com/details?isfromtusoupc=1&tn=pc&carousel=0&promotion_name=pc_image_shituindex&extUiData%5bisLogoShow%5d=1&image=",
yandex: "https://yandex.com/images/search?rpt=imageview&url="
};
// 默认方向设置
const defaultDirections = {
topLeft: 'baidu',
topRight: 'google',
bottomLeft: 'yandex',
bottomRight: 'google'
};
// 获取保存的设置或使用默认值
let directions = GM_getValue('searchDirections', defaultDirections);
// 在搜索引擎定义后添加显示名称映射
const engineDisplayNames = {
google: 'Google搜索',
baidu: '百度搜索',
yandex: 'Yandex搜索'
};
// 创建提示元素
const dragTip = document.createElement('div');
dragTip.style.cssText = `
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 10px 20px;
border-radius: 4px;
font-family: Arial, sans-serif;
font-size: 14px;
z-index: 10000;
display: none;
`;
document.body.appendChild(dragTip);
// 创建设置面板
function createSettingsPanel() {
const panel = document.createElement('div');
panel.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 20px rgba(0,0,0,0.2);
z-index: 10001;
display: none;
font-family: Arial, sans-serif;
`;
const title = document.createElement('h3');
title.textContent = '搜索引擎设置';
title.style.margin = '0 0 15px 0';
const directionConfigs = [
{ key: 'topLeft', name: '左上' },
{ key: 'topRight', name: '右上' },
{ key: 'bottomLeft', name: '左下' },
{ key: 'bottomRight', name: '右下' }
];
const container = document.createElement('div');
container.style.cssText = `
display: grid;
grid-template-columns: auto auto;
gap: 10px;
margin-bottom: 15px;
`;
directionConfigs.forEach(dir => {
const label = document.createElement('label');
label.textContent = `${dir.name}:`;
label.style.marginRight = '10px';
const select = document.createElement('select');
select.id = `setting-${dir.key}`;
select.style.cssText = `
padding: 5px;
border-radius: 4px;
border: 1px solid #ddd;
width: 100px;
`;
[
{ value: 'google', text: '谷歌' },
{ value: 'baidu', text: '百度' },
{ value: 'yandex', text: 'Yandex' }
].forEach(option => {
const opt = document.createElement('option');
opt.value = option.value;
opt.textContent = option.text;
select.appendChild(opt);
});
const wrapper = document.createElement('div');
wrapper.style.display = 'flex';
wrapper.appendChild(label);
wrapper.appendChild(select);
container.appendChild(wrapper);
});
const buttonContainer = document.createElement('div');
buttonContainer.style.textAlign = 'right';
const saveButton = document.createElement('button');
saveButton.textContent = '保存';
saveButton.style.cssText = `
margin-right: 10px;
padding: 5px 15px;
border: none;
border-radius: 4px;
background: #4CAF50;
color: white;
cursor: pointer;
`;
const cancelButton = document.createElement('button');
cancelButton.textContent = '取消';
cancelButton.style.cssText = `
padding: 5px 15px;
border: none;
border-radius: 4px;
background: #f44336;
color: white;
cursor: pointer;
`;
buttonContainer.appendChild(saveButton);
buttonContainer.appendChild(cancelButton);
panel.appendChild(title);
panel.appendChild(container);
panel.appendChild(buttonContainer);
// 保存按钮事件
saveButton.addEventListener('click', () => {
const newSettings = {};
directionConfigs.forEach(dir => {
newSettings[dir.key] = document.getElementById(`setting-${dir.key}`).value;
});
GM_setValue('searchDirections', newSettings);
directions = newSettings;
panel.style.display = 'none';
});
// 取消按钮事件
cancelButton.addEventListener('click', () => {
panel.style.display = 'none';
});
return panel;
}
const settingsPanel = createSettingsPanel();
document.body.appendChild(settingsPanel);
// 修改菜单命令
GM_registerMenuCommand('设置搜索引擎', () => {
// 显示设置面板并设置当前值
const currentSettings = GM_getValue('searchDirections', defaultDirections);
Object.keys(currentSettings).forEach(key => {
const select = document.getElementById(`setting-${key}`);
if (select) {
select.value = currentSettings[key];
}
});
settingsPanel.style.display = 'block';
});
// 监听拖动开始
document.addEventListener('dragstart', function(e) {
const imgElement = e.target;
if (imgElement.tagName === 'IMG') {
isDragging = true;
initialMouseX = e.clientX;
initialMouseY = e.clientY;
// 显示初始方向的提示
const searchEngine = directions.topRight; // 默认显示向右上方向的搜索引擎
dragTip.textContent = engineDisplayNames[searchEngine];
dragTip.style.display = 'block';
}
});
// 监听拖动结束
document.addEventListener('dragend', function(e) {
if (!isDragging) return;
const imgElement = e.target;
if (imgElement.tagName === 'IMG') {
const currentMouseX = e.clientX;
const currentMouseY = e.clientY;
const deltaX = currentMouseX - initialMouseX;
const deltaY = currentMouseY - initialMouseY;
// 获取图片URL
let imageUrl = imgElement.src;
// 确保图片URL是完整的
if (imageUrl.startsWith('//')) {
imageUrl = 'https:' + imageUrl;
} else if (imageUrl.startsWith('/')) {
imageUrl = window.location.origin + imageUrl;
}
// 编码图片URL
const encodedUrl = encodeURIComponent(imageUrl);
let searchEngine;
// 判断拖动方向
if (deltaX < 0) {
// 向左
searchEngine = deltaY < 0 ? directions.topLeft : directions.bottomLeft;
} else {
// 向右
searchEngine = deltaY < 0 ? directions.topRight : directions.bottomRight;
}
// 打开搜索页面
if (searchEngine) {
window.open(searchEngines[searchEngine] + encodedUrl, '_blank');
}
}
isDragging = false;
dragTip.style.display = 'none';
});
// 修改拖动事件监听
document.addEventListener('drag', function(e) {
if (!isDragging) return;
const imgElement = e.target;
if (imgElement.tagName === 'IMG') {
const currentMouseX = e.clientX;
const currentMouseY = e.clientY;
const deltaX = currentMouseX - initialMouseX;
const deltaY = currentMouseY - initialMouseY;
let searchEngine;
// 判断拖动方向
if (deltaX < 0) {
// 向左
searchEngine = deltaY < 0 ? directions.topLeft : directions.bottomLeft;
} else {
// 向右
searchEngine = deltaY < 0 ? directions.topRight : directions.bottomRight;
}
// 更新提示文本
if (searchEngine) {
dragTip.textContent = engineDisplayNames[searchEngine];
dragTip.style.display = 'block';
}
}
});
})();