From 81223ba15e24991815c55db5bdcef9bf39d68c24 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:21:57 -0400 Subject: [PATCH 01/22] Create IrshaadAli --- static/extensions/IrshaadAli | 1 + 1 file changed, 1 insertion(+) create mode 100644 static/extensions/IrshaadAli diff --git a/static/extensions/IrshaadAli b/static/extensions/IrshaadAli new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/static/extensions/IrshaadAli @@ -0,0 +1 @@ + From efc1fcea53dc289b07131d8b0ef0b3518e2041b8 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:23:00 -0400 Subject: [PATCH 02/22] Delete static/extensions/IrshaadAli --- static/extensions/IrshaadAli | 1 - 1 file changed, 1 deletion(-) delete mode 100644 static/extensions/IrshaadAli diff --git a/static/extensions/IrshaadAli b/static/extensions/IrshaadAli deleted file mode 100644 index 8b1378917..000000000 --- a/static/extensions/IrshaadAli +++ /dev/null @@ -1 +0,0 @@ - From d27567f1d94ddf29999c5b9eaeee65801f93a4c6 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:23:14 -0400 Subject: [PATCH 03/22] Create placeholder --- static/extensions/IrshaadAli/placeholder | 1 + 1 file changed, 1 insertion(+) create mode 100644 static/extensions/IrshaadAli/placeholder diff --git a/static/extensions/IrshaadAli/placeholder b/static/extensions/IrshaadAli/placeholder new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/static/extensions/IrshaadAli/placeholder @@ -0,0 +1 @@ + From 6e6cbd97739eb5865aeee6c7bcbc0a68374a2a47 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:24:17 -0400 Subject: [PATCH 04/22] Create placeholder --- static/extensions/IrshaadAli/assets/placeholder | 1 + 1 file changed, 1 insertion(+) create mode 100644 static/extensions/IrshaadAli/assets/placeholder diff --git a/static/extensions/IrshaadAli/assets/placeholder b/static/extensions/IrshaadAli/assets/placeholder new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/static/extensions/IrshaadAli/assets/placeholder @@ -0,0 +1 @@ + From e2219a2b0f55e50b566d0cdc146b87b0591a7e4b Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:24:31 -0400 Subject: [PATCH 05/22] Add files via upload --- static/extensions/IrshaadAli/assets/Rect.svg | 22 +++++++++++++++++++ .../extensions/IrshaadAli/assets/RectIcon.svg | 17 ++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 static/extensions/IrshaadAli/assets/Rect.svg create mode 100644 static/extensions/IrshaadAli/assets/RectIcon.svg diff --git a/static/extensions/IrshaadAli/assets/Rect.svg b/static/extensions/IrshaadAli/assets/Rect.svg new file mode 100644 index 000000000..3428eb77a --- /dev/null +++ b/static/extensions/IrshaadAli/assets/Rect.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/extensions/IrshaadAli/assets/RectIcon.svg b/static/extensions/IrshaadAli/assets/RectIcon.svg new file mode 100644 index 000000000..835161615 --- /dev/null +++ b/static/extensions/IrshaadAli/assets/RectIcon.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file From f7a1de1d7ebce9ab4a1867f32df6f7c27b29fdf2 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:26:20 -0400 Subject: [PATCH 06/22] Update and rename placeholder to rect-links.txt --- static/extensions/IrshaadAli/assets/placeholder | 1 - static/extensions/IrshaadAli/assets/rect-links.txt | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 static/extensions/IrshaadAli/assets/placeholder create mode 100644 static/extensions/IrshaadAli/assets/rect-links.txt diff --git a/static/extensions/IrshaadAli/assets/placeholder b/static/extensions/IrshaadAli/assets/placeholder deleted file mode 100644 index 8b1378917..000000000 --- a/static/extensions/IrshaadAli/assets/placeholder +++ /dev/null @@ -1 +0,0 @@ - diff --git a/static/extensions/IrshaadAli/assets/rect-links.txt b/static/extensions/IrshaadAli/assets/rect-links.txt new file mode 100644 index 000000000..3c6828984 --- /dev/null +++ b/static/extensions/IrshaadAli/assets/rect-links.txt @@ -0,0 +1,2 @@ +Rect = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTg2Ij4KICA8ZGVmcz48L2RlZnM+CiAgPHJlY3Qgd2lkdGg9IjI5OS45ODIiIGhlaWdodD0iMTg2IiBzdHlsZT0icGFpbnQtb3JkZXI6IGZpbGw7IGZpbGwtcnVsZTogbm9uemVybzsgZmlsbDogcmdiKDIxNiwgMCwgODIpOyIgeD0iMC4wMDkiPjwvcmVjdD4KICA8cmVjdCB4PSI5LjU2IiB5PSI4LjczNiIgd2lkdGg9IjI4MC44ODEiIGhlaWdodD0iMTY4LjUyOCIgc3R5bGU9ImZpbGw6IHJnYigyNTUsIDAsIDk3KTsiPjwvcmVjdD4KICA8cmVjdCB4PSIxMTUuNzkyIiB5PSI2Mi43NDkiIHdpZHRoPSI4NC44NTMiIGhlaWdodD0iODQuODUzIiBzdHlsZT0iZmlsbDogbm9uZTsgc3Ryb2tlOiByZ2IoMjU1LCAyNTUsIDI1NSk7IHN0cm9rZS13aWR0aDogOHB4OyI+PC9yZWN0PgogIDxnIHRyYW5zZm9ybT0ibWF0cml4KDEsIDAsIDAsIDEsIDguMjE4MjU3LCA3LjE3NTE0OCkiPgogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoLTIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNTQuOTk4OTA0LCA0LjExNDMzKSIgc3R5bGU9IiI+CiAgICAgIDxwYXRoIGQ9Ik0xLjk5OTc0IDEyLjk5OTlMMS45OTk2IDExTDE1LjU4NTggMTFWNS41ODU4MkwyMiAxMkwxNS41ODU4IDE4LjQxNDJWMTNMMS45OTk3NCAxMi45OTk5WiIgc3R5bGU9ImZpbGw6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcGF0aD4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNDUuMDAxMTAxLCA0LjExNDMzMSkiIHN0eWxlPSIiPgogICAgICA8cGF0aCBkPSJNMS45OTk3NCAxMi45OTk5TDEuOTk5NiAxMUwxNS41ODU4IDExVjUuNTg1ODJMMjIgMTJMMTUuNTg1OCAxOC40MTQyVjEzTDEuOTk5NzQgMTIuOTk5OVoiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3BhdGg+CiAgICA8L2c+CiAgPC9nPgogIDxnIHRyYW5zZm9ybT0ibWF0cml4KDAsIDAuOTk5OTk5LCAtMS4wMDAwMDEsIDAsIC01OS4yODE3MjgsIDc4LjY3NTA5NikiIHN0eWxlPSJ0cmFuc2Zvcm0tb3JpZ2luOiAxNTBweCAyNy41cHg7Ij4KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KC0yLjQ5OTk1LCAwLCAwLCAxLjk0ODgwNCwgMTU0Ljk5ODkwNCwgNC4xMTQzMykiIHN0eWxlPSIiPgogICAgICA8cGF0aCBkPSJNMS45OTk3NCAxMi45OTk5TDEuOTk5NiAxMUwxNS41ODU4IDExVjUuNTg1ODJMMjIgMTJMMTUuNTg1OCAxOC40MTQyVjEzTDEuOTk5NzQgMTIuOTk5OVoiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3BhdGg+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgyLjQ5OTk1LCAwLCAwLCAxLjk0ODgwNCwgMTQ1LjAwMTEwMSwgNC4xMTQzMzEpIiBzdHlsZT0iIj4KICAgICAgPHBhdGggZD0iTTEuOTk5NzQgMTIuOTk5OUwxLjk5OTYgMTFMMTUuNTg1OCAxMVY1LjU4NTgyTDIyIDEyTDE1LjU4NTggMTguNDE0MlYxM0wxLjk5OTc0IDEyLjk5OTlaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyI+PC9wYXRoPgogICAgPC9nPgogIDwvZz4KPC9zdmc+" +RectIcon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+DQogIDxlbGxpcHNlIHN0eWxlPSJmaWxsOiByZ2IoMjE2LCAwLCA4Mik7IiBjeD0iMTAiIGN5PSIxMCIgcng9IjEwIiByeT0iMTAiPjwvZWxsaXBzZT4NCiAgPGVsbGlwc2Ugc3R5bGU9ImZpbGw6IHJnYigyNTUsIDAsIDk3KTsiIGN4PSIxMCIgY3k9IjEwIiByeD0iOSIgcnk9IjkiPjwvZWxsaXBzZT4NCiAgPHJlY3QgeD0iNi45ODMiIHk9IjcuMDE1IiB3aWR0aD0iNy4yMTYiIGhlaWdodD0iNy4yMTYiIHN0eWxlPSJmaWxsOiBub25lOyBzdHJva2U6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcmVjdD4NCiAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wODUwMzksIDAsIDAsIDAuMDg1MDM5LCAtMi4xNjQ3NzgsIDIuMjg5ODk0KSIgc3R5bGU9IiI+DQogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoLTIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNTQuOTk4OTA0LCA0LjExNDMzKSIgc3R5bGU9IiI+DQogICAgICA8cGF0aCBkPSJNMS45OTk3NCAxMi45OTk5TDEuOTk5NiAxMUwxNS41ODU4IDExVjUuNTg1ODJMMjIgMTJMMTUuNTg1OCAxOC40MTQyVjEzTDEuOTk5NzQgMTIuOTk5OVoiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3BhdGg+DQogICAgPC9nPg0KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNDUuMDAxMTAxLCA0LjExNDMzMSkiIHN0eWxlPSIiPg0KICAgICAgPHBhdGggZD0iTTEuOTk5NzQgMTIuOTk5OUwxLjk5OTYgMTFMMTUuNTg1OCAxMVY1LjU4NTgyTDIyIDEyTDE1LjU4NTggMTguNDE0MlYxM0wxLjk5OTc0IDEyLjk5OTlaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyI+PC9wYXRoPg0KICAgIDwvZz4NCiAgPC9nPg0KICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgwLCAtMC4yMTI1OTIsIC0wLjE2NTcyMywgMCwgNi44Mzk1NzIsIDExLjEzMzc4OSkiIHN0eWxlPSIiPg0KICAgIDxwYXRoIGQ9Ik0xLjk5OTc0IDEyLjk5OTlMMS45OTk2IDExTDE1LjU4NTggMTFWNS41ODU4MkwyMiAxMkwxNS41ODU4IDE4LjQxNDJWMTNMMS45OTk3NCAxMi45OTk5WiIgc3R5bGU9ImZpbGw6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcGF0aD4NCiAgPC9nPg0KICA8cGF0aCBkPSJNIDIuNzI1IDEzIEwgMi43MjUgMTIuNjY5IEwgNS42MTMgMTIuNjY5IEwgNS42MTMgMTEuNzcxIEwgNi45NzcgMTIuODM0IEwgNS42MTMgMTMuODk4IEwgNS42MTMgMTMgTCAyLjcyNSAxMyBaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2Utd2lkdGg6IDIuMjI0OyB0cmFuc2Zvcm0tYm94OiBmaWxsLWJveDsgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTsiIHRyYW5zZm9ybT0ibWF0cml4KDAsIDEuMDAwMDA3LCAtMC45OTk5OTMsIDAsIDAuMDAwMDAyLCAwKSI+PC9wYXRoPg0KPC9zdmc+" From ac426cccac32613d73e2b77decfbaaedd7871ef2 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:27:21 -0400 Subject: [PATCH 07/22] Update and rename placeholder to static_Rect.js --- static/extensions/IrshaadAli/placeholder | 1 - static/extensions/IrshaadAli/static_Rect.js | 805 ++++++++++++++++++++ 2 files changed, 805 insertions(+), 1 deletion(-) delete mode 100644 static/extensions/IrshaadAli/placeholder create mode 100644 static/extensions/IrshaadAli/static_Rect.js diff --git a/static/extensions/IrshaadAli/placeholder b/static/extensions/IrshaadAli/placeholder deleted file mode 100644 index 8b1378917..000000000 --- a/static/extensions/IrshaadAli/placeholder +++ /dev/null @@ -1 +0,0 @@ - diff --git a/static/extensions/IrshaadAli/static_Rect.js b/static/extensions/IrshaadAli/static_Rect.js new file mode 100644 index 000000000..985607e68 --- /dev/null +++ b/static/extensions/IrshaadAli/static_Rect.js @@ -0,0 +1,805 @@ +(function (Scratch) { + const Cast = Scratch.Cast + const vm = Scratch.vm + + if (!vm.jwVector) vm.extensionManager.loadExtensionIdSync('jwVector') + + const jwVector = vm.jwVector + const jwVectorType = jwVector.Type + + /** + * @param {number} x + * @returns {string} + */ + function formatNumber(x) { + if (x >= 1e6) { + return x.toExponential(4) + } else { + x = Math.floor(x * 1000) / 1000 + return x.toFixed(Math.min(3, (String(x).split('.')[1] || '').length)) + } + } + + /** + @param {jwVectorType, Array} x + @returns {[number, number]} + */ + function parseToArray(x) { + if (x instanceof jwVectorType && x.length == 2) { return [x.x, x.y] } + if (x instanceof Array) { return x } + + } + + function span(text) { + let el = document.createElement('span') + el.innerHTML = text + el.style.display = 'hidden' + el.style.whiteSpace = 'nowrap' + el.style.width = '100%' + el.style.textAlign = 'center' + return el + } + + class RectType { + customId = "IAliRect" + + constructor(x = 0, y = 0, width = 0, height = 0) { + this.x = isNaN(x) ? 0 : x + this.y = isNaN(y) ? 0 : y + this.width = isNaN(width) ? 0 : width + this.height = isNaN(height) ? 0 : height + } + + static toRect(x) { + if (x instanceof RectType) return x + if (x instanceof Array && x.length == 4) return new RectType(x[0], x[1], x[2], x[3]) + if (x instanceof Array && x.length == 2) return new RectType(x[0][0], x[0][1], x[1][0], x[1][1]) + if (String(x).split(',')) { + let array = String(x).split(',') + return new RectType( + Cast.toNumber(array[0]), + Cast.toNumber(array[1]), + Cast.toNumber(array[2]), + Cast.toNumber(array[3]) + ) + } + return new RectType(0, 0, 0,0) + } + + IAliRectHandler() { + return "Rect" + } + + toString() { + return `${this.x},${this.y},${this.width},${this.height}` + } + + toMonitorContent = () => span(this.toString()) + + toReporterContent() { + let root = document.createElement('div') + root.style.display = 'flex' + root.style.width = "200px" + root.style.overflow = "hidden" + + let details = document.createElement('div') + details.style.display = 'flex' + details.style.flexDirection = 'column' + details.style.justifyContent = 'center' + details.style.width = "100px" + + details.appendChild(span(`X: ${formatNumber(this.x)}`)) + details.appendChild(span(`Y: ${formatNumber(this.y)}`)) + details.appendChild(span(`W: ${formatNumber(this.width)}`)) + details.appendChild(span(`H: ${formatNumber(this.height)}`)) + + root.appendChild(details) + + let square = document.createElement("div") + square.style.width = "84px" + square.style.height = "84px" + square.style.margin = "8px" + square.style.border = "4px solid black" + square.style.boxSizing = "border-box" + + root.append(square) + return root + } + + get offsets() { + return { + 'left': this.width / -2.0, + 'top': this.height / 2.0, + 'right': this.width / 2.0, + 'bottom': this.height / -2.0, + 'center': 0 + } + } + + get singlePoints() { + return { + 'top': this.y + this.offsets.top, + 'left': this.x + this.offsets.left, + 'right': this.x + this.offsets.right, + 'bottom': this.y + this.offsets.bottom, + } + } + + get topleft() { + return new jwVectorType(this.singlePoints.left, this.singlePoints.top) + } + get midtop() { + return new jwVectorType(this.x, this.singlePoints.top) + } + get topright() { + return new jwVectorType(this.singlePoints.right, this.singlePoints.top) + } + get midleft() { + return new jwVectorType(this.singlePoints.left, this.y) + } + get center() { + return new jwVectorType(this.x, this.y) + } + get midright() { + return new jwVectorType(this.singlePoints.right, this.y) + } + get bottomleft() { + return new jwVectorType(this.singlePoints.left, this.singlePoints.bottom) + } + get midbottom() { + return new jwVectorType(this.x, this.singlePoints.bottom) + } + get bottomright() { + return new jwVectorType(this.singlePoints.right, this.singlePoints.bottom) + } + + set topleft(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.left + this.y = values[1] - this.singlePoints.top + } + + set midtop(value) { + let values = parseToArray(value) + this.x = values[0] + this.y = values[1] - this.singlePoints.top + } + + set topright(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.right + this.y = values[1] - this.singlePoints.top + } + + set midleft(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.left + this.y = values[1] + } + + set center(value) { + let values = parseToArray(value) + this.x = values[0] + this.y = values[1] + } + + set midright(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.right + this.y = values[1] + } + + set bottomleft(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.left + this.y = values[1] - this.singlePoints.bottom + } + set midbottom(value) { + let values = parseToArray(value) + this.x = values[0] + this.y = values[1] - this.singlePoints.bottom + } + set bottomright(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.right + this.y = values[1] - this.singlePoints.bottom + } + + get size() { + return jwVectorType(this.width, this.height) + } + + set size(value) { + let values = parseToArray(value) + this.width = isNaN(values[0]) ? 0 : values[0] + this.height = isNaN(values[1]) ? 0 : values[1] + } + + + } + + const Rect = { + Type: RectType, + Block: { + blockType: Scratch.BlockType.REPORTER, + blockShape: Scratch.BlockShape.SQUARE, + forceOutputType: "Rect", + disableMonitor: true, + allowDropAnywhere: true, + }, + Argument: { + shape: Scratch.BlockShape.SQUARE, + check: ["Rect"] + } + } + + const RectArgType1 = { + type: Scratch.ArgumentType.NUMBER, + defaultValue: 0 + } + + + + class Extension { + constructor() { + vm.IAliRect = Rect + vm.runtime.registerSerializer( + "IAliRect", + v => [v.x, v.y, v.width, v.height], + v => new RectType(v.x, v.y, v.width, v.height) + ) + } + + getInfo() { + return { + id: "IAliRect", + name: "Rect", + color1: "#ff0061", + color2: "#d80052", + menuIconURI: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+DQogIDxlbGxpcHNlIHN0eWxlPSJmaWxsOiByZ2IoMjE2LCAwLCA4Mik7IiBjeD0iMTAiIGN5PSIxMCIgcng9IjEwIiByeT0iMTAiPjwvZWxsaXBzZT4NCiAgPGVsbGlwc2Ugc3R5bGU9ImZpbGw6IHJnYigyNTUsIDAsIDk3KTsiIGN4PSIxMCIgY3k9IjEwIiByeD0iOSIgcnk9IjkiPjwvZWxsaXBzZT4NCiAgPHJlY3QgeD0iNi45ODMiIHk9IjcuMDE1IiB3aWR0aD0iNy4yMTYiIGhlaWdodD0iNy4yMTYiIHN0eWxlPSJmaWxsOiBub25lOyBzdHJva2U6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcmVjdD4NCiAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wODUwMzksIDAsIDAsIDAuMDg1MDM5LCAtMi4xNjQ3NzgsIDIuMjg5ODk0KSIgc3R5bGU9IiI+DQogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoLTIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNTQuOTk4OTA0LCA0LjExNDMzKSIgc3R5bGU9IiI+DQogICAgICA8cGF0aCBkPSJNMS45OTk3NCAxMi45OTk5TDEuOTk5NiAxMUwxNS41ODU4IDExVjUuNTg1ODJMMjIgMTJMMTUuNTg1OCAxOC40MTQyVjEzTDEuOTk5NzQgMTIuOTk5OVoiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3BhdGg+DQogICAgPC9nPg0KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNDUuMDAxMTAxLCA0LjExNDMzMSkiIHN0eWxlPSIiPg0KICAgICAgPHBhdGggZD0iTTEuOTk5NzQgMTIuOTk5OUwxLjk5OTYgMTFMMTUuNTg1OCAxMVY1LjU4NTgyTDIyIDEyTDE1LjU4NTggMTguNDE0MlYxM0wxLjk5OTc0IDEyLjk5OTlaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyI+PC9wYXRoPg0KICAgIDwvZz4NCiAgPC9nPg0KICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgwLCAtMC4yMTI1OTIsIC0wLjE2NTcyMywgMCwgNi44Mzk1NzIsIDExLjEzMzc4OSkiIHN0eWxlPSIiPg0KICAgIDxwYXRoIGQ9Ik0xLjk5OTc0IDEyLjk5OTlMMS45OTk2IDExTDE1LjU4NTggMTFWNS41ODU4MkwyMiAxMkwxNS41ODU4IDE4LjQxNDJWMTNMMS45OTk3NCAxMi45OTk5WiIgc3R5bGU9ImZpbGw6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcGF0aD4NCiAgPC9nPg0KICA8cGF0aCBkPSJNIDIuNzI1IDEzIEwgMi43MjUgMTIuNjY5IEwgNS42MTMgMTIuNjY5IEwgNS42MTMgMTEuNzcxIEwgNi45NzcgMTIuODM0IEwgNS42MTMgMTMuODk4IEwgNS42MTMgMTMgTCAyLjcyNSAxMyBaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2Utd2lkdGg6IDIuMjI0OyB0cmFuc2Zvcm0tYm94OiBmaWxsLWJveDsgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTsiIHRyYW5zZm9ybT0ibWF0cml4KDAsIDEuMDAwMDA3LCAtMC45OTk5OTMsIDAsIDAuMDAwMDAyLCAwKSI+PC9wYXRoPg0KPC9zdmc+", + blocks: [ + { + blockType: Scratch.BlockType.LABEL, + text: 'Sprite-Based Rects' + }, + { + opcode: 'fromSprite', + text: 'from [SPRITE]', + arguments: { + SPRITE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "" + } + }, + ...Rect.Block + }, + { + blockType: Scratch.BlockType.LABEL, + text: 'Rect Initialization' + }, + { + opcode: 'newRectX_Y_W_H', + text: 'Rect X: [X] Y: [Y] W: [W] H: [H]', + arguments: { + X: RectArgType1, + Y: RectArgType1, + W: RectArgType1, + H: RectArgType1, + }, + ...Rect.Block + }, + { + opcode: 'newRectXY_WH', + text: "Rect XY: [XY] WH: [WH]", + arguments: { + XY: vm.jwVector.Argument, + WH: vm.jwVector.Argument, + }, + ...Rect.Block + }, + { + blockType: Scratch.BlockType.LABEL, + text: 'Getters' + }, + { + blockType: Scratch.BlockType.LABEL, + text: "Single Positional Value", + }, + { + opcode: 'getRectX', + text: 'Get [RECT] X', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + { + opcode: 'getRectY', + text: 'Get [RECT] Y', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + { + opcode: 'getRectW', + text: 'Get [RECT] Width', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + { + opcode: 'getRectH', + text: 'Get [RECT] Height', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + + { + opcode: 'getRectTopLeftX', + text: 'Get [RECT] TopLeft X', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + + { + opcode: 'getRectTopLeftY', + text: 'Get [RECT] TopLeft Y', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + + { + blockType: Scratch.BlockType.LABEL, + text: 'Vector Positional Value', + }, + + { + opcode: 'getRectTopLeft', + text: 'Get [RECT] TopLeft', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...jwVector.Block + }, + + { + opcode: 'getRectMidTop', + text: 'Get [RECT] MidTop', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...jwVector.Block + }, + + { + opcode: 'getRectTopRight', + text: 'Get [RECT] TopRight', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...jwVector.Block + }, + + { + opcode: 'getRectMidLeft', + text: 'Get [RECT] MidLeft', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...jwVector.Block + }, + + { + opcode: 'getRectCenter', + text: 'Get [RECT] Center', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...jwVector.Block + }, + + { + opcode: 'getRectMidRight', + text: 'Get [RECT] MidRight', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...jwVector.Block + }, + + { + opcode: 'getRectBottomLeft', + text: 'Get [RECT] BottomLeft', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...jwVector.Block + }, + + { + opcode: 'getRectMidBottom', + text: 'Get [RECT] MidBottom', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...jwVector.Block + }, + + { + opcode: 'getRectBottomRight', + text: 'Get [RECT] BottomRight', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...jwVector.Block + }, + + { + blockType: Scratch.BlockType.LABEL, + text: 'Setters', + }, + { + blockType: Scratch.BlockType.LABEL, + text: 'Single Positional Value', + }, + + { + opcode: 'setRectX', + text: 'Set [RECT] X [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: RectArgType1, + }, + ...Rect.Block + }, + + { + opcode: 'setRectY', + text: 'Set [RECT] Y [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: RectArgType1 + }, + ...Rect.Block + }, + + { + opcode: 'setRectW', + text: 'Set [RECT] W [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: RectArgType1 + }, + ...Rect.Block + }, + + { + opcode: 'setRectH', + text: 'Set [RECT] H [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: RectArgType1 + }, + ...Rect.Block + }, + + { + blockType: Scratch.BlockType.LABEL, + text: 'Vector Positional Value', + }, + + { + opcode: 'setRectTopLeft', + text: 'Set [RECT] TopLeft [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectMidTop', + text: 'Set [RECT] MidTop [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectTopRight', + text: 'Set [RECT] TopRight [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectMidLeft', + text: 'Set [RECT] MidLeft [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectCenter', + text: 'Set [RECT] Center [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectMidRight', + text: 'Set [RECT] MidRight [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectBottomLeft', + text: 'Set [RECT] BottomLeft [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectMidBottom', + text: 'Set [RECT] MidBottom [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectBottomRight', + text: 'Set [RECT] BottomRight [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: jwVector.Argument + }, + ...Rect.Block + } + ], + menus: { + roundingFunctions: { + acceptReporters: false, + items: [ + { + text: 'round', + value: 'round' + }, + { + text: 'ceil', // might as well go full in on the inconsistencies since we are already doing "round of" + value: 'ceil' + }, + { + text: 'floor', + value: 'floor' + } + ] + } + } + } + } + + /** + * + * @param args + * @returns {RectType} + */ + newRectX_Y_W_H(args) { + const X = Cast.toNumber(args.X) + const Y = Cast.toNumber(args.Y) + const W = Cast.toNumber(args.W) + const H = Cast.toNumber(args.H) + + return new RectType(X, Y, W, H) + } + + /** + * + * @param args + * @returns {RectType} + */ + newRectXY_WH(args) { + const XY = args.XY + const WH = args.WH + + return new RectType(XY.x, XY.y, WH.x, WH.y) + } + + getRectX(args) { + return RectType.toRect(args.RECT).x + } + + getRectY(args) { + return RectType.toRect(args.RECT).y + } + + getRectW(args) { + return RectType.toRect(args.RECT).width + } + getRectH(args) { + return RectType.toRect(args.RECT).height + } + + getRectTopLeftX(args) { + return RectType.toRect(args.RECT).singlePoints.left + } + + getRectTopLeftY(args) { + return RectType.toRect(args.RECT).singlePoints.top + } + + getRectTopLeft(args) { + return RectType.toRect(args.RECT).topleft + } + + getRectMidTop(args) { + return RectType.toRect(args.RECT).midtop + } + getRectTopRight(args) { + return RectType.toRect(args.RECT).topright + } + + getRectMidLeft(args) { + return RectType.toRect(args.RECT).midleft + } + getRectCenter(args) { + return RectType.toRect(args.RECT).center + } + getRectMidRight(args) { + return RectType.toRect(args.RECT).midright + } + + getRectBottomLeft(args) { + return RectType.toRect(args.RECT).bottomleft + } + getRectMidBottom(args) { + return RectType.toRect(args.RECT).midbottom + } + getRectBottomRight(args) { + return RectType.toRect(args.RECT).bottomright + } + + setRectX(args) { + let rect = RectType.toRect(args.RECT) + rect.x = args.VALUE + return rect + } + + setRectY(args) { + let rect = RectType.toRect(args.RECT) + rect.y = args.VALUE + return rect + } + + setRectW(args) { + let rect = RectType.toRect(args.RECT) + rect.width = args.VALUE + return rect + } + + setRectH(args) { + let rect = RectType.toRect(args.RECT) + rect.height = args.VALUE + return rect + } + + setRectTopLeft(args) { + let rect = RectType.toRect(args.RECT) + rect.topleft = args.VALUE + return rect + } + setRectMidTop(args) { + let rect = RectType.toRect(args.RECT) + rect.midtop = args.VALUE + return rect + } + setRectTopRight(args) { + let rect = RectType.toRect(args.RECT) + rect.topright = args.VALUE + return rect + } + + setRectMidLeft(args) { + let rect = RectType.toRect(args.RECT) + rect.midleft = args.VALUE + return rect + } + + setRectCenter(args) { + let rect = RectType.toRect(args.RECT) + rect.center = args.VALUE + return rect + } + + setRectMidRight(args) { + let rect = RectType.toRect(args.RECT) + rect.midright = args.VALUE + return rect + } + + setRectBottomLeft(args) { + let rect = RectType.toRect(args.RECT) + rect.bottomleft = args.VALUE + return rect + } + + setRectMidBottom(args) { + let rect = RectType.toRect(args.RECT) + rect.midbottom = args.VALUE + return rect + } + + setRectBottomRight(args) { + let rect = RectType.toRect(args.RECT) + rect.bottomright = args.VALUE + return rect + } + + fromSprite({SPRITE}) { + let spr = vm.runtime.getSpriteTargetByName(SPRITE) + console.log(spr) + let x = spr.x + let y = spr.y + + let costume = spr.sprite.costumes_[spr.currentCostume] + let asset = costume.asset + let assetType = asset.assetType.name + let size = costume.size + + return new RectType(x, y, assetType == "ImageBitmap" ? size[0]/2 : size[0], assetType == "ImageBitmap" ? size[1]/2 : size[1]) + } + } + + Scratch.extensions.register(new Extension()) +})(Scratch); From fd89264f9924a4714f4c191a0730a6627226143b Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:46:53 -0400 Subject: [PATCH 08/22] Add files via upload --- static/extensions/IrshaadAli/pmodRect.js | 776 +++++++++++++++++++++++ 1 file changed, 776 insertions(+) create mode 100644 static/extensions/IrshaadAli/pmodRect.js diff --git a/static/extensions/IrshaadAli/pmodRect.js b/static/extensions/IrshaadAli/pmodRect.js new file mode 100644 index 000000000..da7eb04f8 --- /dev/null +++ b/static/extensions/IrshaadAli/pmodRect.js @@ -0,0 +1,776 @@ +// !! READ THIS !! +// This is only a "Translated" version, please check for any errors +const BlockType = require('../../extension-support/block-type') +const BlockShape = require('../../extension-support/block-shape') +const ArgumentType = require('../../extension-support/argument-type') +const TargetType = require('../../extension-support/target-type') +const Cast = require('../../util/cast') + +function formatNumber(x) { + if (x >= 1e6) { + return x.toExponential(4) + } else { + x = Math.floor(x * 1000) / 1000 + return x.toFixed(Math.min(3, (String(x).split('.')[1] || '').length)) + } +} + +/** + @param {vm.jwVector.Type, Array} x + @returns {[number, number]} + */ +function parseToArray(x) { + if (x instanceof vm.jwVector.Type && x.length == 2) { return [x.x, x.y] } + if (x instanceof Array) { return x } +} + +function span(text) { + let el = document.createElement('span') + el.innerHTML = text + el.style.display = 'hidden' + el.style.whiteSpace = 'nowrap' + el.style.width = '100%' + el.style.textAlign = 'center' + return el +} + +class RectType { + customId = "IAliRect" + + constructor(x = 0, y = 0, width = 0, height = 0) { + this.x = x + this.y = y + this.width = width + this.height = height + } + + static toRect(x) { + if (x instanceof RectType) return x + if (x instanceof Array && x.length == 4) return new RectType(x[0], x[1], x[2], x[3]) + if (x instanceof Array && x.length == 2) return new RectType(x[0][0], x[0][1], x[1][0], x[1][1]) + if (String(x).split(',')) { + let array = String(x).split(',') + return new RectType( + Cast.toNumber(array[0]), + Cast.toNumber(array[1]), + Cast.toNumber(array[2]), + Cast.toNumber(array[3]) + ) + } + return new RectType(0, 0, 0,0) + } + + IAliRectHandler() { + return "Rect" + } + + toString() { + return `${this.x},${this.y},${this.width},${this.height}` + } + + toMonitorContent = () => span(this.toString()) + + toReporterContent() { + let root = document.createElement('div') + root.style.display = 'flex' + root.style.width = "200px" + root.style.overflow = "hidden" + + let details = document.createElement('div') + details.style.display = 'flex' + details.style.flexDirection = 'column' + details.style.justifyContent = 'center' + details.style.width = "100px" + + details.appendChild(span(`X: ${formatNumber(this.x)}`)) + details.appendChild(span(`Y: ${formatNumber(this.y)}`)) + details.appendChild(span(`W: ${formatNumber(this.width)}`)) + details.appendChild(span(`H: ${formatNumber(this.height)}`)) + + root.appendChild(details) + + let square = document.createElement("div") + square.style.width = "84px" + square.style.height = "84px" + square.style.margin = "8px" + square.style.border = "4px solid black" + square.style.boxSizing = "border-box" + + root.append(square) + return root + } + + get offsets() { + return { + 'left': this.width / -2.0, + 'top': this.height / 2.0, + 'right': this.width / 2.0, + 'bottom': this.height / -2.0, + 'center': 0 + } + } + + get singlePoints() { + return { + 'top': this.y + this.offsets.top, + 'left': this.x + this.offsets.left, + 'right': this.x + this.offsets.right, + 'bottom': this.y + this.offsets.bottom, + } + } + + get topleft() { + return new vm.jwVector.Type(this.singlePoints.left, this.singlePoints.top) + } + get midtop() { + return new vm.jwVector.Type(this.x, this.singlePoints.top) + } + get topright() { + return new vm.jwVector.Type(this.singlePoints.right, this.singlePoints.top) + } + get midleft() { + return new vm.jwVector.Type(this.singlePoints.left, this.y) + } + get center() { + return new vm.jwVector.Type(this.x, this.y) + } + get midright() { + return new vm.jwVector.Type(this.singlePoints.right, this.y) + } + get bottomleft() { + return new vm.jwVector.Type(this.singlePoints.left, this.singlePoints.bottom) + } + get midbottom() { + return new vm.jwVector.Type(this.x, this.singlePoints.bottom) + } + get bottomright() { + return new vm.jwVector.Type(this.singlePoints.right, this.singlePoints.bottom) + } + + set topleft(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.left + this.y = values[1] - this.singlePoints.top + } + + set midtop(value) { + let values = parseToArray(value) + this.x = values[0] + this.y = values[1] - this.singlePoints.top + } + + set topright(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.right + this.y = values[1] - this.singlePoints.top + } + + set midleft(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.left + this.y = values[1] + } + + set center(value) { + let values = parseToArray(value) + this.x = values[0] + this.y = values[1] + } + + set midright(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.right + this.y = values[1] + } + + set bottomleft(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.left + this.y = values[1] - this.singlePoints.bottom + } + set midbottom(value) { + let values = parseToArray(value) + this.x = values[0] + this.y = values[1] - this.singlePoints.bottom + } + set bottomright(value) { + let values = parseToArray(value) + this.x = values[0] - this.singlePoints.right + this.y = values[1] - this.singlePoints.bottom + } + + get size() { + return vm.jwVector.Type(this.width, this.height) + } + + set size(value) { + let values = parseToArray(value) + this.width = isNaN(values[0]) ? 0 : values[0] + this.height = isNaN(values[1]) ? 0 : values[1] + } +} + +const Rect = { + Type: RectType, + Block: { + blockType: BlockType.REPORTER, + blockShape: BlockShape.SQUARE, + forceOutputType: 'Rect', + disableMonitor: true, + allowDropAnywhere: true, + }, + Argument: { + shape: BlockShape.SQUARE, + check: ["Rect"] + }, + NumArg: { + type: ArgumentType.NUMBER, + defaultValue: 0, + } +} + +class Extension { + constructor() { + vm.IAliRect = Rect + vm.runtime.registerSerializer( + "IAliRect", + v => [v.x, v.y, v.width, v.height], + v => new RectType(v.x, v.y, v.width, v.height) + ) + + if (!vm.jwVector) vm.extensionManager.loadExtensionIdSync('jwVector') + } + + getInfo() { + return { + id: "IAliRect", + name: "Rect", + color1: "#ff0061", + color2: "#d80052", + menuIconURI: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+DQogIDxlbGxpcHNlIHN0eWxlPSJmaWxsOiByZ2IoMjE2LCAwLCA4Mik7IiBjeD0iMTAiIGN5PSIxMCIgcng9IjEwIiByeT0iMTAiPjwvZWxsaXBzZT4NCiAgPGVsbGlwc2Ugc3R5bGU9ImZpbGw6IHJnYigyNTUsIDAsIDk3KTsiIGN4PSIxMCIgY3k9IjEwIiByeD0iOSIgcnk9IjkiPjwvZWxsaXBzZT4NCiAgPHJlY3QgeD0iNi45ODMiIHk9IjcuMDE1IiB3aWR0aD0iNy4yMTYiIGhlaWdodD0iNy4yMTYiIHN0eWxlPSJmaWxsOiBub25lOyBzdHJva2U6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcmVjdD4NCiAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wODUwMzksIDAsIDAsIDAuMDg1MDM5LCAtMi4xNjQ3NzgsIDIuMjg5ODk0KSIgc3R5bGU9IiI+DQogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoLTIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNTQuOTk4OTA0LCA0LjExNDMzKSIgc3R5bGU9IiI+DQogICAgICA8cGF0aCBkPSJNMS45OTk3NCAxMi45OTk5TDEuOTk5NiAxMUwxNS41ODU4IDExVjUuNTg1ODJMMjIgMTJMMTUuNTg1OCAxOC40MTQyVjEzTDEuOTk5NzQgMTIuOTk5OVoiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3BhdGg+DQogICAgPC9nPg0KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNDUuMDAxMTAxLCA0LjExNDMzMSkiIHN0eWxlPSIiPg0KICAgICAgPHBhdGggZD0iTTEuOTk5NzQgMTIuOTk5OUwxLjk5OTYgMTFMMTUuNTg1OCAxMVY1LjU4NTgyTDIyIDEyTDE1LjU4NTggMTguNDE0MlYxM0wxLjk5OTc0IDEyLjk5OTlaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyI+PC9wYXRoPg0KICAgIDwvZz4NCiAgPC9nPg0KICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgwLCAtMC4yMTI1OTIsIC0wLjE2NTcyMywgMCwgNi44Mzk1NzIsIDExLjEzMzc4OSkiIHN0eWxlPSIiPg0KICAgIDxwYXRoIGQ9Ik0xLjk5OTc0IDEyLjk5OTlMMS45OTk2IDExTDE1LjU4NTggMTFWNS41ODU4MkwyMiAxMkwxNS41ODU4IDE4LjQxNDJWMTNMMS45OTk3NCAxMi45OTk5WiIgc3R5bGU9ImZpbGw6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcGF0aD4NCiAgPC9nPg0KICA8cGF0aCBkPSJNIDIuNzI1IDEzIEwgMi43MjUgMTIuNjY5IEwgNS42MTMgMTIuNjY5IEwgNS42MTMgMTEuNzcxIEwgNi45NzcgMTIuODM0IEwgNS42MTMgMTMuODk4IEwgNS42MTMgMTMgTCAyLjcyNSAxMyBaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2Utd2lkdGg6IDIuMjI0OyB0cmFuc2Zvcm0tYm94OiBmaWxsLWJveDsgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTsiIHRyYW5zZm9ybT0ibWF0cml4KDAsIDEuMDAwMDA3LCAtMC45OTk5OTMsIDAsIDAuMDAwMDAyLCAwKSI+PC9wYXRoPg0KPC9zdmc+", + blocks: [ + { + blockType: Scratch.BlockType.LABEL, + text: 'Sprite-Based Rects' + }, + { + opcode: 'fromSprite', + text: 'from [SPRITE]', + arguments: { + SPRITE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "" + } + }, + ...Rect.Block + }, + { + blockType: Scratch.BlockType.LABEL, + text: 'Rect Initialization' + }, + { + opcode: 'newRectX_Y_W_H', + text: 'Rect X: [X] Y: [Y] W: [W] H: [H]', + arguments: { + X: Rect.NumArg, + Y: Rect.NumArg, + W: Rect.NumArg, + H: Rect.NumArg, + }, + ...Rect.Block + }, + { + opcode: 'newRectXY_WH', + text: "Rect XY: [XY] WH: [WH]", + arguments: { + XY: vm.vm.jwVector.Argument, + WH: vm.vm.jwVector.Argument, + }, + ...Rect.Block + }, + { + blockType: Scratch.BlockType.LABEL, + text: 'Getters' + }, + { + blockType: Scratch.BlockType.LABEL, + text: "Single Positional Value", + }, + { + opcode: 'getRectX', + text: 'Get [RECT] X', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + { + opcode: 'getRectY', + text: 'Get [RECT] Y', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + { + opcode: 'getRectW', + text: 'Get [RECT] Width', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + { + opcode: 'getRectH', + text: 'Get [RECT] Height', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + + { + opcode: 'getRectTopLeftX', + text: 'Get [RECT] TopLeft X', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + + { + opcode: 'getRectTopLeftY', + text: 'Get [RECT] TopLeft Y', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + } + }, + + { + blockType: Scratch.BlockType.LABEL, + text: 'Vector Positional Value', + }, + + { + opcode: 'getRectTopLeft', + text: 'Get [RECT] TopLeft', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...vm.jwVector.Block + }, + + { + opcode: 'getRectMidTop', + text: 'Get [RECT] MidTop', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...vm.jwVector.Block + }, + + { + opcode: 'getRectTopRight', + text: 'Get [RECT] TopRight', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...vm.jwVector.Block + }, + + { + opcode: 'getRectMidLeft', + text: 'Get [RECT] MidLeft', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...vm.jwVector.Block + }, + + { + opcode: 'getRectCenter', + text: 'Get [RECT] Center', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...vm.jwVector.Block + }, + + { + opcode: 'getRectMidRight', + text: 'Get [RECT] MidRight', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...vm.jwVector.Block + }, + + { + opcode: 'getRectBottomLeft', + text: 'Get [RECT] BottomLeft', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...vm.jwVector.Block + }, + + { + opcode: 'getRectMidBottom', + text: 'Get [RECT] MidBottom', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...vm.jwVector.Block + }, + + { + opcode: 'getRectBottomRight', + text: 'Get [RECT] BottomRight', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument + }, + ...vm.jwVector.Block + }, + + { + blockType: Scratch.BlockType.LABEL, + text: 'Setters', + }, + { + blockType: Scratch.BlockType.LABEL, + text: 'Single Positional Value', + }, + + { + opcode: 'setRectX', + text: 'Set [RECT] X [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: Rect.NumArg, + }, + ...Rect.Block + }, + + { + opcode: 'setRectY', + text: 'Set [RECT] Y [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: Rect.NumArg + }, + ...Rect.Block + }, + + { + opcode: 'setRectW', + text: 'Set [RECT] W [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: Rect.NumArg + }, + ...Rect.Block + }, + + { + opcode: 'setRectH', + text: 'Set [RECT] H [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: Rect.NumArg + }, + ...Rect.Block + }, + + { + blockType: Scratch.BlockType.LABEL, + text: 'Vector Positional Value', + }, + + { + opcode: 'setRectTopLeft', + text: 'Set [RECT] TopLeft [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: vm.jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectMidTop', + text: 'Set [RECT] MidTop [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: vm.jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectTopRight', + text: 'Set [RECT] TopRight [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: vm.jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectMidLeft', + text: 'Set [RECT] MidLeft [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: vm.jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectCenter', + text: 'Set [RECT] Center [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: vm.jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectMidRight', + text: 'Set [RECT] MidRight [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: vm.jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectBottomLeft', + text: 'Set [RECT] BottomLeft [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: vm.jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectMidBottom', + text: 'Set [RECT] MidBottom [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: vm.jwVector.Argument + }, + ...Rect.Block + }, + + { + opcode: 'setRectBottomRight', + text: 'Set [RECT] BottomRight [VALUE]', + blockType: Scratch.BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + VALUE: vm.jwVector.Argument + }, + ...Rect.Block + } + ], + menus: { + roundingFunctions: { + acceptReporters: false, + items: [ + { + text: 'round', + value: 'round' + }, + { + text: 'ceil', // might as well go full in on the inconsistencies since we are already doing "round of" + value: 'ceil' + }, + { + text: 'floor', + value: 'floor' + } + ] + } + } + } + } + + newRectXY_WH(args) { + const XY = args.XY + const WH = args.WH + + return new RectType(XY.x, XY.y, WH.x, WH.y) + } + + getRectX(args) { + return RectType.toRect(args.RECT).x + } + + getRectY(args) { + return RectType.toRect(args.RECT).y + } + + getRectW(args) { + return RectType.toRect(args.RECT).width + } + getRectH(args) { + return RectType.toRect(args.RECT).height + } + + getRectTopLeftX(args) { + return RectType.toRect(args.RECT).singlePoints.left + } + + getRectTopLeftY(args) { + return RectType.toRect(args.RECT).singlePoints.top + } + + getRectTopLeft(args) { + return RectType.toRect(args.RECT).topleft + } + + getRectMidTop(args) { + return RectType.toRect(args.RECT).midtop + } + getRectTopRight(args) { + return RectType.toRect(args.RECT).topright + } + + getRectMidLeft(args) { + return RectType.toRect(args.RECT).midleft + } + getRectCenter(args) { + return RectType.toRect(args.RECT).center + } + getRectMidRight(args) { + return RectType.toRect(args.RECT).midright + } + + getRectBottomLeft(args) { + return RectType.toRect(args.RECT).bottomleft + } + getRectMidBottom(args) { + return RectType.toRect(args.RECT).midbottom + } + getRectBottomRight(args) { + return RectType.toRect(args.RECT).bottomright + } + + setRectX(args) { + let rect = RectType.toRect(args.RECT) + rect.x = args.VALUE + return rect + } + + setRectY(args) { + let rect = RectType.toRect(args.RECT) + rect.y = args.VALUE + return rect + } + + setRectW(args) { + let rect = RectType.toRect(args.RECT) + rect.width = args.VALUE + return rect + } + + setRectH(args) { + let rect = RectType.toRect(args.RECT) + rect.height = args.VALUE + return rect + } + + setRectTopLeft(args) { + let rect = RectType.toRect(args.RECT) + rect.topleft = args.VALUE + return rect + } + setRectMidTop(args) { + let rect = RectType.toRect(args.RECT) + rect.midtop = args.VALUE + return rect + } + setRectTopRight(args) { + let rect = RectType.toRect(args.RECT) + rect.topright = args.VALUE + return rect + } + + setRectMidLeft(args) { + let rect = RectType.toRect(args.RECT) + rect.midleft = args.VALUE + return rect + } + + setRectCenter(args) { + let rect = RectType.toRect(args.RECT) + rect.center = args.VALUE + return rect + } + + setRectMidRight(args) { + let rect = RectType.toRect(args.RECT) + rect.midright = args.VALUE + return rect + } + + setRectBottomLeft(args) { + let rect = RectType.toRect(args.RECT) + rect.bottomleft = args.VALUE + return rect + } + + setRectMidBottom(args) { + let rect = RectType.toRect(args.RECT) + rect.midbottom = args.VALUE + return rect + } + + setRectBottomRight(args) { + let rect = RectType.toRect(args.RECT) + rect.bottomright = args.VALUE + return rect + } + + fromSprite({SPRITE}) { + let spr = vm.runtime.getSpriteTargetByName(SPRITE) + console.log(spr) + let x = spr.x + let y = spr.y + + let costume = spr.sprite.costumes_[spr.currentCostume] + let asset = costume.asset + let assetType = asset.assetType.name + let size = costume.size + + return new RectType(x, y, assetType == "ImageBitmap" ? size[0]/2 : size[0], assetType == "ImageBitmap" ? size[1]/2 : size[1]) + } +} + +module.exports = Extension \ No newline at end of file From 280ffcd8b7c4226c26a421b4ce1f230dbfe00042 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:47:26 -0400 Subject: [PATCH 09/22] Update and rename pmodRect.js to TRANSLATED_Rect.js --- .../extensions/IrshaadAli/{pmodRect.js => TRANSLATED_Rect.js} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename static/extensions/IrshaadAli/{pmodRect.js => TRANSLATED_Rect.js} (96%) diff --git a/static/extensions/IrshaadAli/pmodRect.js b/static/extensions/IrshaadAli/TRANSLATED_Rect.js similarity index 96% rename from static/extensions/IrshaadAli/pmodRect.js rename to static/extensions/IrshaadAli/TRANSLATED_Rect.js index da7eb04f8..92d075f21 100644 --- a/static/extensions/IrshaadAli/pmodRect.js +++ b/static/extensions/IrshaadAli/TRANSLATED_Rect.js @@ -773,4 +773,4 @@ class Extension { } } -module.exports = Extension \ No newline at end of file +module.exports = Extension From b11a997f8416ab49616383934489bf2750d9a8b5 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:49:44 -0400 Subject: [PATCH 10/22] Create temp --- static/images/IrshaadAli/temp | 1 + 1 file changed, 1 insertion(+) create mode 100644 static/images/IrshaadAli/temp diff --git a/static/images/IrshaadAli/temp b/static/images/IrshaadAli/temp new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/static/images/IrshaadAli/temp @@ -0,0 +1 @@ + From 36950bf0aefaa957ed41e134ee5b0a9b5e306d58 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:50:11 -0400 Subject: [PATCH 11/22] Add files via upload --- static/images/IrshaadAli/Rect.svg | 22 ++++++++++++++++++++++ static/images/IrshaadAli/RectIcon.svg | 17 +++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 static/images/IrshaadAli/Rect.svg create mode 100644 static/images/IrshaadAli/RectIcon.svg diff --git a/static/images/IrshaadAli/Rect.svg b/static/images/IrshaadAli/Rect.svg new file mode 100644 index 000000000..3428eb77a --- /dev/null +++ b/static/images/IrshaadAli/Rect.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/images/IrshaadAli/RectIcon.svg b/static/images/IrshaadAli/RectIcon.svg new file mode 100644 index 000000000..835161615 --- /dev/null +++ b/static/images/IrshaadAli/RectIcon.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file From 0b4adb4f6801aaa108745e0689160607f8459c64 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:50:34 -0400 Subject: [PATCH 12/22] Delete static/images/IrshaadAli/temp --- static/images/IrshaadAli/temp | 1 - 1 file changed, 1 deletion(-) delete mode 100644 static/images/IrshaadAli/temp diff --git a/static/images/IrshaadAli/temp b/static/images/IrshaadAli/temp deleted file mode 100644 index 8b1378917..000000000 --- a/static/images/IrshaadAli/temp +++ /dev/null @@ -1 +0,0 @@ - From 97c3949aa4ac4d23209f3bd7662949c504463d27 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:50:55 -0400 Subject: [PATCH 13/22] Delete static/extensions/IrshaadAli/assets directory --- static/extensions/IrshaadAli/assets/Rect.svg | 22 ------------------- .../extensions/IrshaadAli/assets/RectIcon.svg | 17 -------------- .../IrshaadAli/assets/rect-links.txt | 2 -- 3 files changed, 41 deletions(-) delete mode 100644 static/extensions/IrshaadAli/assets/Rect.svg delete mode 100644 static/extensions/IrshaadAli/assets/RectIcon.svg delete mode 100644 static/extensions/IrshaadAli/assets/rect-links.txt diff --git a/static/extensions/IrshaadAli/assets/Rect.svg b/static/extensions/IrshaadAli/assets/Rect.svg deleted file mode 100644 index 3428eb77a..000000000 --- a/static/extensions/IrshaadAli/assets/Rect.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/static/extensions/IrshaadAli/assets/RectIcon.svg b/static/extensions/IrshaadAli/assets/RectIcon.svg deleted file mode 100644 index 835161615..000000000 --- a/static/extensions/IrshaadAli/assets/RectIcon.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/static/extensions/IrshaadAli/assets/rect-links.txt b/static/extensions/IrshaadAli/assets/rect-links.txt deleted file mode 100644 index 3c6828984..000000000 --- a/static/extensions/IrshaadAli/assets/rect-links.txt +++ /dev/null @@ -1,2 +0,0 @@ -Rect = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTg2Ij4KICA8ZGVmcz48L2RlZnM+CiAgPHJlY3Qgd2lkdGg9IjI5OS45ODIiIGhlaWdodD0iMTg2IiBzdHlsZT0icGFpbnQtb3JkZXI6IGZpbGw7IGZpbGwtcnVsZTogbm9uemVybzsgZmlsbDogcmdiKDIxNiwgMCwgODIpOyIgeD0iMC4wMDkiPjwvcmVjdD4KICA8cmVjdCB4PSI5LjU2IiB5PSI4LjczNiIgd2lkdGg9IjI4MC44ODEiIGhlaWdodD0iMTY4LjUyOCIgc3R5bGU9ImZpbGw6IHJnYigyNTUsIDAsIDk3KTsiPjwvcmVjdD4KICA8cmVjdCB4PSIxMTUuNzkyIiB5PSI2Mi43NDkiIHdpZHRoPSI4NC44NTMiIGhlaWdodD0iODQuODUzIiBzdHlsZT0iZmlsbDogbm9uZTsgc3Ryb2tlOiByZ2IoMjU1LCAyNTUsIDI1NSk7IHN0cm9rZS13aWR0aDogOHB4OyI+PC9yZWN0PgogIDxnIHRyYW5zZm9ybT0ibWF0cml4KDEsIDAsIDAsIDEsIDguMjE4MjU3LCA3LjE3NTE0OCkiPgogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoLTIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNTQuOTk4OTA0LCA0LjExNDMzKSIgc3R5bGU9IiI+CiAgICAgIDxwYXRoIGQ9Ik0xLjk5OTc0IDEyLjk5OTlMMS45OTk2IDExTDE1LjU4NTggMTFWNS41ODU4MkwyMiAxMkwxNS41ODU4IDE4LjQxNDJWMTNMMS45OTk3NCAxMi45OTk5WiIgc3R5bGU9ImZpbGw6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcGF0aD4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNDUuMDAxMTAxLCA0LjExNDMzMSkiIHN0eWxlPSIiPgogICAgICA8cGF0aCBkPSJNMS45OTk3NCAxMi45OTk5TDEuOTk5NiAxMUwxNS41ODU4IDExVjUuNTg1ODJMMjIgMTJMMTUuNTg1OCAxOC40MTQyVjEzTDEuOTk5NzQgMTIuOTk5OVoiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3BhdGg+CiAgICA8L2c+CiAgPC9nPgogIDxnIHRyYW5zZm9ybT0ibWF0cml4KDAsIDAuOTk5OTk5LCAtMS4wMDAwMDEsIDAsIC01OS4yODE3MjgsIDc4LjY3NTA5NikiIHN0eWxlPSJ0cmFuc2Zvcm0tb3JpZ2luOiAxNTBweCAyNy41cHg7Ij4KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KC0yLjQ5OTk1LCAwLCAwLCAxLjk0ODgwNCwgMTU0Ljk5ODkwNCwgNC4xMTQzMykiIHN0eWxlPSIiPgogICAgICA8cGF0aCBkPSJNMS45OTk3NCAxMi45OTk5TDEuOTk5NiAxMUwxNS41ODU4IDExVjUuNTg1ODJMMjIgMTJMMTUuNTg1OCAxOC40MTQyVjEzTDEuOTk5NzQgMTIuOTk5OVoiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3BhdGg+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgyLjQ5OTk1LCAwLCAwLCAxLjk0ODgwNCwgMTQ1LjAwMTEwMSwgNC4xMTQzMzEpIiBzdHlsZT0iIj4KICAgICAgPHBhdGggZD0iTTEuOTk5NzQgMTIuOTk5OUwxLjk5OTYgMTFMMTUuNTg1OCAxMVY1LjU4NTgyTDIyIDEyTDE1LjU4NTggMTguNDE0MlYxM0wxLjk5OTc0IDEyLjk5OTlaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyI+PC9wYXRoPgogICAgPC9nPgogIDwvZz4KPC9zdmc+" -RectIcon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+DQogIDxlbGxpcHNlIHN0eWxlPSJmaWxsOiByZ2IoMjE2LCAwLCA4Mik7IiBjeD0iMTAiIGN5PSIxMCIgcng9IjEwIiByeT0iMTAiPjwvZWxsaXBzZT4NCiAgPGVsbGlwc2Ugc3R5bGU9ImZpbGw6IHJnYigyNTUsIDAsIDk3KTsiIGN4PSIxMCIgY3k9IjEwIiByeD0iOSIgcnk9IjkiPjwvZWxsaXBzZT4NCiAgPHJlY3QgeD0iNi45ODMiIHk9IjcuMDE1IiB3aWR0aD0iNy4yMTYiIGhlaWdodD0iNy4yMTYiIHN0eWxlPSJmaWxsOiBub25lOyBzdHJva2U6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcmVjdD4NCiAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wODUwMzksIDAsIDAsIDAuMDg1MDM5LCAtMi4xNjQ3NzgsIDIuMjg5ODk0KSIgc3R5bGU9IiI+DQogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoLTIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNTQuOTk4OTA0LCA0LjExNDMzKSIgc3R5bGU9IiI+DQogICAgICA8cGF0aCBkPSJNMS45OTk3NCAxMi45OTk5TDEuOTk5NiAxMUwxNS41ODU4IDExVjUuNTg1ODJMMjIgMTJMMTUuNTg1OCAxOC40MTQyVjEzTDEuOTk5NzQgMTIuOTk5OVoiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3BhdGg+DQogICAgPC9nPg0KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNDUuMDAxMTAxLCA0LjExNDMzMSkiIHN0eWxlPSIiPg0KICAgICAgPHBhdGggZD0iTTEuOTk5NzQgMTIuOTk5OUwxLjk5OTYgMTFMMTUuNTg1OCAxMVY1LjU4NTgyTDIyIDEyTDE1LjU4NTggMTguNDE0MlYxM0wxLjk5OTc0IDEyLjk5OTlaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyI+PC9wYXRoPg0KICAgIDwvZz4NCiAgPC9nPg0KICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgwLCAtMC4yMTI1OTIsIC0wLjE2NTcyMywgMCwgNi44Mzk1NzIsIDExLjEzMzc4OSkiIHN0eWxlPSIiPg0KICAgIDxwYXRoIGQ9Ik0xLjk5OTc0IDEyLjk5OTlMMS45OTk2IDExTDE1LjU4NTggMTFWNS41ODU4MkwyMiAxMkwxNS41ODU4IDE4LjQxNDJWMTNMMS45OTk3NCAxMi45OTk5WiIgc3R5bGU9ImZpbGw6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcGF0aD4NCiAgPC9nPg0KICA8cGF0aCBkPSJNIDIuNzI1IDEzIEwgMi43MjUgMTIuNjY5IEwgNS42MTMgMTIuNjY5IEwgNS42MTMgMTEuNzcxIEwgNi45NzcgMTIuODM0IEwgNS42MTMgMTMuODk4IEwgNS42MTMgMTMgTCAyLjcyNSAxMyBaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2Utd2lkdGg6IDIuMjI0OyB0cmFuc2Zvcm0tYm94OiBmaWxsLWJveDsgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTsiIHRyYW5zZm9ybT0ibWF0cml4KDAsIDEuMDAwMDA3LCAtMC45OTk5OTMsIDAsIDAuMDAwMDAyLCAwKSI+PC9wYXRoPg0KPC9zdmc+" From 03a2380982c7bb7b8680f8d2f8e99ff0fed6d20d Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Fri, 3 Oct 2025 19:13:04 -0400 Subject: [PATCH 14/22] Update extensions.js --- src/lib/extensions.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/extensions.js b/src/lib/extensions.js index 9567327ff..4152b0dbb 100644 --- a/src/lib/extensions.js +++ b/src/lib/extensions.js @@ -140,6 +140,13 @@ export default [ documentation: "PenguinAI", unstableReason: "AI models can generate unintended or inappropriate output.\nSome AI models may also become temporarily inaccessible.\n\nUse at your own risk.", }, + { + name: "Rect", // The name of the extension. + description: "Creates a Rectangle-Based object which you can grab positions of (Works with Vectors!)", + code: "IrshaadAli/static_Rect.js", // There exists a translated version too + banner: "IrshaadAli/Rect.svg", // Sorry - Don't know how to avif + creator: "Irshaad_Ali", // Had to create a new one + }, /* { name: "Block AI", From 2b7cded17571dbad52791487a43971008552c66c Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Sat, 4 Oct 2025 09:48:54 -0400 Subject: [PATCH 15/22] Delete static/extensions/IrshaadAli/TRANSLATED_Rect.js --- .../extensions/IrshaadAli/TRANSLATED_Rect.js | 776 ------------------ 1 file changed, 776 deletions(-) delete mode 100644 static/extensions/IrshaadAli/TRANSLATED_Rect.js diff --git a/static/extensions/IrshaadAli/TRANSLATED_Rect.js b/static/extensions/IrshaadAli/TRANSLATED_Rect.js deleted file mode 100644 index 92d075f21..000000000 --- a/static/extensions/IrshaadAli/TRANSLATED_Rect.js +++ /dev/null @@ -1,776 +0,0 @@ -// !! READ THIS !! -// This is only a "Translated" version, please check for any errors -const BlockType = require('../../extension-support/block-type') -const BlockShape = require('../../extension-support/block-shape') -const ArgumentType = require('../../extension-support/argument-type') -const TargetType = require('../../extension-support/target-type') -const Cast = require('../../util/cast') - -function formatNumber(x) { - if (x >= 1e6) { - return x.toExponential(4) - } else { - x = Math.floor(x * 1000) / 1000 - return x.toFixed(Math.min(3, (String(x).split('.')[1] || '').length)) - } -} - -/** - @param {vm.jwVector.Type, Array} x - @returns {[number, number]} - */ -function parseToArray(x) { - if (x instanceof vm.jwVector.Type && x.length == 2) { return [x.x, x.y] } - if (x instanceof Array) { return x } -} - -function span(text) { - let el = document.createElement('span') - el.innerHTML = text - el.style.display = 'hidden' - el.style.whiteSpace = 'nowrap' - el.style.width = '100%' - el.style.textAlign = 'center' - return el -} - -class RectType { - customId = "IAliRect" - - constructor(x = 0, y = 0, width = 0, height = 0) { - this.x = x - this.y = y - this.width = width - this.height = height - } - - static toRect(x) { - if (x instanceof RectType) return x - if (x instanceof Array && x.length == 4) return new RectType(x[0], x[1], x[2], x[3]) - if (x instanceof Array && x.length == 2) return new RectType(x[0][0], x[0][1], x[1][0], x[1][1]) - if (String(x).split(',')) { - let array = String(x).split(',') - return new RectType( - Cast.toNumber(array[0]), - Cast.toNumber(array[1]), - Cast.toNumber(array[2]), - Cast.toNumber(array[3]) - ) - } - return new RectType(0, 0, 0,0) - } - - IAliRectHandler() { - return "Rect" - } - - toString() { - return `${this.x},${this.y},${this.width},${this.height}` - } - - toMonitorContent = () => span(this.toString()) - - toReporterContent() { - let root = document.createElement('div') - root.style.display = 'flex' - root.style.width = "200px" - root.style.overflow = "hidden" - - let details = document.createElement('div') - details.style.display = 'flex' - details.style.flexDirection = 'column' - details.style.justifyContent = 'center' - details.style.width = "100px" - - details.appendChild(span(`X: ${formatNumber(this.x)}`)) - details.appendChild(span(`Y: ${formatNumber(this.y)}`)) - details.appendChild(span(`W: ${formatNumber(this.width)}`)) - details.appendChild(span(`H: ${formatNumber(this.height)}`)) - - root.appendChild(details) - - let square = document.createElement("div") - square.style.width = "84px" - square.style.height = "84px" - square.style.margin = "8px" - square.style.border = "4px solid black" - square.style.boxSizing = "border-box" - - root.append(square) - return root - } - - get offsets() { - return { - 'left': this.width / -2.0, - 'top': this.height / 2.0, - 'right': this.width / 2.0, - 'bottom': this.height / -2.0, - 'center': 0 - } - } - - get singlePoints() { - return { - 'top': this.y + this.offsets.top, - 'left': this.x + this.offsets.left, - 'right': this.x + this.offsets.right, - 'bottom': this.y + this.offsets.bottom, - } - } - - get topleft() { - return new vm.jwVector.Type(this.singlePoints.left, this.singlePoints.top) - } - get midtop() { - return new vm.jwVector.Type(this.x, this.singlePoints.top) - } - get topright() { - return new vm.jwVector.Type(this.singlePoints.right, this.singlePoints.top) - } - get midleft() { - return new vm.jwVector.Type(this.singlePoints.left, this.y) - } - get center() { - return new vm.jwVector.Type(this.x, this.y) - } - get midright() { - return new vm.jwVector.Type(this.singlePoints.right, this.y) - } - get bottomleft() { - return new vm.jwVector.Type(this.singlePoints.left, this.singlePoints.bottom) - } - get midbottom() { - return new vm.jwVector.Type(this.x, this.singlePoints.bottom) - } - get bottomright() { - return new vm.jwVector.Type(this.singlePoints.right, this.singlePoints.bottom) - } - - set topleft(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.left - this.y = values[1] - this.singlePoints.top - } - - set midtop(value) { - let values = parseToArray(value) - this.x = values[0] - this.y = values[1] - this.singlePoints.top - } - - set topright(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.right - this.y = values[1] - this.singlePoints.top - } - - set midleft(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.left - this.y = values[1] - } - - set center(value) { - let values = parseToArray(value) - this.x = values[0] - this.y = values[1] - } - - set midright(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.right - this.y = values[1] - } - - set bottomleft(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.left - this.y = values[1] - this.singlePoints.bottom - } - set midbottom(value) { - let values = parseToArray(value) - this.x = values[0] - this.y = values[1] - this.singlePoints.bottom - } - set bottomright(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.right - this.y = values[1] - this.singlePoints.bottom - } - - get size() { - return vm.jwVector.Type(this.width, this.height) - } - - set size(value) { - let values = parseToArray(value) - this.width = isNaN(values[0]) ? 0 : values[0] - this.height = isNaN(values[1]) ? 0 : values[1] - } -} - -const Rect = { - Type: RectType, - Block: { - blockType: BlockType.REPORTER, - blockShape: BlockShape.SQUARE, - forceOutputType: 'Rect', - disableMonitor: true, - allowDropAnywhere: true, - }, - Argument: { - shape: BlockShape.SQUARE, - check: ["Rect"] - }, - NumArg: { - type: ArgumentType.NUMBER, - defaultValue: 0, - } -} - -class Extension { - constructor() { - vm.IAliRect = Rect - vm.runtime.registerSerializer( - "IAliRect", - v => [v.x, v.y, v.width, v.height], - v => new RectType(v.x, v.y, v.width, v.height) - ) - - if (!vm.jwVector) vm.extensionManager.loadExtensionIdSync('jwVector') - } - - getInfo() { - return { - id: "IAliRect", - name: "Rect", - color1: "#ff0061", - color2: "#d80052", - menuIconURI: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+DQogIDxlbGxpcHNlIHN0eWxlPSJmaWxsOiByZ2IoMjE2LCAwLCA4Mik7IiBjeD0iMTAiIGN5PSIxMCIgcng9IjEwIiByeT0iMTAiPjwvZWxsaXBzZT4NCiAgPGVsbGlwc2Ugc3R5bGU9ImZpbGw6IHJnYigyNTUsIDAsIDk3KTsiIGN4PSIxMCIgY3k9IjEwIiByeD0iOSIgcnk9IjkiPjwvZWxsaXBzZT4NCiAgPHJlY3QgeD0iNi45ODMiIHk9IjcuMDE1IiB3aWR0aD0iNy4yMTYiIGhlaWdodD0iNy4yMTYiIHN0eWxlPSJmaWxsOiBub25lOyBzdHJva2U6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcmVjdD4NCiAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wODUwMzksIDAsIDAsIDAuMDg1MDM5LCAtMi4xNjQ3NzgsIDIuMjg5ODk0KSIgc3R5bGU9IiI+DQogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoLTIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNTQuOTk4OTA0LCA0LjExNDMzKSIgc3R5bGU9IiI+DQogICAgICA8cGF0aCBkPSJNMS45OTk3NCAxMi45OTk5TDEuOTk5NiAxMUwxNS41ODU4IDExVjUuNTg1ODJMMjIgMTJMMTUuNTg1OCAxOC40MTQyVjEzTDEuOTk5NzQgMTIuOTk5OVoiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3BhdGg+DQogICAgPC9nPg0KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNDUuMDAxMTAxLCA0LjExNDMzMSkiIHN0eWxlPSIiPg0KICAgICAgPHBhdGggZD0iTTEuOTk5NzQgMTIuOTk5OUwxLjk5OTYgMTFMMTUuNTg1OCAxMVY1LjU4NTgyTDIyIDEyTDE1LjU4NTggMTguNDE0MlYxM0wxLjk5OTc0IDEyLjk5OTlaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyI+PC9wYXRoPg0KICAgIDwvZz4NCiAgPC9nPg0KICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgwLCAtMC4yMTI1OTIsIC0wLjE2NTcyMywgMCwgNi44Mzk1NzIsIDExLjEzMzc4OSkiIHN0eWxlPSIiPg0KICAgIDxwYXRoIGQ9Ik0xLjk5OTc0IDEyLjk5OTlMMS45OTk2IDExTDE1LjU4NTggMTFWNS41ODU4MkwyMiAxMkwxNS41ODU4IDE4LjQxNDJWMTNMMS45OTk3NCAxMi45OTk5WiIgc3R5bGU9ImZpbGw6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcGF0aD4NCiAgPC9nPg0KICA8cGF0aCBkPSJNIDIuNzI1IDEzIEwgMi43MjUgMTIuNjY5IEwgNS42MTMgMTIuNjY5IEwgNS42MTMgMTEuNzcxIEwgNi45NzcgMTIuODM0IEwgNS42MTMgMTMuODk4IEwgNS42MTMgMTMgTCAyLjcyNSAxMyBaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2Utd2lkdGg6IDIuMjI0OyB0cmFuc2Zvcm0tYm94OiBmaWxsLWJveDsgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTsiIHRyYW5zZm9ybT0ibWF0cml4KDAsIDEuMDAwMDA3LCAtMC45OTk5OTMsIDAsIDAuMDAwMDAyLCAwKSI+PC9wYXRoPg0KPC9zdmc+", - blocks: [ - { - blockType: Scratch.BlockType.LABEL, - text: 'Sprite-Based Rects' - }, - { - opcode: 'fromSprite', - text: 'from [SPRITE]', - arguments: { - SPRITE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "" - } - }, - ...Rect.Block - }, - { - blockType: Scratch.BlockType.LABEL, - text: 'Rect Initialization' - }, - { - opcode: 'newRectX_Y_W_H', - text: 'Rect X: [X] Y: [Y] W: [W] H: [H]', - arguments: { - X: Rect.NumArg, - Y: Rect.NumArg, - W: Rect.NumArg, - H: Rect.NumArg, - }, - ...Rect.Block - }, - { - opcode: 'newRectXY_WH', - text: "Rect XY: [XY] WH: [WH]", - arguments: { - XY: vm.vm.jwVector.Argument, - WH: vm.vm.jwVector.Argument, - }, - ...Rect.Block - }, - { - blockType: Scratch.BlockType.LABEL, - text: 'Getters' - }, - { - blockType: Scratch.BlockType.LABEL, - text: "Single Positional Value", - }, - { - opcode: 'getRectX', - text: 'Get [RECT] X', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - { - opcode: 'getRectY', - text: 'Get [RECT] Y', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - { - opcode: 'getRectW', - text: 'Get [RECT] Width', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - { - opcode: 'getRectH', - text: 'Get [RECT] Height', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - - { - opcode: 'getRectTopLeftX', - text: 'Get [RECT] TopLeft X', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - - { - opcode: 'getRectTopLeftY', - text: 'Get [RECT] TopLeft Y', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - - { - blockType: Scratch.BlockType.LABEL, - text: 'Vector Positional Value', - }, - - { - opcode: 'getRectTopLeft', - text: 'Get [RECT] TopLeft', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...vm.jwVector.Block - }, - - { - opcode: 'getRectMidTop', - text: 'Get [RECT] MidTop', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...vm.jwVector.Block - }, - - { - opcode: 'getRectTopRight', - text: 'Get [RECT] TopRight', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...vm.jwVector.Block - }, - - { - opcode: 'getRectMidLeft', - text: 'Get [RECT] MidLeft', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...vm.jwVector.Block - }, - - { - opcode: 'getRectCenter', - text: 'Get [RECT] Center', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...vm.jwVector.Block - }, - - { - opcode: 'getRectMidRight', - text: 'Get [RECT] MidRight', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...vm.jwVector.Block - }, - - { - opcode: 'getRectBottomLeft', - text: 'Get [RECT] BottomLeft', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...vm.jwVector.Block - }, - - { - opcode: 'getRectMidBottom', - text: 'Get [RECT] MidBottom', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...vm.jwVector.Block - }, - - { - opcode: 'getRectBottomRight', - text: 'Get [RECT] BottomRight', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...vm.jwVector.Block - }, - - { - blockType: Scratch.BlockType.LABEL, - text: 'Setters', - }, - { - blockType: Scratch.BlockType.LABEL, - text: 'Single Positional Value', - }, - - { - opcode: 'setRectX', - text: 'Set [RECT] X [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: Rect.NumArg, - }, - ...Rect.Block - }, - - { - opcode: 'setRectY', - text: 'Set [RECT] Y [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: Rect.NumArg - }, - ...Rect.Block - }, - - { - opcode: 'setRectW', - text: 'Set [RECT] W [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: Rect.NumArg - }, - ...Rect.Block - }, - - { - opcode: 'setRectH', - text: 'Set [RECT] H [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: Rect.NumArg - }, - ...Rect.Block - }, - - { - blockType: Scratch.BlockType.LABEL, - text: 'Vector Positional Value', - }, - - { - opcode: 'setRectTopLeft', - text: 'Set [RECT] TopLeft [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: vm.jwVector.Argument - }, - ...Rect.Block - }, - - { - opcode: 'setRectMidTop', - text: 'Set [RECT] MidTop [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: vm.jwVector.Argument - }, - ...Rect.Block - }, - - { - opcode: 'setRectTopRight', - text: 'Set [RECT] TopRight [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: vm.jwVector.Argument - }, - ...Rect.Block - }, - - { - opcode: 'setRectMidLeft', - text: 'Set [RECT] MidLeft [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: vm.jwVector.Argument - }, - ...Rect.Block - }, - - { - opcode: 'setRectCenter', - text: 'Set [RECT] Center [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: vm.jwVector.Argument - }, - ...Rect.Block - }, - - { - opcode: 'setRectMidRight', - text: 'Set [RECT] MidRight [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: vm.jwVector.Argument - }, - ...Rect.Block - }, - - { - opcode: 'setRectBottomLeft', - text: 'Set [RECT] BottomLeft [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: vm.jwVector.Argument - }, - ...Rect.Block - }, - - { - opcode: 'setRectMidBottom', - text: 'Set [RECT] MidBottom [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: vm.jwVector.Argument - }, - ...Rect.Block - }, - - { - opcode: 'setRectBottomRight', - text: 'Set [RECT] BottomRight [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: vm.jwVector.Argument - }, - ...Rect.Block - } - ], - menus: { - roundingFunctions: { - acceptReporters: false, - items: [ - { - text: 'round', - value: 'round' - }, - { - text: 'ceil', // might as well go full in on the inconsistencies since we are already doing "round of" - value: 'ceil' - }, - { - text: 'floor', - value: 'floor' - } - ] - } - } - } - } - - newRectXY_WH(args) { - const XY = args.XY - const WH = args.WH - - return new RectType(XY.x, XY.y, WH.x, WH.y) - } - - getRectX(args) { - return RectType.toRect(args.RECT).x - } - - getRectY(args) { - return RectType.toRect(args.RECT).y - } - - getRectW(args) { - return RectType.toRect(args.RECT).width - } - getRectH(args) { - return RectType.toRect(args.RECT).height - } - - getRectTopLeftX(args) { - return RectType.toRect(args.RECT).singlePoints.left - } - - getRectTopLeftY(args) { - return RectType.toRect(args.RECT).singlePoints.top - } - - getRectTopLeft(args) { - return RectType.toRect(args.RECT).topleft - } - - getRectMidTop(args) { - return RectType.toRect(args.RECT).midtop - } - getRectTopRight(args) { - return RectType.toRect(args.RECT).topright - } - - getRectMidLeft(args) { - return RectType.toRect(args.RECT).midleft - } - getRectCenter(args) { - return RectType.toRect(args.RECT).center - } - getRectMidRight(args) { - return RectType.toRect(args.RECT).midright - } - - getRectBottomLeft(args) { - return RectType.toRect(args.RECT).bottomleft - } - getRectMidBottom(args) { - return RectType.toRect(args.RECT).midbottom - } - getRectBottomRight(args) { - return RectType.toRect(args.RECT).bottomright - } - - setRectX(args) { - let rect = RectType.toRect(args.RECT) - rect.x = args.VALUE - return rect - } - - setRectY(args) { - let rect = RectType.toRect(args.RECT) - rect.y = args.VALUE - return rect - } - - setRectW(args) { - let rect = RectType.toRect(args.RECT) - rect.width = args.VALUE - return rect - } - - setRectH(args) { - let rect = RectType.toRect(args.RECT) - rect.height = args.VALUE - return rect - } - - setRectTopLeft(args) { - let rect = RectType.toRect(args.RECT) - rect.topleft = args.VALUE - return rect - } - setRectMidTop(args) { - let rect = RectType.toRect(args.RECT) - rect.midtop = args.VALUE - return rect - } - setRectTopRight(args) { - let rect = RectType.toRect(args.RECT) - rect.topright = args.VALUE - return rect - } - - setRectMidLeft(args) { - let rect = RectType.toRect(args.RECT) - rect.midleft = args.VALUE - return rect - } - - setRectCenter(args) { - let rect = RectType.toRect(args.RECT) - rect.center = args.VALUE - return rect - } - - setRectMidRight(args) { - let rect = RectType.toRect(args.RECT) - rect.midright = args.VALUE - return rect - } - - setRectBottomLeft(args) { - let rect = RectType.toRect(args.RECT) - rect.bottomleft = args.VALUE - return rect - } - - setRectMidBottom(args) { - let rect = RectType.toRect(args.RECT) - rect.midbottom = args.VALUE - return rect - } - - setRectBottomRight(args) { - let rect = RectType.toRect(args.RECT) - rect.bottomright = args.VALUE - return rect - } - - fromSprite({SPRITE}) { - let spr = vm.runtime.getSpriteTargetByName(SPRITE) - console.log(spr) - let x = spr.x - let y = spr.y - - let costume = spr.sprite.costumes_[spr.currentCostume] - let asset = costume.asset - let assetType = asset.assetType.name - let size = costume.size - - return new RectType(x, y, assetType == "ImageBitmap" ? size[0]/2 : size[0], assetType == "ImageBitmap" ? size[1]/2 : size[1]) - } -} - -module.exports = Extension From 960f6ab3c38d1612165fb9f784f3cad4875e7eae Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Sat, 4 Oct 2025 09:49:14 -0400 Subject: [PATCH 16/22] Update static_Rect.js --- static/extensions/IrshaadAli/static_Rect.js | 618 ++++++-------------- 1 file changed, 185 insertions(+), 433 deletions(-) diff --git a/static/extensions/IrshaadAli/static_Rect.js b/static/extensions/IrshaadAli/static_Rect.js index 985607e68..cb4428ce3 100644 --- a/static/extensions/IrshaadAli/static_Rect.js +++ b/static/extensions/IrshaadAli/static_Rect.js @@ -2,6 +2,8 @@ const Cast = Scratch.Cast const vm = Scratch.vm + if (vm.IAliRect) vm.extensionManager.removeExtension('IAliRect') + if (!vm.jwVector) vm.extensionManager.loadExtensionIdSync('jwVector') const jwVector = vm.jwVector @@ -218,18 +220,19 @@ } + // Makes it so Vectors & Jsons can grab XYWH const Rect = { Type: RectType, Block: { blockType: Scratch.BlockType.REPORTER, blockShape: Scratch.BlockShape.SQUARE, - forceOutputType: "Rect", + //forceOutputType: "Rect", disableMonitor: true, allowDropAnywhere: true, }, Argument: { shape: Scratch.BlockShape.SQUARE, - check: ["Rect"] + //check: ["Rect"] } } @@ -238,6 +241,17 @@ defaultValue: 0 } + const SingleValue = { + menu: 'singleRectValue', + defaultValue: 'x' + } + + const VectorValue = { + menu: 'vectorRectValue', + defaultValue: 'topleft' + } + + class Extension { @@ -256,30 +270,23 @@ name: "Rect", color1: "#ff0061", color2: "#d80052", - menuIconURI: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+DQogIDxlbGxpcHNlIHN0eWxlPSJmaWxsOiByZ2IoMjE2LCAwLCA4Mik7IiBjeD0iMTAiIGN5PSIxMCIgcng9IjEwIiByeT0iMTAiPjwvZWxsaXBzZT4NCiAgPGVsbGlwc2Ugc3R5bGU9ImZpbGw6IHJnYigyNTUsIDAsIDk3KTsiIGN4PSIxMCIgY3k9IjEwIiByeD0iOSIgcnk9IjkiPjwvZWxsaXBzZT4NCiAgPHJlY3QgeD0iNi45ODMiIHk9IjcuMDE1IiB3aWR0aD0iNy4yMTYiIGhlaWdodD0iNy4yMTYiIHN0eWxlPSJmaWxsOiBub25lOyBzdHJva2U6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcmVjdD4NCiAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wODUwMzksIDAsIDAsIDAuMDg1MDM5LCAtMi4xNjQ3NzgsIDIuMjg5ODk0KSIgc3R5bGU9IiI+DQogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoLTIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNTQuOTk4OTA0LCA0LjExNDMzKSIgc3R5bGU9IiI+DQogICAgICA8cGF0aCBkPSJNMS45OTk3NCAxMi45OTk5TDEuOTk5NiAxMUwxNS41ODU4IDExVjUuNTg1ODJMMjIgMTJMMTUuNTg1OCAxOC40MTQyVjEzTDEuOTk5NzQgMTIuOTk5OVoiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3BhdGg+DQogICAgPC9nPg0KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDIuNDk5OTUsIDAsIDAsIDEuOTQ4ODA0LCAxNDUuMDAxMTAxLCA0LjExNDMzMSkiIHN0eWxlPSIiPg0KICAgICAgPHBhdGggZD0iTTEuOTk5NzQgMTIuOTk5OUwxLjk5OTYgMTFMMTUuNTg1OCAxMVY1LjU4NTgyTDIyIDEyTDE1LjU4NTggMTguNDE0MlYxM0wxLjk5OTc0IDEyLjk5OTlaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyI+PC9wYXRoPg0KICAgIDwvZz4NCiAgPC9nPg0KICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgwLCAtMC4yMTI1OTIsIC0wLjE2NTcyMywgMCwgNi44Mzk1NzIsIDExLjEzMzc4OSkiIHN0eWxlPSIiPg0KICAgIDxwYXRoIGQ9Ik0xLjk5OTc0IDEyLjk5OTlMMS45OTk2IDExTDE1LjU4NTggMTFWNS41ODU4MkwyMiAxMkwxNS41ODU4IDE4LjQxNDJWMTNMMS45OTk3NCAxMi45OTk5WiIgc3R5bGU9ImZpbGw6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcGF0aD4NCiAgPC9nPg0KICA8cGF0aCBkPSJNIDIuNzI1IDEzIEwgMi43MjUgMTIuNjY5IEwgNS42MTMgMTIuNjY5IEwgNS42MTMgMTEuNzcxIEwgNi45NzcgMTIuODM0IEwgNS42MTMgMTMuODk4IEwgNS42MTMgMTMgTCAyLjcyNSAxMyBaIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2Utd2lkdGg6IDIuMjI0OyB0cmFuc2Zvcm0tYm94OiBmaWxsLWJveDsgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTsiIHRyYW5zZm9ybT0ibWF0cml4KDAsIDEuMDAwMDA3LCAtMC45OTk5OTMsIDAsIDAuMDAwMDAyLCAwKSI+PC9wYXRoPg0KPC9zdmc+", + menuIconURI: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+DQogIDxlbGxpcHNlIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAwLCA5Nyk7IHN0cm9rZTogcmdiKDIxNiwgMCwgODIpOyIgY3g9IjEwIiBjeT0iMTAiIHJ4PSI5LjUiIHJ5PSI5LjUiPjwvZWxsaXBzZT4NCiAgPHJlY3QgeD0iNi4wNTkiIHk9IjUuNzkzIiB3aWR0aD0iOS40NzciIGhlaWdodD0iOS40NzciIHN0eWxlPSJmaWxsOiBub25lOyBzdHJva2U6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcmVjdD4NCiAgPHJlY3QgeD0iNS40OTQiIHk9IjMuMjIyIiB3aWR0aD0iMTAuNjQzIiBoZWlnaHQ9IjEuMzcyIiByeD0iMSIgcnk9IjEiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3JlY3Q+DQogIDxyZWN0IHg9IjEuNjA1IiB5PSI3LjQ3MyIgd2lkdGg9IjEwLjY0MyIgaGVpZ2h0PSIxLjM3MiIgcng9IjEiIHJ5PSIxIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2Utd2lkdGg6IDE7IHRyYW5zZm9ybS1ib3g6IGZpbGwtYm94OyB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgNTAlOyIgdHJhbnNmb3JtPSJtYXRyaXgoMCwgMSwgLTEsIDAsIC0yLjcwMTY4NCwgMi41MTc0OCkiPjwvcmVjdD4NCjwvc3ZnPg==", blocks: [ - { - blockType: Scratch.BlockType.LABEL, - text: 'Sprite-Based Rects' - }, { opcode: 'fromSprite', text: 'from [SPRITE]', arguments: { SPRITE: { type: Scratch.ArgumentType.STRING, - defaultValue: "" + menu: "sprites", } }, ...Rect.Block }, - { - blockType: Scratch.BlockType.LABEL, - text: 'Rect Initialization' - }, + '---', { opcode: 'newRectX_Y_W_H', - text: 'Rect X: [X] Y: [Y] W: [W] H: [H]', + text: 'rect x: [X] y: [Y] w: [W] h: [H]', arguments: { X: RectArgType1, Y: RectArgType1, @@ -290,325 +297,80 @@ }, { opcode: 'newRectXY_WH', - text: "Rect XY: [XY] WH: [WH]", + text: "rect xy: [XY] wh: [WH]", arguments: { XY: vm.jwVector.Argument, WH: vm.jwVector.Argument, }, ...Rect.Block }, + '---', { - blockType: Scratch.BlockType.LABEL, - text: 'Getters' - }, - { - blockType: Scratch.BlockType.LABEL, - text: "Single Positional Value", - }, - { - opcode: 'getRectX', - text: 'Get [RECT] X', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - { - opcode: 'getRectY', - text: 'Get [RECT] Y', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - { - opcode: 'getRectW', - text: 'Get [RECT] Width', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - { - opcode: 'getRectH', - text: 'Get [RECT] Height', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - - { - opcode: 'getRectTopLeftX', - text: 'Get [RECT] TopLeft X', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - - { - opcode: 'getRectTopLeftY', - text: 'Get [RECT] TopLeft Y', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - } - }, - - { - blockType: Scratch.BlockType.LABEL, - text: 'Vector Positional Value', - }, - - { - opcode: 'getRectTopLeft', - text: 'Get [RECT] TopLeft', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...jwVector.Block - }, - - { - opcode: 'getRectMidTop', - text: 'Get [RECT] MidTop', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...jwVector.Block - }, - - { - opcode: 'getRectTopRight', - text: 'Get [RECT] TopRight', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...jwVector.Block - }, - - { - opcode: 'getRectMidLeft', - text: 'Get [RECT] MidLeft', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...jwVector.Block - }, - - { - opcode: 'getRectCenter', - text: 'Get [RECT] Center', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...jwVector.Block - }, - - { - opcode: 'getRectMidRight', - text: 'Get [RECT] MidRight', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...jwVector.Block - }, - - { - opcode: 'getRectBottomLeft', - text: 'Get [RECT] BottomLeft', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...jwVector.Block - }, - - { - opcode: 'getRectMidBottom', - text: 'Get [RECT] MidBottom', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...jwVector.Block - }, - - { - opcode: 'getRectBottomRight', - text: 'Get [RECT] BottomRight', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument - }, - ...jwVector.Block - }, - - { - blockType: Scratch.BlockType.LABEL, - text: 'Setters', - }, - { - blockType: Scratch.BlockType.LABEL, - text: 'Single Positional Value', - }, - - { - opcode: 'setRectX', - text: 'Set [RECT] X [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: RectArgType1, - }, - ...Rect.Block - }, - - { - opcode: 'setRectY', - text: 'Set [RECT] Y [VALUE]', + opcode: 'getSingleRectPoint', + text: 'get [RECT] [TYPE]', blockType: Scratch.BlockType.REPORTER, arguments: { RECT: Rect.Argument, - VALUE: RectArgType1 + TYPE: SingleValue }, - ...Rect.Block }, { - opcode: 'setRectW', - text: 'Set [RECT] W [VALUE]', + opcode: 'setSingleRectPoint', + text: 'set [RECT] [TYPE] to [VALUE]', blockType: Scratch.BlockType.REPORTER, arguments: { RECT: Rect.Argument, - VALUE: RectArgType1 - }, - ...Rect.Block - }, - - { - opcode: 'setRectH', - text: 'Set [RECT] H [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: RectArgType1 - }, - ...Rect.Block - }, - - { - blockType: Scratch.BlockType.LABEL, - text: 'Vector Positional Value', - }, - - { - opcode: 'setRectTopLeft', - text: 'Set [RECT] TopLeft [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: jwVector.Argument - }, - ...Rect.Block - }, - - { - opcode: 'setRectMidTop', - text: 'Set [RECT] MidTop [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: jwVector.Argument + TYPE: SingleValue, + VALUE: RectArgType1, }, ...Rect.Block }, - { - opcode: 'setRectTopRight', - text: 'Set [RECT] TopRight [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: jwVector.Argument - }, - ...Rect.Block - }, + '---', { - opcode: 'setRectMidLeft', - text: 'Set [RECT] MidLeft [VALUE]', + opcode: 'getVectorRectPoint', + text: 'get [RECT] [TYPE]', blockType: Scratch.BlockType.REPORTER, arguments: { RECT: Rect.Argument, - VALUE: jwVector.Argument + TYPE: VectorValue, }, - ...Rect.Block + ...jwVector.Block }, { - opcode: 'setRectCenter', - text: 'Set [RECT] Center [VALUE]', + opcode: 'setVectorRectPoint', + text: 'set [RECT] [TYPE] to [VALUE]', blockType: Scratch.BlockType.REPORTER, arguments: { RECT: Rect.Argument, - VALUE: jwVector.Argument + TYPE: VectorValue, + VALUE: jwVector.Argument, }, ...Rect.Block }, - - { - opcode: 'setRectMidRight', - text: 'Set [RECT] MidRight [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: jwVector.Argument - }, - ...Rect.Block + ], + menus: { + sprites: { + acceptReporters: true, + items: this.getSpriteMenu() }, - - { - opcode: 'setRectBottomLeft', - text: 'Set [RECT] BottomLeft [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: jwVector.Argument - }, - ...Rect.Block + singleRectValue: { + acceptReporters: true, + items: ['x', 'y', 'width', 'height', 'topleft x', 'topleft y'] }, - - { - opcode: 'setRectMidBottom', - text: 'Set [RECT] MidBottom [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: jwVector.Argument - }, - ...Rect.Block + vectorRectValue: { + acceptReporters: true, + items: [ + 'topleft', 'midtop', 'topright', + 'midleft', 'center', 'midright', + 'bottomleft', 'midbottom', 'bottomright', + 'size' + ], }, - { - opcode: 'setRectBottomRight', - text: 'Set [RECT] BottomRight [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - VALUE: jwVector.Argument - }, - ...Rect.Block - } - ], - menus: { roundingFunctions: { acceptReporters: false, items: [ @@ -630,16 +392,24 @@ } } + getSpriteMenu (){ + const targets = vm.runtime.targets; + const emptyMenu = [{ text: "", value: "" }]; + if (!targets) return emptyMenu; + const menu = targets.filter(target => target.isOriginal && (!target.isStage)).map(target => ({ text: target.sprite.name, value: target.sprite.name })); + return (menu.length > 0) ? menu : emptyMenu; + } + /** * * @param args * @returns {RectType} */ - newRectX_Y_W_H(args) { - const X = Cast.toNumber(args.X) - const Y = Cast.toNumber(args.Y) - const W = Cast.toNumber(args.W) - const H = Cast.toNumber(args.H) + newRectX_Y_W_H({AX, AY, AW, AH}) { + const X = Cast.toNumber(AX) + const Y = Cast.toNumber(AY) + const W = Cast.toNumber(AW) + const H = Cast.toNumber(AH) return new RectType(X, Y, W, H) } @@ -649,146 +419,128 @@ * @param args * @returns {RectType} */ - newRectXY_WH(args) { - const XY = args.XY - const WH = args.WH - - return new RectType(XY.x, XY.y, WH.x, WH.y) - } - - getRectX(args) { - return RectType.toRect(args.RECT).x - } - - getRectY(args) { - return RectType.toRect(args.RECT).y - } - - getRectW(args) { - return RectType.toRect(args.RECT).width - } - getRectH(args) { - return RectType.toRect(args.RECT).height - } - - getRectTopLeftX(args) { - return RectType.toRect(args.RECT).singlePoints.left - } - - getRectTopLeftY(args) { - return RectType.toRect(args.RECT).singlePoints.top - } - - getRectTopLeft(args) { - return RectType.toRect(args.RECT).topleft - } - - getRectMidTop(args) { - return RectType.toRect(args.RECT).midtop - } - getRectTopRight(args) { - return RectType.toRect(args.RECT).topright - } - - getRectMidLeft(args) { - return RectType.toRect(args.RECT).midleft - } - getRectCenter(args) { - return RectType.toRect(args.RECT).center - } - getRectMidRight(args) { - return RectType.toRect(args.RECT).midright - } - - getRectBottomLeft(args) { - return RectType.toRect(args.RECT).bottomleft - } - getRectMidBottom(args) { - return RectType.toRect(args.RECT).midbottom - } - getRectBottomRight(args) { - return RectType.toRect(args.RECT).bottomright - } - - setRectX(args) { - let rect = RectType.toRect(args.RECT) - rect.x = args.VALUE - return rect - } - - setRectY(args) { - let rect = RectType.toRect(args.RECT) - rect.y = args.VALUE - return rect - } - - setRectW(args) { - let rect = RectType.toRect(args.RECT) - rect.width = args.VALUE - return rect - } - - setRectH(args) { - let rect = RectType.toRect(args.RECT) - rect.height = args.VALUE - return rect - } - - setRectTopLeft(args) { - let rect = RectType.toRect(args.RECT) - rect.topleft = args.VALUE - return rect - } - setRectMidTop(args) { - let rect = RectType.toRect(args.RECT) - rect.midtop = args.VALUE - return rect - } - setRectTopRight(args) { - let rect = RectType.toRect(args.RECT) - rect.topright = args.VALUE - return rect - } - - setRectMidLeft(args) { - let rect = RectType.toRect(args.RECT) - rect.midleft = args.VALUE - return rect - } - - setRectCenter(args) { - let rect = RectType.toRect(args.RECT) - rect.center = args.VALUE - return rect - } - - setRectMidRight(args) { - let rect = RectType.toRect(args.RECT) - rect.midright = args.VALUE - return rect - } - - setRectBottomLeft(args) { - let rect = RectType.toRect(args.RECT) - rect.bottomleft = args.VALUE - return rect - } - - setRectMidBottom(args) { - let rect = RectType.toRect(args.RECT) - rect.midbottom = args.VALUE - return rect - } - - setRectBottomRight(args) { - let rect = RectType.toRect(args.RECT) - rect.bottomright = args.VALUE - return rect + newRectXY_WH({XY, WH}) { + let xy = jwVectorType.toVector(XY) + let wh = jwVectorType.toVector(WH) + return new RectType(xy.x, xy.y, wh.x, wh.y) + } + + getSingleRectPoint({RECT, TYPE}) { + let rect = RectType.toRect(RECT); + switch(TYPE) { + case 'x': + return rect.x; + case 'y': + return rect.y; + case 'width': + return rect.width; + case 'height': + return rect.height; + case 'topleft x': + return rect.topleft.x; + case 'topleft y': + return rect.topleft.y + } + return 0; + } + + setSingleRectPoint({RECT, TYPE, VALUE}) { + let rect = RectType.toRect(RECT); + let value = Cast.toNumber(VALUE); + + switch (TYPE) { + case 'x': + rect.x = value; + break; + case 'y': + rect.y = value; + break; + case 'width': + rect.width = value; + break; + case 'height': + rect.height = value; + break; + case 'topleft x': + rect.topleft = new jwVectorType(value, rect.topleft.y) + break; + case 'topleft y': + rect.topleft = new jwVectorType(rect.topleft.x, value) + break; + } + return rect; + } + + getVectorRectPoint({RECT, TYPE}) { + let rect = RectType.toRect(RECT); + switch (TYPE) { + case 'topleft': + return rect.topleft; + case 'midtop': + return rect.midtop; + case 'topright': + return rect.topright; + + case 'midleft': + return rect.midleft; + case 'center': + return rect.center; + case 'midright': + return rect.midright; + + case 'bottomleft': + return rect.bottomleft; + case 'midbottom': + return rect.midbottom; + case 'bottomright': + return rect.bottomright; + + case 'size': + return rect.size; + } + return new jwVectorType(0, 0); + } + + setVectorRectPoint({RECT, TYPE, VALUE}) { + let rect = RectType.toRect(RECT); + let value = jwVectorType.toVector(VALUE); + switch (TYPE) { + case 'topleft': + rect.topleft = value; + break; + case 'midtop': + rect.midtop = value; + break; + case 'topright': + rect.topright = value; + break; + case 'midleft': + rect.midleft = value; + break; + case 'center': + rect.center = value; + break; + case 'midright': + rect.midright = value; + break; + case 'bottomleft': + rect.bottomleft = value; + break; + case 'midbottom': + rect.midbottom = value; + break; + case 'bottomright': + rect.bottomright = value; + break; + case 'size': + rect.size = value; + break; + } + return rect; } fromSprite({SPRITE}) { let spr = vm.runtime.getSpriteTargetByName(SPRITE) - console.log(spr) let x = spr.x let y = spr.y From 8ae0f802272a2bd30d4672335c1c4451c23da126 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Sat, 4 Oct 2025 09:55:47 -0400 Subject: [PATCH 17/22] Update static_Rect.js --- static/extensions/IrshaadAli/static_Rect.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/static/extensions/IrshaadAli/static_Rect.js b/static/extensions/IrshaadAli/static_Rect.js index cb4428ce3..5a5b4525e 100644 --- a/static/extensions/IrshaadAli/static_Rect.js +++ b/static/extensions/IrshaadAli/static_Rect.js @@ -2,8 +2,6 @@ const Cast = Scratch.Cast const vm = Scratch.vm - if (vm.IAliRect) vm.extensionManager.removeExtension('IAliRect') - if (!vm.jwVector) vm.extensionManager.loadExtensionIdSync('jwVector') const jwVector = vm.jwVector From 97a4c960fb887ccbc85e44d155840adf6dd10873 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Sat, 4 Oct 2025 10:13:59 -0400 Subject: [PATCH 18/22] Update static_Rect.js --- static/extensions/IrshaadAli/static_Rect.js | 60 ++++++++++----------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/static/extensions/IrshaadAli/static_Rect.js b/static/extensions/IrshaadAli/static_Rect.js index 5a5b4525e..640109105 100644 --- a/static/extensions/IrshaadAli/static_Rect.js +++ b/static/extensions/IrshaadAli/static_Rect.js @@ -154,55 +154,55 @@ } set topleft(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.left - this.y = values[1] - this.singlePoints.top + let values = jwVectorType.toVector(value) + this.x = values.x - this.singlePoints.left + this.y = values.y - this.singlePoints.top } set midtop(value) { - let values = parseToArray(value) - this.x = values[0] - this.y = values[1] - this.singlePoints.top + let values = jwVectorType.toVector(value) + this.x = values.x + this.y = values.y - this.singlePoints.top } set topright(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.right - this.y = values[1] - this.singlePoints.top + let values = jwVectorType.toVector(value) + this.x = values.x - this.singlePoints.right + this.y = values.y - this.singlePoints.top } set midleft(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.left - this.y = values[1] + let values = jwVectorType.toVector(value) + this.x = values.x - this.singlePoints.left + this.y = values.y } set center(value) { - let values = parseToArray(value) - this.x = values[0] - this.y = values[1] + let values = jwVectorType.toVector(value) + this.x = values.x + this.y = values.y } set midright(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.right - this.y = values[1] + let values = jwVectorType.toVector(value) + this.x = values.x - this.singlePoints.right + this.y = values.y } set bottomleft(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.left - this.y = values[1] - this.singlePoints.bottom + let values = jwVectorType.toVector(value) + this.x = values.x - this.singlePoints.left + this.y = values.y - this.singlePoints.bottom } set midbottom(value) { - let values = parseToArray(value) - this.x = values[0] - this.y = values[1] - this.singlePoints.bottom + let values = jwVectorType.toVector(value) + this.x = values.x + this.y = values.y - this.singlePoints.bottom } set bottomright(value) { - let values = parseToArray(value) - this.x = values[0] - this.singlePoints.right - this.y = values[1] - this.singlePoints.bottom + let values = jwVectorType.toVector(value) + this.x = values.x - this.singlePoints.right + this.y = values.y - this.singlePoints.bottom } get size() { @@ -210,9 +210,9 @@ } set size(value) { - let values = parseToArray(value) - this.width = isNaN(values[0]) ? 0 : values[0] - this.height = isNaN(values[1]) ? 0 : values[1] + let values = jwVectorType.toVector(value) + this.width = isNaN(values.x) ? 0 : values.x + this.height = isNaN(values.y) ? 0 : values.y } From 7f5302c003171d183004ff61dbbada9308456e2c Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Sat, 4 Oct 2025 13:27:01 -0400 Subject: [PATCH 19/22] Update static_Rect.js --- static/extensions/IrshaadAli/static_Rect.js | 96 +++++++++++++++++++-- 1 file changed, 90 insertions(+), 6 deletions(-) diff --git a/static/extensions/IrshaadAli/static_Rect.js b/static/extensions/IrshaadAli/static_Rect.js index 640109105..7b494aa9c 100644 --- a/static/extensions/IrshaadAli/static_Rect.js +++ b/static/extensions/IrshaadAli/static_Rect.js @@ -215,6 +215,36 @@ this.height = isNaN(values.y) ? 0 : values.y } + collidesXYPoint(x, y) { + x = isNaN(x) ? 0 : x + y = isNaN(y) ? 0 : y + + return ( + x >= this.singlePoints.left && x <= this.singlePoints.right && + y >= this.singlePoints.bottom && y <= this.singlePoints.top + ) + } + + collidesVectorPoint(vec) { + vec = jwVectorType.toVector(vec) + + return ( + vec.x >= this.singlePoints.left && vec.x <= this.singlePoints.right && + vec.y >= this.singlePoints.bottom && vec.y <= this.singlePoints.top + ) + } + + collidesRect(rect) { + rect = RectType.toRect(rect) + + return ( + this.singlePoints.left <= rect.singlePoints.right && + this.singlePoints.right >= rect.singlePoints.left && + this.singlePoints.top >= rect.singlePoints.bottom && + this.singlePoints.bottom <= rect.singlePoints.top + + ) + } } @@ -349,6 +379,42 @@ }, ...Rect.Block }, + + { + blockType: Scratch.BlockType.LABEL, + text: 'Collisions', + }, + + { + opcode: 'isCollidingWithXY', + text: '[RECT] colliding with x: [X] y: [Y]', + blockType: Scratch.BlockType.BOOLEAN, + arguments: { + RECT: Rect.Argument, + X: RectArgType1, + Y: RectArgType1, + } + }, + + { + opcode: 'isCollidingWithPoint', + text: '[RECT] colliding with point [VECTOR]?', + blockType: Scratch.BlockType.BOOLEAN, + arguments: { + RECT: Rect.Argument, + VECTOR: jwVector.Argument, + } + }, + + { + opcode: 'isCollidingWithRect', + text: '[RECTA] colliding with rect [RECTB]', + blockType: Scratch.BlockType.BOOLEAN, + arguments: { + RECTA: Rect.Argument, + RECTB: Rect.Argument, + }, + } ], menus: { sprites: { @@ -403,12 +469,7 @@ * @param args * @returns {RectType} */ - newRectX_Y_W_H({AX, AY, AW, AH}) { - const X = Cast.toNumber(AX) - const Y = Cast.toNumber(AY) - const W = Cast.toNumber(AW) - const H = Cast.toNumber(AH) - + newRectX_Y_W_H({X, Y, W, H}) { return new RectType(X, Y, W, H) } @@ -549,6 +610,29 @@ return new RectType(x, y, assetType == "ImageBitmap" ? size[0]/2 : size[0], assetType == "ImageBitmap" ? size[1]/2 : size[1]) } + + + isCollidingWithXY({RECT, X, Y}) { + RECT = RectType.toRect(RECT); + X = Cast.toNumber(X); + Y = Cast.toNumber(Y); + + return RECT.collidesXYPoint(X, Y); + } + + isCollidingWithPoint({RECT, VECTOR}) { + RECT = RectType.toRect(RECT); + let XY = jwVectorType.toVector(VECTOR); + + return RECT.collidesVectorPoint(XY) + } + + isCollidingWithRect({RECTA, RECTB}) { + RECTA = RectType.toRect(RECTA) + RECTB = RectType.toRect(RECTB) + + return RECTA.collidesRect(RECTB) + } } Scratch.extensions.register(new Extension()) From a65b85c4f668cd9bcacc47161786fcbcf37200da Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Sat, 4 Oct 2025 13:55:37 -0400 Subject: [PATCH 20/22] Update static_Rect.js --- static/extensions/IrshaadAli/static_Rect.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/extensions/IrshaadAli/static_Rect.js b/static/extensions/IrshaadAli/static_Rect.js index 7b494aa9c..fe93ea74d 100644 --- a/static/extensions/IrshaadAli/static_Rect.js +++ b/static/extensions/IrshaadAli/static_Rect.js @@ -387,7 +387,7 @@ { opcode: 'isCollidingWithXY', - text: '[RECT] colliding with x: [X] y: [Y]', + text: '[RECT] colliding with x: [X] y: [Y]?', blockType: Scratch.BlockType.BOOLEAN, arguments: { RECT: Rect.Argument, @@ -408,7 +408,7 @@ { opcode: 'isCollidingWithRect', - text: '[RECTA] colliding with rect [RECTB]', + text: '[RECTA] colliding with rect [RECTB]?', blockType: Scratch.BlockType.BOOLEAN, arguments: { RECTA: Rect.Argument, From 4edea8745e28708caac55771a85e00ef854bdc45 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Sun, 5 Oct 2025 01:30:43 -0400 Subject: [PATCH 21/22] Update static_Rect.js --- static/extensions/IrshaadAli/static_Rect.js | 817 ++++++++++---------- 1 file changed, 405 insertions(+), 412 deletions(-) diff --git a/static/extensions/IrshaadAli/static_Rect.js b/static/extensions/IrshaadAli/static_Rect.js index fe93ea74d..b138e15ff 100644 --- a/static/extensions/IrshaadAli/static_Rect.js +++ b/static/extensions/IrshaadAli/static_Rect.js @@ -1,11 +1,16 @@ (function (Scratch) { - const Cast = Scratch.Cast - const vm = Scratch.vm + const Cast = Scratch.Cast; + const BlockType = Scratch.BlockType; + const BlockShape = Scratch.BlockShape; + const ArgumentType = Scratch.ArgumentType; + + const vm = Scratch.vm; + const mouse = vm.runtime.ioDevices.mouse if (!vm.jwVector) vm.extensionManager.loadExtensionIdSync('jwVector') const jwVector = vm.jwVector - const jwVectorType = jwVector.Type + const Vector = jwVector.Type /** * @param {number} x @@ -20,16 +25,6 @@ } } - /** - @param {jwVectorType, Array} x - @returns {[number, number]} - */ - function parseToArray(x) { - if (x instanceof jwVectorType && x.length == 2) { return [x.x, x.y] } - if (x instanceof Array) { return x } - - } - function span(text) { let el = document.createElement('span') el.innerHTML = text @@ -40,6 +35,7 @@ return el } + class RectType { customId = "IAliRect" @@ -50,20 +46,44 @@ this.height = isNaN(height) ? 0 : height } - static toRect(x) { - if (x instanceof RectType) return x - if (x instanceof Array && x.length == 4) return new RectType(x[0], x[1], x[2], x[3]) - if (x instanceof Array && x.length == 2) return new RectType(x[0][0], x[0][1], x[1][0], x[1][1]) - if (String(x).split(',')) { - let array = String(x).split(',') + static toRect(r) { + if (r instanceof RectType) return r + if (r instanceof Array && r.length == 4) return new RectType(r[0], r[1], r[2], r[3]) + if (r instanceof Array && r.length == 2) { + let x = 0 + let y = 0 + let w = 0 + let h = 0 + + if (r[0] instanceof Vector) { + r[0] = Vector.toVector(r[0]) + x = r[0].x + y = r[0].y + } else { + x = r[0][0] + y = r[0][1] + } + if (r[1] instanceof Vector) { + r[1] = Vector.toVector(r[1]) + w = r[1].x + h = r[1].y + } else { + w = r[1][0] + h = r[1][1] + } + + return new RectType(x, y, w, h) + } + if (String(r).split(',')) { + let array = String(r).split(',').map(value => Cast.toNumber(value)) return new RectType( - Cast.toNumber(array[0]), - Cast.toNumber(array[1]), - Cast.toNumber(array[2]), - Cast.toNumber(array[3]) + array[0], + array[1], + array[2], + array[3], ) } - return new RectType(0, 0, 0,0) + return new RectType(0, 0, 0, 0) } IAliRectHandler() { @@ -116,103 +136,115 @@ } } - get singlePoints() { - return { - 'top': this.y + this.offsets.top, - 'left': this.x + this.offsets.left, - 'right': this.x + this.offsets.right, - 'bottom': this.y + this.offsets.bottom, - } - } - - get topleft() { - return new jwVectorType(this.singlePoints.left, this.singlePoints.top) - } - get midtop() { - return new jwVectorType(this.x, this.singlePoints.top) - } - get topright() { - return new jwVectorType(this.singlePoints.right, this.singlePoints.top) - } - get midleft() { - return new jwVectorType(this.singlePoints.left, this.y) - } - get center() { - return new jwVectorType(this.x, this.y) - } - get midright() { - return new jwVectorType(this.singlePoints.right, this.y) - } - get bottomleft() { - return new jwVectorType(this.singlePoints.left, this.singlePoints.bottom) - } - get midbottom() { - return new jwVectorType(this.x, this.singlePoints.bottom) - } - get bottomright() { - return new jwVectorType(this.singlePoints.right, this.singlePoints.bottom) - } + getPoint(type) { + switch (type) { + case 'x': + return this.x + case 'y': + return this.y + case 'width': + return this.width + case 'height': + return this.height - set topleft(value) { - let values = jwVectorType.toVector(value) - this.x = values.x - this.singlePoints.left - this.y = values.y - this.singlePoints.top - } + case 'left': + return this.x + this.offsets.left + case 'top': + return this.y + this.offsets.top + case 'bottom': + return this.y + this.offsets.bottom + case 'right': + return this.x + this.offsets.right - set midtop(value) { - let values = jwVectorType.toVector(value) - this.x = values.x - this.y = values.y - this.singlePoints.top - } + case 'topleft x': + return this.getPoint('left') + case 'topleft y': + return this.getPoint('top') - set topright(value) { - let values = jwVectorType.toVector(value) - this.x = values.x - this.singlePoints.right - this.y = values.y - this.singlePoints.top - } + case 'topleft': + return new Vector(this.getPoint('left'), this.getPoint('top')) + case 'midtop': + return new Vector(this.x, this.getPoint('top')) + case 'topright': + return new Vector(this.getPoint('right'), this.getPoint('top')) - set midleft(value) { - let values = jwVectorType.toVector(value) - this.x = values.x - this.singlePoints.left - this.y = values.y - } + case 'midleft': + return new Vector(this.getPoint('left'), this.y) + case 'center': + return new Vector(this.x, this.y) + case 'midright': + return new Vector(this.getPoint('right'), this.y) - set center(value) { - let values = jwVectorType.toVector(value) - this.x = values.x - this.y = values.y + case 'bottomleft': + return new Vector(this.getPoint('left'), this.getPoint('bottom')) + case 'midbottom': + return new Vector(this.x, this.getPoint('bottom')) + case 'bottomright': + return new Vector(this.getPoint('right'), this.getPoint('bottom')) + case 'size': + return new Vector(this.width, this.height) + } + return NaN } - set midright(value) { - let values = jwVectorType.toVector(value) - this.x = values.x - this.singlePoints.right - this.y = values.y - } + setSinglePoint(type, value) { + value = Cast.toNumber(value) + switch (type) { + case 'x': this.x = value; break; + case 'y': this.y = value; break; + case 'width': this.width = value; break; + case 'height': this.height = value; break; - set bottomleft(value) { - let values = jwVectorType.toVector(value) - this.x = values.x - this.singlePoints.left - this.y = values.y - this.singlePoints.bottom - } - set midbottom(value) { - let values = jwVectorType.toVector(value) - this.x = values.x - this.y = values.y - this.singlePoints.bottom - } - set bottomright(value) { - let values = jwVectorType.toVector(value) - this.x = values.x - this.singlePoints.right - this.y = values.y - this.singlePoints.bottom + case 'topleft x': this.x = value - this.offsets.left; break; + case 'topleft y': this.y = value - this.offsets.top; break; + } } - get size() { - return jwVectorType(this.width, this.height) - } + setVectorPoint(type, value) { + value = Vector.toVector(value) + switch (type) { + case 'topleft': + this.x = value.x - this.offsets.left; + this.y = value.y - this.offsets.top; + break; + case 'midtop': + this.x = value.x; + this.y = value.y - this.offsets.top; + break; + case 'topright': + this.x = value.x - this.offsets.right; + this.y = value.y - this.offsets.left; + break; + case 'midleft': + this.x = value.x - this.offsets.left; + this.y = value.y; + break; + case 'center': + this.x = value.x + this.y = value.y + break; + case 'midright': + this.x = value.x - this.offsets.right; + this.y = value.y; + break; + case 'bottomleft': + this.x = value.x - this.offsets.left; + this.y = value.y - this.offsets.bottom; + break; + case 'midbottom': + this.x = value.x; + this.y = value.y - this.offsets.bottom; + break; + case 'bottomright': + this.x = value.x - this.offsets.right; + this.y = value.y - this.offsets.bottom; + break; - set size(value) { - let values = jwVectorType.toVector(value) - this.width = isNaN(values.x) ? 0 : values.x - this.height = isNaN(values.y) ? 0 : values.y + case 'size': + this.width = value.x; + this.height = value.y; + break; + } } collidesXYPoint(x, y) { @@ -220,17 +252,17 @@ y = isNaN(y) ? 0 : y return ( - x >= this.singlePoints.left && x <= this.singlePoints.right && - y >= this.singlePoints.bottom && y <= this.singlePoints.top + x >= this.getPoint('left') && x <= this.getPoint('right') && + y >= this.getPoint('bottom') && y <= this.getPoint('top') ) } collidesVectorPoint(vec) { - vec = jwVectorType.toVector(vec) + vec = Vector.toVector(vec) return ( - vec.x >= this.singlePoints.left && vec.x <= this.singlePoints.right && - vec.y >= this.singlePoints.bottom && vec.y <= this.singlePoints.top + vec.x >= this.getPoint('left') && vec.x <= this.getPoint('right') && + vec.y >= this.getPoint('bottom') && vec.y <= this.getPoint('top') ) } @@ -238,52 +270,45 @@ rect = RectType.toRect(rect) return ( - this.singlePoints.left <= rect.singlePoints.right && - this.singlePoints.right >= rect.singlePoints.left && - this.singlePoints.top >= rect.singlePoints.bottom && - this.singlePoints.bottom <= rect.singlePoints.top - + this.getPoint('left') <= rect.getPoint('right') && + this.getPoint('right') >= rect.getPoint('left') && + this.getPoint('top') >= rect.getPoint('bottom') && + this.getPoint('bottom') <= rect.getPoint('top') ) } - } - // Makes it so Vectors & Jsons can grab XYWH const Rect = { Type: RectType, Block: { - blockType: Scratch.BlockType.REPORTER, - blockShape: Scratch.BlockShape.SQUARE, - //forceOutputType: "Rect", + blockType: BlockType.REPORTER, + blockShape: BlockShape.SQUARE, + // forceOutputType: "Rect", disableMonitor: true, allowDropAnywhere: true, }, Argument: { - shape: Scratch.BlockShape.SQUARE, - //check: ["Rect"] - } - } + shape: BlockShape.SQUARE, + }, - const RectArgType1 = { - type: Scratch.ArgumentType.NUMBER, - defaultValue: 0 - } + NumberArg: { + type: ArgumentType.NUMBER, + defaultValue: 0, + }, - const SingleValue = { - menu: 'singleRectValue', - defaultValue: 'x' - } + SinglePointArg: { + menu: 'singlePoint', + defaultValue: 'x' + }, - const VectorValue = { - menu: 'vectorRectValue', - defaultValue: 'topleft' + VectorPointArg: { + menu: 'vectorPoint', + defaultValue: 'topleft', + } } - - - class Extension { - constructor() { + constructor () { vm.IAliRect = Rect vm.runtime.registerSerializer( "IAliRect", @@ -293,139 +318,185 @@ } getInfo() { - return { - id: "IAliRect", - name: "Rect", - color1: "#ff0061", - color2: "#d80052", - menuIconURI: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+DQogIDxlbGxpcHNlIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAwLCA5Nyk7IHN0cm9rZTogcmdiKDIxNiwgMCwgODIpOyIgY3g9IjEwIiBjeT0iMTAiIHJ4PSI5LjUiIHJ5PSI5LjUiPjwvZWxsaXBzZT4NCiAgPHJlY3QgeD0iNi4wNTkiIHk9IjUuNzkzIiB3aWR0aD0iOS40NzciIGhlaWdodD0iOS40NzciIHN0eWxlPSJmaWxsOiBub25lOyBzdHJva2U6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcmVjdD4NCiAgPHJlY3QgeD0iNS40OTQiIHk9IjMuMjIyIiB3aWR0aD0iMTAuNjQzIiBoZWlnaHQ9IjEuMzcyIiByeD0iMSIgcnk9IjEiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3JlY3Q+DQogIDxyZWN0IHg9IjEuNjA1IiB5PSI3LjQ3MyIgd2lkdGg9IjEwLjY0MyIgaGVpZ2h0PSIxLjM3MiIgcng9IjEiIHJ5PSIxIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2Utd2lkdGg6IDE7IHRyYW5zZm9ybS1ib3g6IGZpbGwtYm94OyB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgNTAlOyIgdHJhbnNmb3JtPSJtYXRyaXgoMCwgMSwgLTEsIDAsIC0yLjcwMTY4NCwgMi41MTc0OCkiPjwvcmVjdD4NCjwvc3ZnPg==", - blocks: [ - { - opcode: 'fromSprite', - text: 'from [SPRITE]', - arguments: { - SPRITE: { - type: Scratch.ArgumentType.STRING, - menu: "sprites", - } - }, - ...Rect.Block + let blocks = [ + { + opcode: 'fromSprite', + text: 'from [SPRITE]', + arguments: { + SPRITE: { + type: ArgumentType.STRING, + menu: 'sprites' + } }, - '---', - { - opcode: 'newRectX_Y_W_H', - text: 'rect x: [X] y: [Y] w: [W] h: [H]', - arguments: { - X: RectArgType1, - Y: RectArgType1, - W: RectArgType1, - H: RectArgType1, - }, - ...Rect.Block + ...Rect.Block + }, + '---', + { + opcode: 'newRect4', + text: 'rect x: [X] y: [Y] w: [W] h: [H]', + arguments: { + X: Rect.NumberArg, + Y: Rect.NumberArg, + W: Rect.NumberArg, + H: Rect.NumberArg, }, - { - opcode: 'newRectXY_WH', - text: "rect xy: [XY] wh: [WH]", - arguments: { - XY: vm.jwVector.Argument, - WH: vm.jwVector.Argument, - }, - ...Rect.Block + ...Rect.Block + }, + { + opcode: 'newRect2', + text: 'rect xy: [XY] wh: [WH]', + arguments: { + XY: jwVector.Argument, + WH: jwVector.Argument, }, - '---', - { - opcode: 'getSingleRectPoint', - text: 'get [RECT] [TYPE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - TYPE: SingleValue - }, - }, - - { - opcode: 'setSingleRectPoint', - text: 'set [RECT] [TYPE] to [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - TYPE: SingleValue, - VALUE: RectArgType1, - }, - ...Rect.Block + ...Rect.Block + }, + ] + + blocks = blocks.concat([{ + opcode: 'newRect1', + text: 'rect xywh: [XYWH]', + hideFromPalette: !vm.runtime.ext_jwArray, + arguments: { + XYWH: vm.runtime.ext_jwArray ? vm.jwArray.Argument : ArgumentType.CUSTOM, + }, + ...Rect.Block + }]) + + blocks = blocks.concat([ + '---', + { + opcode: 'getSinglePoint', + text: 'get [RECT] [TYPE]', + blockType: BlockType.REPORTER, + arguments: { + RECT: Rect.Argument, + TYPE: Rect.SinglePointArg + } + }, + { + opcode: 'setSinglePoint', + text: 'set [RECT] [TYPE] to [VALUE]', + arguments: { + RECT: Rect.Argument, + TYPE: Rect.SinglePointArg, + VALUE: Rect.NumberArg, }, + ...Rect.Block + }, - '---', + '---', - { - opcode: 'getVectorRectPoint', - text: 'get [RECT] [TYPE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - TYPE: VectorValue, - }, - ...jwVector.Block + { + opcode: 'getVectorPoint', + text: 'get [RECT] [TYPE]', + arguments: { + RECT: Rect.Argument, + TYPE: Rect.VectorPointArg }, - - { - opcode: 'setVectorRectPoint', - text: 'set [RECT] [TYPE] to [VALUE]', - blockType: Scratch.BlockType.REPORTER, - arguments: { - RECT: Rect.Argument, - TYPE: VectorValue, - VALUE: jwVector.Argument, - }, - ...Rect.Block + ...jwVector.Block + }, + { + opcode: 'setVectorPoint', + text: 'set [VALUE] [TYPE] to [VALUE]', + arguments: { + RECT: Rect.Argument, + TYPE: Rect.VectorPointArg, + VALUE: jwVector.Argument }, - - { - blockType: Scratch.BlockType.LABEL, - text: 'Collisions', + ...Rect.Block + }, + + { + blockType: BlockType.LABEL, + text: 'Collisions' + }, + + { + opcode: 'collidingXY', + text: '[RECT] colliding with x: [X] y: [Y]?', + blockType: BlockType.BOOLEAN, + arguments: { + RECT: Rect.Argument, + X: Rect.NumberArg, + Y: Rect.NumberArg, + } + }, + + { + opcode: 'collidingPoint', + text: '[RECT] colliding with point [VECTOR]?', + blockType: BlockType.BOOLEAN, + arguments: { + RECT: Rect.Argument, + VECTOR: jwVector.Argument, + } + }, + + { + opcode: 'collidingRect', + text: '[RECTA] colliding with rect [RECTB]?', + blockType: Scratch.BlockType.BOOLEAN, + arguments: { + RECTA: Rect.Argument, + RECTB: Rect.Argument, }, - - { - opcode: 'isCollidingWithXY', - text: '[RECT] colliding with x: [X] y: [Y]?', - blockType: Scratch.BlockType.BOOLEAN, - arguments: { - RECT: Rect.Argument, - X: RectArgType1, - Y: RectArgType1, - } + }, + + { + opcode: 'collidingMouse', + text: '[RECT] touching mouse (via client [CLIENT] and centered [CENTERED])?', + blockType: BlockType.BOOLEAN, + arguments: { + RECT: Rect.Argument, + CLIENT: {type: ArgumentType.BOOLEAN, shape: BlockShape.HEXAGONAL}, + CENTERED: {type: ArgumentType.BOOLEAN, shape: BlockShape.HEXAGONAL}, + } + }, + + { + blockType: BlockType.LABEL, + text: 'Extras' + }, + + { + opcode: 'mousePos', + text: 'mouse pos (client: [CLIENT] and centered: [CENTERED])', + arguments: { + CLIENT: { + type: ArgumentType.BOOLEAN, + shape: BlockShape.HEXAGONAL, + }, + CENTERED: {type: ArgumentType.BOOLEAN, shape: BlockShape.HEXAGONAL}, }, + ...jwVector.Block + }, - { - opcode: 'isCollidingWithPoint', - text: '[RECT] colliding with point [VECTOR]?', - blockType: Scratch.BlockType.BOOLEAN, - arguments: { - RECT: Rect.Argument, - VECTOR: jwVector.Argument, - } - }, + { + opcode: 'screenSize', + text: 'screen size', + ...jwVector.Block + } + ]) - { - opcode: 'isCollidingWithRect', - text: '[RECTA] colliding with rect [RECTB]?', - blockType: Scratch.BlockType.BOOLEAN, - arguments: { - RECTA: Rect.Argument, - RECTB: Rect.Argument, - }, - } - ], + return { + id: "IAliRect", + name: "Rect", + color1: "#ff0061", + color2: "#d80052", + menuIconURI: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+DQogIDxlbGxpcHNlIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAwLCA5Nyk7IHN0cm9rZTogcmdiKDIxNiwgMCwgODIpOyIgY3g9IjEwIiBjeT0iMTAiIHJ4PSI5LjUiIHJ5PSI5LjUiPjwvZWxsaXBzZT4NCiAgPHJlY3QgeD0iNi4wNTkiIHk9IjUuNzkzIiB3aWR0aD0iOS40NzciIGhlaWdodD0iOS40NzciIHN0eWxlPSJmaWxsOiBub25lOyBzdHJva2U6IHJnYigyNTUsIDI1NSwgMjU1KTsiPjwvcmVjdD4NCiAgPHJlY3QgeD0iNS40OTQiIHk9IjMuMjIyIiB3aWR0aD0iMTAuNjQzIiBoZWlnaHQ9IjEuMzcyIiByeD0iMSIgcnk9IjEiIHN0eWxlPSJmaWxsOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48L3JlY3Q+DQogIDxyZWN0IHg9IjEuNjA1IiB5PSI3LjQ3MyIgd2lkdGg9IjEwLjY0MyIgaGVpZ2h0PSIxLjM3MiIgcng9IjEiIHJ5PSIxIiBzdHlsZT0iZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2Utd2lkdGg6IDE7IHRyYW5zZm9ybS1ib3g6IGZpbGwtYm94OyB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgNTAlOyIgdHJhbnNmb3JtPSJtYXRyaXgoMCwgMSwgLTEsIDAsIC0yLjcwMTY4NCwgMi41MTc0OCkiPjwvcmVjdD4NCjwvc3ZnPg==", + + blocks: blocks, menus: { sprites: { acceptReporters: true, items: this.getSpriteMenu() }, - singleRectValue: { + singlePoint: { acceptReporters: true, items: ['x', 'y', 'width', 'height', 'topleft x', 'topleft y'] }, - vectorRectValue: { + vectorPoint: { acceptReporters: true, items: [ 'topleft', 'midtop', 'topright', @@ -433,30 +504,30 @@ 'bottomleft', 'midbottom', 'bottomright', 'size' ], - }, - - roundingFunctions: { - acceptReporters: false, - items: [ - { - text: 'round', - value: 'round' - }, - { - text: 'ceil', // might as well go full in on the inconsistencies since we are already doing "round of" - value: 'ceil' - }, - { - text: 'floor', - value: 'floor' - } - ] } + }, + + roundingFunctions: { + acceptReporters: false, + items: [ + { + text: 'round', + value: 'round' + }, + { + text: 'ceil', // might as well go full in on the inconsistencies since we are already doing "round of" + value: 'ceil' + }, + { + text: 'floor', + value: 'floor' + } + ] } } } - getSpriteMenu (){ + getSpriteMenu(){ const targets = vm.runtime.targets; const emptyMenu = [{ text: "", value: "" }]; if (!targets) return emptyMenu; @@ -464,155 +535,57 @@ return (menu.length > 0) ? menu : emptyMenu; } - /** - * - * @param args - * @returns {RectType} - */ - newRectX_Y_W_H({X, Y, W, H}) { - return new RectType(X, Y, W, H) - } + fromSprite({SPRITE}) { + let spr = vm.runtime.getSpriteTargetByName(SPRITE) + let x = spr.x + let y = spr.y - /** - * - * @param args - * @returns {RectType} - */ - newRectXY_WH({XY, WH}) { - let xy = jwVectorType.toVector(XY) - let wh = jwVectorType.toVector(WH) - return new RectType(xy.x, xy.y, wh.x, wh.y) - } + let costume = spr.sprite.costumes_[spr.currentCostume] + let asset = costume.asset + let assetType = asset.assetType.name + let size = costume.size - getSingleRectPoint({RECT, TYPE}) { - let rect = RectType.toRect(RECT); - switch(TYPE) { - case 'x': - return rect.x; - case 'y': - return rect.y; - case 'width': - return rect.width; - case 'height': - return rect.height; - case 'topleft x': - return rect.topleft.x; - case 'topleft y': - return rect.topleft.y - } - return 0; + return new RectType(x, y, assetType == "ImageBitmap" ? size[0]/2 : size[0], assetType == "ImageBitmap" ? size[1]/2 : size[1]) } - setSingleRectPoint({RECT, TYPE, VALUE}) { - let rect = RectType.toRect(RECT); - let value = Cast.toNumber(VALUE); - switch (TYPE) { - case 'x': - rect.x = value; - break; - case 'y': - rect.y = value; - break; - case 'width': - rect.width = value; - break; - case 'height': - rect.height = value; - break; - case 'topleft x': - rect.topleft = new jwVectorType(value, rect.topleft.y) - break; - case 'topleft y': - rect.topleft = new jwVectorType(rect.topleft.x, value) - break; - } - return rect; + newRect4({X, Y, W, H}) { + return new RectType(X, Y, W, H); } - getVectorRectPoint({RECT, TYPE}) { - let rect = RectType.toRect(RECT); - switch (TYPE) { - case 'topleft': - return rect.topleft; - case 'midtop': - return rect.midtop; - case 'topright': - return rect.topright; - - case 'midleft': - return rect.midleft; - case 'center': - return rect.center; - case 'midright': - return rect.midright; - - case 'bottomleft': - return rect.bottomleft; - case 'midbottom': - return rect.midbottom; - case 'bottomright': - return rect.bottomright; - - case 'size': - return rect.size; - } - return new jwVectorType(0, 0); + newRect2({XY, WH}) { + XY = Vector.toVector(XY) + WH = Vector.toVector(WH) + return RectType.toRect([XY, WH]); } - setVectorRectPoint({RECT, TYPE, VALUE}) { - let rect = RectType.toRect(RECT); - let value = jwVectorType.toVector(VALUE); - switch (TYPE) { - case 'topleft': - rect.topleft = value; - break; - case 'midtop': - rect.midtop = value; - break; - case 'topright': - rect.topright = value; - break; - case 'midleft': - rect.midleft = value; - break; - case 'center': - rect.center = value; - break; - case 'midright': - rect.midright = value; - break; - case 'bottomleft': - rect.bottomleft = value; - break; - case 'midbottom': - rect.midbottom = value; - break; - case 'bottomright': - rect.bottomright = value; - break; - case 'size': - rect.size = value; - break; - } - return rect; + newRect1({XYWH}) { + return RectType.toRect(XYWH) } - fromSprite({SPRITE}) { - let spr = vm.runtime.getSpriteTargetByName(SPRITE) - let x = spr.x - let y = spr.y + getSinglePoint({RECT, TYPE}) { + let val = RectType.toRect(RECT).getPoint(TYPE) + return isNaN(val) ? 0 : val + } - let costume = spr.sprite.costumes_[spr.currentCostume] - let asset = costume.asset - let assetType = asset.assetType.name - let size = costume.size + getVectorPoint({RECT, TYPE}) { + let val = RectType.toRect(RECT).getPoint(TYPE); + return isNaN(val) ? val : new Vector() + } - return new RectType(x, y, assetType == "ImageBitmap" ? size[0]/2 : size[0], assetType == "ImageBitmap" ? size[1]/2 : size[1]) + setSinglePoint({RECT, TYPE, VALUE}) { + RECT = RectType.toRect(RECT) + RECT.setSinglePoint(TYPE, VALUE); + return RECT; } + setVectorPoint({RECT, TYPE, VALUE}) { + RECT = RectType.toRect(RECT) + RECT.setVectorPoint(TYPE, VALUE); + return RECT; + } - isCollidingWithXY({RECT, X, Y}) { + collidingXY({RECT, X, Y}) { RECT = RectType.toRect(RECT); X = Cast.toNumber(X); Y = Cast.toNumber(Y); @@ -620,19 +593,39 @@ return RECT.collidesXYPoint(X, Y); } - isCollidingWithPoint({RECT, VECTOR}) { + collidingPoint({RECT, VECTOR}) { RECT = RectType.toRect(RECT); - let XY = jwVectorType.toVector(VECTOR); + let XY = Vector.toVector(VECTOR); return RECT.collidesVectorPoint(XY) } - isCollidingWithRect({RECTA, RECTB}) { + collidingRect({RECTA, RECTB}) { RECTA = RectType.toRect(RECTA) RECTB = RectType.toRect(RECTB) return RECTA.collidesRect(RECTB) } + + collidingMouse({RECT, CLIENT, CENTERED}) { + RECT = RectType.toRect(RECT); + let vector = new Vector(CLIENT ? mouse.getClientX() : mouse.getScratchX(), CLIENT ? mouse.getClientY() : mouse.getScratchY()); + vector = CENTERED && CLIENT ? new Vector(vector.x - vm.runtime.stageWidth / 2, -vector.y + vm.runtime.stageHeight / 2) : vector; + return RECT.collidesVectorPoint(vector); + } + + + mousePos({CLIENT, CENTERED}) { + let vector = new Vector(CLIENT ? mouse.getClientX() : mouse.getScratchX(), CLIENT ? mouse.getClientY() : mouse.getScratchY()); + vector = CENTERED && CLIENT ? new Vector(vector.x - vm.runtime.stageWidth / 2, -vector.y + vm.runtime.stageHeight / 2) : vector; + return vector; + } + + screenSize() { + return new Vector(vm.runtime.stageWidth, vm.runtime.stageHeight) + } + + } Scratch.extensions.register(new Extension()) From 8c2eeda819564cab582c4ccaf4cb85bea75bea09 Mon Sep 17 00:00:00 2001 From: Irshaad <98787249+IrshaadAli1@users.noreply.github.com> Date: Tue, 7 Oct 2025 12:29:03 -0400 Subject: [PATCH 22/22] Update extensions.js --- src/lib/extensions.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lib/extensions.js b/src/lib/extensions.js index 4152b0dbb..cc6fa89da 100644 --- a/src/lib/extensions.js +++ b/src/lib/extensions.js @@ -19,6 +19,13 @@ export default [ banner: "pooiod/B2Dimg.svg", creator: "pooiod7", }, + { + name: "Rect", // The name of the extension. + description: "Creates a Rectangle-Based object which you can grab positions of (Works with Vectors!)", + code: "IrshaadAli/static_Rect.js", // There exists a translated version too + banner: "IrshaadAli/Rect.svg", // Sorry - Don't know how to avif + creator: "Irshaad_Ali", // Had to create a new one + }, { name: "3D Math", description: "A handful of utilities for making your own sprite-based 3D engine.", @@ -140,13 +147,6 @@ export default [ documentation: "PenguinAI", unstableReason: "AI models can generate unintended or inappropriate output.\nSome AI models may also become temporarily inaccessible.\n\nUse at your own risk.", }, - { - name: "Rect", // The name of the extension. - description: "Creates a Rectangle-Based object which you can grab positions of (Works with Vectors!)", - code: "IrshaadAli/static_Rect.js", // There exists a translated version too - banner: "IrshaadAli/Rect.svg", // Sorry - Don't know how to avif - creator: "Irshaad_Ali", // Had to create a new one - }, /* { name: "Block AI",