[MX] 'Graphite'-style line fill?

This is my scenario: I have a pencil that uses the simple drawing feature. When the mouse is pressed and dragged, the pencil draws a line. Basic stuff. What i want to do is have the line be a ‘graphite’ type of color, instead of the boring black, red etc. I’m thinking that i would use a mask with the graphite color layer on the bottom, and a blank white layer on top, then when the line is drawn, the pencil is actually erasing the top layer, to reveal the bottom graphite layer. :sigh: This seems somewhat farfetched.

What would be the best approach at achieving this ‘graphite’-style line fill?
Thanks for all that took the time to read this. Take care.

Victor.

How are you drawing this line? If you are doing it via the drawing API just change the color in the lineStyle().

lineStyle(size, color, opacity);

Color is written in hex… with the prefix of “0x” (so in HTML a color could be #FF0000 but in Flash it would be 0xFF0000)

Thanks for replying LostinBeta. I am using variables to draw my line, a la:

var lineThickness = 2;
var lineColor = 0x666666;

Can i still achieve what you suggested with this method?

And also, by ‘graphite’ i mean the material used in a pencil which is composed of tiny particles with slightly different shades. So i’m not sure if altering the opacity, size, and color will solve the problem. But i’m most likely wrong. Take care.

Victor.

Ohhh, I see now. The idea I am getting is that you basically want to draw a rough line… sorta like the kind you can choose in the properties panel for a manually drawn line via the line tool? Is this correct? If so, then yeah that wouldn’t exactly be the easiest thing to pull off with AS (you could, but i’m not exactly sure how efficient something like that would be).

Yea, you are correct about the properties window line tool. So…it sounds like i’m in a little over my head, eh?

I think your idea about masking to reveal a hidden graphite texture is a good one. Just keep in mind that dynamic masks only work if you use beginFill() and endFill() - masks that are made using line drawing only won’t work.

Enclosed is a sample .fla that produces this basic effect, although my
’graphite’ picture is not very good.

Here’s the script:



_root.createEmptyMovieClip("paper_mc", 10);
graphite_mc.setMask(_root.paper_mc);
graphite_mc._alpha = 75; 

PenNib = 2; // size of nib

drawStuff = function()
{
   // draw a continuous line from last mouse position to this one

   var dx = this._xmouse - this.lx;
   var dy = this._ymouse - this.ly;
   var dist = Math.sqrt(dx*dx+dy*dy);
   var idist = Math.floor(dist);
   var vx = dx/idist;
   var vy = dy/idist;
   var x = this.lx;
   var y = this.ly;
   this.beginFill(0x000000, 100);
   for (var i = 0; i < idist; ++i) 
   {
      this.moveTo(x-PenNib, y);
      this.lineTo(x, y-PenNib);
      this.lineTo(x+PenNib, y);
      this.lineTo(x, y+PenNib);
      this.lineTo(x-PenNib, y);
      x += vx;
      y += vy;
  }
  this.endFill();
  this.lx = this._xmouse;
  this.ly = this._ymouse;
}

paper_mc.onMouseDown = function()
{
    this.lx = this._xmouse;
  this.ly = this._ymouse;
  this.onMouseMove = drawStuff;
}

paper_mc.onMouseUp = _root.mask_mc.onReleaseOutside = function()
{
  this.onMouseMove = undefined;
}
                   

  • Jim

Wow, Jbum i can’t believe my masking idea actually worked :slight_smile: But one last thing, is it possible to erase the image revealed from the mask? I’m assuming this won’t work since the “line” that is drawn isn’t actually a line.

eraseBtn.onPress = function(){
	_root.line.clear();
}

Any ideas? Thanks, Jbum.

Victor.

It’s posible to implement erasing, but it’s somewhat complicated. Currently I’m drawing a series of small diamond shapes, which represent the nib of the pen hitting the paper. After I draw them I forget about them.

If instead, as I drew them, I stored the center coordinates of each nib
in an array, then I could recreate (and modify i.e. erase parts of) the
pen ‘path’.

I’m doing something very similar to this in the spyrograph movie on my website (it keeps track of the path of the spyrograph in an array, and erases it as it goes).

The method I’m using for coloring my spyrograph might also work for a graphite effect (I’m not using a mask, but instead I’m drawing a series of colored dots). See the link in my signature…

I’ll experiment with a graphite style coloring effect in the spyrograph, and if I come up with anything, I’ll incorporate it into that movie.

  • Jim

You were speaking about this one, right?:
http://www.krazydad.com/bestiary/bestiary_spyrograph.html
If so, then that looks like a solution. I’ll work on it myself and see if i can come up with anything. Thanks for all your help and get back to me whenever you have a revelation :slight_smile:

Victor.

Yeah, that’s the one.

My spyrograph draws curve segments that are too large for the graphite effect to work (although I added an amusing ‘tiger’ button while I was playing with changing the colors).

The basic technique of storing coordinates in an array might work for you, but otherwise, the techniques in the movie aren’t that relevant.

Is your intent to provide the user a separate mouse-driven pencil tool and erase tool, like a paint program?

Or do you wish to animate a pencil drawing something ?

Or do you want a combination of the two? The user draws something, and then you produce an animated pencil-drawing which has a trailing edge which erases?

  • Jim

My drawing situation is somewhat complicated. Mike from the FlashKit forums helped me create this navigation system that detects whether a circle is drawn around a movieclip, then loads a .swf into an empty movieclip. You honestly need to see the AS in action in order to fully comprehend what the situation is. However, the zip is too large to upload here at the forums, can i email it to you instead? Take care.

Victor.

Yeah, send it if you like - my email is on the bottom of each page of my site.

Or just post a link to a sample swf.

O.K. sent to email…hopefully the zipfile was attached, Lycos.com is pretty flakey when it comes to that :slight_smile: Take care.

Victor.

Got it, i’ll take a look tomorrow after caffeine.

  • Jim

Alright, sounds good. I’ll await your response back. And again, thanks for helping out. Take care.

Victor.

Using clear() works just fine for erasing the stuff that is drawn in the mask. A simple trick you can use if you want to do partial erases, it to make a mask which contains multiple clips on multiple layers. If each pen stroke is drawn on a different sub-clip in the mask, then you can erase the strokes individually.

The movie you sent seems to be working fine…

hm, i’m not really following Jbum…How do i implement your masking effect and clear effect into my existing movie?

Victor.

Sorry, still not sure what you want. Are you saying that you want the pencil stroke to erase itself in the same way that my spyrograph does? following the path of the stroke? As if you were writing in invisible ink?

Yes, a very slow invisible ink would work. But keeping in mind the .fla i sent you, will the detection of the circle drawn around the movieclip, and loads a .swf, still function alright with this new masking alteration we’re adding to it?

Victor.

Yeah, I think this will work. Here’s a modified version of the script in my original ‘graphite’ movie from a few posts ago. The pen points are stored in an array, which is drawn from the onEnterFrame handler. It uses splice() to eat away at the beginning of the line. There are some variables at the top which you can tweak.


_root.createEmptyMovieClip("paper_mc", 10);
graphite_mc.setMask(_root.paper_mc);
graphite_mc._alpha = 75; 

PenNib = 2; // size of nib
writeDetail = 2; // higher numbers make movie more responsive
                 // lower numbers look more realistic
eraseSpeed = 3;				 

stroke = []; // stores pen-stroke

paper_mc.onEnterFrame = function()
{
	this.clear();
	var len = stroke.length;
	if (len) {
		this.beginFill(0x000000, 100);
		for (var i = 0 ; i < len; ++i)
		{
			var x = stroke*.x;
			var y = stroke*.y;
			this.moveTo(x-PenNib, y);
			this.lineTo(x, y-PenNib);
			this.lineTo(x+PenNib, y);
			this.lineTo(x, y+PenNib);
			this.lineTo(x-PenNib, y);
		}
		this.endFill();
		stroke.splice(0,eraseSpeed); // eat the beginning of the stroke
	}
}

drawStuff = function()
{
   // draw a continuous line from last mouse position to this one

   var dx = this._xmouse - this.lx;
   var dy = this._ymouse - this.ly;
   var dist = Math.sqrt(dx*dx+dy*dy);
   var idist = Math.floor(dist);
   var vx = dx/idist;
   var vy = dy/idist;
   var x = this.lx;
   var y = this.ly;
   for (var i = 0; i < idist; i += writeDetail) 
   {
	   stroke.push({x:x, y:y});
	   x += vx*writeDetail;
	   y += vy*writeDetail;
	}
	this.lx = this._xmouse;
	this.ly = this._ymouse;
}

paper_mc.onMouseDown = function()
{
    this.lx = this._xmouse;
	this.ly = this._ymouse;
	this.onMouseMove = drawStuff;
}

paper_mc.onMouseUp = _root.mask_mc.onReleaseOutside = function()
{
	this.onMouseMove = undefined;
}
									 

If I can integrate this easily with your movie, I’ll post that code later…
I have no clue how you’re planning on detecting your circle- did you do that already?

EDIT:

Ah yeah, looking at your movie, I see you’re already storing the points in path - I can just use that… Pretty simple mod really…