// ==UserScript==
// @name 123pan JSON秒传链接工具
// @namespace http://tampermonkey.net/
// @version 1.1.2
// @description 优化版:更稳定
// @author Tocpomk
// @match *://*.www.123pan.com
// @match *://www.123pan.cn
// @match *://*.123865.com
// @match *://*.123684.com
// @match *://*.123912.com
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @run-at document-end
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 添加样式
GM_addStyle(`
#json-tool-float-btn {
position: fixed;
top: 50%;
right: 20px;
transform: translateY(-50%);
width: 60px;
height: 60px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
border-radius: 50%;
color: white;
font-size: 24px;
cursor: pointer;
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
z-index: 9999;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
user-select: none;
animation: pulse 2s infinite;
touch-action: none;
}
#json-tool-float-btn:hover {
transform: translateY(-50%) scale(1.1);
box-shadow: 0 6px 20px rgba(0,0,0,0.3);
}
#json-tool-float-btn:active {
transform: translateY(-50%) scale(0.95);
}
#json-tool-float-btn.dragging {
opacity: 0.8;
cursor: grabbing;
transform: none !important;
box-shadow: 0 8px 25px rgba(0,0,0,0.4);
}
#json-tool-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
visibility: hidden;
transition: all 0.4s cubic-bezier(0.32, 0.72, 0, 1);
pointer-events: none;
}
#json-tool-modal.show {
opacity: 1;
visibility: visible;
pointer-events: all;
}
#json-tool-content {
width: 90%;
height: 90%;
max-width: 1200px;
background: white;
border-radius: 16px;
box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
display: flex;
flex-direction: column;
overflow: hidden;
transform: translateY(50px) scale(0.95);
opacity: 0;
transition: all 0.5s cubic-bezier(0.32, 0.72, 0, 1);
}
#json-tool-modal.show #json-tool-content {
transform: translateY(0) scale(1);
opacity: 1;
}
#json-tool-close {
position: absolute;
top: 18px;
right: 18px;
background: rgba(0,0,0,0.2);
border: none;
color: white;
font-size: 26px;
cursor: pointer;
width: 42px;
height: 42px;
border-radius: 50%;
transition: all 0.3s ease;
z-index: 10001;
display: flex;
align-items: center;
justify-content: center;
}
#json-tool-close:hover {
background: rgba(0,0,0,0.5);
transform: scale(1.15) rotate(90deg);
}
#json-tool-iframe {
width: 100%;
height: 100%;
border: none;
border-radius: 0 0 16px 16px;
}
#json-tool-header {
height: 60px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
color: white;
font-weight: bold;
font-size: 18px;
}
#json-tool-title {
display: flex;
align-items: center;
gap: 12px;
}
#json-tool-title svg {
width: 24px;
height: 24px;
fill: white;
}
.json-tool-drag-handle {
width: 100%;
height: 30px;
position: absolute;
top: 0;
left: 0;
cursor: move;
z-index: 1;
}
/* 响应式设计 */
@media (max-width: 768px) {
#json-tool-content {
width: 95%;
height: 95%;
}
#json-tool-float-btn {
width: 50px;
height: 50px;
font-size: 20px;
right: 15px;
}
#json-tool-header {
padding: 0 15px;
height: 50px;
font-size: 16px;
}
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(102, 126, 234, 0.6); }
70% { box-shadow: 0 0 0 12px rgba(102, 126, 234, 0); }
100% { box-shadow: 0 0 0 0 rgba(102, 126, 234, 0); }
}
.json-tool-tooltip {
position: absolute;
top: -45px;
left: 50%;
transform: translateX(-50%);
background: rgba(0,0,0,0.7);
color: white;
padding: 8px 12px;
border-radius: 6px;
font-size: 14px;
white-space: nowrap;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s ease;
}
.json-tool-tooltip::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border-width: 6px;
border-style: solid;
border-color: rgba(0,0,0,0.7) transparent transparent transparent;
}
#json-tool-float-btn:hover .json-tool-tooltip {
opacity: 1;
}
`);
// 创建悬浮按钮
function createFloatButton() {
const btn = document.createElement('button');
btn.id = 'json-tool-float-btn';
btn.innerHTML = `
🔗
<div class="json-tool-tooltip">拖拽移动位置</div>
`;
btn.title = 'JSON秒传链接工具';
// 从存储中获取位置
const savedPosition = GM_getValue('floatButtonPosition', null);
if (savedPosition) {
btn.style.left = `${savedPosition.x}px`;
btn.style.top = `${savedPosition.y}px`;
btn.style.right = 'auto';
btn.style.transform = 'none';
}
// 添加拖拽功能
let isDragging = false;
let dragOffsetX, dragOffsetY;
btn.addEventListener('mousedown', startDrag);
btn.addEventListener('touchstart', startDragTouch, { passive: false });
function startDrag(e) {
e.preventDefault();
isDragging = true;
btn.classList.add('dragging');
const rect = btn.getBoundingClientRect();
dragOffsetX = e.clientX - rect.left;
dragOffsetY = e.clientY - rect.top;
document.addEventListener('mousemove', onDrag);
document.addEventListener('mouseup', stopDrag);
}
function startDragTouch(e) {
if (e.touches.length !== 1) return;
e.preventDefault();
isDragging = true;
btn.classList.add('dragging');
const touch = e.touches[0];
const rect = btn.getBoundingClientRect();
dragOffsetX = touch.clientX - rect.left;
dragOffsetY = touch.clientY - rect.top;
document.addEventListener('touchmove', onDragTouch, { passive: false });
document.addEventListener('touchend', stopDrag);
}
function onDrag(e) {
if (!isDragging) return;
e.preventDefault();
updatePosition(e.clientX, e.clientY);
}
function onDragTouch(e) {
if (!isDragging || e.touches.length !== 1) return;
e.preventDefault();
const touch = e.touches[0];
updatePosition(touch.clientX, touch.clientY);
}
function updatePosition(clientX, clientY) {
const x = clientX - dragOffsetX;
const y = clientY - dragOffsetY;
// 限制按钮不超出屏幕边界
const maxX = window.innerWidth - btn.offsetWidth;
const maxY = window.innerHeight - btn.offsetHeight;
btn.style.left = `${Math.max(0, Math.min(x, maxX))}px`;
btn.style.top = `${Math.max(0, Math.min(y, maxY))}px`;
btn.style.right = 'auto';
btn.style.transform = 'none';
}
function stopDrag() {
if (!isDragging) return;
isDragging = false;
btn.classList.remove('dragging');
// 保存位置
GM_setValue('floatButtonPosition', {
x: parseInt(btn.style.left),
y: parseInt(btn.style.top)
});
document.removeEventListener('mousemove', onDrag);
document.removeEventListener('touchmove', onDragTouch);
document.removeEventListener('mouseup', stopDrag);
document.removeEventListener('touchend', stopDrag);
}
// 点击事件
btn.addEventListener('click', function(e) {
if (!isDragging) {
showModal();
}
});
document.body.appendChild(btn);
return btn;
}
// 创建弹窗
function createModal() {
const modal = document.createElement('div');
modal.id = 'json-tool-modal';
modal.innerHTML = `
<div id="json-tool-content">
<div class="json-tool-drag-handle"></div>
<div id="json-tool-header">
<div id="json-tool-title">
<svg viewBox="0 0 24 24">
<path d="M14,11H10V9h4V11z M14,8H10V6h4V8z M20,4V20H4V4H20 M20,2H4C2.9,2,2,2.9,2,4v16c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V4 C22,2.9,21.1,2,20,2L20,2z M16,15H8v-2h8V15z M16,18H8v-2h8V18z M6,15H4v2h2V15z M6,18H4v2h2V18z M6,6H4v8h2V6z"></path>
</svg>
<span>JSON秒传链接工具</span>
</div>
<button id="json-tool-close">×</button>
</div>
<iframe id="json-tool-iframe" src="https://123.487510.xyz/"></iframe>
</div>
`;
// 关闭按钮事件
modal.querySelector('#json-tool-close').addEventListener('click', hideModal);
// 点击背景关闭
modal.addEventListener('click', function(e) {
if (e.target === modal) {
hideModal();
}
});
// ESC键关闭
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
hideModal();
}
});
// 添加弹窗拖拽功能
let isModalDragging = false;
let modalStartX, modalStartY;
const dragHandle = modal.querySelector('.json-tool-drag-handle');
const content = modal.querySelector('#json-tool-content');
dragHandle.addEventListener('mousedown', startModalDrag);
function startModalDrag(e) {
isModalDragging = true;
modalStartX = e.clientX;
modalStartY = e.clientY;
content.style.transition = 'none'; // 拖动时禁用过渡效果
document.addEventListener('mousemove', onModalDrag);
document.addEventListener('mouseup', stopModalDrag);
}
function onModalDrag(e) {
if (!isModalDragging) return;
const deltaX = e.clientX - modalStartX;
const deltaY = e.clientY - modalStartY;
content.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
}
function stopModalDrag() {
if (!isModalDragging) return;
isModalDragging = false;
content.style.transition = '';
content.style.transform = '';
document.removeEventListener('mousemove', onModalDrag);
document.removeEventListener('mouseup', stopModalDrag);
}
document.body.appendChild(modal);
return modal;
}
// 显示弹窗
function showModal() {
const modal = document.getElementById('json-tool-modal');
if (modal) {
document.body.style.overflow = 'hidden';
setTimeout(() => {
modal.classList.add('show');
}, 10);
}
}
// 隐藏弹窗
function hideModal() {
const modal = document.getElementById('json-tool-modal');
if (modal) {
modal.classList.remove('show');
setTimeout(() => {
document.body.style.overflow = '';
}, 300); // 匹配动画时间
}
}
// 初始化
function init() {
// 等待页面加载完成
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
createFloatButton();
createModal();
});
} else {
createFloatButton();
createModal();
}
}
// 启动脚本
init();
})();