顯示所有方格的顏色順序。
// ==UserScript==
// @name [Tool] Arealme - Color Hue Test
// @namespace -
// @version 1.0
// @description 顯示所有方格的顏色順序。
// @author LianSheng
// @match https://www.arealme.com/color-hue-test/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=arealme.com
// @grant none
// @license MIT
// ==/UserScript==
(function () {
/**
* 將文字格式 `rgb(r, g, b)` 轉成陣列 `[r, g, b]`.
* @param {string} raw
* @returns {Array<number>}
*/
function toRGB(raw) {
raw = raw.replace("rgb(", "").replace(")", "");
return raw.split(", ").map(Number);
}
/**
* 選擇排序依據的色彩通道.
* @param {Array<number>} a `A[r, g, b]`
* @param {Array<number>} b `B[r, g, b]`
* @returns {number} Array index
*/
function selectCriteriaChannel(a, b) {
for (let i = 0; i <= 2; i++) {
if (a[i] !== b[i]) {
return i;
}
}
}
/**
* 計算每個 box 的順序,並將其值附加至屬性 `ord`.
* @param {Array<HTMLElement>} boxes
* @returns {void}
*/
function sortBoxes(boxes) {
const criteria = selectCriteriaChannel(
toRGB(boxes[0].style.backgroundColor),
toRGB(boxes[boxes.length - 1].style.backgroundColor)
);
const firstBox = boxes[0];
boxes.sort((a, b) => toRGB(a.style.backgroundColor)[criteria] - toRGB(b.style.backgroundColor)[criteria]);
if (boxes[0] !== firstBox) {
boxes.reverse();
}
boxes.forEach((each, idx) => each.setAttribute("ord", idx + 1));
}
/**
* 標記所有 box.
* @param {Array<HTMLElement>} boxes
* @returns {void}
*/
function markBoxes(boxes) {
boxes.forEach(b => b.classList.add("modified"));
}
/**
* 追加 [Show Hint] 按鈕到原本的打勾按鈕後面.
* @returns {void}
*/
function appendHintButton() {
const confirm = document.querySelector(".dp-confirm-btn");
const hint = document.createElement("button");
hint.classList.add("show-hint");
hint.style.backgroundColor = "red";
hint.style.color = "black";
hint.style.margin = "5em 1em";
hint.style.padding = "6px 12px";
hint.style.fontSize = "1.5rem";
hint.style.fontWeight = "bold";
hint.style.textShadow = "-1px 0 white, 0 1px white, 1px 0 white, 0 -1px white";
hint.style.border = "4px solid #9999";
hint.innerText = "Show Answer";
hint.onclick = _ => {
showHint();
solveHandler();
};
confirm.insertAdjacentElement("afterend", hint);
confirm.addEventListener("click", solveHandler);
}
/**
* 在所有 box 上顯示答案.
* @returns {void}
*/
function showHint() {
const boxes = [...document.querySelectorAll(".dp-box")];
boxes.forEach(each => {
each.innerText = each.getAttribute("ord");
each.style.fontWeight = "bold";
each.style.textShadow = "-1px 0 white, 0 1px white, 1px 0 white, 0 -1px white";
});
}
/**
* 主要程式
* @returns {void}
*/
function solveHandler() {
const container = document.querySelector(".dp-box-container");
if (container) {
const boxes = [...document.querySelectorAll(".dp-box")];
const hint = document.querySelector(".show-hint");
if (boxes[0].classList.contains("modified")) {
return;
}
if (!hint) {
appendHintButton();
}
markBoxes(boxes);
sortBoxes(boxes);
return;
}
setTimeout(solveHandler, 100);
}
solveHandler();
})();