拖拽弹窗,滑块设置分钟+秒,右上角显示剩余时间
当前为
// ==UserScript==
// @name 定时关闭网页
// @namespace https://github.com/yingchen6
// @version 1.8.7.2
// @description 拖拽弹窗,滑块设置分钟+秒,右上角显示剩余时间
// @author yingchen6
// @match *://*/*
// @grant GM_registerMenuCommand
// @license MIT
// ==/UserScript==
(function(){
'use strict';
let timerId = null;
let remainingSeconds = 0;
let totalSeconds = 0;
let displayBox = null;
let canvas = null;
let paused = false;
function formatTime(seconds){
const m = Math.floor(seconds/60);
const s = seconds%60;
return `${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}`;
}
function showDisplayBox(minutes){
if(displayBox) displayBox.remove();
totalSeconds = remainingSeconds = minutes*60;
paused = false;
displayBox = document.createElement("div");
displayBox.id = "display-box";
displayBox.style.position = "fixed";
displayBox.style.top = "20px";
displayBox.style.left = "20px";
displayBox.style.width = "160px";
displayBox.style.height = "160px";
displayBox.style.background = "rgba(30,30,30,0.7)";
displayBox.style.backdropFilter = "blur(10px)";
displayBox.style.borderRadius = "50%";
displayBox.style.display = "flex";
displayBox.style.alignItems = "center";
displayBox.style.justifyContent = "center";
displayBox.style.boxShadow = "0 8px 30px rgba(0,0,0,0.6)";
displayBox.style.cursor = "grab";
displayBox.style.zIndex = "999999";
displayBox.style.userSelect = "none";
document.body.appendChild(displayBox);
// Canvas环形进度
canvas = document.createElement("canvas");
canvas.width = 160;
canvas.height = 160;
canvas.style.position = "absolute";
canvas.style.top = "0";
canvas.style.left = "0";
displayBox.appendChild(canvas);
const timeLabel = document.createElement("div");
timeLabel.id = "time-label";
timeLabel.style.fontSize = "28px";
timeLabel.style.fontWeight = "bold";
timeLabel.style.color = "#00ffcc";
timeLabel.style.zIndex = "2";
displayBox.appendChild(timeLabel);
const pauseBtn = document.createElement("button");
pauseBtn.id = "pause-btn";
pauseBtn.textContent = "暂停";
pauseBtn.style.position = "absolute";
pauseBtn.style.bottom = "10px";
pauseBtn.style.fontSize = "14px";
pauseBtn.style.padding = "4px 10px";
pauseBtn.style.border = "none";
pauseBtn.style.borderRadius = "8px";
pauseBtn.style.background = "linear-gradient(135deg,#ff9a00,#ffdc00)";
pauseBtn.style.color = "#222";
pauseBtn.style.fontWeight = "bold";
pauseBtn.style.cursor = "pointer";
pauseBtn.style.boxShadow = "0 4px 12px rgba(0,0,0,0.3)";
pauseBtn.onmouseover = ()=>{ pauseBtn.style.opacity = "0.8"; };
pauseBtn.onmouseout = ()=>{ pauseBtn.style.opacity = "1"; };
displayBox.appendChild(pauseBtn);
pauseBtn.addEventListener("click",(e)=>{
e.stopPropagation();
paused = !paused;
pauseBtn.textContent = paused ? "继续" : "暂停";
});
// 拖拽 + 双击修改
let isDown = false;
let startX=0,startY=0;
let offsetX=0,offsetY=0;
let downTime=0;
displayBox.addEventListener("mousedown",(e)=>{
isDown = true;
startX = e.clientX;
startY = e.clientY;
offsetX = displayBox.offsetLeft;
offsetY = displayBox.offsetTop;
downTime = Date.now();
displayBox.style.cursor="grabbing";
});
document.addEventListener("mousemove",(e)=>{
if(!isDown) return;
const dx = e.clientX - startX;
const dy = e.clientY - startY;
displayBox.style.left = offsetX+dx+"px";
displayBox.style.top = offsetY+dy+"px";
});
document.addEventListener("mouseup",(e)=>{
if(!isDown) return;
isDown = false;
displayBox.style.cursor="grab";
const elapsed = Date.now()-downTime;
if(elapsed<300){
showTimeSetting(Math.floor(remainingSeconds/60), remainingSeconds%60);
}
});
startCountdown();
}
function startCountdown(){
if(timerId) clearInterval(timerId);
const label = document.getElementById("time-label");
timerId = setInterval(()=>{
if(!paused){
remainingSeconds--;
if(remainingSeconds<=0){
clearInterval(timerId);
window.location.href = "about:blank";
return;
}
label.textContent = formatTime(remainingSeconds);
// 绘制环形进度
const ctx = canvas.getContext("2d");
ctx.clearRect(0,0,canvas.width,canvas.height);
const center = canvas.width/2;
const radius = 70;
// 背景环
ctx.beginPath();
ctx.arc(center,center,radius,0,2*Math.PI);
ctx.strokeStyle = "rgba(255,255,255,0.2)";
ctx.lineWidth = 12;
ctx.stroke();
// 渐变进度
const fraction = remainingSeconds/totalSeconds;
const grad = ctx.createLinearGradient(0,0,canvas.width,canvas.height);
grad.addColorStop(0,"#ff6ec7");
grad.addColorStop(0.5,"#00ffe0");
grad.addColorStop(1,"#fffd00");
ctx.beginPath();
ctx.arc(center,center,radius,-Math.PI/2,-Math.PI/2 + 2*Math.PI*fraction);
ctx.strokeStyle = grad;
ctx.lineWidth = 12;
ctx.lineCap = "round";
ctx.shadowBlur = 10;
ctx.shadowColor = "#00ffe0";
ctx.stroke();
}
},1000);
}
function showTimeSetting(defaultMin=30, defaultSec=0){
const wrapper = document.createElement("div");
wrapper.innerHTML = `
<div style="display:flex;flex-direction:column;align-items:center;gap:15px;padding:20px;background:rgba(20,20,20,0.9);border-radius:20px;backdrop-filter:blur(12px);">
<h2 style="color:#ffdd55;font-size:22px;margin:0;">设置倒计时</h2>
<div style="display:flex;gap:10px;align-items:center;">
<input id="minRange" type="range" min="0" max="180" value="${defaultMin}" style="width:180px;">
<span id="minLabel" style="color:#00ffe0;font-weight:bold;">${defaultMin} 分钟</span>
</div>
<div style="display:flex;gap:10px;align-items:center;">
<input id="secRange" type="range" min="0" max="59" value="${defaultSec}" style="width:180px;">
<span id="secLabel" style="color:#00ffe0;font-weight:bold;">${defaultSec} 秒</span>
</div>
</div>
`;
swal({
content: wrapper,
buttons: {
cancel:{text:"取消",className:"swal-btn-cancel"},
confirm:{text:"确定",className:"swal-btn-confirm"}
}
}).then((ok)=>{
if(!ok) return;
const minutes = parseInt(wrapper.querySelector("#minRange").value);
const seconds = parseInt(wrapper.querySelector("#secRange").value);
showDisplayBox(minutes+seconds/60);
});
const minRange = wrapper.querySelector("#minRange");
const minLabel = wrapper.querySelector("#minLabel");
minRange.addEventListener("input",()=>{ minLabel.textContent = minRange.value+" 分钟"; });
const secRange = wrapper.querySelector("#secRange");
const secLabel = wrapper.querySelector("#secLabel");
secRange.addEventListener("input",()=>{ secLabel.textContent = secRange.value+" 秒"; });
}
if(typeof GM_registerMenuCommand!=="undefined"){
GM_registerMenuCommand("开始计时",()=>{ showTimeSetting(30,0); });
}
})();