Drawing and exporting SVG from Flash AS3

I recently needed to do a little flash app allowing people to draw using the mouse, and then save the data on a server. The most generic and compatible way of doing this I think is converting the shape data to SVG. Below I've listed the code which does this simple conversion. I've stripped a lot of stuff out here to keep this code quite minimal, eventually it would be much better to draw (and save) as curves (instead of straight lines) and do some curve optimization, but that is not within the scope of this post. Also you can add many drawing/painting features to the app like circles, rectangles, text etc.. and just add the corresponding text to the SVG info. Some good SVG documentation can be found at www.w3.org/TR/SVG.

See a demo of it in action here.

One thing to point out: if you were quite critical of bandwidth, SVG or any text based format would not really be the way to go if you wanted to send and store this data on a server. Sending the data in a custom binary format would be much more optimal - I've found on average 10 times smaller (e.g. 1KB instead of 10KB).

So if you expect to have hundreds of saves a day I wouldn't recommend sending the data to your server as SVG... but otherwise its perfect, here is the code (this doesn't take care of actually saving the data, you would need a backend script like PHP to receive and store the data. This code just prepares the data as SVG, then you can do with it what you will):

var theShape:Shape = new Shape;		// the shape we will be drawing in
mcCanvas.addChild(theShape);		// add the shape to the canvas (paper movieclip)
 
const SVG_TERMINATOR = "\n</svg>";	// terminator string for the data
var svgData:String = "";			// the string which contains the full XML. could have made this an XML instance
 
init();								// call the init function
 
 
// init function
function init() {
	svgData =  "<?xml version='1.0'?>\n<svg>";
	updateText(true);
}
 
 
// update the textarea
function updateText(bFull:Boolean) {
	var SVGSize:String = "SVG: " +  String(svgData.length + SVG_TERMINATOR.length) + " bytes\n";
	txtSVGSize.text = SVGSize;
	if (bFull) txtSVG.text = svgData + SVG_TERMINATOR;
}
 
/*********************** Event handlers **********************/
mcCanvas.addEventListener(MouseEvent.MOUSE_DOWN, _MouseDownHandler, false, 0, true);
mcCanvas.addEventListener(MouseEvent.MOUSE_UP, _MouseUpHandler, false, 0, true);
mcClear.addEventListener(MouseEvent.CLICK, _ClearCanvas, false, 0, true);
 
// called when mouse moves (only registered on MOUSE_DOWN)
function _MouseMoveHandler(event:MouseEvent):void {
	var dx:Number = Math.round(event.localX);	// x coordinate of mouse
	var dy:Number = Math.round(event.localY);	// y coordinate of mouse
	svgData += ", " + dx + ", " + dy;			// add the info to the SVG String
	updateText(false);							// update the textarea
	theShape.graphics.lineTo(dx, dy);			// draw the line
}
 
// called when mouse if clicked
function _MouseDownHandler(event:MouseEvent):void {
	var dx:Number = Math.round(event.localX);	// x coordinate of mouse 
	var dy:Number = Math.round(event.localY);	// y coordinate of mouse
	theShape.graphics.lineStyle(mcThickness.value, mcColorPicker.selectedColor, 1);	// set drawing style
	svgData += "\n<path fill='none' stroke='#" + mcColorPicker.hexValue + "' stroke-width='" + mcThickness.value + "' d='M" + dx + ", " + dy + " L" + dx + ", " + dy; // update SVG info
	theShape.graphics.moveTo(dx-0.5, dy);
	theShape.graphics.lineTo(dx, dy);
	updateText(false);
 
	mcCanvas.addEventListener(MouseEvent.MOUSE_MOVE, _MouseMoveHandler, false, 0, true);	// register callback for MOUSE_MOVE
}
 
 
function _MouseUpHandler(event:MouseEvent):void {
	var dx:Number = Math.round(event.localX);
	var dy:Number = Math.round(event.localY);
	svgData += " '/>";
	updateText(true);
	mcCanvas.removeEventListener(MouseEvent.MOUSE_MOVE, _MouseMoveHandler);	// remove callback for MOUSE_MOVE
}
 
 
function _ClearCanvas(event:MouseEvent):void {
	theShape.graphics.clear();
	init();
}

AttachmentSize
View demo70.44 KB
Download source FLA590.52 KB