Archive for December 2010 - Purple Squirrels

I found a Jackson Pollock style painting example written in AS2 called ‘Splatter’ over at stamen.com. I wanted to include a Pollock style brush in my painting application so I converted it into AS3. Just copy and past the following code into a new AS3 document in Flash.
import flash.events.MouseEvent;
import flash.display.MovieClip;
//set up some vars
var new_size_influence:Number = 0.5;
var mid_point_push:Number = 0.75;
var max_line_width:Number = (Math.random() * 50) + 50;
//vars for line colour and alpha
var _colour:uint = 0x000000;
var _alpha:Number = 1;
//create var to hold all mouse position data
var obj:Object = new Object();
obj.x = 0;
obj.y = 0;
obj.start_x = obj.mid_x = obj.end_x = (stage.stageWidth / 2);
obj.start_y = obj.mid_y = obj.end_y = (stage.stageHeight / 2);
obj.size = 0;
//add mouse down event listener
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
function onDown(e:MouseEvent):void
{
//create random colour
_colour = Math.random()*0xFFFFFF;
//set all line data to current mouse position
obj.start_x = obj.mid_x = obj.end_x = mouseX;
obj.start_y = obj.mid_y = obj.end_y = mouseY;
//add mouse up and mouse move event listeners
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
function onUp(e:MouseEvent):void
{
//remove mouse up and mouse move event listeners
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
}
function onMove(e:MouseEvent):void
{
//find the mid point between current and last mouse position
obj.mid_x = ((obj.end_x - obj.start_x) * (1 + mid_point_push)) + obj.start_x;
obj.mid_y = ((obj.end_y - obj.start_y) * (1 + mid_point_push)) + obj.start_y;
//set start to last point
obj.start_x = obj.end_x;
obj.start_y = obj.end_y;
//set end to current point
obj.end_x = mouseX;
obj.end_y = mouseY;
//get distance between start and end point
var distance:Number = Math.sqrt(Math.pow((obj.end_x - obj.start_x), 2) + Math.pow((obj.end_y - obj.start_y), 2));
//set size depending on distance
var new_size:Number = max_line_width / distance;
obj.size = (new_size_influence * new_size) + ((1 - new_size_influence) * obj.size);
//draw the line
graphics.lineStyle(obj.size,_colour,_alpha);
graphics.moveTo(obj.start_x, obj.start_y);
graphics.curveTo(obj.mid_x, obj.mid_y, obj.end_x, obj.end_y);
// splotch
var dd:Number = Math.sqrt(Math.pow((obj.end_x - obj.start_x), 2) + Math.pow((obj.end_y - obj.start_y), 2));
for (var i:int = 0; i<Math.floor(5*Math.pow(Math.random(), 4)); i++)
{
// positioning of splotch varies between ±4dd, tending towards 0
var splat_range:int = 1;
var x4:Number = dd * 1 * (Math.pow(Math.random(), splat_range) - (splat_range/2));
var y4:Number = dd * 1 * (Math.pow(Math.random(), splat_range) - (splat_range/2));
// direction of splotch varies between ±0.5
var x5:Number = Math.random() - 0.5;
var y5:Number = Math.random() - 0.5;
var d_:Number = obj.size*(0.5+Math.random());
//draw the splotches
graphics.lineStyle(d_, _colour, _alpha);
graphics.moveTo((obj.start_x+x4), (obj.start_y+y4));
graphics.lineTo((obj.start_x+x4+x5), (obj.start_y+y4+y5));
}
}
import flash.display.MovieClip;
//set up some vars
var new_size_influence:Number = 0.5;
var mid_point_push:Number = 0.75;
var max_line_width:Number = (Math.random() * 50) + 50;
//vars for line colour and alpha
var _colour:uint = 0x000000;
var _alpha:Number = 1;
//create var to hold all mouse position data
var obj:Object = new Object();
obj.x = 0;
obj.y = 0;
obj.start_x = obj.mid_x = obj.end_x = (stage.stageWidth / 2);
obj.start_y = obj.mid_y = obj.end_y = (stage.stageHeight / 2);
obj.size = 0;
//add mouse down event listener
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
function onDown(e:MouseEvent):void
{
//create random colour
_colour = Math.random()*0xFFFFFF;
//set all line data to current mouse position
obj.start_x = obj.mid_x = obj.end_x = mouseX;
obj.start_y = obj.mid_y = obj.end_y = mouseY;
//add mouse up and mouse move event listeners
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
function onUp(e:MouseEvent):void
{
//remove mouse up and mouse move event listeners
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
}
function onMove(e:MouseEvent):void
{
//find the mid point between current and last mouse position
obj.mid_x = ((obj.end_x - obj.start_x) * (1 + mid_point_push)) + obj.start_x;
obj.mid_y = ((obj.end_y - obj.start_y) * (1 + mid_point_push)) + obj.start_y;
//set start to last point
obj.start_x = obj.end_x;
obj.start_y = obj.end_y;
//set end to current point
obj.end_x = mouseX;
obj.end_y = mouseY;
//get distance between start and end point
var distance:Number = Math.sqrt(Math.pow((obj.end_x - obj.start_x), 2) + Math.pow((obj.end_y - obj.start_y), 2));
//set size depending on distance
var new_size:Number = max_line_width / distance;
obj.size = (new_size_influence * new_size) + ((1 - new_size_influence) * obj.size);
//draw the line
graphics.lineStyle(obj.size,_colour,_alpha);
graphics.moveTo(obj.start_x, obj.start_y);
graphics.curveTo(obj.mid_x, obj.mid_y, obj.end_x, obj.end_y);
// splotch
var dd:Number = Math.sqrt(Math.pow((obj.end_x - obj.start_x), 2) + Math.pow((obj.end_y - obj.start_y), 2));
for (var i:int = 0; i<Math.floor(5*Math.pow(Math.random(), 4)); i++)
{
// positioning of splotch varies between ±4dd, tending towards 0
var splat_range:int = 1;
var x4:Number = dd * 1 * (Math.pow(Math.random(), splat_range) - (splat_range/2));
var y4:Number = dd * 1 * (Math.pow(Math.random(), splat_range) - (splat_range/2));
// direction of splotch varies between ±0.5
var x5:Number = Math.random() - 0.5;
var y5:Number = Math.random() - 0.5;
var d_:Number = obj.size*(0.5+Math.random());
//draw the splotches
graphics.lineStyle(d_, _colour, _alpha);
graphics.moveTo((obj.start_x+x4), (obj.start_y+y4));
graphics.lineTo((obj.start_x+x4+x5), (obj.start_y+y4+y5));
}
}
30 DEC

After seeing the Wii Spray demo videos a year or so ago I have since been wondering how they did the stencils. I couldn’t find any information on how to achieve an effect like paint stenciling so today I decided to give it a shot myself. Below is a small demo where you can have a go and spraying some stencils. Instructions are in the bottom left corner. Here is how it works:
Layers (top to bottom):
- Draw Layer Bitmap – contains BitmapData where the spray paint is drawn
- Stencil MovieClip – the stencil you see on screen containing artwork with transparency
- Stencil BitmapData – stencil is drawn to this bitmap data (not added to display list)
- Canvas Bitmap – where final artwork is drawn to
The process
- when stencil is moved and placed somewhere, the Stencil BitmapData is filled with red, then the Stencil MovieClip is drawn on top.
- you then paint with the mouse – paint is drawn to Draw Layer Bitmap
- on mouse up a Temporary BitmapData is created
- it then loops through all pixels in Stencil BitmapData – if pixel is Red: copy corresponding pixel from Draw Layer Bitmap to Temporary BitmapData
- when the loop is complete draw the Temporary BitmapData to the Canvas BitmapData
- Draw Layer Bitmap is then cleared
