Skip to content

Commit f68518d

Browse files
committed
paint-boolean-ops: improve UX — better descriptions, tooltips, swap subtract default to punch-through
1 parent 706398d commit f68518d

3 files changed

Lines changed: 44 additions & 11 deletions

File tree

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
{
22
"paint-boolean-ops/shaping": "Shaping",
33
"paint-boolean-ops/unite": "Unite",
4+
"paint-boolean-ops/unite-desc": "Unite — merge selected shapes into one, filling all overlapping areas",
45
"paint-boolean-ops/subtract": "Subtract",
5-
"paint-boolean-ops/subtract-alt": "Subtract (Shift: Punch Through)",
6+
"paint-boolean-ops/subtract-alt": "Subtract — cut the front shape out of every selected shape beneath it (Alt: keep the cutter; Shift: subtract all fronts from back shape only)",
67
"paint-boolean-ops/intersect": "Intersect",
7-
"paint-boolean-ops/intersect-alt": "Intersect (Alt: Divide)",
8+
"paint-boolean-ops/intersect-alt": "Intersect — keep only where shapes overlap (Alt: divide at all intersections)",
89
"paint-boolean-ops/divide": "Divide",
910
"paint-boolean-ops/combine": "Combine",
11+
"paint-boolean-ops/combine-desc": "Combine — merge shapes into a compound path; overlapping areas become transparent holes",
1012
"paint-boolean-ops/release": "Release",
13+
"paint-boolean-ops/release-desc": "Release — split this compound path back into separate individual shapes",
1114
"paint-boolean-ops/expand": "Expand",
15+
"paint-boolean-ops/expand-desc": "Expand — grow (positive) or shrink (negative) the shape outline by a set amount",
1216
"paint-boolean-ops/open-path": "Open Path",
1317
"paint-boolean-ops/close-path": "Close Path"
1418
}

addons/paint-boolean-ops/addon.json

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,33 @@
11
{
22
"name": "Boolean shape operations",
3-
"description": "Adds boolean path operations to the vector costume editor: unite, subtract, intersect, exclude, combine, release, expand, open/close path, and a shaping sub-menu.",
3+
"description": "Adds a Shaping panel to the vector costume editor: Unite · Subtract · Intersect · Combine/Release · Expand",
4+
"info": [
5+
{
6+
"type": "info",
7+
"text": "Unite — merge all selected shapes into one filled shape",
8+
"id": "infoUnite"
9+
},
10+
{
11+
"type": "info",
12+
"text": "Subtract — front shape cuts a hole in every selected shape below it (Shift: cuts back shape only; Alt: keeps the cutter)",
13+
"id": "infoSubtract"
14+
},
15+
{
16+
"type": "info",
17+
"text": "Intersect — keep only the overlapping areas of selected shapes (Alt: divide all into distinct regions)",
18+
"id": "infoIntersect"
19+
},
20+
{
21+
"type": "info",
22+
"text": "Combine / Release — Combine groups shapes into a compound path where overlaps become transparent holes; Release splits it back into separate shapes",
23+
"id": "infoCombine"
24+
},
25+
{
26+
"type": "info",
27+
"text": "Expand — grow a shape by its outline width",
28+
"id": "infoExpand"
29+
}
30+
],
431
"credits": [
532
{
633
"name": "griffpatch",

addons/paint-boolean-ops/userscript.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ export default async function ({ addon, msg }) {
7575
return btn;
7676
};
7777

78-
const uniteBtn = makeItem("unite.svg", msg("unite"), msg("unite"), "unite");
78+
const uniteBtn = makeItem("unite.svg", msg("unite"), msg("unite-desc"), "unite");
7979
const subtractBtn = makeItem("subtract.svg", msg("subtract"), msg("subtract-alt"), "subtract");
8080
const intersectBtn = makeItem("intersect.svg", msg("intersect"), msg("intersect-alt"), "intersect");
81-
const compoundBtn = makeItem("combine.svg", msg("combine"), msg("combine"), "combine");
82-
const expandBtn = makeItem("expand.svg", msg("expand"), msg("expand"), "expand");
81+
const compoundBtn = makeItem("combine.svg", msg("combine"), msg("combine-desc"), "combine");
82+
const expandBtn = makeItem("expand.svg", msg("expand"), msg("expand-desc"), "expand");
8383
const allItems = [uniteBtn, subtractBtn, intersectBtn, compoundBtn, expandBtn];
8484

8585
// Initially place items in the dropdown rows (collapsed is the default until measured).
@@ -163,8 +163,8 @@ export default async function ({ addon, msg }) {
163163
else if (op === "release") performRelease();
164164
else if (op === "expand") performOffset();
165165
else if (op === "intersect" && e.altKey) performDivide();
166-
else if (op === "subtract" && e.shiftKey && e.altKey) performPunchThrough(true);
167-
else if (op === "subtract" && e.shiftKey) performPunchThrough(false);
166+
else if (op === "subtract" && e.shiftKey) performBooleanOp("subtract", e.altKey);
167+
else if (op === "subtract") performPunchThrough(e.altKey);
168168
else performBooleanOp(op, e.altKey);
169169
};
170170
shapingSection.addEventListener("click", handleClick);
@@ -211,7 +211,7 @@ export default async function ({ addon, msg }) {
211211
// Compound button morphs: combine ↔ release based on selection.
212212
const compoundOp = hasMultiple ? "combine" : hasCompound ? "release" : "combine";
213213
compoundBtn.dataset.saOp = compoundOp;
214-
compoundBtn.title = msg(compoundOp);
214+
compoundBtn.title = msg(`${compoundOp}-desc`);
215215
compoundBtn.querySelector(".sa-shaping-item-icon").src = `${addon.self.dir}/icons/${compoundOp}.svg`;
216216
compoundBtn.querySelector(".sa-shaping-item-label").textContent = msg(compoundOp);
217217
// Open/Close button morphs: "Open Path" when selection is closed, "Close Path" when open.
@@ -989,7 +989,7 @@ export default async function ({ addon, msg }) {
989989
// Extract layout and separator classes from native toolbar elements.
990990
const nativeDashedGroup = fixedToolsRow.querySelector("[class*='mod-dashed-border']");
991991
dashedBorderClass = nativeDashedGroup
992-
? [...nativeDashedGroup.classList].find((c) => c.includes("mod-dashed-border")) ?? ""
992+
? ([...nativeDashedGroup.classList].find((c) => c.includes("mod-dashed-border")) ?? "")
993993
: "";
994994

995995
// Add a dashed separator to the LEFT of our section (right border on preceding group).
@@ -1012,7 +1012,9 @@ export default async function ({ addon, msg }) {
10121012
const anyTitle = fixedToolsRow.querySelector("[class*='labeled-icon-button_edit-field-title']");
10131013

10141014
const anyDisabled = document.querySelector("[class*='button_mod-disabled']");
1015-
modDisabledClass = anyDisabled ? [...anyDisabled.classList].find((c) => c.includes("mod-disabled")) ?? "" : "";
1015+
modDisabledClass = anyDisabled
1016+
? ([...anyDisabled.classList].find((c) => c.includes("mod-disabled")) ?? "")
1017+
: "";
10161018

10171019
if (anyBtn) shapingBtn.className += " " + anyBtn.className;
10181020
if (anyIcon) shapingIcon.className += " " + anyIcon.className;

0 commit comments

Comments
 (0)