From 8d37f13a147e96274f68ffee556aba8d1bc1e9a4 Mon Sep 17 00:00:00 2001 From: LegoBrainBiker Date: Fri, 2 May 2025 09:34:13 -0700 Subject: [PATCH 1/5] legobrainbiker/more mouse controlls: implementation --- extensions/extensions.json | 1 + .../legobrainbiker/more mouse controls.js | 137 ++++++++++++++++++ images/legobrainbiker/more mouse controls.svg | 1 + 3 files changed, 139 insertions(+) create mode 100644 extensions/legobrainbiker/more mouse controls.js create mode 100644 images/legobrainbiker/more mouse controls.svg diff --git a/extensions/extensions.json b/extensions/extensions.json index d8ed71e33d..d6552981a3 100644 --- a/extensions/extensions.json +++ b/extensions/extensions.json @@ -7,6 +7,7 @@ "files", "pointerlock", "cursor", + "legobrainbiker/more mouse controls", "runtime-options", "fetch", "text", diff --git a/extensions/legobrainbiker/more mouse controls.js b/extensions/legobrainbiker/more mouse controls.js new file mode 100644 index 0000000000..79b17333ad --- /dev/null +++ b/extensions/legobrainbiker/more mouse controls.js @@ -0,0 +1,137 @@ +// Name: More Mouse Controls +// ID: legobrainbikerMoreMouseControls +// Description: Some features I felt were missing from the mouse, including right click detection. +// By: legobrainbiker +// License: MPL-2.0 +((Scratch) => { + "use strict"; + class moreMouseControls { + constructor() { + this.mouseX = 0; + this.mouseY = 0; + this.scroll = 0; + this.buttons = []; + document.addEventListener("mousewheel", (e) => { + this.mouseWheelDelta = e.deltaY; + Scratch.vm.runtime.startHats( + "legobrainbikerMoreMouseControls_onScroll" + ); + }); + document.addEventListener("mouseup", (e) => { + this.buttons[e.button] = false; + }); + document.addEventListener("mousedown", (e) => { + this.buttons[e.button] = true; + }); + document.addEventListener("mousemove", (e) => { + this.mouseX = e.clientX; + this.mouseY = e.clientY; + }); + } + getInfo() { + return { + id: "legobrainbikerMoreMouseControls", + name: Scratch.translate("More Mouse Controls"), + menuIconURI: + "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIzNi4zOTI4MSIgaGVpZ2h0PSIzNS40MjY1OSIgdmlld0JveD0iMCwwLDM2LjM5MjgxLDM1LjQyNjU5Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTU2Ljg4NTQxLC0xNTcuNjM4NDcpIj48ZyBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCI+PHBhdGggZD0iTTE2Mi44NjU0NCwxNjcuNDYzMDljMCwtMi4wNDY3NCAxLjc0NjIsLTMuNzA1OTQgMy45MDAyNCwtMy43MDU5NGMyLjE1NDA0LDAgMy45MDAyNCwxLjY1OTIxIDMuOTAwMjQsMy43MDU5NGMwLDIuMDQ2NzQgLTEuNzQ2MiwzLjcwNTk1IC0zLjkwMDI0LDMuNzA1OTVjLTIuMTU0MDQsMCAtMy45MDAyNCwtMS42NTkyMSAtMy45MDAyNCwtMy43MDU5NXoiIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMi41IiBzdHJva2UtbGluZWNhcD0iYnV0dCIvPjxwYXRoIGQ9Ik0xNTguMTM1NDEsMTY3LjQ2MzA5YzAsLTQuNzM1NjMgMy44NjM5LC04LjU3NDYyIDguNjMwMjcsLTguNTc0NjJjNC43NjYzNywwIDguNjMwMjcsMy44Mzg5OSA4LjYzMDI3LDguNTc0NjJjMCw0LjczNTYzIC0zLjg2MzksOC41NzQ2MiAtOC42MzAyNyw4LjU3NDYyYy00Ljc2NjM3LDAgLTguNjMwMjcsLTMuODM4OTkgLTguNjMwMjcsLTguNTc0NjJ6IiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjIuNSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMTY3LjE0OTM5LDE3MC45MDY1YzEuNzMxMTMsMy41NzM5NSA3LjA5NTEzLDE0LjY0ODAxIDkuODg1MzksMjAuNDA4NTVjMS4wNDI2OSwyLjE1MjY1IDIuMzMzMzgsMS4xMzM2NiAyLjc1MjMyLC0wLjU0MjA4YzAuNDY3NjksLTEuODcwNzUgMS41NTMyMywtNi4yMTI5MiAyLjE0OTI5LC04LjU5NzE0YzAuMjQ3MDcsLTAuOTg4MjggMS4yMjc3NCwtMS45Mzk5OCAyLjAwNjEzLC0yLjIyNTM5YzEuMTc1NDYsLTAuNDMxIDQuNjg3NzgsLTEuNzE4ODUgNy41ODU3MSwtMi43ODE0MmMyLjMzMSwtMC44NTQ3IDIuMzU5MTIsLTIuMTQzNTMgLTAuNDQ3MjksLTIuOTk3NjVjLTYuNTM1MzMsLTEuOTg5MDEgLTE3Ljk1NzAzLC01LjQ2NTE4IC0yMS41ODI1MiwtNi41Njg1OWMtMi4xNzUxNCwtMC42NjIgLTMuNDAzNTEsMS4xMjY3MyAtMi4zNDkwMywzLjMwMzczeiIgZmlsbD0iI2EzYTNhMyIgc3Ryb2tlLXdpZHRoPSIzLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvZz48L2c+PC9zdmc+", + blockIconURI: + "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIzNi4zOTI4MSIgaGVpZ2h0PSIzNS40MjY1OSIgdmlld0JveD0iMCwwLDM2LjM5MjgxLDM1LjQyNjU5Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTU2Ljg4NTQxLC0xNTcuNjM4NDcpIj48ZyBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCI+PHBhdGggZD0iTTE2Mi44NjU0NCwxNjcuNDYzMDljMCwtMi4wNDY3NCAxLjc0NjIsLTMuNzA1OTQgMy45MDAyNCwtMy43MDU5NGMyLjE1NDA0LDAgMy45MDAyNCwxLjY1OTIxIDMuOTAwMjQsMy43MDU5NGMwLDIuMDQ2NzQgLTEuNzQ2MiwzLjcwNTk1IC0zLjkwMDI0LDMuNzA1OTVjLTIuMTU0MDQsMCAtMy45MDAyNCwtMS42NTkyMSAtMy45MDAyNCwtMy43MDU5NXoiIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMi41IiBzdHJva2UtbGluZWNhcD0iYnV0dCIvPjxwYXRoIGQ9Ik0xNTguMTM1NDEsMTY3LjQ2MzA5YzAsLTQuNzM1NjMgMy44NjM5LC04LjU3NDYyIDguNjMwMjcsLTguNTc0NjJjNC43NjYzNywwIDguNjMwMjcsMy44Mzg5OSA4LjYzMDI3LDguNTc0NjJjMCw0LjczNTYzIC0zLjg2MzksOC41NzQ2MiAtOC42MzAyNyw4LjU3NDYyYy00Ljc2NjM3LDAgLTguNjMwMjcsLTMuODM4OTkgLTguNjMwMjcsLTguNTc0NjJ6IiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjIuNSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMTY3LjE0OTM5LDE3MC45MDY1YzEuNzMxMTMsMy41NzM5NSA3LjA5NTEzLDE0LjY0ODAxIDkuODg1MzksMjAuNDA4NTVjMS4wNDI2OSwyLjE1MjY1IDIuMzMzMzgsMS4xMzM2NiAyLjc1MjMyLC0wLjU0MjA4YzAuNDY3NjksLTEuODcwNzUgMS41NTMyMywtNi4yMTI5MiAyLjE0OTI5LC04LjU5NzE0YzAuMjQ3MDcsLTAuOTg4MjggMS4yMjc3NCwtMS45Mzk5OCAyLjAwNjEzLC0yLjIyNTM5YzEuMTc1NDYsLTAuNDMxIDQuNjg3NzgsLTEuNzE4ODUgNy41ODU3MSwtMi43ODE0MmMyLjMzMSwtMC44NTQ3IDIuMzU5MTIsLTIuMTQzNTMgLTAuNDQ3MjksLTIuOTk3NjVjLTYuNTM1MzMsLTEuOTg5MDEgLTE3Ljk1NzAzLC01LjQ2NTE4IC0yMS41ODI1MiwtNi41Njg1OWMtMi4xNzUxNCwtMC42NjIgLTMuNDAzNTEsMS4xMjY3MyAtMi4zNDkwMywzLjMwMzczeiIgZmlsbD0iI2EzYTNhMyIgc3Ryb2tlLXdpZHRoPSIzLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvZz48L2c+PC9zdmc+", + color1: "#99bbbb", + color2: "#88bbbb", + color3: "#88bbbb", + blocks: [ + { + opcode: "onMouseUp", + blockType: Scratch.BlockType.HAT, + text: Scratch.translate("when mouse button [button] is released"), + isEdgeActivated: true, + arguments: { + button: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "0", + }, + }, + }, + { + opcode: "onMouseDown", + blockType: Scratch.BlockType.HAT, + text: Scratch.translate("when mouse button [button] is pressed"), + isEdgeActivated: true, + arguments: { + button: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "0", + }, + }, + }, + { + opcode: "buttonPressed", + blockType: Scratch.BlockType.BOOLEAN, + text: Scratch.translate("mouse button [button] is pressed"), + arguments: { + button: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "0", + }, + }, + }, + { + opcode: "dissableContextMenu", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("disable context menu"), + }, + { + opcode: "onScroll", + blockType: Scratch.BlockType.EVENT, + text: Scratch.translate("when scrolling"), + isEdgeActivated: false, + }, + { + opcode: "scrollamount", + blockType: Scratch.BlockType.REPORTER, + text: Scratch.translate("scroll amount"), + }, + { + opcode: "mouseGlobalX", + blockType: Scratch.BlockType.REPORTER, + text: Scratch.translate("mouse global x position"), + }, + { + opcode: "mouseGlobalY", + blockType: Scratch.BlockType.REPORTER, + text: Scratch.translate("mouse global y position"), + }, + ], + }; + } + onMouseUp(args) { + return !this.buttonPressed(args); + } + onMouseDown(args) { + return this.buttonPressed(args); + } + buttonPressed({ button }) { + console.log(button); + console.log(Scratch.Cast.toNumber(button)); + console.log(this.buttons[Scratch.Cast.toNumber(button)]); + return this.buttons[Scratch.Cast.toNumber(button)] || false; + } + dissableContextMenu() { + document.addEventListener("contextmenu", (e) => { + e.preventDefault(); + }); + } + scrollamount() { + return this.mouseWheelDelta || 0; + } + mouseGlobalX() { + const canvas = Scratch.renderer.canvas.getBoundingClientRect(); + return this.mouseX - canvas.x - canvas.width / 2; + } + mouseGlobalY() { + const canvas = Scratch.renderer.canvas.getBoundingClientRect(); + return -(this.mouseY - canvas.y - canvas.height / 2); + } + } + Scratch.extensions.register(new moreMouseControls()); +})(Scratch); diff --git a/images/legobrainbiker/more mouse controls.svg b/images/legobrainbiker/more mouse controls.svg new file mode 100644 index 0000000000..0d46c87595 --- /dev/null +++ b/images/legobrainbiker/more mouse controls.svg @@ -0,0 +1 @@ + \ No newline at end of file From 67cfbeb73cb12d5f19db031d6871714a9ebb23cc Mon Sep 17 00:00:00 2001 From: LegoBrainBiker Date: Fri, 2 May 2025 12:06:56 -0700 Subject: [PATCH 2/5] legobrainbiker/moremousecontrolls: update based on suggestions --- extensions/extensions.json | 2 +- .../{more mouse controls.js => MoreMouseControls.js} | 11 +++++------ ...{more mouse controls.svg => MoreMouseControls.svg} | 0 3 files changed, 6 insertions(+), 7 deletions(-) rename extensions/legobrainbiker/{more mouse controls.js => MoreMouseControls.js} (52%) rename images/legobrainbiker/{more mouse controls.svg => MoreMouseControls.svg} (100%) diff --git a/extensions/extensions.json b/extensions/extensions.json index d6552981a3..f57e0c3c11 100644 --- a/extensions/extensions.json +++ b/extensions/extensions.json @@ -7,7 +7,7 @@ "files", "pointerlock", "cursor", - "legobrainbiker/more mouse controls", + "legobrainbiker/MoreMouseControls", "runtime-options", "fetch", "text", diff --git a/extensions/legobrainbiker/more mouse controls.js b/extensions/legobrainbiker/MoreMouseControls.js similarity index 52% rename from extensions/legobrainbiker/more mouse controls.js rename to extensions/legobrainbiker/MoreMouseControls.js index 79b17333ad..8fc2ba8ab1 100644 --- a/extensions/legobrainbiker/more mouse controls.js +++ b/extensions/legobrainbiker/MoreMouseControls.js @@ -1,10 +1,11 @@ // Name: More Mouse Controls // ID: legobrainbikerMoreMouseControls -// Description: Some features I felt were missing from the mouse, including right click detection. +// Description: adds more options to detect properties of the cursor, including its position, clicking, and scrolling. // By: legobrainbiker // License: MPL-2.0 -((Scratch) => { +(function (Scratch) { "use strict"; + const iconURI = 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIzNi4zOTI4MSIgaGVpZ2h0PSIzNS40MjY1OSIgdmlld0JveD0iMCwwLDM2LjM5MjgxLDM1LjQyNjU5Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTU2Ljg4NTQxLC0xNTcuNjM4NDcpIj48ZyBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCI+PHBhdGggZD0iTTE2Mi44NjU0NCwxNjcuNDYzMDljMCwtMi4wNDY3NCAxLjc0NjIsLTMuNzA1OTQgMy45MDAyNCwtMy43MDU5NGMyLjE1NDA0LDAgMy45MDAyNCwxLjY1OTIxIDMuOTAwMjQsMy43MDU5NGMwLDIuMDQ2NzQgLTEuNzQ2MiwzLjcwNTk1IC0zLjkwMDI0LDMuNzA1OTVjLTIuMTU0MDQsMCAtMy45MDAyNCwtMS42NTkyMSAtMy45MDAyNCwtMy43MDU5NXoiIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMi41IiBzdHJva2UtbGluZWNhcD0iYnV0dCIvPjxwYXRoIGQ9Ik0xNTguMTM1NDEsMTY3LjQ2MzA5YzAsLTQuNzM1NjMgMy44NjM5LC04LjU3NDYyIDguNjMwMjcsLTguNTc0NjJjNC43NjYzNywwIDguNjMwMjcsMy44Mzg5OSA4LjYzMDI3LDguNTc0NjJjMCw0LjczNTYzIC0zLjg2MzksOC41NzQ2MiAtOC42MzAyNyw4LjU3NDYyYy00Ljc2NjM3LDAgLTguNjMwMjcsLTMuODM4OTkgLTguNjMwMjcsLTguNTc0NjJ6IiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjIuNSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMTY3LjE0OTM5LDE3MC45MDY1YzEuNzMxMTMsMy41NzM5NSA3LjA5NTEzLDE0LjY0ODAxIDkuODg1MzksMjAuNDA4NTVjMS4wNDI2OSwyLjE1MjY1IDIuMzMzMzgsMS4xMzM2NiAyLjc1MjMyLC0wLjU0MjA4YzAuNDY3NjksLTEuODcwNzUgMS41NTMyMywtNi4yMTI5MiAyLjE0OTI5LC04LjU5NzE0YzAuMjQ3MDcsLTAuOTg4MjggMS4yMjc3NCwtMS45Mzk5OCAyLjAwNjEzLC0yLjIyNTM5YzEuMTc1NDYsLTAuNDMxIDQuNjg3NzgsLTEuNzE4ODUgNy41ODU3MSwtMi43ODE0MmMyLjMzMSwtMC44NTQ3IDIuMzU5MTIsLTIuMTQzNTMgLTAuNDQ3MjksLTIuOTk3NjVjLTYuNTM1MzMsLTEuOTg5MDEgLTE3Ljk1NzAzLC01LjQ2NTE4IC0yMS41ODI1MiwtNi41Njg1OWMtMi4xNzUxNCwtMC42NjIgLTMuNDAzNTEsMS4xMjY3MyAtMi4zNDkwMywzLjMwMzczeiIgZmlsbD0iI2EzYTNhMyIgc3Ryb2tlLXdpZHRoPSIzLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvZz48L2c+PC9zdmc+' class moreMouseControls { constructor() { this.mouseX = 0; @@ -32,10 +33,8 @@ return { id: "legobrainbikerMoreMouseControls", name: Scratch.translate("More Mouse Controls"), - menuIconURI: - "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIzNi4zOTI4MSIgaGVpZ2h0PSIzNS40MjY1OSIgdmlld0JveD0iMCwwLDM2LjM5MjgxLDM1LjQyNjU5Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTU2Ljg4NTQxLC0xNTcuNjM4NDcpIj48ZyBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCI+PHBhdGggZD0iTTE2Mi44NjU0NCwxNjcuNDYzMDljMCwtMi4wNDY3NCAxLjc0NjIsLTMuNzA1OTQgMy45MDAyNCwtMy43MDU5NGMyLjE1NDA0LDAgMy45MDAyNCwxLjY1OTIxIDMuOTAwMjQsMy43MDU5NGMwLDIuMDQ2NzQgLTEuNzQ2MiwzLjcwNTk1IC0zLjkwMDI0LDMuNzA1OTVjLTIuMTU0MDQsMCAtMy45MDAyNCwtMS42NTkyMSAtMy45MDAyNCwtMy43MDU5NXoiIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMi41IiBzdHJva2UtbGluZWNhcD0iYnV0dCIvPjxwYXRoIGQ9Ik0xNTguMTM1NDEsMTY3LjQ2MzA5YzAsLTQuNzM1NjMgMy44NjM5LC04LjU3NDYyIDguNjMwMjcsLTguNTc0NjJjNC43NjYzNywwIDguNjMwMjcsMy44Mzg5OSA4LjYzMDI3LDguNTc0NjJjMCw0LjczNTYzIC0zLjg2MzksOC41NzQ2MiAtOC42MzAyNyw4LjU3NDYyYy00Ljc2NjM3LDAgLTguNjMwMjcsLTMuODM4OTkgLTguNjMwMjcsLTguNTc0NjJ6IiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjIuNSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMTY3LjE0OTM5LDE3MC45MDY1YzEuNzMxMTMsMy41NzM5NSA3LjA5NTEzLDE0LjY0ODAxIDkuODg1MzksMjAuNDA4NTVjMS4wNDI2OSwyLjE1MjY1IDIuMzMzMzgsMS4xMzM2NiAyLjc1MjMyLC0wLjU0MjA4YzAuNDY3NjksLTEuODcwNzUgMS41NTMyMywtNi4yMTI5MiAyLjE0OTI5LC04LjU5NzE0YzAuMjQ3MDcsLTAuOTg4MjggMS4yMjc3NCwtMS45Mzk5OCAyLjAwNjEzLC0yLjIyNTM5YzEuMTc1NDYsLTAuNDMxIDQuNjg3NzgsLTEuNzE4ODUgNy41ODU3MSwtMi43ODE0MmMyLjMzMSwtMC44NTQ3IDIuMzU5MTIsLTIuMTQzNTMgLTAuNDQ3MjksLTIuOTk3NjVjLTYuNTM1MzMsLTEuOTg5MDEgLTE3Ljk1NzAzLC01LjQ2NTE4IC0yMS41ODI1MiwtNi41Njg1OWMtMi4xNzUxNCwtMC42NjIgLTMuNDAzNTEsMS4xMjY3MyAtMi4zNDkwMywzLjMwMzczeiIgZmlsbD0iI2EzYTNhMyIgc3Ryb2tlLXdpZHRoPSIzLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvZz48L2c+PC9zdmc+", - blockIconURI: - "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIzNi4zOTI4MSIgaGVpZ2h0PSIzNS40MjY1OSIgdmlld0JveD0iMCwwLDM2LjM5MjgxLDM1LjQyNjU5Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTU2Ljg4NTQxLC0xNTcuNjM4NDcpIj48ZyBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCI+PHBhdGggZD0iTTE2Mi44NjU0NCwxNjcuNDYzMDljMCwtMi4wNDY3NCAxLjc0NjIsLTMuNzA1OTQgMy45MDAyNCwtMy43MDU5NGMyLjE1NDA0LDAgMy45MDAyNCwxLjY1OTIxIDMuOTAwMjQsMy43MDU5NGMwLDIuMDQ2NzQgLTEuNzQ2MiwzLjcwNTk1IC0zLjkwMDI0LDMuNzA1OTVjLTIuMTU0MDQsMCAtMy45MDAyNCwtMS42NTkyMSAtMy45MDAyNCwtMy43MDU5NXoiIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMi41IiBzdHJva2UtbGluZWNhcD0iYnV0dCIvPjxwYXRoIGQ9Ik0xNTguMTM1NDEsMTY3LjQ2MzA5YzAsLTQuNzM1NjMgMy44NjM5LC04LjU3NDYyIDguNjMwMjcsLTguNTc0NjJjNC43NjYzNywwIDguNjMwMjcsMy44Mzg5OSA4LjYzMDI3LDguNTc0NjJjMCw0LjczNTYzIC0zLjg2MzksOC41NzQ2MiAtOC42MzAyNyw4LjU3NDYyYy00Ljc2NjM3LDAgLTguNjMwMjcsLTMuODM4OTkgLTguNjMwMjcsLTguNTc0NjJ6IiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjIuNSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMTY3LjE0OTM5LDE3MC45MDY1YzEuNzMxMTMsMy41NzM5NSA3LjA5NTEzLDE0LjY0ODAxIDkuODg1MzksMjAuNDA4NTVjMS4wNDI2OSwyLjE1MjY1IDIuMzMzMzgsMS4xMzM2NiAyLjc1MjMyLC0wLjU0MjA4YzAuNDY3NjksLTEuODcwNzUgMS41NTMyMywtNi4yMTI5MiAyLjE0OTI5LC04LjU5NzE0YzAuMjQ3MDcsLTAuOTg4MjggMS4yMjc3NCwtMS45Mzk5OCAyLjAwNjEzLC0yLjIyNTM5YzEuMTc1NDYsLTAuNDMxIDQuNjg3NzgsLTEuNzE4ODUgNy41ODU3MSwtMi43ODE0MmMyLjMzMSwtMC44NTQ3IDIuMzU5MTIsLTIuMTQzNTMgLTAuNDQ3MjksLTIuOTk3NjVjLTYuNTM1MzMsLTEuOTg5MDEgLTE3Ljk1NzAzLC01LjQ2NTE4IC0yMS41ODI1MiwtNi41Njg1OWMtMi4xNzUxNCwtMC42NjIgLTMuNDAzNTEsMS4xMjY3MyAtMi4zNDkwMywzLjMwMzczeiIgZmlsbD0iI2EzYTNhMyIgc3Ryb2tlLXdpZHRoPSIzLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvZz48L2c+PC9zdmc+", + menuIconURI: iconURI, + blockIconURI: iconURI, color1: "#99bbbb", color2: "#88bbbb", color3: "#88bbbb", diff --git a/images/legobrainbiker/more mouse controls.svg b/images/legobrainbiker/MoreMouseControls.svg similarity index 100% rename from images/legobrainbiker/more mouse controls.svg rename to images/legobrainbiker/MoreMouseControls.svg From 04b7b1a408d9918d284c631bf0e3a35ae86120f4 Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Fri, 2 May 2025 19:09:24 +0000 Subject: [PATCH 3/5] [Automated] Format code --- extensions/legobrainbiker/MoreMouseControls.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/legobrainbiker/MoreMouseControls.js b/extensions/legobrainbiker/MoreMouseControls.js index 8fc2ba8ab1..7cdb8f143c 100644 --- a/extensions/legobrainbiker/MoreMouseControls.js +++ b/extensions/legobrainbiker/MoreMouseControls.js @@ -5,7 +5,8 @@ // License: MPL-2.0 (function (Scratch) { "use strict"; - const iconURI = 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIzNi4zOTI4MSIgaGVpZ2h0PSIzNS40MjY1OSIgdmlld0JveD0iMCwwLDM2LjM5MjgxLDM1LjQyNjU5Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTU2Ljg4NTQxLC0xNTcuNjM4NDcpIj48ZyBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCI+PHBhdGggZD0iTTE2Mi44NjU0NCwxNjcuNDYzMDljMCwtMi4wNDY3NCAxLjc0NjIsLTMuNzA1OTQgMy45MDAyNCwtMy43MDU5NGMyLjE1NDA0LDAgMy45MDAyNCwxLjY1OTIxIDMuOTAwMjQsMy43MDU5NGMwLDIuMDQ2NzQgLTEuNzQ2MiwzLjcwNTk1IC0zLjkwMDI0LDMuNzA1OTVjLTIuMTU0MDQsMCAtMy45MDAyNCwtMS42NTkyMSAtMy45MDAyNCwtMy43MDU5NXoiIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMi41IiBzdHJva2UtbGluZWNhcD0iYnV0dCIvPjxwYXRoIGQ9Ik0xNTguMTM1NDEsMTY3LjQ2MzA5YzAsLTQuNzM1NjMgMy44NjM5LC04LjU3NDYyIDguNjMwMjcsLTguNTc0NjJjNC43NjYzNywwIDguNjMwMjcsMy44Mzg5OSA4LjYzMDI3LDguNTc0NjJjMCw0LjczNTYzIC0zLjg2MzksOC41NzQ2MiAtOC42MzAyNyw4LjU3NDYyYy00Ljc2NjM3LDAgLTguNjMwMjcsLTMuODM4OTkgLTguNjMwMjcsLTguNTc0NjJ6IiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjIuNSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMTY3LjE0OTM5LDE3MC45MDY1YzEuNzMxMTMsMy41NzM5NSA3LjA5NTEzLDE0LjY0ODAxIDkuODg1MzksMjAuNDA4NTVjMS4wNDI2OSwyLjE1MjY1IDIuMzMzMzgsMS4xMzM2NiAyLjc1MjMyLC0wLjU0MjA4YzAuNDY3NjksLTEuODcwNzUgMS41NTMyMywtNi4yMTI5MiAyLjE0OTI5LC04LjU5NzE0YzAuMjQ3MDcsLTAuOTg4MjggMS4yMjc3NCwtMS45Mzk5OCAyLjAwNjEzLC0yLjIyNTM5YzEuMTc1NDYsLTAuNDMxIDQuNjg3NzgsLTEuNzE4ODUgNy41ODU3MSwtMi43ODE0MmMyLjMzMSwtMC44NTQ3IDIuMzU5MTIsLTIuMTQzNTMgLTAuNDQ3MjksLTIuOTk3NjVjLTYuNTM1MzMsLTEuOTg5MDEgLTE3Ljk1NzAzLC01LjQ2NTE4IC0yMS41ODI1MiwtNi41Njg1OWMtMi4xNzUxNCwtMC42NjIgLTMuNDAzNTEsMS4xMjY3MyAtMi4zNDkwMywzLjMwMzczeiIgZmlsbD0iI2EzYTNhMyIgc3Ryb2tlLXdpZHRoPSIzLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvZz48L2c+PC9zdmc+' + const iconURI = + "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIzNi4zOTI4MSIgaGVpZ2h0PSIzNS40MjY1OSIgdmlld0JveD0iMCwwLDM2LjM5MjgxLDM1LjQyNjU5Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTU2Ljg4NTQxLC0xNTcuNjM4NDcpIj48ZyBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCI+PHBhdGggZD0iTTE2Mi44NjU0NCwxNjcuNDYzMDljMCwtMi4wNDY3NCAxLjc0NjIsLTMuNzA1OTQgMy45MDAyNCwtMy43MDU5NGMyLjE1NDA0LDAgMy45MDAyNCwxLjY1OTIxIDMuOTAwMjQsMy43MDU5NGMwLDIuMDQ2NzQgLTEuNzQ2MiwzLjcwNTk1IC0zLjkwMDI0LDMuNzA1OTVjLTIuMTU0MDQsMCAtMy45MDAyNCwtMS42NTkyMSAtMy45MDAyNCwtMy43MDU5NXoiIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMi41IiBzdHJva2UtbGluZWNhcD0iYnV0dCIvPjxwYXRoIGQ9Ik0xNTguMTM1NDEsMTY3LjQ2MzA5YzAsLTQuNzM1NjMgMy44NjM5LC04LjU3NDYyIDguNjMwMjcsLTguNTc0NjJjNC43NjYzNywwIDguNjMwMjcsMy44Mzg5OSA4LjYzMDI3LDguNTc0NjJjMCw0LjczNTYzIC0zLjg2MzksOC41NzQ2MiAtOC42MzAyNyw4LjU3NDYyYy00Ljc2NjM3LDAgLTguNjMwMjcsLTMuODM4OTkgLTguNjMwMjcsLTguNTc0NjJ6IiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjIuNSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMTY3LjE0OTM5LDE3MC45MDY1YzEuNzMxMTMsMy41NzM5NSA3LjA5NTEzLDE0LjY0ODAxIDkuODg1MzksMjAuNDA4NTVjMS4wNDI2OSwyLjE1MjY1IDIuMzMzMzgsMS4xMzM2NiAyLjc1MjMyLC0wLjU0MjA4YzAuNDY3NjksLTEuODcwNzUgMS41NTMyMywtNi4yMTI5MiAyLjE0OTI5LC04LjU5NzE0YzAuMjQ3MDcsLTAuOTg4MjggMS4yMjc3NCwtMS45Mzk5OCAyLjAwNjEzLC0yLjIyNTM5YzEuMTc1NDYsLTAuNDMxIDQuNjg3NzgsLTEuNzE4ODUgNy41ODU3MSwtMi43ODE0MmMyLjMzMSwtMC44NTQ3IDIuMzU5MTIsLTIuMTQzNTMgLTAuNDQ3MjksLTIuOTk3NjVjLTYuNTM1MzMsLTEuOTg5MDEgLTE3Ljk1NzAzLC01LjQ2NTE4IC0yMS41ODI1MiwtNi41Njg1OWMtMi4xNzUxNCwtMC42NjIgLTMuNDAzNTEsMS4xMjY3MyAtMi4zNDkwMywzLjMwMzczeiIgZmlsbD0iI2EzYTNhMyIgc3Ryb2tlLXdpZHRoPSIzLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvZz48L2c+PC9zdmc+"; class moreMouseControls { constructor() { this.mouseX = 0; From 35beeaf88ce969c58365dd7f14e91372150f32cb Mon Sep 17 00:00:00 2001 From: LegoBrainBiker Date: Fri, 2 May 2025 13:16:34 -0700 Subject: [PATCH 4/5] legobrainbiker/moremousecontrols: implement mouse pad controls --- .../legobrainbiker/MoreMouseControls.js | 66 +++++++++++++++++-- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/extensions/legobrainbiker/MoreMouseControls.js b/extensions/legobrainbiker/MoreMouseControls.js index 7cdb8f143c..881503337d 100644 --- a/extensions/legobrainbiker/MoreMouseControls.js +++ b/extensions/legobrainbiker/MoreMouseControls.js @@ -1,6 +1,6 @@ // Name: More Mouse Controls // ID: legobrainbikerMoreMouseControls -// Description: adds more options to detect properties of the cursor, including its position, clicking, and scrolling. +// Description: Adds more options to detect properties of the cursor, including its position, clicking, and scrolling. // By: legobrainbiker // License: MPL-2.0 (function (Scratch) { @@ -11,10 +11,20 @@ constructor() { this.mouseX = 0; this.mouseY = 0; - this.scroll = 0; + this.mouseWheelDelta = 0; + this.mouseWheelDeltaX = 0; + this.mouseZoomDelta = 0; this.buttons = []; - document.addEventListener("mousewheel", (e) => { - this.mouseWheelDelta = e.deltaY; + document.addEventListener("wheel", (e) => { + if (e.ctrlKey) { + this.mouseZoomDelta = e.deltaY; + this.mouseWheelDelta = 0; + this.mouseWheelDeltaX = 0; + } else { + this.mouseZoomDelta = 0; + this.mouseWheelDelta = e.deltaY; + this.mouseWheelDeltaX = e.deltaX; + } Scratch.vm.runtime.startHats( "legobrainbikerMoreMouseControls_onScroll" ); @@ -80,6 +90,11 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("disable context menu"), }, + { + opcode: "dissableScroll", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("disable scrolling and zooming"), + }, { opcode: "onScroll", blockType: Scratch.BlockType.EVENT, @@ -87,10 +102,20 @@ isEdgeActivated: false, }, { - opcode: "scrollamount", + opcode: "scrollAmount", blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("scroll amount"), }, + { + opcode: "horozontalScrollAmount", + blockType: Scratch.BlockType.REPORTER, + text: Scratch.translate("horozontal scroll amount"), + }, + { + opcode: "zoomAmount", + blockType: Scratch.BlockType.REPORTER, + text: Scratch.translate("zoom amount"), + }, { opcode: "mouseGlobalX", blockType: Scratch.BlockType.REPORTER, @@ -121,8 +146,35 @@ e.preventDefault(); }); } - scrollamount() { - return this.mouseWheelDelta || 0; + dissableScroll() { + Scratch.renderer.canvas.addEventListener( + "wheel", + (e) => { + e.preventDefault(); + if (e.ctrlKey) { + this.mouseZoomDelta = e.deltaY; + this.mouseWheelDelta = 0; + this.mouseWheelDeltaX = 0; + } else { + this.mouseZoomDelta = 0; + this.mouseWheelDelta = e.deltaY; + this.mouseWheelDeltaX = e.deltaX; + } + Scratch.vm.runtime.startHats( + "legobrainbikerMoreMouseControls_onScroll" + ); + }, + { passive: false } + ); + } + scrollAmount() { + return this.mouseWheelDelta; + } + horozontalScrollAmount() { + return this.mouseWheelDeltaX; + } + zoomAmount() { + return -this.mouseZoomDelta; } mouseGlobalX() { const canvas = Scratch.renderer.canvas.getBoundingClientRect(); From dbabd4af9a537d2b363a0f87a87cfe362fc988b2 Mon Sep 17 00:00:00 2001 From: LegoBrainBiker Date: Wed, 21 May 2025 12:59:53 -0700 Subject: [PATCH 5/5] legobrainbiker/moremousecontrols: consistency improvements --- .../legobrainbiker/MoreMouseControls.js | 84 +++++++++---------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/extensions/legobrainbiker/MoreMouseControls.js b/extensions/legobrainbiker/MoreMouseControls.js index 881503337d..fc37564b1a 100644 --- a/extensions/legobrainbiker/MoreMouseControls.js +++ b/extensions/legobrainbiker/MoreMouseControls.js @@ -15,20 +15,34 @@ this.mouseWheelDeltaX = 0; this.mouseZoomDelta = 0; this.buttons = []; - document.addEventListener("wheel", (e) => { - if (e.ctrlKey) { - this.mouseZoomDelta = e.deltaY; - this.mouseWheelDelta = 0; - this.mouseWheelDeltaX = 0; - } else { - this.mouseZoomDelta = 0; - this.mouseWheelDelta = e.deltaY; - this.mouseWheelDeltaX = e.deltaX; + this.contextMenuDissabled = false; + document.addEventListener("contextmenu", (e) => { + if (this.contextMenuDissabled) { + e.preventDefault(); } - Scratch.vm.runtime.startHats( - "legobrainbikerMoreMouseControls_onScroll" - ); }); + this.scrollDissabled = false; + document.addEventListener( + "wheel", + (e) => { + if (this.scrollDissabled) { + e.preventDefault(); + } + if (e.ctrlKey) { + this.mouseZoomDelta = e.deltaY; + this.mouseWheelDelta = 0; + this.mouseWheelDeltaX = 0; + } else { + this.mouseZoomDelta = 0; + this.mouseWheelDelta = e.deltaY; + this.mouseWheelDeltaX = e.deltaX; + } + Scratch.vm.runtime.startHats( + "legobrainbikerMoreMouseControls_onScroll" + ); + }, + { passive: false } + ); document.addEventListener("mouseup", (e) => { this.buttons[e.button] = false; }); @@ -39,6 +53,11 @@ this.mouseX = e.clientX; this.mouseY = e.clientY; }); + document.addEventListener("mouseleave", (e) => { + this.mouseX = NaN; + this.mouseY = NaN; + // this could be problomatic for some projects. it's not great to add another edge case + }); } getInfo() { return { @@ -86,14 +105,14 @@ }, }, { - opcode: "dissableContextMenu", + opcode: "toggleContextMenu", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("disable context menu"), + text: Scratch.translate("toggle context menu"), }, { - opcode: "dissableScroll", + opcode: "toggleScroll", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("disable scrolling and zooming"), + text: Scratch.translate("toggle scrolling and zooming"), }, { opcode: "onScroll", @@ -136,39 +155,16 @@ return this.buttonPressed(args); } buttonPressed({ button }) { - console.log(button); - console.log(Scratch.Cast.toNumber(button)); - console.log(this.buttons[Scratch.Cast.toNumber(button)]); return this.buttons[Scratch.Cast.toNumber(button)] || false; } - dissableContextMenu() { - document.addEventListener("contextmenu", (e) => { - e.preventDefault(); - }); + toggleContextMenu() { + this.contextMenuDissabled = !this.contextMenuDissabled; } - dissableScroll() { - Scratch.renderer.canvas.addEventListener( - "wheel", - (e) => { - e.preventDefault(); - if (e.ctrlKey) { - this.mouseZoomDelta = e.deltaY; - this.mouseWheelDelta = 0; - this.mouseWheelDeltaX = 0; - } else { - this.mouseZoomDelta = 0; - this.mouseWheelDelta = e.deltaY; - this.mouseWheelDeltaX = e.deltaX; - } - Scratch.vm.runtime.startHats( - "legobrainbikerMoreMouseControls_onScroll" - ); - }, - { passive: false } - ); + toggleScroll() { + this.scrollDissabled = !this.scrollDissabled; } scrollAmount() { - return this.mouseWheelDelta; + return -this.mouseWheelDelta; } horozontalScrollAmount() { return this.mouseWheelDeltaX;