I have a small drawing application that I built some time ago. I just re-opened the project to add some improvements, but now whenever I call graphics.clear() I cannot draw again. I have reversed everything I have changed, but to no avail. Here is the relevant code from my custom drawing component (based on s:Group):
private var prevX:Number = 0;
private var prevY:Number = 0;
private function startDrawing(event:MouseEvent):void {
addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove, false, 0, true);
}
private function stopDrawing(event:MouseEvent):void {
prevX = 0;
prevY = 0;
removeEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove, false);
}
private function handleMouseMove(event:MouseEvent) {
//Set line style using graphics.lineStyle()
graphics.moveTo(prevX, prevY);
graphics.lineTo(event.localX, event.localY);
prevX = event.localX;
prevY = event.localY;
}
public function clearCanvas():void {
//After I call this I can no longer draw.
graphics.clear();
}
Any help would be appreciated, thanks!
Edit: Some additional info: startDrawing is called on MouseDown, stopDrawing is called on MouseUp, and clearCanvas is called from a button press. I also went from Flash Builder 4.6 to 4.7, not sure if there was an SDK change.
Edit: I worked on the code a bit today, and here is what I came up with. I can see the line when I click and drag, but for some reason can't redraw it onto the main canvas on the MouseUp. When I trace the code, it is transferring and apparently drawing everything correctly (although the smoothing mode is not working yet).
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:local="*"
xmlns:s="library://ns.adobe.com/flex/spark"
mouseEnabledWhereTransparent="true"
mouseDown="startDrawing(event)"
mouseUp="stopDrawing(event)">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.containers.Canvas;
//########## Public Variables ##########
public var __DrawingColor:uint = 0x000000;
public var __DrawingWidth:Number = 4;
public var __DrawingAlpha:Number = 1;
public var __DrawingSmoothing:Boolean = false;
//########## Private Variables ##########
private static const ___SMOOTHING_AMOUNT:Number = 5;
private var _History:ArrayCollection;
private var _CurrentPoints:Array;
private var _LiveCanvas:Canvas;
private var _LiveObject:Object;
private var _PrevX:Number = 0;
private var _PrevY:Number = 0;
//########## Public Functions ##########
public function init():void{
_History = new ArrayCollection();
}
public function clearAll():void {
graphics.clear();
_History = new ArrayCollection();
graphics.beginFill(0xffffff, 0);
graphics.drawRect(0, 0, width, height);
graphics.endFill();
}
public function clearLast():void {
if (_History.length > 0) {
_History.removeItemAt(_History.length - 1);
drawLines(_History);
}
}
//########## Private Functions ##########
private function startDrawing(event:MouseEvent):void {
addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove, false, 0, true);
_CurrentPoints = new Array();
_LiveCanvas = new Canvas();
addElement(_LiveCanvas);
_LiveCanvas.x = 0;
_LiveCanvas.y = 0;
_LiveCanvas.width = this.width;
_LiveCanvas.height = this.height;
_LiveCanvas.setStyle("backgroundColor", 0xFFFFFF);
_LiveCanvas.setStyle("backgroundAlpha", "0");
}
private function handleMouseMove(event:MouseEvent):void {
if (_PrevX != 0 && _PrevY != 0) {
_CurrentPoints.push(new Point(event.localX, event.localY));
_LiveCanvas.graphics.lineStyle(__DrawingWidth, __DrawingColor, __DrawingAlpha);
_LiveCanvas.graphics.moveTo(_PrevX, _PrevY);
_LiveCanvas.graphics.lineTo(event.localX, event.localY);
}
_PrevX = event.localX;
_PrevY = event.localY;
}
private function stopDrawing(event:MouseEvent):void {
_CurrentPoints.push(new Point(event.localX, event.localY));
_PrevX = 0;
_PrevX = 0;
this.removeElement(_LiveCanvas);
_LiveCanvas = null;
if (__DrawingSmoothing) {
_CurrentPoints = smoothPoints(_CurrentPoints);
}
var addItem:Object = new Object();
addItem.color = __DrawingColor;
addItem.width = __DrawingWidth;
addItem.alpha = __DrawingAlpha;
addItem.lines = pointsToLines(_CurrentPoints);
_History.addItem(addItem);
drawLines(_History);
removeEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove, false);
}
private function smoothPoints(points:Array):Array {
var len:uint = points.length;
var p:Point;
var ret:Array = new Array();
var t:Number = 1 / ___SMOOTHING_AMOUNT;
while (t < 1) {
p = getPoint(t, points);
ret.push(p);
t += 1 / ___SMOOTHING_AMOUNT;
}
return ret;
}
private function pointsToLines(points:Array):Array {
var ret:Array = new Array();
var lineObject:Object = new Object();
for (var i:Number = 0; i < points.length; i++) {
if (!lineObject.hasOwnProperty("x1")) {
lineObject.x1 = Point(points[i]).x;
lineObject.y1 = Point(points[i]).y;
} else if (!lineObject.hasOwnProperty("x2")) {
lineObject.x2 = Point(points[i]).x;
lineObject.y2 = Point(points[i]).y;
} else {
ret.push(lineObject);
lineObject = new Object();
lineObject.x1 = Point(points[i]).x;
lineObject.y1 = Point(points[i]).y;
}
}
return ret;
}
private function drawLines(lines:ArrayCollection):void {
graphics.clear();
graphics.beginFill(0xFFFFFF, 0);
graphics.drawRect(0, 0, width, height);
graphics.endFill();
var currentPoints:Object;
for (var x:Number = 0; x < lines.length; x++) {
currentPoints = lines[x];
graphics.lineStyle(currentPoints.width, currentPoints.color, currentPoints.alpha);
for (var i:Number = 0; i < currentPoints.lines.length; i++) {
graphics.moveTo(currentPoints.lines[i].x1, currentPoints.lines[i].y1);
graphics.lineTo(currentPoints.lines[i].x2, currentPoints.lines[i].y2);
}
}
}
private function getPoint(t:Number, points:Array):Point {
var x:Number = 0;
var y:Number = 0;
var n:uint = points.length-1;
var factn:Number = factoral(n);
for (var i:uint=0;i<=n;i++) {
var b:Number = factn/(factoral(i)*factoral(n-i));
var k:Number = Math.pow(1-t, n-i)*Math.pow(t, i);
x += b*k*points[i].x;
y += b*k*points[i].y;
}
return new Point(x, y);
}
private function factoral(value:uint):Number {
if (value==0)
return 1;
var total:Number = value;
while (--value>1)
total *= value;
return total;
}
]]>
</mx:Script>
</s:Group>
Finally figured it out, the working code is posted below if anyone is interested. Thanks!
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:local="*"
xmlns:s="library://ns.adobe.com/flex/spark"
mouseDown="startDrawing(event)"
mouseUp="stopDrawing(event)">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
//########## Public Variables ##########
public var __DrawingColor:uint = 0x000000;
public var __DrawingWidth:Number = 4;
public var __DrawingAlpha:Number = 1;
public var __DrawingSmoothing:Boolean = false;
//########## Private Variables ##########
private var _History:ArrayCollection;
private var _CurrentPoints:Array;
private var _LiveObject:Object;
//########## Public Functions ##########
public function init():void{
_History = new ArrayCollection();
}
public function clearAll():void {
graphics.clear();
_History = new ArrayCollection();
graphics.beginFill(0xffffff, 0);
graphics.drawRect(0, 0, width, height);
graphics.endFill();
}
public function clearLast():void {
if (_History.length > 0) {
_History.removeItemAt(_History.length - 1);
drawLines(_History);
}
}
//########## Private Functions ##########
private function startDrawing(event:MouseEvent):void {
addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove, false, 0, true);
_CurrentPoints = new Array();
_CurrentPoints.push(new Point(event.localX, event.localY));
_LiveCanvas.visible = true;
_LiveCanvas.graphics.clear();
_LiveCanvas.graphics.beginFill(0xFFFFFF, 0);
_LiveCanvas.graphics.drawRect(0, 0, width, height);
_LiveCanvas.graphics.endFill();
_LiveCanvas.graphics.moveTo(event.localX, event.localY);
}
private function handleMouseMove(event:MouseEvent):void {
_CurrentPoints.push(new Point(event.localX, event.localY));
_LiveCanvas.graphics.lineStyle(__DrawingWidth, __DrawingColor, __DrawingAlpha);
_LiveCanvas.graphics.lineTo(event.localX, event.localY);
}
private function stopDrawing(event:MouseEvent):void {
removeEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove, false);
_CurrentPoints.push(new Point(event.localX, event.localY));
_LiveCanvas.graphics.clear();
_LiveCanvas.visible = false;
if (__DrawingSmoothing) {
_CurrentPoints = smoothPoints(_CurrentPoints);
}
var addItem:Object = new Object();
addItem.color = __DrawingColor;
addItem.width = __DrawingWidth;
addItem.alpha = __DrawingAlpha;
addItem.points = _CurrentPoints;
_History.addItem(addItem);
drawLines(_History);
}
private function smoothPoints(points:Array):Array {
var len:uint = points.length;
var p:Point;
var ret:Array = new Array();
var t:Number = 1 / (points.length);
while (t < 1) {
p = getPoint(t, points);
ret.push(p);
t += 1 / (points.length);
}
return ret;
}
private function drawLines(lines:ArrayCollection):void {
graphics.clear();
graphics.beginFill(0xFFFFFF, 0);
graphics.drawRect(0, 0, width, height);
graphics.endFill();
var currentPoints:Object;
for (var x:Number = 0; x < lines.length; x++) {
currentPoints = lines[x];
graphics.lineStyle(currentPoints.width, currentPoints.color, currentPoints.alpha);
if (currentPoints.points.length > 0) {
graphics.moveTo(Point(currentPoints.points[0]).x, Point(currentPoints.points[0]).y);
for (var i:Number = 0; i < currentPoints.points.length; i++) {
graphics.lineTo(currentPoints.points[i].x, currentPoints.points[i].y);
}
}
}
}
private function getPoint(t:Number, points:Array):Point {
var x:Number = 0;
var y:Number = 0;
var n:uint = points.length-1;
var factn:Number = factoral(n);
for (var i:uint=0;i<=n;i++) {
var b:Number = factn/(factoral(i)*factoral(n-i));
var k:Number = Math.pow(1-t, n-i)*Math.pow(t, i);
x += b*k*points[i].x;
y += b*k*points[i].y;
}
return new Point(x, y);
}
private function factoral(value:uint):Number {
if (value==0)
return 1;
var total:Number = value;
while (--value>1)
total *= value;
return total;
}
]]>
</mx:Script>
<mx:Canvas id="_LiveCanvas" left="0" right="0" top="0" bottom="0" backgroundAlpha="0" backgroundColor="0xFFFFFF"/>
</mx:Canvas>