Greasy Fork is available in English.

Enhanced Scratch UI and Block Editor

Enhance Scratch UI with custom block colors, themes, and more.

  1. // ==UserScript==
  2. // @name Enhanced Scratch UI and Block Editor
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Enhance Scratch UI with custom block colors, themes, and more.
  6. // @match https://scratch.mit.edu/projects/*
  7. // @match https://scratch.mit.edu/editor/*
  8. // @match https://scratch.mit.edu/ideas*
  9. // @grant GM_addStyle
  10. // @run-at document-end
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // Utility function to add global styles
  17. function addGlobalStyle(css) {
  18. const style = document.createElement('style');
  19. style.type = 'text/css';
  20. style.innerHTML = css;
  21. document.head.appendChild(style);
  22. }
  23.  
  24. // Add global styles for the GUI
  25. addGlobalStyle(`
  26. body {
  27. font-family: 'Comic Sans MS', cursive, sans-serif;
  28. }
  29. #scratch-custom-gui {
  30. position: fixed;
  31. top: 10px;
  32. right: 10px;
  33. background-color: #fef9e9;
  34. border: 2px solid #d1a3a4;
  35. padding: 15px;
  36. z-index: 1000;
  37. border-radius: 10px;
  38. box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
  39. font-family: 'Comic Sans MS', cursive, sans-serif;
  40. color: #333;
  41. display: none;
  42. }
  43. #scratch-custom-gui h2 {
  44. font-size: 24px;
  45. border-bottom: 2px dashed #d1a3a4;
  46. padding-bottom: 10px;
  47. margin-bottom: 10px;
  48. }
  49. #scratch-custom-gui button {
  50. margin: 5px;
  51. padding: 8px 15px;
  52. border: 2px solid #d1a3a4;
  53. border-radius: 8px;
  54. background-color: #f8d5d5;
  55. color: #333;
  56. cursor: pointer;
  57. font-family: 'Comic Sans MS', cursive, sans-serif;
  58. font-size: 14px;
  59. }
  60. #scratch-custom-gui button:hover {
  61. background-color: #e8b1b4;
  62. }
  63. #scratch-custom-gui input[type="color"],
  64. #scratch-custom-gui input[type="text"],
  65. #scratch-custom-gui select {
  66. border: 2px solid #d1a3a4;
  67. border-radius: 8px;
  68. padding: 5px;
  69. font-family: 'Comic Sans MS', cursive, sans-serif;
  70. font-size: 14px;
  71. }
  72. #scratch-custom-gui #gui-content {
  73. margin-top: 15px;
  74. }
  75. #scratch-custom-gui #modifiers-list div {
  76. margin: 5px 0;
  77. padding: 5px;
  78. border: 1px dashed #d1a3a4;
  79. border-radius: 8px;
  80. background-color: #fbe8e8;
  81. }
  82. #theme-styles {
  83. position: fixed;
  84. top: 0;
  85. left: 0;
  86. width: 100%;
  87. height: 100%;
  88. z-index: -1;
  89. }
  90. `);
  91.  
  92. // Create and open GUI
  93. function createAndOpenGUI() {
  94. const gui = document.createElement('div');
  95. gui.id = 'scratch-custom-gui';
  96. gui.innerHTML = `
  97. <h2>Custom Scratch GUI</h2>
  98. <button id="open-block-color-changer">Block Color Changer</button>
  99. <button id="open-block-editor">Block Editor</button>
  100. <button id="open-theme-changer">Theme Changer</button>
  101. <button id="open-modifiers">Modifiers</button>
  102. <button id="close-gui">Close</button>
  103. <div id="gui-content"></div>
  104. `;
  105. document.body.appendChild(gui);
  106.  
  107. // Event listeners for buttons
  108. document.getElementById('open-block-color-changer').addEventListener('click', openBlockColorChanger);
  109. document.getElementById('open-block-editor').addEventListener('click', openBlockEditor);
  110. document.getElementById('open-theme-changer').addEventListener('click', openThemeChanger);
  111. document.getElementById('open-modifiers').addEventListener('click', openModifiers);
  112. document.getElementById('close-gui').addEventListener('click', closeGUI);
  113.  
  114. // Open GUI initially
  115. gui.style.display = 'block';
  116. }
  117.  
  118. // Function to open block color changer
  119. function openBlockColorChanger() {
  120. document.getElementById('gui-content').innerHTML = `
  121. <h3>Block Color Changer</h3>
  122. <label for="block-select-color">Select Block:</label>
  123. <select id="block-select-color">
  124. <!-- Populate with block options dynamically -->
  125. </select>
  126. <br/><br/>
  127. <label for="block-new-color">New Block Color:</label>
  128. <input type="color" id="block-new-color" />
  129. <br/><br/>
  130. <label for="block-inside-color">Inside Color:</label>
  131. <input type="color" id="block-inside-color" />
  132. <br/><br/>
  133. <button onclick="changeBlockColor()">Change Color</button>
  134. `;
  135. populateBlockOptions(); // Populate block options dynamically
  136. }
  137.  
  138. // Function to open block editor
  139. function openBlockEditor() {
  140. document.getElementById('gui-content').innerHTML = `
  141. <h3>Block Editor</h3>
  142. <label for="block-name">Block Name:</label>
  143. <input type="text" id="block-name" />
  144. <br/><br/>
  145. <label for="block-color">Block Color:</label>
  146. <input type="color" id="block-color" />
  147. <br/><br/>
  148. <label for="block-inside-color">Inside Color:</label>
  149. <input type="color" id="block-inside-color" />
  150. <br/><br/>
  151. <label for="block-function">Function:</label>
  152. <input type="text" id="block-function" />
  153. <br/><br/>
  154. <button onclick="createCustomBlock()">Create Custom Block</button>
  155. `;
  156. }
  157.  
  158. // Function to open theme changer
  159. function openThemeChanger() {
  160. document.getElementById('gui-content').innerHTML = `
  161. <h3>Theme Changer</h3>
  162. <label for="theme-select">Select Theme:</label>
  163. <select id="theme-select">
  164. <option value="cupcake">Cupcake</option>
  165. <option value="candy">Candy</option>
  166. <option value="dark">Dark</option>
  167. <option value="marshmallow">Marshmallow</option>
  168. <option value="bloody">Bloody</option>
  169. <option value="image">Image</option>
  170. </select>
  171. <br/><br/>
  172. <label for="theme-image-url" id="image-url-label" style="display: none;">Image URL:</label>
  173. <input type="text" id="theme-image-url" style="display: none;" />
  174. <br/><br/>
  175. <button onclick="applyTheme()">Apply Theme</button>
  176. `;
  177. document.getElementById('theme-select').addEventListener('change', function() {
  178. document.getElementById('image-url-label').style.display = this.value === 'image' ? 'block' : 'none';
  179. document.getElementById('theme-image-url').style.display = this.value === 'image' ? 'block' : 'none';
  180. });
  181. }
  182.  
  183. // Function to open modifiers
  184. function openModifiers() {
  185. document.getElementById('gui-content').innerHTML = `
  186. <h3>Modifiers</h3>
  187. <label for="modifier-name">Modifier Name:</label>
  188. <input type="text" id="modifier-name" />
  189. <br/><br/>
  190. <button onclick="addModifier()">Add Modifier</button>
  191. <br/><br/>
  192. <div id="modifiers-list"></div>
  193. `;
  194. }
  195.  
  196. // Populate block options for color changer
  197. function populateBlockOptions() {
  198. const blockSelect = document.getElementById('block-select-color');
  199. // This example assumes some predefined blocks
  200. // In practice, you might need to fetch block data from Scratch's editor API
  201. const blocks = [
  202. { id: 'block1', name: 'Block 1' },
  203. { id: 'block2', name: 'Block 2' },
  204. { id: 'block3', name: 'Block 3' }
  205. ];
  206. blocks.forEach(block => {
  207. const option = document.createElement('option');
  208. option.value = block.id;
  209. option.textContent = block.name;
  210. blockSelect.appendChild(option);
  211. });
  212. }
  213.  
  214. // Change block color
  215. function changeBlockColor() {
  216. const blockId = document.getElementById('block-select-color').value;
  217. const color = document.getElementById('block-new-color').value;
  218. const insideColor = document.getElementById('block-inside-color').value;
  219. console.log(`Changing block ${blockId} color to ${color}, inside color ${insideColor}`);
  220. // Implement the actual API call to change the block color
  221. }
  222.  
  223. // Create custom block
  224. function createCustomBlock() {
  225. const name = document.getElementById('block-name').value;
  226. const color = document.getElementById('block-color').value;
  227. const insideColor = document.getElementById('block-inside-color').value;
  228. const func = document.getElementById('block-function').value;
  229. console.log(`Creating custom block: ${name}, Color: ${color}, Inside Color: ${insideColor}, Function: ${func}`);
  230. // Implement the actual API call to create a custom block
  231. }
  232.  
  233. // Apply theme
  234. function applyTheme() {
  235. const theme = document.getElementById('theme-select').value;
  236. const imageUrl = document.getElementById('theme-image-url').value;
  237. console.log(`Applying theme: ${theme}, Image URL: ${imageUrl}`);
  238. // Implement the actual API call to apply the theme
  239. }
  240.  
  241. // Add modifier
  242. function addModifier() {
  243. const name = document.getElementById('modifier-name').value;
  244. const modifiersList = document.getElementById('modifiers-list');
  245. const div = document.createElement('div');
  246. div.textContent = name;
  247. modifiersList.appendChild(div);
  248. console.log(`Added modifier: ${name}`);
  249. }
  250.  
  251. // Close the GUI
  252. function closeGUI() {
  253. document.getElementById('scratch-custom-gui').style.display = 'none';
  254. }
  255.  
  256. // Initialize GUI creation
  257. createAndOpenGUI();
  258. })();