From fcd2960a5b166b681b69d5b217c28e4b71dd1890 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Tue, 8 Apr 2025 23:59:09 -0700 Subject: [PATCH 1/4] Update LooksPlus.js --- extensions/Lily/LooksPlus.js | 62 ++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/extensions/Lily/LooksPlus.js b/extensions/Lily/LooksPlus.js index 2a7bc3bfe5..7e98482af6 100644 --- a/extensions/Lily/LooksPlus.js +++ b/extensions/Lily/LooksPlus.js @@ -20,6 +20,23 @@ return true; }; + /** + * @param {RenderWebGL.SVGSkin} svgSkin + * @returns {Promise} + */ + const svgSkinFinishedLoading = (svgSkin) => new Promise((resolve) => { + if (svgSkin._svgImageLoaded) { + resolve(); + } else { + svgSkin._svgImage.addEventListener("load", () => { + resolve(); + }); + svgSkin._svgImage.addEventListener("error", () => { + resolve(); + }); + } + }); + /** * @param {VM.BlockUtility} util * @param {unknown} targetName @@ -176,6 +193,7 @@ opcode: "replaceCostumeContent", blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set [TYPE] for [COSTUME] to [CONTENT]"), + hideFromPalette: true, // needed for compatibility, also superceeded by skins arguments: { TYPE: { type: Scratch.ArgumentType.STRING, @@ -192,6 +210,21 @@ }, extensions: ["colours_looks"], }, + { + opcode: "replaceCostumeContentNew", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("set svg for [COSTUME] to [CONTENT]"), + arguments: { + COSTUME: { + type: Scratch.ArgumentType.COSTUME, + }, + CONTENT: { + type: Scratch.ArgumentType.STRING, + defaultValue: "", + }, + }, + extensions: ["colours_looks"], + }, { opcode: "restoreCostumeContent", blockType: Scratch.BlockType.COMMAND, @@ -482,6 +515,35 @@ console.error("Options other than SVG are currently unavailable"); } } + + async replaceCostumeContentNew(args, util) { + const costumeIndex = this.getCostumeInput(args.COSTUME, util.target); + const costume = util.target.sprite.costumes[costumeIndex]; + if (!costume) { + console.error("Costume doesn't exist"); + return; + } + + //This is here to ensure no changes are made to bitmap costumes, as changes are irreversible + //Check will be removed when it's possible to edit bitmap skins + const format = costume.asset.assetType.runtimeFormat; + if (format !== "svg") { + console.error("Costume is not vector"); + return; + } + + const content = args.CONTENT; + try { + renderer.updateSVGSkin( + costume.skinId, + Scratch.Cast.toString(content) + ); + await svgSkinFinishedLoading(renderer._allSkins[costume.skinId]); + renderer._allSkins[costume.skinId].differsFromAsset = true; + } catch (e) { + console.error(e); + } + } restoreCostumeContent(args, util) { const costumeIndex = this.getCostumeInput(args.COSTUME, util.target); From 96f88d7c50261bb3e9d2dd33353138ec314ef687 Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Wed, 9 Apr 2025 07:03:04 +0000 Subject: [PATCH 2/4] [Automated] Format code --- extensions/Lily/LooksPlus.js | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/extensions/Lily/LooksPlus.js b/extensions/Lily/LooksPlus.js index 7e98482af6..f17a37faa7 100644 --- a/extensions/Lily/LooksPlus.js +++ b/extensions/Lily/LooksPlus.js @@ -24,18 +24,19 @@ * @param {RenderWebGL.SVGSkin} svgSkin * @returns {Promise} */ - const svgSkinFinishedLoading = (svgSkin) => new Promise((resolve) => { - if (svgSkin._svgImageLoaded) { - resolve(); - } else { - svgSkin._svgImage.addEventListener("load", () => { + const svgSkinFinishedLoading = (svgSkin) => + new Promise((resolve) => { + if (svgSkin._svgImageLoaded) { resolve(); - }); - svgSkin._svgImage.addEventListener("error", () => { - resolve(); - }); - } - }); + } else { + svgSkin._svgImage.addEventListener("load", () => { + resolve(); + }); + svgSkin._svgImage.addEventListener("error", () => { + resolve(); + }); + } + }); /** * @param {VM.BlockUtility} util @@ -515,7 +516,7 @@ console.error("Options other than SVG are currently unavailable"); } } - + async replaceCostumeContentNew(args, util) { const costumeIndex = this.getCostumeInput(args.COSTUME, util.target); const costume = util.target.sprite.costumes[costumeIndex]; @@ -534,10 +535,7 @@ const content = args.CONTENT; try { - renderer.updateSVGSkin( - costume.skinId, - Scratch.Cast.toString(content) - ); + renderer.updateSVGSkin(costume.skinId, Scratch.Cast.toString(content)); await svgSkinFinishedLoading(renderer._allSkins[costume.skinId]); renderer._allSkins[costume.skinId].differsFromAsset = true; } catch (e) { From e0c8fe30694a22e8dbef621e3e9e6eb7bfde256f Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 16 Apr 2025 20:13:27 -0700 Subject: [PATCH 3/4] Update LooksPlus.js --- extensions/Lily/LooksPlus.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/extensions/Lily/LooksPlus.js b/extensions/Lily/LooksPlus.js index f17a37faa7..e803e0c721 100644 --- a/extensions/Lily/LooksPlus.js +++ b/extensions/Lily/LooksPlus.js @@ -28,14 +28,20 @@ new Promise((resolve) => { if (svgSkin._svgImageLoaded) { resolve(); - } else { - svgSkin._svgImage.addEventListener("load", () => { - resolve(); - }); - svgSkin._svgImage.addEventListener("error", () => { - resolve(); - }); + return; } + + const handleEvent = () => { + cleanup(); + resolve(); + }; + const cleanup = () => { + svgSkin._svgImage.removeEventListener("load", handleEvent); + svgSkin._svgImage.removeEventListener("error", handleEvent); + }; + + svgSkin._svgImage.addEventListener("load", handleEvent); + svgSkin._svgImage.addEventListener("error", handleEvent); }); /** From ccaccbb6f31a2c37bb658cd331ff4f2fbc4fb8ce Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Tue, 20 May 2025 23:27:13 -0500 Subject: [PATCH 4/4] set differsFromAsset before waiting --- extensions/Lily/LooksPlus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/Lily/LooksPlus.js b/extensions/Lily/LooksPlus.js index e803e0c721..c987b334d6 100644 --- a/extensions/Lily/LooksPlus.js +++ b/extensions/Lily/LooksPlus.js @@ -542,8 +542,8 @@ const content = args.CONTENT; try { renderer.updateSVGSkin(costume.skinId, Scratch.Cast.toString(content)); - await svgSkinFinishedLoading(renderer._allSkins[costume.skinId]); renderer._allSkins[costume.skinId].differsFromAsset = true; + await svgSkinFinishedLoading(renderer._allSkins[costume.skinId]); } catch (e) { console.error(e); }