diff --git a/feature-locales/paint-align/en.json b/feature-locales/paint-align/en.json new file mode 100644 index 00000000..ba3fca46 --- /dev/null +++ b/feature-locales/paint-align/en.json @@ -0,0 +1,3 @@ +{ + "align": "Align" +} diff --git a/features/features.json b/features/features.json index 32ee58e7..1a6014eb 100644 --- a/features/features.json +++ b/features/features.json @@ -1,4 +1,9 @@ [ + { + "version": 2, + "id": "paint-align", + "versionAdded": "v4.0.0" + }, { "version": 2, "id": "rotate-gradient", diff --git a/features/paint-align/align.svg b/features/paint-align/align.svg new file mode 100644 index 00000000..c853f82a --- /dev/null +++ b/features/paint-align/align.svg @@ -0,0 +1,19 @@ + + + + + + + + \ No newline at end of file diff --git a/features/paint-align/data.json b/features/paint-align/data.json new file mode 100644 index 00000000..70807724 --- /dev/null +++ b/features/paint-align/data.json @@ -0,0 +1,13 @@ +{ + "title": "Align Objects in Paint Editor", + "description": "Change the opacity of objects in the paint editor.", + "credits": [ + { "username": "rgantzos", "url": "https://scratch.mit.edu/users/rgantzos/" } + ], + "type": ["Editor"], + "tags": ["New"], + "dynamic": true, + "scripts": [{ "file": "script.js", "runOn": "/projects/*" }], + "styles": [{ "file": "style.css", "runOn": "/projects/*" }], + "resources": [{ "name": "paint-align", "path": "/align.svg" }] +} diff --git a/features/paint-align/script.js b/features/paint-align/script.js new file mode 100644 index 00000000..7af6a455 --- /dev/null +++ b/features/paint-align/script.js @@ -0,0 +1,84 @@ +export default async function ({ feature }) { + ScratchTools.waitForElements("div[class^='mode-tools_mod-labeled-icon-height_']", function(row) { + if (row.querySelector(".ste-align-items")) return; + + let span = document.createElement("span") + span.className = "button_button_u6SE2 labeled-icon-button_mod-edit-field_1bXYC ste-align-items" + span.role = "button" + + let img = document.createElement("img") + img.src = feature.self.getResource("paint-align") + img.className = "labeled-icon-button_edit-field-icon_3j-Pf" + img.alt = feature.msg("align") + img.title = feature.msg("align") + img.draggable = false + span.appendChild(img) + + let label = document.createElement("span") + label.textContent = feature.msg("align") + label.className = "labeled-icon-button_edit-field-title_1ZoEV" + span.appendChild(label) + + span.addEventListener("click", function() { + if (span.className.includes("disabled")) return; + centerObjects() + }) + + row.appendChild(span) + }) + + feature.redux.subscribe(function() { + if (document.querySelector(".ste-align-items")) { + let span = document.querySelector(".ste-align-items") + + if (feature.traps.paint().format === "BITMAP" || feature.traps.paint().selectedItems?.length < 2) { + span.classList.add("disabled") + } else { + span.classList.remove("disabled") + } + } + }) + + function centerObjects() { + let items = feature.traps.paint().selectedItems; + + let allX = []; + let allY = []; + let average = (array) => array.reduce((a, b) => a + b) / array.length; + + for (var i in items) { + allX.push(getMidPoint(items[i].segments).x); + allY.push(getMidPoint(items[i].segments).y); + } + + let trueMidpoint = { x: average(allX), y: average(allY) }; + + for (var i in items) { + let selfMidpoint = getMidPoint(items[i].segments); + let adjustX = trueMidpoint.x - selfMidpoint.x; + let adjustY = trueMidpoint.y - selfMidpoint.y; + + for (var seg in items[i].segments) { + items[i].segments[seg]._point._x += adjustX; + items[i].segments[seg]._point._y += adjustY; + } + } + + feature.traps.getPaper().tool.onUpdateImage(); + } + + function getMidPoint(segments) { + let x = []; + let y = []; + + for (var i in segments) { + x.push(segments[i]._point._x); + y.push(segments[i]._point._y); + } + + let xAverage = (Math.min(...x) + Math.max(...x)) / 2; + let yAverage = (Math.min(...y) + Math.max(...y)) / 2; + + return { x: xAverage, y: yAverage }; + } +} diff --git a/features/paint-align/style.css b/features/paint-align/style.css new file mode 100644 index 00000000..4b091de6 --- /dev/null +++ b/features/paint-align/style.css @@ -0,0 +1,4 @@ +.ste-align-items.disabled { + cursor: auto; + opacity: .5; +} \ No newline at end of file