Undo/redo adding objects - actionscript-3

I have a custom banner maker program in which the following can be done:
Different banner shapes can be selected (Buttons clicked to place the corresponding movieclip onto the stage)
Different banner colors can be selected by using a ColorTransform that is linked to buttons i.e. a red button turns the banner red
Textfields can be added to the stage, dragged and dropped using startDrag and stopDrag, and the text color can be changed with a ColorPicker as well as being able to change the font size and font itself
Pre-loaded images can be selected from a panel and added to the banner (Buttons that are clicked to add a corresponding movieclip to the stage)
Images can be uploaded directly onto the stage and can be resized
I need to figure out a way of being able to essentially add undo and redo features to do things like remove an image/textbox that was placed, change the banner color back to whatever color it was previously, reset the position of an object that was dragged from its default position etc.
I'm not sure how to best go about this using AS3?

Not hard. Use removeChild(instance name of Child here) to remove an object from the stage.
Atriace's idea is sensible. You didn't say if you'll want to remember the positions of things after you stop running your program. Or is it only while you're running?
If the latter I'd create an array for each banner or textfield, and store in that array the current values of the properties you want to record. So, for instance:
var A:Array = new Array
A.push(textfield1.text)
will put your current text in textfield1 into the first index position in array A. You can call that little bit of code when you initially add the text (on a button click or whatever). Later, if you want that text back you'd do it like
textfield1.text = A[0]
assuming that your old text was in the first index position in the array.
If you want to remember values between runs of the program use a SharedObject to write the value to disk. Too much to write about that here -- look it up!

Related

How to change the color of a rectangle border in actionscript 3

I am currently following an online programming class at my school. We are studying Flash and therefore actionscript 3 and I am having difficulty in one of my projects.
I want to easily be able to change the border color of my button when the user clicks on it but I can't seem to find how. Until now, I used to change the entire button's color, but I want to try a new effect. To change the entire color I used this code :
var ctAvance:ColorTransform = btnAvance.transform.colorTransform;
ctAvance.color = 0x00CCCC;
btnAvance.transform.colorTransform=ctAvance;
Thanks a lot in advance!
its a possible duplicate of this question
its impossible in that way (using ColorTransform) however:
you have another option, if your btnAvance is a Movieclip or something else, convert*1 it to a Button instead, then inside your object, you have 4 frames in the names of Up Over Down Hit, under Over frame press F6 (insert keyframe) and simply change your button border color
Edit:
*1 : you must convert it in library, not only your instance in stage, find your btnAvance in library list, rightclick on it then select properties and change its type.

as3 erasing text on a graphics object

I have a project i'm working on that allows the user to "Type" text onto a graphics object (in this case it is a canvas). So the text follows the mouse cursor and whenever a user types text appears on the graphics object. If the user clicks, the text is pasted down onto the graphics object. I need to figure out how to allow the user to make this text go away (for when the graphics object gets too crowded). What method could I use to erase all the text inside the graphics object?
Screenshot (hopefully this helps, I know this is a difficult to understand question):
The white background is the graphics object and the text is "pasted down". Now my objective is to create a button to clear all the text on the graphics object. Instinctively I would use graphicsObject.graphics.clear() but this is obviously not the solution here.
The answer is: as long as you don not store each element which should be drawn separately, you can not just delete the text. By this I mean that you need a stack with all the elements to draw and each time one of the elements changes, is added or removed, you clear the whole canvas and repaint every element from the stack.

Highlighting Graph Points clicked on in HTML Canvas

I currently have an html page that produces a line graph inside a canvas element. I have also implemented a feature so that when you click on a point in the graph, a table below the canvas displays the information for that graph point, and clears if you click somewhere that isn't a graph point on the canvas. However, there is currently no indicator for what graph point you have selected.
I would like to make it so that the dot you click on either gets bigger, or highlighted, or something. Unfortunately, I don't think there's any way to do that on the one canvas without needing to redraw the entire graph afterwards. If I drew a bigger dot on top of the original, I would then need to erase it and replace it with the smaller one, as well as redrawing the segment of the line graph that was covered by the larger dot.
I was looking into using a second canvas on top of the first with identical dimensions, using a z-index to control which was on top. However, I don't know how this would affect the click event. If two canvasses are on top of each other, is it possible for the click event to register the lower canvas? Does it only register the higher one? I guess I could just change the click event to be for whichever canvas is on top, but keep all the code for drawing on the canvas the same.
Any advice for how to solve this problem?
Solved a few of my own questions.
Firstly, the click event will only recognize whichever canvas is on top. However, I did like I said, and changed my click event to be for the top canvas, while leaving all instructions on the inside to be for the top canvas. Thank goodness I didn't use the 'this' keyword, or the change would have been much more annoying.
To make the graph points highlight, I first added a second canvas on top of my first one, placing them on top of each other by making their positions "absolute" and giving them a z-index of 0 and 1 respectively. Then, inside the if statement where the original click event recognized that a point had been clicked on, I told the top canvas to draw a larger dot on the same coordinates as the first dot (which I had saved in an array). First, I had it clear the top canvas though, so any other highlighted dots would no longer be highlighted. If the canvas was clicked on somewhere other than a dot, nothing was highlighted.

as3 how can i prevent that a new instance is created by entering a frame?

i am working with several nested movieclip objects in a project. but i get into trouble with the buttons i created and implemented in the nested movieclips:
to describe it in a simple way:
I have a main movieclip with five frames, including two buttons with listeners to browse between the frames. Then inside of one Frame I have another movieclip with its own buttons. i instanciated it by hand not through code and gave it a specific name like "nestedMc".
Now I dont want to build the Listeners for those buttons inside the class of the nested movieclip class but in its parent class, which works fine until i then goto another frame in the main movieclips timeline and come back.
obviously every time flash enters a frame its contents get created anew (and therefore get new instance names). I could now try solve this through filling the frames via code.
But maybe there is another way to make sure the frame contains the same instance everytime i enter?
Timeline scripting is a dirty business, and really, a carry-over compatibility layer for Actionscript 2 projects. Whenever possible, I highly recommend not doing it, and simply keeping all of your code in your document class. As you're experiencing, timeline code causes headaches.
Consider instead just creating both states of your Stage (it sounds like that's what your two buttons are jumping between) and simply hiding them offstage or setting their alpha to zero and their mouseEnabled state to false. Furthermore, if the purpose of your frames is to play animation (a tween), consider instead switching to a much more powerful suite such as TweenLite. Moving an object over a hundred pixels (smoothly) can be as easy as:
TweenLite.to(redBall, 3, {x:100});
Now, if you're manually adding these items to the stage, as long as the object is a dynamic one, you can assign an instance name to it which will be saved between frame loads. Be aware the object name is not the same as the instanced name. For example:
var redBall:Ball = new Ball();
redBall.name = "bubbles";
The object's name is Ball, but it's represented as a variable called redBall. Its actual DisplayList name will likely be ambiguous (such as "Instance71"), and I can manually define it as "bubbles". 3 different names for the same object, all very different and necessary.
Even if you give the object a displayList name, you may not be able to reference it through code unless you enable Automatically declare stage instances, which basically creates on each object a pointer to the displayList object.
That said, you can always fetch the object by other means. Obviously, your buttons are always appearing, but you're trying to find a very specific object on the stage. At this point, we can use getChildByName() or getChildAt().
Hope that helps.
-Cheers

Drag objects in canvas

Im looking for an easy to use method of assigning drag behavior to multiple objects (images, shapes etc) in canvas. Does anyone have a good way or know of any libraries for dragging objects around? Thanks
Creating your own mouse events takes a little work - ideally you should either create or use some kind of mini-library. I'm thinking of creating something like this in the near future. Anyway, I created a drag and drop demo on jsFiddle showing how to drag images - you can view it here.
You can create draggable images like this:
var myImage = new DragImage(sourcePath, x, y);
Let me know if you have any questions about this. Hope it helps.
EDIT
There was a bug when dragging multiple images. Here is a new version.
Another thing you might want to check out is easeljs it sort of in the style of AS3... mouseEvents dragging etc...
The HTML Canvas—unlike SVG or HTML—uses a non-retained (or immediate) graphics API. This means that when you draw something (like an image) to the canvas no knowledge of that thing remains. The only thing left is pixels on the canvas, blended with all the previous pixels. You can't really drag a subset of pixels; for one thing, the pixels that were 'under' them are gone. What you would have to do is:
Track the mousedown event and see if it's in the 'right' location for dragging. (You'll have to keep track of what images/objects are where and perform mouse hit detection.)
As the user drags the mouse, redraw the entire canvas from scratch, drawing the image in a new location each time based on the offset between the current mouse location and the initial mousedown location.
Some alternatives that I might suggest:
SVG
Pure HTML
Multiple layered canvases, and drag one transparent canvas over another.
The HTML Canvas is good for a lot of things. User interaction with "elements" that appear to be distinct (but are not) is not one of those things.
Update: Here are some examples showing dragging on the canvas:
http://developer.yahoo.com/yui/examples/dragdrop/dd-region.html
http://www.redsquirrel.com/dave/work/interactivecanvas/
http://langexplr.blogspot.com/2008/11/using-canvas-html-element.html
None of these have created a separate library for tracking your shapes for you, however.
KineticJS is one such Javascript Library that u can use exclusively for animations
Heres the Link html5canvastutorials
Canvas and jCanvas
You're definitely gonna want to check out jCanvas. It's a super clean wrapper for Canvas, which kicks open a lot of doors without adding code complexity. It makes things like this a breeze.
For example, here's a little sandbox of something close to what you're after, with dragging and redrawing built right in:
Drawing an Arrow Between Two Elements.
I ventured down the road of doing everything with DIVs and jQuery but it always fell short on interactivity and quality.
Hope that helps others, like me.
JP
As you create new objects whether they are windows, cards, shapes or images to be draggable, you can store them in an array of "objects currently not selected". When you click on them or select them or start dragging them you can remove them from the array of "objects not selected". This way you can control what can move in the event of a particular mousedown event or mousemove event by checking if it isn't selected. If it is selected it will not be in the "not selected" array and you can move the mouse pointer over other shapes while dragging shapes without them becoming dragged.
Creating arrays of objects you would like to drag also helps with hierarchy. Canvas draws the pixels belonging to the foremost object last. So if the objects are in an array you simply switch their instance as in element in the array say from objectArray[20] to objectArray[4] as you iterate through the array and draw the objects stored in the array elements you can change whether other objects are seen on top or behind other objects.