Warp Lines
Lines that repeats the user gesture and warps around the canvas
/**
* Copyright will_costa ( http://wonderfl.net/user/will_costa )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/hJFx
*/
package {
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
/**
* @author Will Costa
* @author http://www.willcosta.net
*/
[SWF(backgroundColor="#000000", frameRate="60", width="465", height="465")]
public class Snakes2 extends Sprite {
private var _maxLines:int = 6;
private var _currentLine : Line;
private var _lines : Vector.<Line>;
private var _canvas : WarpBitmapData;
public function Snakes2() {
Wonderfl.capture_delay(15);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
graphics.beginFill(0x000000);
graphics.drawRect(0,0,465,465);
_lines = new Vector.<Line>();
_canvas = new WarpBitmapData(465, 465, true, 0);
addChild(new Bitmap(_canvas));
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
}
//----------------------------------
// Event Handlers
//----------------------------------
private function onMouseDownHandler(event : MouseEvent) : void {
_currentLine = new Line();
_currentLine.addPoint(mouseX, mouseY);
_lines.push(_currentLine);
if(_lines.length > _maxLines) _lines.shift();
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
}
private function onMouseMoveHandler(event : MouseEvent) : void {
_currentLine.addPoint(mouseX, mouseY);
}
private function onMouseUpHandler(event : MouseEvent) : void {
_currentLine.finished = true;
_currentLine = null;
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
}
private function onEnterFrameHandler(event : Event) : void {
_canvas.fillRect(_canvas.rect, 0);
graphics.clear();
graphics.lineStyle(1, 0xff0000);
for each (var line : Line in _lines) {
line.render();
_canvas.drawWarp(this,line);
}
}
}
}
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Rectangle;
class Line extends Sprite {
public var finished : Boolean = false;
private var _vertices : Vector.<Vertex>;
private var jumpDx : Number;
private var jumpDy : Number;
public function Line() {
_vertices = new Vector.<Vertex>();
}
public function addPoint(x : Number,y : Number) : void {
var vert : Vertex = new Vertex(x, y, 0);
_vertices.push(vert);
if (numVertices > 1) {
jumpDx = _vertices[0].x - _vertices[numVertices - 1].x;
jumpDy = _vertices[0].y - _vertices[numVertices - 1].y;
}
}
private function advanceLine() : void {
var jx : Number = jumpDx;
var jy : Number = jumpDy;
if (numVertices > 0) {
for (var i : int = 0;i < numVertices-1;i++) {
_vertices[i].x = _vertices[i + 1].x;
_vertices[i].y = _vertices[i + 1].y;
}
_vertices[numVertices-1].x = _vertices[0].x - jx;
_vertices[numVertices-1].y = _vertices[0].y - jy;
}
}
private function updatePressures() : void {
var pressure : Number;
var t : Number = 0;
var u : Number = 1.0 / (_vertices.length - 1) * (2 * Math.PI);
for (var i : int = 0;i < _vertices.length;i++) {
pressure = Math.sqrt((1.0 - Math.cos(t)) * 0.5);
_vertices[i].p = pressure;
t += u;
}
}
private function smooth() : void {
var weight : Number = 15;
var scale : Number = 1.0 / (weight + 2);
var lower : Vertex;
var center : Vertex;
var upper : Vertex;
for (var i : int = 1;i < numVertices-2;i++) {
lower = _vertices[i - 1];
center = _vertices[i];
upper = _vertices[i + 1];
center.x = (lower.x + weight * center.x + upper.x) * scale;
center.y = (lower.y + weight * center.y + upper.y) * scale;
}
}
public function render() : void {
if(finished) {
advanceLine();
} else {
smooth();
updatePressures();
}
var v : Vertex = _vertices[0];
graphics.clear();
graphics.moveTo(v.x, v.y);
graphics.lineStyle(v.p * 10, 0xFFFFFF);
graphics.lineTo(v.x, v.y);
for (var i : int = 0;i < numVertices;i++) {
v = _vertices[i];
graphics.lineStyle(v.p * 8, 0xFFFFFF);
graphics.lineTo(v.x, v.y);
}
}
public function get numVertices() : int {
return _vertices.length;
}
}
internal class Vertex {
public var x : Number = 0;
public var y : Number = 0;
public var p : Number = 0;
public function Vertex(x : Number, y : Number, p : Number) {
this.x = x;
this.y = y;
this.p = p;
}
}
internal class WarpBitmapData extends BitmapData{
public function WarpBitmapData(width:Number, height:Number, transparent:Boolean = true, fillColor:uint = 0){
super(width, height, transparent, fillColor);
}
public function drawWarp(area:Sprite,source:DisplayObject):void{
var bounding:Rectangle = source.getBounds(area);
var m:Matrix;
var w:Number = width;
var h:Number = height;
var pos:Array = [{x:0,y:0},{x:-w,y:-h},{x:0,y:-h},{x:w,y:-h},{x:w,y:0},{x:w,y:h},{x:0,y:h},{x:-w,y:h},{x:-w,y:0}];
var n : int = pos.length;
for (var i : int = 0;i < n;i++) {
m = source.transform.matrix.clone();
m.tx += pos[i].x;
m.ty += pos[i].y;
draw(source, m);
}
if(bounding.x > width) {
source.x -= width;
}else if(bounding.x < -bounding.width) {
source.x += width;
}
if(bounding.y > height) {
source.y -= height;
}else if(bounding.y < -bounding.height){
source.y += height;
}
}
}