🎉 JointJS has new documentation! 🥳
Path editor allows users to edit <path>
elements via an editing overlay. Users can interact with the path's segments, anchor points and curve control points.
Include joint.ui.pathEditor.css
and joint.ui.pathEditor.js
files to your HTML.
<link rel="stylesheet" type="text/css" href="joint.ui.pathEditor.css">
<script src="joint.ui.pathEditor.js"></script>
First, we create a PathEditor object. The constructor needs a reference to a <path>
SVGPathElement on the page.
new joint.dia.PathEditor({
pathElement: document.querySelector('path')
});
The joint.ui.PathEditor
constructor accepts the following options:
pathElement | SVGPathElement | Required. The path element to be edited. The PathEditor will be rendered on top of it. |
---|---|---|
anchorPointMarkup | string | Optional. The SVG markup of anchor point overlay elements. Default is '<circle r="2.5"/>' . (CSS styling should use the .joint-path-editor .anchor-point CSS selector.)
|
controlPointMarkup | string | Optional. The SVG markup of control point overlay elements. Default is '<circle r="2.5"/>' . (CSS styling should use the .joint-path-editor .control-point CSS selector.)
|
The joint.ui.PathEditor
object provides the following methods:
render() | Render the path editor overlay. Called automatically after object is instantiated. |
---|---|
remove() | Remove the path editor. |
adjustAnchorPoint(index, dx, dy, evt [, opt]) | Adjust the position of an anchor point. Identified by index , the index of the anchor point within path segment list (starting from 0 for the endpoint of the first moveto segment). The anchor point is translated by (dx ,dy ). The evt is the original user interaction event.The opt parameter is optional; it is used by internal methods. It can have one property: dry (indicating that corresponding 'path:editing' and 'path:edit' events will be suppressed).
|
adjustControlPoint(index, controlPointIndex, dx, dy, evt [, opt]) | Adjust the position of a control point. Identified by index , the index of the path segment it is attached to within path segment list (starting from 1 for the first non-moveto segment), and controlPointIndex , the index of the control point within the segment (1 for the firstcontrol point - the one visually attached to the previous anchor point, or 2 for the secondcontrol point - the one visually attached to this segment's anchor point). The control point is translated by ( dx ,dy ). The evt is the original user interaction event.The opt parameter is optional; it is used by internal methods. It can have one property: dry (indicating that corresponding 'path:editing' /'path:edit' events will be suppressed).
|
adjustSegment(index, dx, dy, evt) | Adjust the position of a segment. Identified by its index within path segment list (starting from 1 for the first non-moveto segment). The evt is the original user interaction event.
|
getControlPointLockedStates() | Return an array of arrays that records, for every control point (identified as [index][controlPointIndex] ), whether it is currently locked with another point (true ) or not (false ). In tandem with setControlPointLockedStates(lockedStates) , the function can be used to preserve locking information across multiple path editor sessions for a given element.
|
setControlPointLockedStates(lockedStates) | Change the locked status of the editor's control points, so they correspond to the information in the given lockedStates list (e.g. the output of the getControlPointLockedStates() function). A true value adds the 'locked' class to the control point element; a false value removes the class.
|
The following methods are meant to be called in response to user interaction events (e.g. click, touch, dblclick). Some of them are bound with user interactions by default (see the Interaction section), but others are not. Those may be called upon by delegated events from your application. For example:
pathEditor.delegate('contextmenu', '.segment-path', function(event) {
event.stopPropagation();
event.preventDefault();
this.convertSegmentPath(event);
}.bind(pathEditor));
startMoving(event) | Bound with 'mousedown' /'touchstart' events by default.The selected anchor point / control point / segment path starts moving with user pointer. Trigger a corresponding 'path:interact' event.To start listening for the move() and stopMoving() methods, call delegateDocumentEvents() .
|
---|---|
move(event) | Bound with 'mousemove' /'touchmove' events by default (after delegateDocumentEvents() is called).The selected anchor point / control point / segment path moves with user pointer. Trigger corresponding 'path:editing' events.
|
stopMoving(event) | Bound with 'mouseup' /'touchend' /'touchcancel' events by default (after delegateDocumentEvents() is called).The selected anchor point / control point / segment path stops moving with user pointer. Trigger a corresponding 'path:edit' event.To stop listening for the move() and stopMoving() methods, call undelegateDocumentEvents() .
|
createAnchorPoint(event) | Bound with 'dblclick .segment-path' event by default.If event is targeted on a segment path, create an anchor point at the location of the user click and insert it into the path segment list. Trigger the 'path:anchor-point:create' event.Note: Due to current limitations, the function does not work properly for closepath segments in paths that have 2 or more closepath segments (the anchor points are created at wrong position). |
removeAnchorPoint(event) | Bound with 'dblclick .anchor-point' event by default.If event is targeted on an anchor point, remove it. Trigger the 'path:anchor-point:remove' event. If only one anchor point remains in the path after the removal, also trigger the 'path:invalid' event.
|
lockControlPoint(event) | Bound with 'dblclick .control-point' event by default.If event is targeted on a control point of a curveto segment, and the control point is immediately adjacent to a control point of another curveto segment, toggle its locked status. Trigger the corresponding 'path:control-point:lock' /'path:control-point:unlock' event.Note that the locking action necessarily causes a change in the path markup which does not trigger an 'path:edit' event!
|
addClosePathSegment(event) | Not bound with any user interaction by default. If event is targeted on the first or last anchor point, and the path segment list contains no closepath segment, append a closepath segment to the path segment list.
|
removeClosePathSegment(event) | Not bound with any user interaction by default. If event is targeted on a closepath segment, remove the segment from the path segment list.
|
convertSegmentPath(event) | Not bound with any user interaction by default. If event is targeted on a path segment, convert the segment from linear to curved or vice versa. A curveto segment is replaced by a lineto segment. A lineto /closepath segment is replaced by a curveto segment whose control points are coincident with anchor points; a replacement closepath segment is appended to the path segment list if the converted segment was a closepath segment.Note: Due to current limitations, the function does not work properly for closepath segments in paths that have 2 or more closepath segments (the anchor points are created at wrong position). |
Users can interact with joint.ui.PathEditor
objects by clicking/touching editor overlay elements:
mousedown touchstart |
|
---|
Double-clicking editor overlay elements triggers additional actions:
dblclick |
|
---|
For the documentation of the called functions, see the Interaction API section.
The joint.ui.PathEditor
object triggers various events that you can react on:
clear | Triggered when the pathEditor is cleared. | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
path:interact | Triggered when the user interacts with (clicks/touches) the path. The following specific events are triggered alongside this generic event:
|
||||||||||||||||
path:editing | Triggered while the user is editing the path. The handler is passed a reference to the updated svgPath SVGPathElement, and evt (the user interaction event).The following specific events are triggered alongside this generic event:
|
||||||||||||||||
path:edit | Triggered when the user edits the path. The handler is passed a reference to the updated svgPath SVGPathElement, and evt (the user interaction event).The following specific events are triggered alongside this generic event:
|
||||||||||||||||
path:invalid | Triggered when user modifications result in an invalid path (e.g. after removing, a path that has only one anchor point). The handler is passed a reference to the svgPath SVGPathElement, and evt (the user interaction event).
|
You can react to these events by using the on()
method:
pathEditor.on({
'path:control-point:select': console.log('started moving control point'),
'path:control-point:adjusting': console.log('moving control point'),
'path:control-point:adjust': console.log('stopped moving control point')
});
It is also possible to specify a custom context for the on()
method. This is useful when you need to handle user interaction on your PathEditor from within another Backbone object, for instance:
pathEditor.on({
'path:edit': this.onPathEdit.bind(this),
}, this);