[MX] 'Graphite'-style line fill?

That line-fading is very nifty :pleased: Thanks a lot Jbum. And yes, i have already made the AS for the detection of the circle drawn. If you still have the .fla i sent to your email, you can see it in action. Draw a circle around the “portfolio” text, and a .swf should load on the mainstage. I’ll work on implementing your code into my current code and see if anything works. Could you also do the same possibly? Thanks, Jbum:)

If you happen to need the .fla again, i can send it to you again.

Victor.

Not so simple to the average joe like myself though, Jbum :slight_smile: I guess i’ll just wait patiently while you work your magic.

Victor.

Yes, I saw it. Here’s a modified version of YOUR script, with the line erasing added. The circle detection still appears to work. Use a larger number with the splice if you want a faster erase.


// *******************************************************\
// Detect whether a drawn path encircles one or more points.
// Any movieclip in the movieclip called "iconPanel" will
// be tested, and corresponding .swf will be loaded.  E.g.,
// if an icon called "bill" is circled, then "bill.swf" will be
// loaded into a holder movieclip.
// 
// Michael J. Kantor 2004.03.21
// \*******************************************************
// set line thickness and color here
var lineThickness = 2;
var lineColor = 0x000000;
isDrawing = false;
pencil._visible = false;
var canvas = iconPanel.createEmptyMovieClip("canvas", 1);


writeDetail = 2; // higher numbers make movie more responsive, but make pencil path jaggier

// jim note: we create path at the beginning, and keep it around
canvas.path = [];

// jim note: this function is new - it draws the current path, and erases line
canvas.onEnterFrame = function()
{
	this.clear();
	this.lineStyle(lineThickness, lineColor);
	var len = this.path.length;
	if (len) {
		this.moveTo(this.path[0].x, this.path[0].y);
		for (var i = 1 ; i < len; ++i) {
			if (this.path*.startStroke != undefined)
				this.moveTo(this.path*.x,this.path*.y);
			else
				this.lineTo(this.path*.x,this.path*.y);
		}
		this.path.splice(0,1); // eat the beginning of the stroke
	}
}

// jim note: This function has been modified - it no longer draws, just
// adds points to the path.  We know use a small increment than 10 for
// writeDetail, because we're gonna view the path and we want it to look nice.

canvas.onMouseDown = function() {
	if (!isDrawing) {
		return;
	}
	if (!iconPanel.hitTest(_root._xmouse, _root._ymouse, true)) {
		return;
	}
	var currX = this._xmouse;
	var currY = this._ymouse;
	this.path.push({x:currX, y:currY,startStroke:1});
	// add point to path
	this.onMouseMove = function() {
		// record only movements of more than 10 pixels
		if (Math.abs(this._xmouse-currX)<writeDetail && Math.abs(this._ymouse-currY)<writeDetail) {
			return;
		}
		// update position and add point to path
		currX = this._xmouse;
		currY = this._ymouse;
		this.path.push({x:currX, y:currY});
	};
};
canvas.onMouseUp = function() {
	delete this.onMouseMove;
	if (!iconPanel.hitTest(_root._xmouse, _root._ymouse, false)) {
		return;
	}
	var iconX, iconY, point, theIcon;
	for (var icon in iconPanel) {
		theIcon = iconPanel[icon];
		// the icon being tested
		iconX = theIcon._x;
		iconY = theIcon._y;
		point = {x:iconX, y:iconY};
		if (this.isEncircled(point)) {
			// Here's where the action takes place when an icon has
			// been circled.  Here, we call the play() method of the
			// icon, and also call a custom function which loads a
			// .swf file.  We pass the instance name of the icon to
			// the movie-loading function.
			theIcon.play();
			loadAMovie(theIcon._name);
			break; // load only ONE movie, even if multiple items circled
		}
	}
};
// test whether the points in this.path encircle given point
canvas.isEncircled = function(point) {
	var x, y, angle, prevAngle, windingChange, p;
	var bx = point.x;
	var by = point.y;
	windingNumber = 0;
	// how many times around the point we wind
	// get initial angle from icon to mouse position
	p = this.path[0];
	x = p.x;
	y = p.y;
	prevAngle = Math.atan2(y-by, x-bx);
	// now follow the path, keeping track of the winding number
	for (var i = 1; i<canvas.path.length; i++) {
		p = this.path*;
		x = p.x;
		y = p.y;
		angle = Math.atan2(y-by, x-bx);
		windingChange = (angle-prevAngle)/(2*Math.PI);
		prevAngle = angle;
		// adjust for the sudden jumps between -180 and 180 degrees
		windingChange -= Math.round(windingChange);
		windingNumber += windingChange;
	}
	// it counts if it's almost all the way around
	if (Math.abs(windingNumber)>.8) {
		return true;
	}
	return false;
};
pencil.onMouseMove = function() {
	if (iconPanel.hitTest(_root._xmouse, _root._ymouse, false)) {
		isDrawing = true;
		this._visible = true;
		Mouse.hide()
		canvas.lineStyle(lineThickness, lineColor);
	} else {
		isDrawing = false;
		this._visible = false;
		Mouse.show()
		canvas.lineStyle(lineThickness, lineColor, 0);
		return;
	}
	this._x = _root._xmouse;
	this._y = _root._ymouse;
};
// This function gets called when an icon is encircled.
// The incoming parameter movieName is the instance name of
// the icon that was circled.
loadAMovie = function (movieName) { 
	if (_root.holder == null) {
		_root.createEmptyMovieClip("holder", _root.getNextHighestDepth());
	}
// these lines set the position of the loaded movie
	holder._x = 100;   
	holder._y = 200;
	holder.loadMovie("http://us.a1.yimg.com/us.yimg.com/a/1-/flash/hp/pb/" + movieName + ".swf"); 
}

// diagnostic routine to list things that will be tested for circling
trace("iconPanel : " + iconPanel);
for(var m in iconPanel) {
	trace("	" + iconPanel[m]);
}

Excellent, so for the ‘graphite’ line fill i would just add the graphite image above the notepad image?

I think so. There are other differences as well. In your script, I’m simply using moveTos and lineTos. In the Graphite version, I’m drawing little diamonds with fills - I have to do that in the graphite version because masks only work with filled shapes, you can’t just use lineTos in a dynamic mask.

The other difference is that in my version I’m actually doing a kind of line-draw from point-to-point to make the path continuous, as I add the points to the stroke. You can probably leave that out.

But, assuming you replace the lineto code with a little diamond-shaped fill, you basically want to chance it so that your ‘canvas’ is your mask. You’ll see in my script, the ‘paper_mc’ movie I’m drawing into is the mask, and has a higher layer number than the graphite movie (the graphite movie does a setMask() on it).

  • Jim