From 5914db3bb4491f686428064f96f5f5509b5f70b1 Mon Sep 17 00:00:00 2001 From: rgantzos <86856959+rgantzos@users.noreply.github.com> Date: Mon, 2 Sep 2024 14:01:09 -0700 Subject: [PATCH] More Paint Functions --- features/features.json | 5 + features/more-editor-fonts/script.js | 1 + features/more-paint-functions/data.json | 22 +++ .../more-paint-functions/icons/exclude.svg | 13 ++ .../more-paint-functions/icons/intersect.svg | 20 +++ .../more-paint-functions/icons/subtract.svg | 17 ++ features/more-paint-functions/icons/unite.svg | 13 ++ features/more-paint-functions/script.js | 161 ++++++++++++++++++ features/more-paint-functions/style.css | 7 + 9 files changed, 259 insertions(+) create mode 100644 features/more-paint-functions/data.json create mode 100644 features/more-paint-functions/icons/exclude.svg create mode 100644 features/more-paint-functions/icons/intersect.svg create mode 100644 features/more-paint-functions/icons/subtract.svg create mode 100644 features/more-paint-functions/icons/unite.svg create mode 100644 features/more-paint-functions/script.js create mode 100644 features/more-paint-functions/style.css diff --git a/features/features.json b/features/features.json index 9f0054a1..9588ccbe 100644 --- a/features/features.json +++ b/features/features.json @@ -1,4 +1,9 @@ [ + { + "version": 2, + "id": "more-paint-functions", + "versionAdded": "v4.0.0" + }, { "version": 2, "id": "asset-size", diff --git a/features/more-editor-fonts/script.js b/features/more-editor-fonts/script.js index 791529dc..7efad503 100644 --- a/features/more-editor-fonts/script.js +++ b/features/more-editor-fonts/script.js @@ -9,6 +9,7 @@ export default async function ({ feature, console }) { feature.page.waitForElements( "div[class^='asset-panel_wrapper_'] div[class^='action-menu_more-buttons_']", function (menu) { + if (feature.traps.gui().editorTab.activeTabIndex !== 1) return; if (menu.querySelector(".ste-more-fonts")) return; let div = document.createElement("div"); diff --git a/features/more-paint-functions/data.json b/features/more-paint-functions/data.json new file mode 100644 index 00000000..11c00e90 --- /dev/null +++ b/features/more-paint-functions/data.json @@ -0,0 +1,22 @@ +{ + "title": "More Paint Functions", + "description": "Adds new functions to the paint editor. The new functions include unite (combining them into one), subtract (removing one shape from another), exclude (removing the overlap of 2 items), and intersect (removing everything but the overlap of 2 items). Each function only works with 2 items.", + "credits": [ + { "username": "rgantzos", "url": "https://scratch.mit.edu/users/rgantzos/" } + ], + "type": ["Editor"], + "tags": ["New", "Featured"], + "dynamic": true, + "scripts": [{ "file": "script.js", "runOn": "/projects/*" }], + "styles": [{ "file": "style.css", "runOn": "/projects/*" }], + "resources": [ + { "name": "function-exclude", "path": "/icons/exclude.svg" }, + { "name": "function-intersect", "path": "/icons/intersect.svg" }, + { "name": "function-subtract", "path": "/icons/subtract.svg" }, + { "name": "function-unite", "path": "/icons/unite.svg" } + ], + "components": [{ + "type": "warning", + "content": "In order to avoid clutter in the paint editor, this feature replaces the Copy, Paste and Delete buttons. However, hotkeys still work." + }] +} diff --git a/features/more-paint-functions/icons/exclude.svg b/features/more-paint-functions/icons/exclude.svg new file mode 100644 index 00000000..76c50759 --- /dev/null +++ b/features/more-paint-functions/icons/exclude.svg @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/features/more-paint-functions/icons/intersect.svg b/features/more-paint-functions/icons/intersect.svg new file mode 100644 index 00000000..399d3a7d --- /dev/null +++ b/features/more-paint-functions/icons/intersect.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/features/more-paint-functions/icons/subtract.svg b/features/more-paint-functions/icons/subtract.svg new file mode 100644 index 00000000..4d10c195 --- /dev/null +++ b/features/more-paint-functions/icons/subtract.svg @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/features/more-paint-functions/icons/unite.svg b/features/more-paint-functions/icons/unite.svg new file mode 100644 index 00000000..dee97002 --- /dev/null +++ b/features/more-paint-functions/icons/unite.svg @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/features/more-paint-functions/script.js b/features/more-paint-functions/script.js new file mode 100644 index 00000000..ddfd0849 --- /dev/null +++ b/features/more-paint-functions/script.js @@ -0,0 +1,161 @@ +export default async function ({ feature, console }) { + function unite() { + let paper = feature.traps.getPaper(); + let items = paper.project.selectedItems; + + if (items.length !== 2) return; + + for (var i in items) { + if (i > 0) { + items[0].unite(items[i]); + } + } + + for (var i in items) { + items[i].remove(); + } + + paper.tool.onUpdateImage(); + } + + function subtract() { + let paper = feature.traps.getPaper(); + let items = paper.project.selectedItems; + + if (items.length !== 2) return; + + for (var i in items) { + if (i > 0) { + items[0].subtract(items[i]); + } + } + + for (var i in items) { + items[i].remove(); + } + + paper.tool.onUpdateImage(); + } + + function exclude() { + let paper = feature.traps.getPaper(); + let items = paper.project.selectedItems; + + if (items.length !== 2) return; + + for (var i in items) { + if (i > 0) { + items[0].exclude(items[i]); + } + } + + for (var i in items) { + items[i].remove(); + } + + paper.tool.onUpdateImage(); + } + + function intersect() { + let paper = feature.traps.getPaper(); + let items = paper.project.selectedItems; + + if (items.length !== 2) return; + + for (var i in items) { + if (i > 0) { + items[0].intersect(items[i]); + } + } + + for (var i in items) { + items[i].remove(); + } + + paper.tool.onUpdateImage(); + } + + ScratchTools.waitForElements( + "div[class^='mode-tools_mod-labeled-icon-height_']", + async function (row) { + if (row.querySelector(".ste-more-functions")) return; + + let functions = [ + { + name: "Unite", + icon: "function-unite", + callback: unite, + }, + { + name: "Subtract", + icon: "function-subtract", + callback: subtract, + }, + { + name: "Exclude", + icon: "function-exclude", + callback: exclude, + }, + { + name: "Intersect", + icon: "function-intersect", + callback: intersect, + }, + ]; + + for (var i in functions) { + row.appendChild(makeButton(functions[i])); + } + + let align = await ScratchTools.waitForElement(".ste-align-items"); + row.appendChild(align); + } + ); + + feature.redux.subscribe(function () { + if (document.querySelector(".ste-more-functions")) { + let span = document.querySelector(".ste-more-functions"); + if ( + feature.traps.paint().format === "BITMAP" || + feature.traps.paint().selectedItems?.length < 2 + ) { + document.querySelectorAll(".ste-more-functions").forEach(function (el) { + el.classList.add("button_mod-disabled_1rf31"); + }); + } else { + document.querySelectorAll(".ste-more-functions").forEach(function (el) { + el.classList.remove("button_mod-disabled_1rf31"); + }); + } + } + }); + + function makeButton({ name, icon, callback }) { + let span = document.createElement("span"); + span.className = + "button_button_u6SE2 labeled-icon-button_mod-edit-field_1bXYC ste-more-functions"; + span.role = "button"; + + let img = document.createElement("img"); + img.src = feature.self.getResource(icon); + img.className = "labeled-icon-button_edit-field-icon_3j-Pf"; + img.alt = name; + img.title = name; + img.draggable = false; + span.appendChild(img); + + let label = document.createElement("span"); + label.textContent = name; + label.className = "labeled-icon-button_edit-field-title_1ZoEV"; + span.appendChild(label); + + span.addEventListener("click", function (e) { + if (span.className.includes("disabled")) return; + callback(); + }); + + feature.self.hideOnDisable(span); + + return span; + } +} diff --git a/features/more-paint-functions/style.css b/features/more-paint-functions/style.css new file mode 100644 index 00000000..752ac1b7 --- /dev/null +++ b/features/more-paint-functions/style.css @@ -0,0 +1,7 @@ +div[class*='mode-tools_mode-tools_'] > div[class*='mode-tools_mod-dashed-border_']:nth-child(1), div[class*='mode-tools_mode-tools_'] > div[class*='mode-tools_mod-dashed-border_']:nth-child(2) { + display: none; +} + +div[class*='mode-tools_mode-tools_'] > div[class*='mode-tools_mod-labeled-icon-height_']:nth-child(3) { + margin-left: 0px !important; +} \ No newline at end of file