Object SnappingΒΆ
Pencil users will know that Pencil provides snapping between objects. Object snapping is very useful for aligning objects so that drawing operations can be done quickly. There are 6 default snappings in Pencil:
Top-to-Top
Bottom-to-Bottom
Center-to-Center (horizontal)
Left-to-Left
Right-to-Right
Middle-to-Middle (vertical)
Sometimes the snapping needs to be customized for specific purposes. This
tutorial will show how to create new custom snappings. These definitions are
put into an <Action></Action> which must have the exact id of
getSnappingGuide.
<Shape id="RoundedRect" displayName="Rectangle" icon="Icons/rectangle.png">
<Properties>
...
</Properties>
<Behaviors>
...
</Behaviors>
<Actions>
<Action id="getSnappingGuide">
<Impl>
var b = this.getBounding();
return [
new SnappingData("FrameTop", b.y + b.height/2, "TabBottom", false, this.id),
new SnappingData("Top", b.y + b.height, "Top", false, this.id),
new SnappingData("Bottom", b.y, "Bottom", false, this.id),
new SnappingData("Left", b.x + b.width, "Left", true, this.id),
new SnappingData("Right", b.x, "Right", true, this.id)
];
</Impl>
</Action>
</Actions>
<p:Content xmlns:p="http://www.evolus.vn/Namespace/Pencil"
xmlns="http://www.w3.org/2000/svg">
<rect id="rrRect" x="0" y="0" />
</p:Content>
</Shape>
The getSnappingGuide action is expected to return an array of snapping
hints. Each snapping hint is composed of an object of type SnappingData:
new SnappingData(snappingName, position, toSnappingName, isHorizontalSnapping, this.id)
Where:
- snappingName: is the name of this snapping hint.
- position: is the position in this shape when the snapping hint is defined (vertical or horizontal).
- toSnappingName: is the Snapping name of other hints that can be snapped to this hint.
- isHorizontalSnapping: if true, the snapping will be in the Horizontal direction.
Built-in snapping data: by default, even if you don’t provide snapping definitions, Pencil has the following snapping data defined for all objects:
new SnappingData("Top", b.y, "Top", false, this.id),
new SnappingData("Bottom", b.y + b.height, "Bottom", false, this.id),
new SnappingData("HCenter", b.y + b.height / 2, "HCenter", false, this.id),
new SnappingData("Left", b.x, "Left", true, this.id),
new SnappingData("Right", b.x + b.width, "Right", true, this.id),
new SnappingData("VCenter", b.x + b.width / 2, "VCenter", true, this.id),
where b is the object bounds, b.y is the object’s top position, b.x
is the object’s left position, b.height is the object bound height,
b.width is the object bound width.
In the above example for the Rectangle shape, four default snappings are
modified and a new snapping is created.
In the above example, A‘s Top snapping was modified by new
SnappingData("Top", b.y + b.height, "Top", false, this.id),. So other objects
that have Top snapping will snap to A‘s new Top. The logic for Bottom,
Left, Right snappings are the same.
Also in this example, a custom, new snapping hint is introduced. This is good for special stencils where we would like to have very specific snappings defined:
new SnappingData("FrameTop", b.y + b.height/2, "TabBottom", false, this.id)
Suppose that we have another stencil named B with the following custom snapping defined:
new SnappingData("TabBottom", b.y, "FrameTop", false, this.id)
So, A has a new snapping, FrameTop, which allows other snappings of
type TabBottom to be snapped to. Since B has a snapping hint called
TabBottom defined, it will be possible for B to snap to A at the
expected position.
If other shapes want to snap to A at FrameTop, they just need to define
a snapping with the name TabBottom like B does.
As noted above, all objects in Pencil have a Top snapping hint defined by
default as its top position, so to have all objects be able to snap to our
A‘s special FrameTop snapping point, just modify the SnappingData
definition to the following:
new SnappingData("FrameTop", b.y + b.height/2, "Top", false, this.id)