Actionscript: Make a mask follow a line (and "grow") - actionscript-3

does anybody know/have some idea how to make a mask follow a line? Basically I have a drawing made with 1px line and I need to gradually mask this shape so it actually looks like it is being drawn. The thing is that I cannot just increase the width of the mask (it would simple draw a vertical line in one step which is not desired), it has to be a linear movement along the "guide" line, so the vertical line gets drawn in several steps. Doing this manually will/would be a major pain. This is what I am trying to achieve:
Thanks a lot!

You have to do it manually. Though there are some shortcuts you can take:
Create a Guide layer in Flash Pro.
Copy a vector of your path to this guide layer.
Create a new layer below it, put a circle on that layer at the start of the path and make a classic tween of that circle.
Dock your circle layer under your guide layer and at the last frame of your tween move the circle to the end of the path. This will make the circle go along the path.
Follow the animation and manually fill the covered parts.
Put your guide, circle animation and following animation into a MovieClip and put it above your to be masked symbol and make its layer a mask.
Here's an example I made for you if I wasn't clear enough: http://db.tt/kvaaYaLA
Note that this method is only useful if you need a static animation, not for a dynamic one.

Related

Actionscript 3 - Bitmaps and Symbols

I am working on flash professional cs5.5 and actionscript 3. I need to use symbols of customized sizes to test the hitTestOjbect() function. However, when i convert the bitmap to a symbol, by default it goes into a rectangular size and the empty space all around is also detected as part of the symbol.
Is there any way to keep the size of the symbol customized ?
That is the nature of a bitmap. Technically, bitmaps are always rectangular. Transparent areas are just fills with alpha-0. When you convert a bitmap to a symbol, the bitmap still exists, just inside the context of the symbol.
One of the fastest ways to fix this is to use a mask inside your MovieClip. Create a plain drawing object in the exact shape of the hit area you want. Then, place that on your timeline on it's own layer. Right-click the layer with the mask, click "Mask", and then drag the bitmap's layer under the mask one. Lock both layers, and exit symbol editing.
Now your hit area will be limited to only the masked area.
EDIT: I appear to be mistaken - hitTestArea is always rectangular. See the top answer to hitTestObject Collision Not Registering Correctly.

HTML5 - Canvas, layers, copy

so what I want to achieve is drawing a rectangle with either a color/fillRect or with clearRect and then copy it to the other canvas layer under the one I was drawing on. Also I want to set a background to this layer with opacity.
What I've tried is setting background with fillStyle and fillRect and it went fine. Also I could draw the rectangle with fillRect on the upper canvas which had no background and then copy the rectangle to the other one with drawImage.
Problem was when I tried to create a rectangle with clearRect and copy it. As I noticed I can only clearRect with another rectangle. But then I have to set a background to the upper canvas, which is ok, but when I copy it to the other one it gets darker and darker every time (well of course..)
So how is this possible?
When you work with alpha channel you will as you already noticed accumulate alpha channel values as long as alpha < 255. The only way to "reset" this is to start fresh so-to-speak.
Here are a couple of options to get around this -
Option 1
Don't copy anything from the draft canvas to the main canvas but store all points and shapes into a 2-dimensional array or an array consisting of the shape objects with its points, color, line width and so forth.
When you need to update the main canvas, clear both canvases and then re-render all the shapes to the main one.
Option 2
If all shapes on the main canvas is suppose to have the same opacity then use a third off-screen canvas. Draw everything to this canvas non-transparent (this last is important).
When updating main canvas clear it, set globalAlpha on it and then draw the off-screen canvas to it.
So we'll probably need some example code, because I'm not 100% sure what your trying to do... your using 2 canvas objects, drawing on the top canvas, and copying that to the bottom canvas... something like?:
ctx2.drawImage(canvas1,0,0);
then your clearing the top canvas:
ctx1.clearRect(0,0,canvas1.width,canvas1.height);
and doing your draw routine again? are you trying to get some sort of trail effect or something?

As3, OOP strategy for custom class DrawVectorLineArt

I am doing some math projects that require a lot of vector line art--that is a line drawn between to points with a circle at the start point and an arrow at the end point. A call to Math.atan2() keeps the arrow aligned. I call this class DrawVectorLineArt() and it creates instances of 2 other custom classes DrawArrow() and DrawCircle().
So far so good--DrawVectorLineArt() draws just what I need. Now I need to animate the vector art.
So in a function onEnterFrame I want to update the postion of arrow and circle, the objects created by DrawArrow() and DrawCircle(), respectively. I also need to clear and redraw the line drawn between them. At this point I am not sure how to proceed in an OOP framework. Do I need to create methods of my custorm class DrawVectorLineArt() to update the position of arrow and circle and subsequently clear and redraw the connecting line?
Any advice or links appreciated. Thanks!
"Do I need to create methods of my custorm class DrawVectorLineArt() to update the position of arrow and circle and subsequently clear and redraw the connecting line?"
Yes.
The arrow and the circle are very members of DrawVectorLineArt, and going by its name and choice of members, so should the line (if it's implemented through actual data). DrawVectorLineArt should contain and implement the whole animation between the circle, arrow, and line. As such, if the animation's supposed to be able to change after creation, the same instance of DrawVectorLineArt should be able to take any two legitimate points supplied to it (or that it becomes aware of internally, depending on what you're doing), reposition the three components, and turn the arrow and line appropriately, within its own code.

Drawing overlapping semi-transparent lines without visible overlap

I'm developing a painter program using HTML5 canvas. I have created a drawing tool where the user drags and moves the mouse.
I have a listener on mousemove event that draws short lines:
Painter.mainCanvas.beginPath();
Painter.mainCanvas.moveTo(Painter.lastX, Painter.lastY);
Painter.lastX = e.offsetX;
Painter.lastY = e.offsetY;
Painter.mainCanvas.lineTo(Painter.lastX, Painter.lastY);
Painter.mainCanvas.stroke();
Everything works well until I set the global Alpha to < 1. When using this method to draw, the end dot is also start dot. So the dot is drawn twice. And because we have transparent color, the dot now has different color with other dots in line.
I tried another method that when mousemove fires, it only uses lineTo() and stroke() when mouseup fires.
This solves the double drawing problem, but also introduces a new problem: when user intend to draw same dot twice, ie, cross line without mouseup, the dot won't be drawn twice. Because lineTo() function won't draw a dot twice without stroke between.
(Restating your problem) Your original problem was that by calling beginPath() and stroke() for each segment you had many overlapping semi-transparent paths. Your new "problem" is that by creating all your lineTo() commands as part of the same path and then calling stroke() once at the end any self-intersecting paths intended by the user do not show a visible overlap.
Here is an example showing the difference between making
many semi-transparent lines in a single path and stroking once (upper left), versus
many semi-transparent lines in distinct paths and stroking each (bottom right)
http://jsfiddle.net/jhyG5/2/
I would say that your current solution (a single path) is the correct way to do it, even though a single self-crossing path does not double-up in opacity. This is what you see in Adobe Photoshop and Illustrator when drawing semi-transparent paths: all drawing with the mouse down is part of the same, single, non-overlapping transparent object. Only when the user releases and re-presses the mouse button do you accumulate more transparency:
Two Photoshop paintbrush strokes at 50% opacity:
Two Illustrator paths at 50% opacity:
Notice in particular that the self-intersecting stroke and path do not show double the opacity during crossing, but that a separate new path does.
I recommend that you stick with your current solution given that this is how these traditional, well-thought-out applications behave. I say this both because you want your package to mimic user expectations, and also because if these packages do it like this, there's probably a very good reason for it: the exact problem you originally had! :)

HTML5 canvas - opacity problem with a paint app

I'm trying to program a paint application using Canvas.
the way it works is by connection lines when the mouse is pressed.
when the line is opaque it works well, but when I change the alpha parameter I get a problem.
I tried two options:
a. The path begins when the mouse is down for the first time and ends when the mouse is up again:
every move of the mouse calls the stroke() function. because the line is transparent the beginning of the whole path will become opaque and the end won't, because stroke() is called many times, and it drwas the whole path again and again.
b. The path begins and ends every move of the mouse:
the line is transparent through the whole way, but the matching point between every path and path are less transparent (because they're made of two lines). so the whole path is not solid.
the only way I get a good result is when I call stroke() only when the mouse is up again. then it strokes the whole path well, but I see nothing while actually drawing it.
what can I do?
thanks
I think your best bet is to create a second overlay canvas that is positioned (using absolute positioning) over your primary canvas.
During a mouse drag, for every mousemove event use a clearRect() to clear your overlay canvas and then draw the entire stroke-in-progress.
When you get a mouseup, clear the overlay and draw the entire stroke to the primary canvas.
Here's a live example:
http://jsfiddle.net/rnNFB/1/