Arrow heads in Sketch ===================== The situation in 0.6.x ---------------------- In 0.6, an arrow head is given as a single bezier path that is either stroked or filled with the line color of the object it's associated with. The coordinates of the path are given in the arrow coordinate system which is rotated and translated such that the arrow's tip points in the direction of the positive x-axis and the origin coincides with the end-point of the curve. The unit is the line width of the object. The Problem ----------- One disadvantage of this is that the tip of the arrow is normally not exactly the end-point of the curve and since the end-point is snapped to the grid the arrow tip is not on the grid (or other points Sketch snaps to). The tip can't be on the end-point with the current arrow model because the line would protrude from the arrow tip like this: |\ | \ | \ | \ -- -- ---------------------+----\--+ | \ | | \| | /| | / | -- -- ---------------------+----/--+ | / | / | / |/ Possible remedies ----------------- So far, I've come up with two different solutions: A. Associate a parameter with an arrow tip description that defines how far the curve has to be foreshortened. This way, a curve will stop shortly before the real endpoint of the curve and the arrow tip can be exactly at the endpoint. B. Have an arrow property that defines where exactly the tip is in the arrow coordinate system. With this information, Sketch can determine the real position of the arrow tip and use that for snapping if the user drags a start or end-point of a curve. In Sketch 0.7.4, I've implemented both variants and it seems that both have advantages and disadvantages: Solution A requires considerable changes to the drawing code to make sure that drawing stops a little before the end points while B requires no changes in the drawing code. A is easier to use in my opinion because the tip and the end-point coincide. This is an advantage when dragging the end-point since the arrow head is not visible during a drag (although this could be changed, of course) and when moving the control-point that controls the tangent at the end-point because the tip doesn't move and stays on the grid. With B the tip would move when the control point is changed. B is more flexible than A because it allows for asymmetric arrow heads where the tip is not located on the x-axis in the arrow coordinate system. With A, the tip has to be at the origin (of the arrow coordinate system) if it is to snap to the grid. Conclusion ---------- Both solutions have advantages and disadvantages and they're not mutually exclusive, so it would seem like a good idea to implement them both. I'm not really comfortable with that, though, for several reasons. All changes that affect the file format will have to be supported in future versions of Sketch to ensure backwards compatability. For solution B this would be trivial as one could simply ignore the additional information, for A this might require more work if the arrow semantics should change. There might be a better solution that is even better than A and B together.