Last active
August 3, 2019 21:13
-
-
Save cpryland/b2524d96000f278ce4cfd5516fc9412b to your computer and use it in GitHub Desktop.
One theory about how to compute the edit context given a selection in XD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Artboard, Group } from 'scenegraph' | |
// Strictly speaking, promoteArtboards means follow the spec. | |
// For some usage, we don't want that behavior. | |
function computeEditContextRoot(selection, promoteArtboards = true) { | |
// Number of nodes above the given node in the artwork tree. | |
function computeDepthToRoot(node) { | |
let depth = 0 | |
while (node.parent != null) { | |
node = node.parent | |
++depth | |
} | |
return depth | |
} | |
// If no selection, no edit context. | |
if (selection.items.length == 0) return null | |
// contextNode is the eventual edit context root. | |
let contextNode, contextDepth | |
selection.items.forEach((node, idx) => { | |
if (idx == 0) { | |
const origNode = node | |
// Prime the pump on the first iteration. | |
contextNode = node.parent | |
contextDepth = computeDepthToRoot(contextNode) | |
} else { | |
const origNode = node | |
node = node.parent | |
// Pull the deeper one up to the shallower's level, | |
// and then search up the tree on both sides | |
// for a common ancestor. We'll eventually hit | |
// the root together, as a termination guarantee. | |
let nodeDepth = computeDepthToRoot(node) | |
while (nodeDepth > contextDepth) { | |
node = node.parent | |
--nodeDepth | |
} | |
while (nodeDepth < contextDepth) { | |
contextNode = contextNode.parent | |
--contextDepth | |
} | |
while (contextNode != node) { | |
contextNode = contextNode.parent | |
node = node.parent | |
--contextDepth | |
--nodeDepth | |
} | |
} | |
}) | |
// Special case: if the edit context root would be an Artboard, | |
// the result is promoted up to the document root. | |
if (promoteArtboards && contextNode instanceof Artboard) | |
contextNode = contextNode.parent | |
return contextNode | |
} | |
export default computeEditContextRoot |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment