diff --git a/features/features.json b/features/features.json index 9588ccbe..caa770ce 100644 --- a/features/features.json +++ b/features/features.json @@ -1,4 +1,9 @@ [ + { + "version": 2, + "id": "outline-shape-options", + "versionAdded": "v4.0.0" + }, { "version": 2, "id": "more-paint-functions", diff --git a/features/outline-shape-options/data.json b/features/outline-shape-options/data.json new file mode 100644 index 00000000..a7606f33 --- /dev/null +++ b/features/outline-shape-options/data.json @@ -0,0 +1,25 @@ +{ + "title": "Customizable Shape Outlines", + "description": "Adds more options in the outline dropdown to allow you to customize the shape of the outline, such as making corners round.", + "credits": [ + { + "username": "Masaabu-YT", + "url": "https://scratch.mit.edu/users/Masaabu-YT/" + } + ], + "type": ["Editor"], + "tags": ["New", "Featured"], + "dynamic": true, + "scripts": [{ "file": "script.js", "runOn": "/projects/*" }], + "styles": [{ "file": "style.css", "runOn": "/projects/*" }], + "resources": [ + { "name": "Join-miter", "path": "/resources/join-miter.svg" }, + { "name": "Join-round", "path": "/resources/join-round.svg" }, + { "name": "Join-bevel", "path": "/resources/join-bevel.svg" }, + { "name": "Join-arcs", "path": "/resources/join-arcs.svg" }, + { "name": "Join-miter-clip", "path": "/resources/join-miter-clip.svg" }, + { "name": "Cap-butt", "path": "/resources/cap-butt.svg" }, + { "name": "Cap-round", "path": "/resources/cap-round.svg" }, + { "name": "Cap-square", "path": "/resources/cap-square.svg" } + ] +} diff --git a/features/outline-shape-options/resources/cap-butt.svg b/features/outline-shape-options/resources/cap-butt.svg new file mode 100644 index 00000000..65b4c0e8 --- /dev/null +++ b/features/outline-shape-options/resources/cap-butt.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/features/outline-shape-options/resources/cap-round.svg b/features/outline-shape-options/resources/cap-round.svg new file mode 100644 index 00000000..1b0cf28d --- /dev/null +++ b/features/outline-shape-options/resources/cap-round.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/features/outline-shape-options/resources/cap-square.svg b/features/outline-shape-options/resources/cap-square.svg new file mode 100644 index 00000000..c5d67c40 --- /dev/null +++ b/features/outline-shape-options/resources/cap-square.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/features/outline-shape-options/resources/join-arcs.svg b/features/outline-shape-options/resources/join-arcs.svg new file mode 100644 index 00000000..65452e9d --- /dev/null +++ b/features/outline-shape-options/resources/join-arcs.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/features/outline-shape-options/resources/join-bevel.svg b/features/outline-shape-options/resources/join-bevel.svg new file mode 100644 index 00000000..e6886775 --- /dev/null +++ b/features/outline-shape-options/resources/join-bevel.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/features/outline-shape-options/resources/join-miter-clip.svg b/features/outline-shape-options/resources/join-miter-clip.svg new file mode 100644 index 00000000..6004671c --- /dev/null +++ b/features/outline-shape-options/resources/join-miter-clip.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/features/outline-shape-options/resources/join-miter.svg b/features/outline-shape-options/resources/join-miter.svg new file mode 100644 index 00000000..710ba8f2 --- /dev/null +++ b/features/outline-shape-options/resources/join-miter.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/features/outline-shape-options/resources/join-round.svg b/features/outline-shape-options/resources/join-round.svg new file mode 100644 index 00000000..707fb425 --- /dev/null +++ b/features/outline-shape-options/resources/join-round.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/features/outline-shape-options/script.js b/features/outline-shape-options/script.js new file mode 100644 index 00000000..f6bcae54 --- /dev/null +++ b/features/outline-shape-options/script.js @@ -0,0 +1,80 @@ +export default async function ({ feature, console }) { + const icons = { + Cap: ["butt", "round", "square"], + Join: ["miter", "round", "bevel", "arcs", "miter-clip"], + }; + + function createSection(type) { + const selectedItems = feature.traps.getPaper().project.selectedItems; + const result = document.createElement("div"); + let strokeValue = undefined; + + function changeItems(pos, value) { + for (var i in selectedItems) { + if (selectedItems[i][pos] !== undefined) { + selectedItems[i][pos] = value; + } + } + } + + const row = document.createElement("div"); + row.classList.add("color-picker_row-header_173LQ"); + const labelName = document.createElement("span"); + labelName.classList.add("color-picker_label-name_17igY"); + labelName.textContent = `Line ${type}`; + const labelReadout = document.createElement("span"); + labelReadout.classList.add("color-picker_label-readout_9vjb2"); + if (selectedItems.length === 1) { + strokeValue = `${selectedItems[0][`stroke${type}`]}`; + labelReadout.textContent = strokeValue; + } + row.appendChild(labelName); + row.appendChild(labelReadout); + + const content = document.createElement("div"); + content.classList.add("color-picker_gradient-picker-row_mnu4O"); + icons[type].forEach((iconName) => { + const icon = document.createElement("img"); + icon.classList.add(`ste-outline-shape-options-${iconName}`); + icon.src = feature.self.getResource(`${type}-${iconName}`); + if (iconName !== strokeValue) + icon.classList.add("ste-outline-shape-options-passive"); + icon.addEventListener("click", () => { + changeItems(`stroke${type}`, `${iconName}`); + labelReadout.textContent = iconName; + const elements = content.getElementsByTagName("*"); + for (let i = 0; i < elements.length; i++) { + if ( + elements[i].classList.contains( + `ste-outline-shape-options-${iconName}` + ) + ) + elements[i].classList.remove("ste-outline-shape-options-passive"); + else elements[i].classList.add("ste-outline-shape-options-passive"); + } + }); + content.appendChild(icon); + }); + + result.appendChild(row); + result.appendChild(content); + feature.self.hideOnDisable(result) + return result; + } + + ScratchTools.waitForElements( + "div[class*='color-picker_swatch-row_']", + function (element) { + if (feature.traps.paint().modals.fillColor) return; + if (feature.traps.getPaper().project.selectedItems.length < 1) return; + const dividerLine = document.createElement("div"); + dividerLine.classList.add("color-picker_divider_3a3qR"); + const sectionCap = createSection("Cap"); + const sectionJoin = createSection("Join"); + + element.insertAdjacentElement("afterend", sectionJoin); + element.insertAdjacentElement("afterend", sectionCap); + element.insertAdjacentElement("afterend", dividerLine); + } + ); +} diff --git a/features/outline-shape-options/style.css b/features/outline-shape-options/style.css new file mode 100644 index 00000000..15c1a549 --- /dev/null +++ b/features/outline-shape-options/style.css @@ -0,0 +1,3 @@ +.ste-outline-shape-options-passive { + filter: saturate(0%); +} \ No newline at end of file