Greasy Fork is available in English.

Color Picker

Color picker for Sketchful

Tính đến 29-06-2020. Xem phiên bản mới nhất.

// ==UserScript==
// @name        Color Picker
// @namespace   https://greasyfork.org/users/281093
// @match       https://sketchful.io/*
// @grant       none
// @version     0.2.1
// @author      Bell
// @description Color picker for Sketchful 
// @run-at      document-end
// jshint esversion: 6
// ==/UserScript==

let storedPalettes = JSON.parse(localStorage.getItem('palettes'));
let palettes = storedPalettes || [
    [],
    [
        "#3a3a3c", "#8e8e93", "#f8f9fa", "#ffadad", "#ffd6a5", "#fdffb6", "#caffbf", "#9bf6ff", "#a0c4ff", "#bdb2ff", "#ffc6ff", "#fdad88", "#9e5425",
        "#2c2c2e", "#636366", "#e0e0e0", "#ff7070", "#f3a220", "#f9e079", "#049d6f", "#92ddea", "#6dafe0", "#ab87ff", "#ff87ab", "#e38a5e", "#5e320d",
        "#1c1c1e", "#48484a", "#c2c2c2", "#f54d4d", "#dc8700", "#f0c808", "#00766a", "#219bc3", "#548bbc", "#715aff", "#ff5d8f", "#d1754e", "#421e06"
    ],
];

const canvas = document.querySelector("#canvas");
const ctx = canvas.getContext("2d");
const gameTools = document.querySelector("#gameTools");
const chatBox = document.querySelector("#gameChat");
const colorPickerWrapper = document.createElement("div");
const colorInput = document.createElement("input");
const colorPicker = document.createElement("input");
const colorButtons = document.querySelectorAll(".gameToolsColor");

const inputStyle = `margin: 5px 0;
                    height: 20px;
                    width: 50%;
                    text-align: center;
                    border: none;
                    font-weight: 800;
                    border-radius: 5px;
                    background-color: #CBCBCB;`;

const wrapperStyle = `position: absolute;
                      margin: 5px 50%;
                      height: 20px;
                      width: 30px;
                      border-radius: 5px;`;

document.querySelector("#gameToolsSlider").style.top = "77px";
canvas.addEventListener('pointerdown', pickCanvasColor, false);
gameTools.style.height = "200px";

const config = {
    attributes: true,
    childList: false,
    subtree: false
};

const heightObserver = new MutationObserver(adjustChatSize);

heightObserver.observe(gameTools, config);
heightObserver.observe(chatBox, config);

const colorsDiv = document.querySelector("#gameToolsColors");
colorsDiv.addEventListener("click", removeColor, false);

(function addPicker() {
    colorPicker.type = "color";
    colorPicker.setAttribute("style", "opacity: 0; width: 30px; cursor: pointer;");
    colorPicker.oninput = updatePicker;

    colorPickerWrapper.setAttribute("style", wrapperStyle);
    colorPickerWrapper.style.backgroundColor = colorPicker.value;
    colorPickerWrapper.appendChild(colorPicker);

    colorInput.oninput = updateInput;
    colorInput.addEventListener("click", selectInputText, false);
    colorInput.setAttribute("style", inputStyle);
    colorInput.setAttribute("spellcheck", "false");
    colorInput.value = colorPicker.value;

    gameTools.appendChild(colorPickerWrapper);
    gameTools.appendChild(colorInput);
})();

let paletteIndex = 0;

(function addButtons() {
    let prevPaletteBtn = document.createElement("button");
    let nextPaletteBtn = document.createElement("button");
    let saveColorBtn = document.createElement("button");

    addButton(saveColorBtn, "save", "5px 5px 5px 70px;");
    addButton(prevPaletteBtn, "arrow-left", "5px 5px 5px 40px;");
    addButton(nextPaletteBtn, "arrow-right", "5px 5px 5px 100px;");

    prevPaletteBtn.addEventListener("click", prevPalette, false);
    nextPaletteBtn.addEventListener("click", nextPalette, false);
    saveColorBtn.addEventListener("click", saveColor, false);
})();

function nextPalette() {
    paletteIndex < (palettes.length - 1) && paletteIndex++;
    changePalette(paletteIndex);
}

function prevPalette() {
    paletteIndex > 0 && paletteIndex--;
    changePalette(paletteIndex);
}

function saveColor() {
    let currentPalette = palettes[paletteIndex];
    while (currentPalette.length >= 39) {
        paletteIndex++;
        if (paletteIndex === palettes.length) {
            palettes.push([]);
        }
        currentPalette = palettes[paletteIndex];
    }
    palettes[paletteIndex].push(colorPicker.value);
    changePalette(paletteIndex);
    localStorage.setItem("palettes", JSON.stringify(palettes));
}

function removeColor(event) {
    if (event.altKey) {
        event.preventDefault();
        let color = event.target;
        var index = Array.prototype.indexOf.call(colorButtons, color);
        if (index >= 0 && paletteIndex > 1) {
            let palette = palettes[paletteIndex]
            palette.splice(index, 1);
            if (!palette.length) {
                palettes.splice(paletteIndex, 1);
                paletteIndex--;
            } 
            changePalette(paletteIndex);
            localStorage.setItem("palettes", JSON.stringify(palettes));
        }
    }
}

function addButton(button, icon, pos, id = "") {
    let buttonStyle = `margin: ${pos};
                       position: absolute;
                       height: 20px;
                       border: none;
                       background-color: #CBCBCB;
                       border-radius: 5px;`;

    button.setAttribute("style", buttonStyle);
    button.setAttribute("class", `fas fa-${icon}`);
    button.id = id;
    gameTools.appendChild(button);
}

function updatePicker(event) {
    let color = event.target.value;
    colorPickerWrapper.style.backgroundColor = color;
    colorInput.value = color;
    setColor(color);
}

function updateInput(event) {
    let color = event.target.value;
    colorPickerWrapper.style.backgroundColor = color;
    colorPicker.value = color;
    setColor(color);
}

function setColor(color) {
    let colorButton = document.querySelector("#gameToolsColors > div:nth-child(1) > div:nth-child(1)");
    let prevColor = colorButton.style.backgroundColor;
    colorButton.style.backgroundColor = color;
    colorButton.dispatchEvent(new Event("pointerdown"));
    colorButton.style.backgroundColor = prevColor;
}

function selectInputText() {
    colorInput.select();
}

function pickCanvasColor(event) {
    if (event.button === 1) {
        event.stopImmediatePropagation();
        let pos = getPos(event);
        let [r, g, b, a] = ctx.getImageData(pos.x, pos.y, 1, 1).data;
        let color = `rgb(${r}, ${g}, ${b})`;
        setColor(color);
    }
}

function getPos(event) {
    let canvasRect = canvas.getBoundingClientRect();
    let canvasScale = canvas.width / canvasRect.width;

    return {
        x: (event.clientX - canvasRect.left) * canvasScale,
        y: (event.clientY - canvasRect.top) * canvasScale
    };
}

function changePalette(palette) {
    colorButtons.forEach((button, idx) => {
        let color = palettes[palette][idx] || "#fff";
        button.style.backgroundColor = color;
    });
}

(function getDefaultPalette() {
    if (!palettes[0][0]) {
        colorButtons.forEach((button, idx) => {
            palettes[0][idx] = button.style.backgroundColor;
        });
    }
})();

function isDrawing() {
    return document.querySelector("#gameTools").style.display !== "none";
}

function adjustChatSize() {
    chatBox.style.height = isDrawing() ? "calc(100% - 200px)" : "calc(100% - 180px)";
}