// ==UserScript==
// @name K線倒數計時器(滑鼠穿透 + 重新倒數前三秒長亮 + 最後10秒閃爍)
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 所有網頁都顯示,每次倒數重新開始的前三秒長亮 + 最後10秒直接切換原色閃爍,且滑鼠無視背景
// @author issac
// @match *://*/*
// @license GPL-3.0 License
// @grant none
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
function initTimer() {
const timerContainer = document.createElement('div');
timerContainer.id = "timerContainer";
document.body.appendChild(timerContainer);
const style = document.createElement('style');
style.innerHTML = `
#timerContainer {
position: fixed;
bottom: 0;
left: 50%;
transform: translateX(-50%);
display: flex;
align-items: stretch;
gap: 8px;
background: rgba(0,0,0,0.7);
padding: 8px 12px;
border-radius: 10px 10px 0 0;
font-family: monospace;
color: white;
z-index: 999999;
pointer-events: none; /* 背景穿透 */
}
#timerContainer * {
pointer-events: auto; /* 讓內部元素可點擊 */
}
.timer {
padding: 4px 8px;
border-radius: 5px;
text-align: center;
font-size: 14px;
cursor: default;
display: flex;
flex-direction: column;
justify-content: center;
}
.timer span {
display: block;
}
#currentTime {
padding: 4px 8px;
background: rgba(255,255,255,0.1);
border-radius: 5px;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
}
#toggleBtn {
position: fixed;
bottom: 5px;
right: 5px;
background: rgba(0,0,0,0.7);
color: white;
padding: 5px 10px;
border-radius: 5px;
font-size: 12px;
cursor: pointer;
z-index: 1000000;
pointer-events: auto; /* 讓按鈕可點擊 */
}
#settingsPanel {
position: fixed;
bottom: 40px;
right: 5px;
background: rgba(0,0,0,0.8);
color: white;
padding: 10px;
border-radius: 5px;
font-size: 12px;
display: none;
z-index: 1000000;
pointer-events: auto; /* 讓設定面板可點擊 */
}
#settingsPanel label {
display: block;
margin-top: 5px;
}
`;
document.head.appendChild(style);
const currentTimeDiv = document.createElement('div');
currentTimeDiv.id = "currentTime";
currentTimeDiv.innerText = "--:--:--";
timerContainer.appendChild(currentTimeDiv);
const toggleBtn = document.createElement('div');
toggleBtn.id = "toggleBtn";
toggleBtn.innerText = "倒數計時器設定";
document.body.appendChild(toggleBtn);
const settingsPanel = document.createElement('div');
settingsPanel.id = "settingsPanel";
document.body.appendChild(settingsPanel);
const intervals = [
{min: 1, color: "#ff4d4d"},
{min: 5, color: "#4da6ff"},
{min: 15, color: "#4dff88"},
{min: 30, color: "#ffd24d"},
{min: 60, color: "#b84dff"}
];
intervals.forEach(item => {
const div = document.createElement("div");
div.className = "timer";
div.id = "timer_" + item.min;
div.dataset.baseColor = item.color;
div.style.background = item.color + "33";
div.innerHTML = `${item.min} 分--:--`;
timerContainer.appendChild(div);
const label = document.createElement("label");
label.innerHTML = `${item.min} 分顏色: `;
settingsPanel.appendChild(label);
});
const sizeLabel = document.createElement("label");
sizeLabel.innerHTML = `字體大小: px`;
settingsPanel.appendChild(sizeLabel);
const paddingLabel = document.createElement("label");
paddingLabel.innerHTML = `間距: px`;
settingsPanel.appendChild(paddingLabel);
toggleBtn.onclick = () => {
settingsPanel.style.display = settingsPanel.style.display === "block" ? "none" : "block";
};
document.getElementById("fontSize").addEventListener("input", function() {
document.querySelectorAll(".timer").forEach(div => {
div.style.fontSize = this.value + "px";
});
currentTimeDiv.style.fontSize = this.value + "px";
});
document.getElementById("paddingSize").addEventListener("input", function() {
timerContainer.style.gap = this.value + "px";
});
settingsPanel.querySelectorAll("input[type=color]").forEach(input => {
input.addEventListener("change", function() {
const min = this.getAttribute("data-min");
const div = document.getElementById("timer_" + min);
div.dataset.baseColor = this.value;
div.style.background = this.value + "33";
});
});
let blinkFlag = false;
function updateTimers() {
const now = new Date();
const seconds = now.getSeconds();
const minutes = now.getMinutes();
const hours = now.getHours();
currentTimeDiv.innerText = `${hours.toString().padStart(2,'0')}:${minutes.toString().padStart(2,'0')}:${seconds.toString().padStart(2,'0')}`;
blinkFlag = !blinkFlag;
intervals.forEach(item => {
let totalSeconds = item.min * 60;
let elapsedSeconds = (minutes % item.min) * 60 + seconds;
let remaining = totalSeconds - elapsedSeconds;
if (remaining < 0) remaining = 0;
const m = Math.floor(remaining / 60).toString().padStart(2, '0');
const s = (remaining % 60).toString().padStart(2, '0');
const timerDiv = document.querySelector(`#timer_${item.min}`);
timerDiv.querySelector("span:nth-child(2)").innerText = `${m}:${s}`;
if (remaining >= totalSeconds - 3) {
// 重新倒數開始的前三秒長亮
timerDiv.style.background = item.color;
} else if (remaining <= 10) {
// 最後10秒閃爍
timerDiv.style.background = blinkFlag ? item.color : item.color + "33";
} else {
timerDiv.style.background = item.color + "33";
}
});
}
setInterval(updateTimers, 500);
updateTimers();
}
if (document.readyState === "complete" || document.readyState === "interactive") {
initTimer();
} else {
window.addEventListener("DOMContentLoaded", initTimer);
}
})();