Skip to content

Commit a8d2365

Browse files
committed
Anchor: add !anchor chain command for mutual ring-linking
1 parent 68fda3a commit a8d2365

2 files changed

Lines changed: 40 additions & 2 deletions

File tree

Anchor/2.1.0/anchor.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ var Anchor = Anchor || (() => {
186186
...Object.keys(ALIAS_MAP),
187187
'remove', 'lock', 'unlock', 'center', 'update', 'info',
188188
'track', 'untrack', 'retrack',
189+
'chain',
189190
'ignore-selected', 'persist',
190191
'config',
191192
'--help',
@@ -1132,6 +1133,9 @@ var Anchor = Anchor || (() => {
11321133
`<b>${CMD_TOKEN} center [ignore-selected] [child_id...]</b>`,
11331134
'Snap child(ren) to anchor centre (0 offset, 0 rotation, 1:1 scale).',
11341135
'',
1136+
`<b>${CMD_TOKEN} chain [component flags] [ignore-selected] [child_id...]</b>`,
1137+
'Mutually anchor tokens in a ring (A\u2192B, B\u2192C, C\u2192A). Move any one, all follow.',
1138+
'',
11351139
`<b>${CMD_TOKEN} update [ignore-selected] [child_id...]</b>`,
11361140
'Force immediate transform sync.',
11371141
'',
@@ -1507,7 +1511,7 @@ var Anchor = Anchor || (() => {
15071511
// Only skip the first otherArg as a potential anchor ID when we're
15081512
// establishing a new anchor relationship AND it's actually a valid graphic.
15091513
// If there's no valid graphic as the first arg, all otherArgs are child IDs.
1510-
const ACTION_FLAGS = ['remove', 'lock', 'unlock', 'center', 'update', 'info', 'track', 'untrack', 'retrack'];
1514+
const ACTION_FLAGS = ['remove', 'lock', 'unlock', 'center', 'update', 'info', 'track', 'untrack', 'retrack', 'chain'];
15111515
const hasAction = ACTION_FLAGS.some(f => flags.has(f));
15121516
const isNewAnchor = !hasAction && (Object.keys(FLAG_EXPANSIONS).some(f => flags.has(f)) || flags.size === 0);
15131517
const firstArgIsAnchor = isNewAnchor &&
@@ -1640,6 +1644,21 @@ var Anchor = Anchor || (() => {
16401644
});
16411645
}
16421646

1647+
// Chain — circular anchor ring: A→B, B→C, C→A
1648+
if (flags.has('chain')) {
1649+
const comps = resolveComponents(flags);
1650+
const ids = resolveChildIds(msg, flags, otherArgs);
1651+
if (ids.length < 2) {
1652+
reply(msg, 'Error', 'Chain requires at least 2 tokens.');
1653+
} else {
1654+
for (var i = 0; i < ids.length; i++) {
1655+
var nextIdx = (i + 1) % ids.length;
1656+
anchorObj(ids[i], ids[nextIdx], comps);
1657+
}
1658+
reply(msg, 'Info', 'Chain-linked ' + ids.length + ' tokens in a ring.');
1659+
}
1660+
}
1661+
16431662
// Info
16441663
if (flags.has('info')) {
16451664
if (childIds.length > 0) {

Anchor/anchor.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ var Anchor = Anchor || (() => {
186186
...Object.keys(ALIAS_MAP),
187187
'remove', 'lock', 'unlock', 'center', 'update', 'info',
188188
'track', 'untrack', 'retrack',
189+
'chain',
189190
'ignore-selected', 'persist',
190191
'config',
191192
'--help',
@@ -1132,6 +1133,9 @@ var Anchor = Anchor || (() => {
11321133
`<b>${CMD_TOKEN} center [ignore-selected] [child_id...]</b>`,
11331134
'Snap child(ren) to anchor centre (0 offset, 0 rotation, 1:1 scale).',
11341135
'',
1136+
`<b>${CMD_TOKEN} chain [component flags] [ignore-selected] [child_id...]</b>`,
1137+
'Mutually anchor tokens in a ring (A\u2192B, B\u2192C, C\u2192A). Move any one, all follow.',
1138+
'',
11351139
`<b>${CMD_TOKEN} update [ignore-selected] [child_id...]</b>`,
11361140
'Force immediate transform sync.',
11371141
'',
@@ -1507,7 +1511,7 @@ var Anchor = Anchor || (() => {
15071511
// Only skip the first otherArg as a potential anchor ID when we're
15081512
// establishing a new anchor relationship AND it's actually a valid graphic.
15091513
// If there's no valid graphic as the first arg, all otherArgs are child IDs.
1510-
const ACTION_FLAGS = ['remove', 'lock', 'unlock', 'center', 'update', 'info', 'track', 'untrack', 'retrack'];
1514+
const ACTION_FLAGS = ['remove', 'lock', 'unlock', 'center', 'update', 'info', 'track', 'untrack', 'retrack', 'chain'];
15111515
const hasAction = ACTION_FLAGS.some(f => flags.has(f));
15121516
const isNewAnchor = !hasAction && (Object.keys(FLAG_EXPANSIONS).some(f => flags.has(f)) || flags.size === 0);
15131517
const firstArgIsAnchor = isNewAnchor &&
@@ -1640,6 +1644,21 @@ var Anchor = Anchor || (() => {
16401644
});
16411645
}
16421646

1647+
// Chain — circular anchor ring: A→B, B→C, C→A
1648+
if (flags.has('chain')) {
1649+
const comps = resolveComponents(flags);
1650+
const ids = resolveChildIds(msg, flags, otherArgs);
1651+
if (ids.length < 2) {
1652+
reply(msg, 'Error', 'Chain requires at least 2 tokens.');
1653+
} else {
1654+
for (var i = 0; i < ids.length; i++) {
1655+
var nextIdx = (i + 1) % ids.length;
1656+
anchorObj(ids[i], ids[nextIdx], comps);
1657+
}
1658+
reply(msg, 'Info', 'Chain-linked ' + ids.length + ' tokens in a ring.');
1659+
}
1660+
}
1661+
16431662
// Info
16441663
if (flags.has('info')) {
16451664
if (childIds.length > 0) {

0 commit comments

Comments
 (0)