Color Picker

Color picker for Sketchful

目前为 2020-06-29 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Color Picker
  3. // @namespace https://greasyfork.org/users/281093
  4. // @match https://sketchful.io/*
  5. // @grant none
  6. // @version 0.4
  7. // @author Bell
  8. // @description Color picker for Sketchful
  9. // @run-at document-end
  10. // jshint esversion: 6
  11. // ==/UserScript==
  12.  
  13. let storedPalettes = JSON.parse(localStorage.getItem('palettes'));
  14. let paletteIndex = 0;
  15. let palettes = storedPalettes || [
  16. [],
  17. [
  18. "#3a3a3c", "#8e8e93", "#f8f9fa", "#ffadad", "#ffd6a5", "#fdffb6", "#caffbf", "#9bf6ff", "#a0c4ff", "#bdb2ff", "#ffc6ff", "#fdad88", "#9e5425",
  19. "#2c2c2e", "#636366", "#e0e0e0", "#ff7070", "#f3a220", "#f9e079", "#049d6f", "#92ddea", "#6dafe0", "#ab87ff", "#ff87ab", "#e38a5e", "#5e320d",
  20. "#1c1c1e", "#48484a", "#c2c2c2", "#f54d4d", "#dc8700", "#f0c808", "#00766a", "#219bc3", "#548bbc", "#715aff", "#ff5d8f", "#d1754e", "#421e06"
  21. ],
  22. ];
  23.  
  24. const canvas = document.querySelector("#canvas");
  25. const ctx = canvas.getContext("2d");
  26. const gameTools = document.querySelector("#gameTools");
  27. const chatBox = document.querySelector("#gameChat");
  28. const colorButtons = document.querySelectorAll(".gameToolsColor");
  29. const colorsDiv = document.querySelector("#gameToolsColors");
  30. const colorButton = document.querySelector("#gameToolsColors > div:nth-child(1) > div:nth-child(1)");
  31.  
  32. const colorPickerWrapper = document.createElement("div");
  33. const colorInput = document.createElement("input");
  34. const colorPicker = document.createElement("input");
  35. const inputStyle = `margin: 5px 0; height: 20px; width: 50%; text-align: center; border: none;font-weight: 800; border-radius: 5px; background-color: #CBCBCB;`;
  36. const wrapperStyle = `position: absolute; margin: 5px 50%; height: 20px; width: 30px; border-radius: 5px;`;
  37.  
  38. (function init() {
  39. updatePageStyle();
  40. addListeners();
  41. addObservers();
  42. addPicker();
  43. })();
  44.  
  45. function addPicker() {
  46. colorPicker.type = "color";
  47. colorPicker.setAttribute("style", "opacity: 0; width: 30px; cursor: pointer;");
  48. colorPicker.oninput = updatePicker;
  49.  
  50. colorPickerWrapper.setAttribute("style", wrapperStyle);
  51. colorPickerWrapper.style.backgroundColor = colorPicker.value;
  52. colorPickerWrapper.appendChild(colorPicker);
  53.  
  54. colorInput.oninput = updateInput;
  55. colorInput.addEventListener("click", selectInputText, false);
  56. colorInput.setAttribute("style", inputStyle);
  57. colorInput.setAttribute("spellcheck", "false");
  58. colorInput.value = colorPicker.value;
  59.  
  60. gameTools.appendChild(colorPickerWrapper);
  61. gameTools.appendChild(colorInput);
  62. addButtons();
  63. }
  64.  
  65. function addObservers() {
  66. const heightObserver = new MutationObserver(adjustChatSize);
  67. const config = {
  68. attributes: true,
  69. childList: false,
  70. subtree: false
  71. };
  72. heightObserver.observe(gameTools, config);
  73. heightObserver.observe(chatBox, config);
  74. }
  75.  
  76. function addListeners() {
  77. canvas.addEventListener('pointerdown', pickCanvasColor, false);
  78. colorsDiv.addEventListener("click", removeColor, false);
  79. }
  80.  
  81. function updatePageStyle() {
  82. document.querySelector("#gameToolsSlider").style.top = "77px";
  83. gameTools.style.height = "200px";
  84. getDefaultPalette();
  85. }
  86.  
  87. function addButtons() {
  88. let prevPaletteBtn = document.createElement("button");
  89. let nextPaletteBtn = document.createElement("button");
  90. let saveColorBtn = document.createElement("button");
  91.  
  92. addButton(saveColorBtn, "save", "5px 5px 5px 70px;");
  93. addButton(prevPaletteBtn, "arrow-left", "5px 5px 5px 40px;");
  94. addButton(nextPaletteBtn, "arrow-right", "5px 5px 5px 100px;");
  95.  
  96. prevPaletteBtn.addEventListener("click", prevPalette, false);
  97. nextPaletteBtn.addEventListener("click", nextPalette, false);
  98. saveColorBtn.addEventListener("click", saveColor, false);
  99. }
  100.  
  101. function nextPalette() {
  102. paletteIndex < (palettes.length - 1) && paletteIndex++;
  103. changePalette(paletteIndex);
  104. }
  105.  
  106. function prevPalette() {
  107. paletteIndex > 0 && paletteIndex--;
  108. changePalette(paletteIndex);
  109. }
  110.  
  111. function saveColor() {
  112. let currentPalette = palettes[paletteIndex];
  113. while (currentPalette.length >= 39) {
  114. paletteIndex++;
  115. if (paletteIndex === palettes.length) {
  116. palettes.push([]);
  117. }
  118. currentPalette = palettes[paletteIndex];
  119. }
  120. palettes[paletteIndex].push(colorPicker.value);
  121. changePalette(paletteIndex);
  122. localStorage.setItem("palettes", JSON.stringify(palettes));
  123. }
  124.  
  125. function removeColor(event) {
  126. if (event.altKey) {
  127. event.preventDefault();
  128. let color = event.target;
  129. let index = Array.prototype.indexOf.call(colorButtons, color);
  130. if (index >= 0 && paletteIndex > 1) {
  131. let palette = palettes[paletteIndex];
  132. palette.splice(index, 1);
  133. if (!palette.length) {
  134. palettes.splice(paletteIndex, 1);
  135. paletteIndex--;
  136. }
  137. changePalette(paletteIndex);
  138. localStorage.setItem("palettes", JSON.stringify(palettes));
  139. }
  140. }
  141. }
  142.  
  143. function addButton(button, icon, pos, id = "") {
  144. let buttonStyle = `margin: ${pos}; position: absolute; height: 20px; border: none; background-color: #CBCBCB; border-radius: 5px;`;
  145. button.setAttribute("style", buttonStyle);
  146. button.setAttribute("class", `fas fa-${icon}`);
  147. button.id = id;
  148. gameTools.appendChild(button);
  149. }
  150.  
  151. function updatePicker(event) {
  152. let color = event.target.value;
  153. colorPickerWrapper.style.backgroundColor = color;
  154. colorInput.value = color;
  155. setColor(color);
  156. }
  157.  
  158. function updateInput(event) {
  159. let color = event.target.value;
  160. colorPickerWrapper.style.backgroundColor = color;
  161. colorPicker.value = color;
  162. setColor(color);
  163. }
  164.  
  165. function setColor(color) {
  166. let prevColor = colorButton.style.backgroundColor;
  167. colorButton.style.backgroundColor = color;
  168. colorButton.dispatchEvent(new Event("pointerdown"));
  169. colorButton.style.backgroundColor = prevColor;
  170. }
  171.  
  172. function selectInputText() {
  173. colorInput.select();
  174. }
  175.  
  176. function pickCanvasColor(event) {
  177. if (event.altKey) {
  178. event.stopImmediatePropagation();
  179. let pos = getPos(event);
  180. let [r, g, b, a] = ctx.getImageData(pos.x, pos.y, 1, 1).data;
  181. let color = `rgb(${r}, ${g}, ${b})`;
  182. setColor(color);
  183. }
  184. }
  185.  
  186. function getPos(event) {
  187. let canvasRect = canvas.getBoundingClientRect();
  188. let canvasScale = canvas.width / canvasRect.width;
  189. return {
  190. x: (event.clientX - canvasRect.left) * canvasScale,
  191. y: (event.clientY - canvasRect.top) * canvasScale
  192. };
  193. }
  194.  
  195. function changePalette(palette) {
  196. colorButtons.forEach((button, idx) => {
  197. let color = palettes[palette][idx] || "#fff";
  198. button.style.backgroundColor = color;
  199. });
  200. }
  201.  
  202. function getDefaultPalette() {
  203. if (!palettes[0][0]) {
  204. colorButtons.forEach((button, idx) => {
  205. palettes[0][idx] = button.style.backgroundColor;
  206. });
  207. }
  208. }
  209.  
  210. function isDrawing() {
  211. return document.querySelector("#gameTools").style.display !== "none";
  212. }
  213.  
  214. function adjustChatSize() {
  215. chatBox.style.height = isDrawing() ? "calc(100% - 200px)" : "calc(100% - 180px)";
  216. }