Wednesday, September 21, 2011

Flex 4 Path Builder


April 2013 - added View Source to right click menu.

I got a little carried away making an application that lets you manipulate Flex Path objects. This application lets you easily design a path by double clicking to make each end point in your path. You can select each individual line, move, or curve segment and manipulate the end points () and the curve control points (). Click on the screenshot above to see it in action. I'm sure there will be bugs, so use at your own risk. There is no undo support either.

To use this tool, you can start by adding different kind of path segments - move, lines, and curves - by clicking on one of the 6 buttons along the top in the blue titlebar. This will cause the path segment to be appended to the currently displayed path. Each path segment also shows up in the list on the left side. Click on an individual path segment in this list to highlight it in the path. The red end points () are draggable - move them around to adjust the path. Note that the following path segment will be moved to start wherever the current path segment ends. You can also click and drag the circle control points () to adjust the quadratic and cubic Bezier Curves.
Alternatively you can use the new "Path Designer" option (which is explained in the top panel on the left side). The path designer lets you double click on the white graph area to create each segment of your path. Here are the instructions:
  • To create a line: Double-click on the graph
  • To create a straight line (horizontal, vertical, or at 45°): Shift + double-click on the graph
  • To create a quadradic curve: Ctrl(⌘) + double-click on the graph (you can edit the control point later)
  • To create a cubic bezier curve: Ctrl(⌘) + shift + double-click on the graph
  • If you check the Use relative positions checkbox the path segments will use relative positions instead of absolute (lower case letters like "l", "m", "c", "q", etc)
  • If you check the Snap To Grid checkbox, then the end points are all shifted to fit on a grid defined by the number of pixels you choose. This is a nice way to easily get nice round numbers like 20, 50, 100.

If you have an existing path you can paste the data string (e.g. "M 100 100 L 150 150 H 200") into the textbox at the top and click Update. This will render your path on the screen and allow you to manipulate it.

I've also added support for ActionScript GraphicsPath commands to be pasted in the same textbox in this format:
"1 2;10 10 20 20"
The first set of numbers before the semi-colon are the commands (defined by the constants in GraphicsPathCommand). The second set of numbers after the semi-colon are the coordinates of each path segment. In your program you can use a trace statements like this on your GraphicsPath object to output the correct format:
trace(path.commands.join(" ") + ";" + path.data.join(" "));

And finally, if you have a path created in ActionScript using a Graphics object or a GraphicsPath object like this:
var g:Graphics = uiComponent.graphics;
g.moveTo(10, 10);
g.lineTo(50, 10);
g.moveTo(50, 50);
g.lineTo(10, 50);
You can copy that code and paste it into the same textbox at the top. It will pick out the move, line, and quad curve commands. This will only work if you use all numbers in your code - no variables or constants.

The Translate X/Y option lets you move every single point on the screen by the given x and y offset values. This includes the control points. So think of it as shifting the entire path. Note that the points can't be moved into negative values (even though they are allowed), so unexpected things will happen if you try to do this.

On the right side of the app (not shown in the screenshot) there is an edit panel which lets you type in the exact numeric values that you want for each point in the selected path segment. This way you can easily tweak your path to look just right.

Below the Edit Panel is the Stroke & Fill Properties panel. This lets you define the path stroke and fill properties.

Below that is the MXML and FXG output windows which let you copy the MXML/FXG source code used to render the path, so you can paste it into your own application. If you are using FXG, then in Flash Builder choose "File > New > File". Then enter in the filename you want like "mypath.fxg". In the editor paste in the FXG, it has all the declaration xml that you should need.

Feedback welcome, have fun playing.

I haven't enabled view-source for this project yet, hopefully one day.

20 comments:

  1. Hey Dear,,,
    Thanks for sharing a informative post. Its really helpful post..

    ReplyDelete
  2. Nice! Would be rad if it also supported as3-only graphics.drawPath vectors.

    ReplyDelete
  3. Hey Intoxopox - what are you looking for in terms of support for AS3 graphic paths? A window that shows the AS3 commands for drawing the Path?
    e.g.
    var path:GraphicsPath = new GraphicsPath();
    path.moveTo(x1, y1);
    path.lineTo(x2, y2);
    ...
    graphics.drawPath(path.commands, path.data, path.winding);

    Or something else? Also as far as I can see the GraphicsPath stuff doesn't support cubic curves though (2 control points), only quadratic curves (1 control point).

    Chris

    ReplyDelete
  4. Right. No cubic curve support. I'm just looking for support for pasting in the commands vector and data vector expected by graphics.drawPath. That would be rad. Also would be super rad to spit out a FXG from this stuff.
    Hope that makes sense.

    ReplyDelete
  5. Oh I see. Okay, I'll see what I can do. I hope to have a new version some time in the next week or two.

    FXG is a good idea, I'll do that too.

    ReplyDelete
  6. I have found a no of people having the same issue but then here http://www.futurehardware.com/pc-softwares-applications/118.htm are some solutions that you can try out, just check it out

    ReplyDelete
  7. Hi

    How do you add click event listeners to the Path (which is a primitive, and I thought could not have click event)?? Would love to know:(

    Brian Bishop

    ReplyDelete
  8. Hi Brian,
    You are right, you can't add mouse listeners to the Path directly.

    In the Path Builder code above, the only Mouse click event listeners are added to the start, end, and control points, which are a custom component called DragControl.mxml (extends Group).

    One thing you can do is create a Group with the property mouseEnabledWhereTransparent="false" and put a path inside the group, and add a MouseEvent.CLICK listener to the group and it will only be triggered when you click on the path - either on the stroke border, or the fill depending on your path.

    E.g.
    <s:Group click="trace('triangle clicked')"
    mouseEnabledWhereTransparent="false">
    <s:Path data="H 40 V 40 Z">
    <s:stroke>
    <s:SolidColorStroke color="#336699"
    weight="3"/>
    </s:stroke>
    </s:Path>
    </s:Group>

    Clicking on the border of the triangle will trigger the click event, clicking anywhere else won't.

    ReplyDelete
  9. Wow this is really a great tool! Is there a way to scale / zoom the canvas so that even tiny graphics like icons can be designed? If not, is this project hosted on GitHub or somewhere so that I could submit a patch?

    Thanks,
    Borek

    ReplyDelete
  10. Hi Borek,

    I agree that it would be nice to be able to work on small graphics, currently there is no way to zoom the canvas.

    What I usually do is just design the path to be larger than I need, and when I import it into Flash Builder, I set the scaleX and scaleY to be 0.5 or similar to make it smaller. It's not the most efficient, but it works.

    Perhaps another option would be to allow the user to scale the values before exporting.

    Anyway, if you're really keen I can email you the source code. It's not in a public repository. If you succeed, then you're welcome to send it back to me and I'll update this blog post accordingly.

    Chris

    ReplyDelete
  11. This is really great! Thanks so much for sharing it!

    ReplyDelete
  12. This comment has been removed by a blog administrator.

    ReplyDelete
  13. Really great! Any chance you'd open-source the application?

    ReplyDelete
  14. Hi Michael,

    I've updated the project above to include the source code.

    If you click on the image above, and then right click on the app you should see the "View Source" option. It has the same open source license listed on the right (LGPL).

    Chris

    ReplyDelete
  15. Thanks, Chris, this is really cool!

    ReplyDelete
  16. Your swell tool was about to come in handy again for me, but my path data doesn't seem to be working. Don't suppose you see anything terribly amiss in the following:
    M 57.65 13.45 Q 61.3 20.2 61.05 26.9 60.9 30.9 58.3 34.35 55.85 37.55 52.3 39.05 51.05 47.3 41.45 50.85 36.6 52.65 30.95 52.2 25.7 51.75 23 49.75 19.15 50.55 15.05 49.6 10.05 48.45 6.25 45 1.45 40.7 0.35 33.2 -0.45 27.7 0.75 19 1.2 15.75 24.7 8.75 47.85 1.8 49.5 3.25 54.6 7.8 57.65 13.45

    The above was taken from a fxg file and spaces were added around the M and
    Q. Running update puts Qs where needed before every set of 4 coordinates. However, only the 1st qCurve seems to be drawn. Any thoughts?

    ReplyDelete
  17. Hi Intoxopox,
    There must be a bug in the Update code - it changes your path so that it has the exact same bezier curve repeated ~10 times, instead of the one you pasted in.

    This is what yours should be (I manually put in Q's after every 4 numbers) - which draws a circular shape:
    M 57.65 13.45 Q 61.3 20.2 61.05 26.9 Q 60.9 30.9 58.3 34.35 Q 55.85 37.55 52.3 39.05 Q 51.05 47.3 41.45 50.85 Q 36.6 52.65 30.95 52.2 Q 25.7 51.75 23 49.75 Q 19.15 50.55 15.05 49.6 Q 10.05 48.45 6.25 45 Q 1.45 40.7 0.35 33.2 Q -0.45 27.7 0.75 19 Q 1.2 15.75 24.7 8.75 Q 47.85 1.8 49.5 3.25 Q 54.6 7.8 57.65 13.45

    ReplyDelete
  18. Thanks so much! I should've inspected more carefully after hitting update.

    ReplyDelete
  19. No worries - all those numbers looked the same to me too :)

    ReplyDelete
  20. This comment has been removed by a blog administrator.

    ReplyDelete