In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

line expander

Expands a series of points to a wider line.
Get Adobe Flash player
by grapefrukt 14 Dec 2010
/**
 * Copyright grapefrukt ( http://wonderfl.net/user/grapefrukt )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/4qXM
 */

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	/**
	 * ...
	 * @author Martin Jonasson (m@grapefrukt.com)
	 */
	public class Main extends Sprite {
		
		static private const LINE_WIDTH	:Number = 20;
		private var _animation_offset	:int = 0;
		private var _nodes		:Vector.<Point>;
		
		public function Main():void {
			// create a list with a bunch of points
			_nodes = new Vector.<Point>();
			for (var i:int = 0; i < 20; i++) _nodes.push(new Point);
			
			addEventListener(Event.ENTER_FRAME, handleEnterFrame)
		}
		
		private function handleEnterFrame(e:Event):void {
			var i:int = 0;
			
			// step the animation forward
			_animation_offset += 4;
			
			// move the nodes
			for (i = 0; i < _nodes.length; i++) {
				_nodes[i].x = 50 + 20 * (i);
				_nodes[i].y = 250 + Math.sin((_animation_offset + i * 40) / 100) * 150;
			}
			
			// two lists for coordinates, one for each side of the line			
			var coords1:Vector.<Point> = new Vector.<Point>();
			var coords2:Vector.<Point> = new Vector.<Point>();
			
			// step over all coords in the list
			for (i = 0; i < _nodes.length; i++) {
				
				// calculate the position relative to the previous segment
				var angle_prev:Point = new Point;
				if (i > 0) {
					angle_prev.x = _nodes[i - 1].x - _nodes[i].x; 
					angle_prev.y = _nodes[i - 1].y - _nodes[i].y;
				
				// if this is the first segment we use the angle to the next segment instead
				} else {
					angle_prev.x = _nodes[i].x - _nodes[i + 1].x;
					angle_prev.y = _nodes[i].y - _nodes[i + 1].y;
				}
				
				// and again the relative position compared to the next segment
				var angle_next:Point = new Point;
				if (i < _nodes.length - 1) {
					angle_next.x = _nodes[i + 1].x - _nodes[i].x; 
					angle_next.y = _nodes[i + 1].y - _nodes[i].y;
				
				// if this is the last segment we look back at the previous segment instead
				// this and the previous else-block could be skipped since they will give the same
				// results for both angle_next and angle_prev, but i'm keeping them to make the later
				// parts of the function simpler
				} else {
					angle_next.x = _nodes[i].x - _nodes[i - 1].x; 
					angle_next.y = _nodes[i].y - _nodes[i - 1].y;
				}
				
				// then we normalize the points to a lenght of one, since we only 
				// really care about the angle not the distance. 
				angle_prev.normalize(1);
				angle_next.normalize(1);
				
				// now we use the current node's position as a starting 
				// point adding in the average of the two angle offsets
				// we calculated. by inverting and swapping the x/y 
				// values we rotate the angle by 90 degrees to get a line 
				// that extends from the side of the line instead of alongside it. 
				// we multiply that vector by the desired line width
				var p1:Point = new Point;
				p1.x = _nodes[i].x + ((-angle_next.y+angle_prev.y) / 2) * LINE_WIDTH;
				p1.y = _nodes[i].y + ((+angle_next.x-angle_prev.x) / 2) * LINE_WIDTH;
				
				var p2:Point = new Point;
				// then the same procedure for the other side
				p2.x = _nodes[i].x + ((+angle_next.y-angle_prev.y) / 2) * LINE_WIDTH;
				p2.y = _nodes[i].y + ((-angle_next.x+angle_prev.x) / 2) * LINE_WIDTH;
				
				// then add the two coordinates to the lists
				coords1.push(p1);
				coords2.push(p2);
			}
			
			// clear the graphics and get ready for drawing the next frame
			graphics.clear();
			graphics.lineStyle();
			graphics.beginFill(Math.random()*0xffffff);
			
			// move the draw head to the first coord in the list
			graphics.moveTo(coords1[0].x, coords1[0].y);
			
			// start by doing lines along one side
			for (i = 0; i < coords1.length; i++) {
				graphics.lineTo(coords1[i].x, coords1[i].y);
			}
			
			// and then draw the other side in reverse to get a fill that goes around the shape
			for (i = coords2.length - 1; i >= 0; i--) {
				graphics.lineTo(coords2[i].x, coords2[i].y);
			}
			
			graphics.endFill();
			
			// finally draw the center line
			graphics.lineStyle(3, 0);
			graphics.moveTo(_nodes[0].x, _nodes[0].y);
			for (i = 1; i < _nodes.length; i++) {
				graphics.lineTo(_nodes[i].x, _nodes[i].y);
			}
		}
		
	}
	
}