Skip to main content

Anchor position finders

· 4 min read
Simon Porritt

Version 5.4.0 of the Community edition, which was released today, has support for a new concept - the ability to specify at drag start/stop what the location of an anchor should be. In actual fact this concept is not entirely new: there was, in 2.x, the concept of an Assign anchor, which worked in a similar way, but this did not get ported to 5.x, and anchor position finders are much more straightforward to work with.


The best way to illustrate this is with an example. You can drag a connection from either box below. Where you drop the connection, though, has a bearing on the target anchor's position: if you drop it on the left hand side of the target element, the anchor will be positioned on the left. If you drop it on the right hand side, the anchor will be positioned on the right.

Anchor Position Finders
The code to make this happen looks like this:
import { newInstance } from "@jsplumb/browser-ui"  const instance = newInstance({    anchor: "Continuous",    endpoint: "Dot"})
instance.addTargetSelector({   "[data-jtk-managed]":{       anchorPositionFinder:function(el, elxy) {           var x = elxy.x < 0.5 ? 0 : 1,               ox = x === 0 ? -1 : 1;                          return [x, 0.5, ox, 0]       }   }})

We create a new instance and give it defaults for anchor and endpoint, then add a source and target selector to it. Note that as a result of the selector we use for the source - [data-jtk-managed] - the elements end up not draggable in the demonstration, because that selector identifies the entire element, and when you register a source selector on an instance of jsPlumb, that selector is automatically added to the instance's drag filter.

The anchorPositionFinder in the target selector is where we make our decision about the location of the target anchor:

anchorPositionFinder:function(el, elxy) {   var x = elxy.x < 0.5 ? 0 : 1,       ox = x === 0 ? -1 : 1;          return [x, 0.5, ox, 0]}

el is the DOM element on which the connection is being dropped, and elxy is a PointXY object whose values are the proportional location of the drop event on the target element. For instance, this value:

{ x:0;5, y:0.5 }

would mean that the drop event occurred in the center of the element. In our position finder, set x=0 if elxy.x is less than 0.5, and 1 otherwise (I could have used Math.round(..) but I wanted to make it more explicit).

Another Example#

This also works when adding a source selector. Consider this code:

import { newInstance } from "@jsplumb/browser-ui"  const instance = newInstance({    endpoint: "Dot"})
instance.addSourceSelector("[data-jtk-managed]",{    anchorPositionFinder:function(el, elxy) {       var x = Math.round(elxy.x),            y = Math.round(elxy.y)                  return [x, y, 0, 0]   }})
instance.addTargetSelector({   "[data-jtk-managed]":{       anchorPositionFinder:function(el, elxy) {           return [0.5, 0.5, 0, 0]       }   }})

When we run this, we get a setup where the source anchor ends up at the corner of the quadrant from which you dragged:

Anchor Position Finders

The target anchor always ends up in the middle, because the anchor position finder on the target selector only ever returns an anchor located at the center.