From dadaee3188ccaf7604995caa4c375c6a29a60f05 Mon Sep 17 00:00:00 2001 From: CreatorADOfficial Date: Sun, 13 Sep 2026 20:10:53 +0000 Subject: [PATCH] Automated Extension submission for issue #2261 --- extensions/community/ObjectCliping.json | 525 ++++++++++++++++++++++++ 1 file changed, 525 insertions(+) create mode 100644 extensions/community/ObjectCliping.json diff --git a/extensions/community/ObjectCliping.json b/extensions/community/ObjectCliping.json new file mode 100644 index 000000000..e35383e30 --- /dev/null +++ b/extensions/community/ObjectCliping.json @@ -0,0 +1,525 @@ +{ + "author": "", + "category": "Visual effect", + "dimension": "2D", + "extensionNamespace": "", + "fullName": "Object Clipping", + "gdevelopVersion": "", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLXNjaXNzb3JzLWN1dHRpbmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTEsMjFIN1YxOUgxMVYyMU0xNS41LDE5SDE3VjIxSDEzVjE5SDEzLjJMMTEuOCwxMi45TDkuMywxMy41QzkuMiwxNCA5LDE0LjQgOC44LDE0LjhDNy45LDE2LjMgNiwxNi43IDQuNSwxNS44QzMsMTQuOSAyLjYsMTMgMy41LDExLjVDNC40LDEwIDYuMyw5LjYgNy44LDEwLjVDOC4yLDEwLjcgOC41LDExLjEgOC43LDExLjRMMTEuMiwxMC44TDEwLjYsOC4zQzEwLjIsOC4yIDkuOCw4IDkuNCw3LjhDOCw2LjkgNy41LDUgOC40LDMuNUM5LjMsMiAxMS4yLDEuNiAxMi43LDIuNUMxNC4yLDMuNCAxNC42LDUuMyAxMy43LDYuOEMxMy41LDcuMiAxMy4xLDcuNSAxMi44LDcuN0wxNS41LDE5TTcsMTEuOEM2LjMsMTEuMyA1LjMsMTEuNiA0LjgsMTIuM0M0LjMsMTMgNC42LDE0IDUuMywxNC40QzYsMTQuOSA3LDE0LjcgNy41LDEzLjlDNy45LDEzLjIgNy43LDEyLjIgNywxMS44TTEyLjQsNkMxMi45LDUuMyAxMi42LDQuMyAxMS45LDMuOEMxMS4yLDMuMyAxMC4yLDMuNiA5LjcsNC4zQzkuMyw1IDkuNSw2IDEwLjMsNi41QzExLDYuOSAxMiw2LjcgMTIuNCw2TTEyLjgsMTEuM0MxMi42LDExLjIgMTIuNCwxMS4yIDEyLjMsMTEuNEMxMi4yLDExLjYgMTIuMiwxMS44IDEyLjQsMTEuOUMxMi42LDEyIDEyLjgsMTIgMTIuOSwxMS44QzEzLjEsMTEuNiAxMywxMS40IDEyLjgsMTEuM00yMSw4LjVMMTQuNSwxMEwxNSwxMi4yTDIyLjUsMTAuNEwyMyw5LjdMMjEsOC41TTIzLDE5SDE5VjIxSDIzVjE5TTUsMTlIMVYyMUg1VjE5WiIgLz48L3N2Zz4=", + "name": "ObjectCliping", + "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/208d7609afe6655c8d1450202a4aa4d50129f813dab825baa583228f104a47ab_scissors-cutting.svg", + "shortDescription": "Render objects as circle cut out for circular profile pictures.", + "version": "1.0.0", + "description": [ + "Now you can clip profile pictures or images so you don't render a square, features added:", + "- Circle Clipping (Radius)", + "- Square Clipping (Size)", + "- Free Clipping (Points)", + "", + "That's all, thanks for supporting the extension." + ], + "tags": [ + "Clip", + "Object", + "Rendering" + ], + "authorIds": [ + "LmDPcZ5ey4WWF4VdoEQcmPVTmFu2" + ], + "dependencies": [], + "globalVariables": [], + "sceneVariables": [], + "eventsFunctions": [ + { + "description": "Cut out rendering outside the radius.", + "fullName": "Circle Clipping", + "functionType": "Action", + "name": "CircleClipping", + "sentence": "Circle Clipping _PARAM1_; _PARAM2_,_PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const objects = eventsFunctionContext.getObjects(\"Object\");", + "const radius = Number(eventsFunctionContext.getArgument(\"Radius\"));", + "const inverse = eventsFunctionContext.getArgument(\"Inverse\");", + "", + "if (!objects || objects.length === 0) {", + " return;", + " }", + "", + " const object = objects[0];", + " const rendererObject = object.getRendererObject();", + "", + " if (!rendererObject || !rendererObject.parent) {", + " return;", + " }", + "", + " const PIXI = globalThis.PIXI;", + "", + " if (!PIXI || !PIXI.Graphics) {", + " return;", + " }", + "", + " if (rendererObject.__circleClipMask) {", + " const oldMask = rendererObject.__circleClipMask;", + "", + " if (oldMask.parent) {", + " oldMask.parent.removeChild(oldMask);", + " }", + "", + " oldMask.destroy();", + " rendererObject.__circleClipMask = null;", + " }", + "", + " if (!inverse) {", + " const mask = new PIXI.Graphics();", + "", + " mask.beginFill(0xffffff);", + " mask.drawCircle(0, 0, radius);", + " mask.endFill();", + "", + " rendererObject.parent.addChild(mask);", + "", + " rendererObject.mask = mask;", + " rendererObject.__circleClipMask = mask;", + "", + " mask.position.set(", + " rendererObject.x,", + " rendererObject.y", + " );", + "", + " mask.rotation = rendererObject.rotation;", + " mask.scale.set(", + " rendererObject.scale.x,", + " rendererObject.scale.y", + " );", + " } else {", + " const bounds = rendererObject.getLocalBounds();", + "", + " const mask = new PIXI.Graphics();", + "", + " mask.beginFill(0xffffff);", + " mask.drawRect(", + " bounds.x - 10,", + " bounds.y - 10,", + " bounds.width + 20,", + " bounds.height + 20", + " );", + " mask.beginHole();", + " mask.drawCircle(", + " (bounds.x + bounds.width / 2),", + " (bounds.y + bounds.height / 2),", + " radius", + " );", + " mask.endHole();", + " mask.endFill();", + "", + " rendererObject.addChild(mask);", + "", + " rendererObject.mask = mask;", + " rendererObject.__circleClipMask = mask;", + "", + " mask.position.set(0, 0);", + " }" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Radius", + "name": "Radius", + "type": "expression" + }, + { + "description": "Inverse?", + "longDescription": "When Inverse, it flips from cutting edges to cutting the inside.", + "name": "Inverse", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Cut out rendering outside the width and height.", + "fullName": "Sqaure Clipping", + "functionType": "Action", + "name": "SquareClipping", + "sentence": "Sqaure Clipping _PARAM1_; _PARAM2_,_PARAM3_,_PARAM4_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const objects = eventsFunctionContext.getObjects(\"Object\");", + "const width = Number(eventsFunctionContext.getArgument(\"Width\"));", + "const height = Number(eventsFunctionContext.getArgument(\"Height\"));", + "const inverse = eventsFunctionContext.getArgument(\"Inverse\");", + "", + "if (!objects || objects.length === 0) {", + " return;", + " }", + "", + " const object = objects[0];", + " const rendererObject = object.getRendererObject();", + "", + " if (!rendererObject || !rendererObject.parent) {", + " return;", + " }", + "", + " const PIXI = globalThis.PIXI;", + "", + " if (!PIXI || !PIXI.Graphics) {", + " return;", + " }", + "", + " if (rendererObject.__squareClipMask) {", + " const oldMask = rendererObject.__squareClipMask;", + "", + " if (oldMask.parent) {", + " oldMask.parent.removeChild(oldMask);", + " }", + "", + " oldMask.destroy();", + " rendererObject.__squareClipMask = null;", + " }", + "", + " const mask = new PIXI.Graphics();", + "", + " if (!inverse) {", + " mask.beginFill(0xffffff);", + " mask.drawRect(", + " -width / 2,", + " -height / 2,", + " width,", + " height", + " );", + " mask.endFill();", + "", + " rendererObject.parent.addChild(mask);", + "", + " rendererObject.mask = mask;", + " rendererObject.__squareClipMask = mask;", + "", + " mask.position.set(", + " rendererObject.x,", + " rendererObject.y", + " );", + "", + " mask.rotation = rendererObject.rotation;", + " mask.scale.set(", + " rendererObject.scale.x,", + " rendererObject.scale.y", + " );", + " } else {", + " const bounds = rendererObject.getLocalBounds();", + "", + " mask.beginFill(0xffffff);", + " mask.drawRect(", + " bounds.x - 10,", + " bounds.y - 10,", + " bounds.width + 20,", + " bounds.height + 20", + " );", + "", + " mask.beginHole();", + " mask.drawRect(", + " -width / 2,", + " -height / 2,", + " width,", + " height", + " );", + " mask.endHole();", + "", + " mask.endFill();", + "", + " rendererObject.addChild(mask);", + "", + " rendererObject.mask = mask;", + " rendererObject.__squareClipMask = mask;", + "", + " mask.position.set(0, 0);", + " }" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Width", + "name": "Width", + "type": "expression" + }, + { + "description": "Height", + "name": "Height", + "type": "expression" + }, + { + "description": "Inverse?", + "longDescription": "When Inverse, it flips from cutting edges to cutting the inside.", + "name": "Inverse", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Cut out rendering outside the points, relative to center so use -x and -y.", + "fullName": "Free Clipping", + "functionType": "Action", + "name": "FreeClipping", + "sentence": "Free Clipping _PARAM1_; _PARAM10_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const objects = eventsFunctionContext.getObjects(\"Object\");", + "", + "const p1x = Number(eventsFunctionContext.getArgument(\"P1X\"));", + "const p1y = Number(eventsFunctionContext.getArgument(\"P1Y\"));", + "const p2x = Number(eventsFunctionContext.getArgument(\"P2X\"));", + "const p2y = Number(eventsFunctionContext.getArgument(\"P2Y\"));", + "const p3x = Number(eventsFunctionContext.getArgument(\"P3X\"));", + "const p3y = Number(eventsFunctionContext.getArgument(\"P3Y\"));", + "const p4x = Number(eventsFunctionContext.getArgument(\"P4X\"));", + "const p4y = Number(eventsFunctionContext.getArgument(\"P4Y\"));", + "const inverse = eventsFunctionContext.getArgument(\"Inverse\");", + "", + "if (!objects || objects.length === 0) {", + " return;", + " }", + "", + " const object = objects[0];", + " const rendererObject = object.getRendererObject();", + "", + " if (!rendererObject || !rendererObject.parent) {", + " return;", + " }", + "", + " const PIXI = globalThis.PIXI;", + "", + " if (!PIXI || !PIXI.Graphics) {", + " return;", + " }", + "", + " if (rendererObject.__freeClipMask) {", + " const oldMask = rendererObject.__freeClipMask;", + "", + " if (oldMask.parent) {", + " oldMask.parent.removeChild(oldMask);", + " }", + "", + " oldMask.destroy();", + " rendererObject.__freeClipMask = null;", + " }", + "", + " const mask = new PIXI.Graphics();", + "", + " if (!inverse) {", + " mask.beginFill(0xffffff);", + "", + " mask.moveTo(p1x, p1y);", + " mask.lineTo(p2x, p2y);", + " mask.lineTo(p3x, p3y);", + " mask.lineTo(p4x, p4y);", + " mask.closePath();", + "", + " mask.endFill();", + "", + " rendererObject.addChild(mask);", + "", + " rendererObject.mask = mask;", + " rendererObject.__freeClipMask = mask;", + "", + " mask.position.set(0, 0);", + " } else {", + " const bounds = rendererObject.getLocalBounds();", + "", + " mask.beginFill(0xffffff);", + "", + " mask.drawRect(", + " bounds.x - 10,", + " bounds.y - 10,", + " bounds.width + 20,", + " bounds.height + 20", + " );", + "", + " mask.beginHole();", + "", + " mask.moveTo(p1x, p1y);", + " mask.lineTo(p2x, p2y);", + " mask.lineTo(p3x, p3y);", + " mask.lineTo(p4x, p4y);", + " mask.closePath();", + "", + " mask.endHole();", + " mask.endFill();", + "", + " rendererObject.addChild(mask);", + "", + " rendererObject.mask = mask;", + " rendererObject.__freeClipMask = mask;", + "", + " mask.position.set(0, 0);", + " }" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Top-Left X", + "name": "P1X", + "type": "expression" + }, + { + "description": "Top-Left Y", + "name": "P1Y", + "type": "expression" + }, + { + "description": "Top-Right X", + "name": "P2X", + "type": "expression" + }, + { + "description": "Top-Right Y", + "name": "P2Y", + "type": "expression" + }, + { + "description": "Down-Right X", + "name": "P3X", + "type": "expression" + }, + { + "description": "Down-Right Y", + "name": "P3Y", + "type": "expression" + }, + { + "description": "Down-Left X", + "name": "P4X", + "type": "expression" + }, + { + "description": "Down-Left Y", + "name": "P4Y", + "type": "expression" + }, + { + "description": "Inverse?", + "longDescription": "When Inverse, it flips from cutting edges to cutting the inside.", + "name": "Inverse", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Clean The Clip Before Changing From Circle To Square Since It Can Break.", + "fullName": "Clear Rendering", + "functionType": "Action", + "name": "CleanRender", + "sentence": "Clear Rendering _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const objects = eventsFunctionContext.getObjects(\"Object\");", + "", + "if (!objects || objects.length === 0) {", + " return;", + " }", + "", + " for (const object of objects) {", + " const rendererObject = object.getRendererObject();", + "", + " if (!rendererObject) {", + " continue;", + " }", + "", + " const maskNames = [", + " \"__circleClipMask\",", + " \"__squareClipMask\",", + " \"__freeClipMask\"", + " ];", + "", + " for (const name of maskNames) {", + " const mask = rendererObject[name];", + "", + " if (mask) {", + " if (mask.parent) {", + " mask.parent.removeChild(mask);", + " }", + "", + " mask.destroy();", + " rendererObject[name] = null;", + " }", + " }", + "", + " rendererObject.mask = null;", + " }" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "objectList" + } + ], + "objectGroups": [] + } + ], + "eventsFunctionsFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "functionName": "CircleClipping" + }, + { + "functionName": "SquareClipping" + }, + { + "functionName": "FreeClipping" + }, + { + "functionName": "CleanRender" + } + ] + }, + "eventsBasedBehaviors": [], + "eventsBasedObjects": [] +}