Home > Flex > Drawing curved lines and arrows in Flex


Drawing curved lines and arrows in Flex

February 18th, 2009

While working on one of my mapping projects, I needed to draw some arrows between different points on the map.  After searching the web I found something close to what I was looking for, but I wanted curved arrows for a slick look.

If you haven’t already, you should read up on the features provided by the Flex 3 drawing API.  Most components in Flex have a graphics layer(i.e. Canvas.graphics) on which you can draw lines and shapes.  Drawing a simple line goes as follows:

var origin:Point = new Point(0,0);
var destination:Point = new Point(lineLength,lineHeight);

var lineThickness:Number = 2;
var lineColor:Number = 0x000000;
var lineAlpha:Number = 1;

graphics.clear();
graphics.lineStyle(lineThickness,lineColor,lineAlpha);
graphics.moveTo(origin.x,origin.y);
graphics.lineTo(destination.x,destination.y);

Drawing a curved line can be acomplished by supplying a control point that the curve must pass through on its way to the destination.  I used simple vector geometry to calculate the control point in this example:

var origin:Point = new Point(0,0);
var destination:Point = new Point(lineLength,lineHeight);

// start curve anchor at halfway point between origin and destination
var curveAnchor:Point = new Point(
    (origin.x + destination.x)/2,
    (origin.y + destination.y)/2);

// shift point perpendicular to line that is curvePercent of original line
if (origin.x > destination.x)
{
    curveAnchor.x -= (destination.y-origin.y) * curvePercent;
    curveAnchor.y += (destination.x-origin.x) * curvePercent;
}
else
{
    curveAnchor.x += (destination.y-origin.y) * curvePercent;
    curveAnchor.y -= (destination.x-origin.x) * curvePercent;
}

var lineThickness:Number = 2;
var lineColor:Number = 0x000000;
var lineAlpha:Number = 1;

graphics.clear();
graphics.lineStyle(lineThickness,lineColor,lineAlpha);
graphics.moveTo(origin.x,origin.y);
graphics.curveTo(curveAnchor.x,curveAnchor.y,destination.x,destination.y);

Noel Billig of dncompute.com created a great API for drawing arrows at the end of lines.  Utilizing his API we can quickly create a straight line with an arrow at the end:

var origin:Point = new Point(0,0);
var destination:Point = new Point(lineLength,lineHeight);

var lineThickness:Number = 2;
var lineColor:Number = 0x000000;
var lineAlpha:Number = 1;

graphics.clear();
graphics.beginFill(lineColor,lineAlpha);
GraphicsUtil.drawArrow(graphics,origin,destination,
    {shaftThickness:lineThickness,headWidth:10,headLength:15,
     shaftPosition:.20,edgeControlPosition:.5
    }
);

Starting with Noel’s code, I made some enhancements so I could draw a curved arrow instead of just a straight one.  It took quite a bit of tinkering but I eventually found a solution that works great.  The syntax is similar to above but now we pass in the control point also:

GraphicsUtil.drawArrow(graphics,origin,destination,curveAnchor,
    {shaftThickness:lineThickness,headWidth:10,headLength:15,
     shaftPosition:.20,edgeControlPosition:.5
    }
);

Check out the demo below which outlines each of these examples.  Right-click to view source.



Christopher Flex

  1. No comments yet.
  1. No trackbacks yet.
You must be logged in to post a comment.