forked from: forked from: forked from: forked from: INK BLEED
forked from forked from: forked from: forked from: INK BLEED (diff: 7)
few changes form forked
ActionScript3 source code
/**
* Copyright aobyrne ( http://wonderfl.net/user/aobyrne )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/nfEq
*/
package
{
import flash.display.BlendMode;
import flash.display.Graphics;
import flash.display.Sprite;
[SWF(width=465, height=465, frameRate=30)]
/**
* <p>Ink Bleed</p>
* @author monoDreamer, aka ryo
* @langversion ActionScript 3.0
* @playerversion Flash 10.2+
* @see
*/
public class InkBleedRectangleClient extends Sprite
{
public function InkBleedRectangleClient()
{
var tejido:Sprite = (new Tejido) as Sprite;
var inkBleed:InkBleedEmbeded = new InkBleedEmbeded(tejido);
//inkBleedRectangleEmbeded.blendMode = BlendMode.HARDLIGHT
addChild(inkBleed);
//addChild(tejido);
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.ColorTransform;
import flash.geom.Point;
import flash.utils.Timer;
import net.hires.debug.Stats;
import flash.display.Sprite;
class InkBleedEmbeded extends Sprite
{
//----------------------------------------------------------------
// Properties
//----------------------------------------------------------------
//----------------------------------------------------------------
// Getter/Setter Method
//----------------------------------------------------------------
//----------------------------------------------------------------
// Public method
//----------------------------------------------------------------
//----------------------------------------------------------------
// Protected Method
//----------------------------------------------------------------
protected function timerHandler($e:TimerEvent):void
{
var i:int = _pnum;
while (--i>-1) {
_dots[i].diffuse();
}
}
protected function render($e:Event):void
{
var d:Dot, i:int, c:uint;
if (_isMouseDown) {
i = _px + _py * _cw;
_dots[i].cur += 0x2f0;
}
i = _pnum;
while (--i>-1) {
c = _dots[i].cur;
_canvasData[i] = (c > 0xff ? 0xff : c) << 24;
}
_canvas.setVector(_canvas.rect, _canvasData);
}
protected function downHandler($e:MouseEvent):void
{
var mx:int = stage.mouseX>>DX, my:int = stage.mouseY>>DY;
if (_canvas.rect.contains(mx, my)) {
_px = mx;
_py = my;
_isMouseDown = true;
stage.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
}
}
protected function moveHandler($e:MouseEvent):void
{
if(_isMouseDown) {
var mx:int = stage.mouseX>>DX, my:int = stage.mouseY>>DY;
if (_canvas.rect.contains(mx, my))
{
t_efla(_px, _py, mx, my, 0x1ff);
_px = mx;
_py = my;
}
}
}
protected function upHandler($e:MouseEvent):void
{
_isMouseDown = false;
stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
}
protected function t_efla($sx:int, $sy:int, $ex:int, $ey:int, $color:uint):void
{
var shortLen:int = $ey - $sy;
var longLen:int = $ex - $sx;
if (!longLen) if (!shortLen) return;
var i:int, id:int, inc:int;
var multDiff:Number;
var idx:int;
// TODO: check for this above, swap x/y/len and optimize loops to ++ and -- (operators twice as fast, still only 2 loops)
if ((shortLen ^ (shortLen >> 31)) - (shortLen >> 31) > (longLen ^ (longLen >> 31)) - (longLen >> 31)) {
if (shortLen < 0) {
inc = -1;
id = -shortLen & 3;
} else {
inc = 1;
id = shortLen & 3;
}
multDiff = !shortLen ? longLen : longLen / shortLen;
if (id) {
idx = $sx + $sy*_cw;
_dots[idx].cur += $color;
i += inc;
if (--id) {
idx = roundPlus($sx + i * multDiff) + ($sy + i)*_cw;
_dots[idx].cur += $color;
i += inc;
if (--id) {
idx = roundPlus($sx + i * multDiff) + ($sy + i)*_cw;
_dots[idx].cur += $color;
i += inc;
}
}
}
while (i != shortLen) {
idx = roundPlus($sx + i * multDiff) + ($sy + i) * _cw;
_dots[idx].cur += $color;
i += inc;
idx = roundPlus($sx + i * multDiff) + ($sy + i) * _cw;
_dots[idx].cur += $color;
i += inc;
idx = roundPlus($sx + i * multDiff) + ($sy + i) * _cw;
_dots[idx].cur += $color;
i += inc;
idx = roundPlus($sx + i * multDiff) + ($sy + i) * _cw;
_dots[idx].cur += $color;
i += inc;
}
}
else {
if (longLen < 0) {
inc = -1;
id = -longLen & 3;
} else {
inc = 1;
id = longLen & 3;
}
multDiff = !longLen ? shortLen : shortLen / longLen;
if (id) {
idx = $sx + $sy * _cw;
_dots[idx].cur += $color;
i += inc;
if (--id) {
idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
_dots[idx].cur += $color;
i += inc;
if (--id) {
idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
_dots[idx].cur += $color;
i += inc;
}
}
}
while (i != longLen) {
idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
_dots[idx].cur += $color;
i += inc;
idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
_dots[idx].cur += $color;
i += inc;
idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
_dots[idx].cur += $color;
i += inc;
idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
_dots[idx].cur += $color;
i += inc;
}
}
}
protected function roundPlus($value:Number):int {
return ($value + BIG_ENOUGH_ROUND) - BIG_ENOUGH_INT;
}
//----------------------------------------------------------------
// Private Method
//----------------------------------------------------------------
/** Constructor */
public function InkBleedEmbeded(vectorCanvas:Sprite):void
{
this.vectorCanvas = vectorCanvas;
//super();
_cw = 200
_ch = 200;
_pnum = _cw * _ch;
if (stage) init();
else (addEventListener(Event.ADDED_TO_STAGE, doInit));
}
private function doInit(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, doInit);
init();
}
/** Initialize */
private function init():void
{
initTimer();
initDots();
initCanvas();
addListeners();
_timer.start();
}
private function initTimer():void
{
_timer = new Timer(100);
_timer.addEventListener(TimerEvent.TIMER, timerHandler);
}
private function initCanvas():void
{
_canvas = new BitmapData(_cw, _ch, true, 0);
_canvasData = _canvas.getVector(_canvas.rect);
_canvasData.fixed = true;
var map:BitmapData = new BitmapData(_cw * SCX, _ch *SCY);
map.perlinNoise(map.width * .4, map.height * .4, 8, Math.random()*100, true, true, 1, true);
var bmp:Bitmap = new Bitmap(_canvas);
bmp.smoothing = true;
bmp.scaleX = SCX;
bmp.scaleY = SCY;
bmp.filters = [new DisplacementMapFilter(map, new Point(), 1, 1, 32, 32, DisplacementMapFilterMode.CLAMP)];
addChild(bmp);
graphics.lineStyle(1);
graphics.drawRect(0, 0, _cw * SCX, _ch * SCY);
var stat:Stats = new Stats();
stat.x = 400;
addChild(stat);
}
private function addListeners():void
{
addEventListener(Event.ENTER_FRAME, render);
stage.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
}
private function initDots():void
{
var absorbMap:BitmapData = new BitmapData(_cw, _ch, false, 0);
absorbMap.perlinNoise(_cw/2, _ch/2, 5, 100*Math.random(), true, true, 1, true);
absorbMap.colorTransform(absorbMap.rect, new ColorTransform(.2, .2, .2));
var maxCapMap:BitmapData = new BitmapData(_cw, _ch, false, 0xffffff);
maxCapMap.perlinNoise(_cw, _ch, 5, 100 * Math.random(), true, true, 1, true);
maxCapMap.colorTransform(maxCapMap.rect, new ColorTransform(1.8, 1.8, 1.8));
var d:Dot, i:int = _pnum;
_dots = new Vector.<Dot>(_pnum, true);
while(--i>-1) {
_dots[i] = new Dot();
}
var neighbors:Array;
for (var my:int=0; my<_ch; my++)
{
for (var mx:int=0; mx<_cw; mx++)
{
i = mx + my*_cw;
d = _dots[i];
neighbors = [];
d.abs = absorbMap.getPixel(mx, my) & 0xff;
d.max = maxCapMap.getPixel(mx, my) & 0xff;
if (mx>0) neighbors.push(_dots[i-1]);
if (mx<_cw-1) neighbors.push(_dots[i+1]);
if (my>0) neighbors.push(_dots[i-_cw]);
if (my<_ch-1) neighbors.push(_dots[i+_cw]);
d.setNeighbors(neighbors);
}
}
var bitmapData:BitmapData = new BitmapData(_cw, _ch,false,0);
bitmapData.draw(vectorCanvas);
var bitmap:Bitmap = new Bitmap(bitmapData);
//addChild(bitmap);
var vector:Vector.<uint> = bitmapData.getVector(bitmapData.rect);
var k:int = _pnum;
while (--k > -1) {
_dots[k].cur = (vector[k] & 0xff) ? 200 + uint(400 * (vector[k] & 0xff) / 255):0;
}
}
private const BIG_ENOUGH_INT:int = 16 * 1024;
private const BIG_ENOUGH_ROUND:Number = BIG_ENOUGH_INT + 0.5;
private const SCX:int = 2;
private const SCY:int = 2;
private var DX:int = 1;
private var DY:int = 1;
private var _canvasData:Vector.<uint>;
private var _canvas:BitmapData;
private var _pnum:int;
private var _dots:Vector.<Dot>;
private var _cw:int;
private var _ch:int;
private var _px:int;
private var _py:int;
private var _isMouseDown:Boolean;
private var vectorCanvas:Sprite;
private var _timer:Timer;
}
class Dot
{
public var max:uint;
public var cur:uint;
public var abs:uint;
public var isOver:Boolean;
public function setNeighbors($neighbors:Array):void
{
_neighbors = Vector.<Dot>($neighbors);
_neighbors.fixed = true;
_len = _neighbors.length;
}
public function diffuse():void
{
if (cur <= max) return;
isOver = true;
var d:Dot, l:int = _len;
while (--l > -1) {
d = _neighbors[l];
if (d.isOver|| cur<d.abs) continue;
d.cur += d.abs;
}
cur -= d.abs * .2;
}
private var _neighbors:Vector.<Dot>;
private var _len:int;
}
import com.bit101.components.CheckBox;
import com.bit101.components.HUISlider;
import com.bit101.components.VBox;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.system.fscommand;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
class Tejido extends Sprite
{
static private const GOLDEN_RATIO:Number = 0.618;
private var tejidoGrid:TejidoGrid;
private var elementWidth:Number;
private var gridWidth:int;
private var gridHeight:int;
private var isRandom:Boolean;
private var isTransforming:Boolean;
private var hUISliderRatio:HUISlider;
private var checkBoxTransforming:CheckBox;
private var perlinNoiseOffset:uint;
private var pnOffsetPoint:Point;
private var textTransformationMatrix:Matrix;
public function Tejido():void
{
init();
//if (stage)
//else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
graphics.lineStyle(0,0xffffff);
elementWidth = 28;
isRandom = false;
isTransforming = true;
resetTejidoGrid();
//tejidoGrid.bitmapData.fillRect(tejidoGrid.bitmapData.rect, 0xffffff);
//tejidoGrid.bitmapData.fillRect(tejidoGrid.bitmapData.rect, 0);
var number:Number = 2;
//graphics.lineStyle(1);
tejidoGrid.draw(graphics,isTransforming);
//graphics.lineStyle(10);
//graphics.drawRect(0, 0, gridWidth, gridHeight);
//vBox.addChildAt(hUISliderRatio, vBox.numChildren);
//hUISliderRatioAbility();
pnOffsetPoint = new Point(perlinNoiseOffset, 0);
//addEventListener(Event.ENTER_FRAME, loopIt);
}
private function loopIt(e:Event):void
{
if (isRandom)
{
perlinNoiseOffset += 10;
pnOffsetPoint.x=perlinNoiseOffset;
tejidoGrid.bitmapData.perlinNoise(50, 50, 1, 1, false, true, 7, true, [pnOffsetPoint]);
//tejidoGrid.bitmapData.draw(ve,textTransformationMatrix);
clearGraphics();
tejidoGrid.draw(graphics, isTransforming);
}
}
private function onTransform(e:Event):void
{
isTransforming = CheckBox(e.target).selected;
clearGraphics();
tejidoGrid.draw(graphics, isTransforming);
hUISliderRatioAbility();
hUISliderRatio.enabled = !isTransforming;
}
private function hUISliderRatioAbility():void
{
hUISliderRatio.enabled = !tejidoGrid.isRandomRatio;
checkBoxTransforming.enabled = !tejidoGrid.isRandomRatio;
hUISliderRatio.enabled = !isTransforming && !tejidoGrid.isRandomRatio;
}
private function onRandom(e:Event):void
{
clearGraphics();
isRandom= tejidoGrid.isRandomRatio = CheckBox(e.target).selected;
tejidoGrid.draw(graphics, isTransforming);
hUISliderRatioAbility();
}
private function onRatio(e:Event):void
{
clearGraphics();
tejidoGrid.ratio = HUISlider(e.target).value;
tejidoGrid.draw(graphics, isTransforming);
}
private function resetTejidoGrid():void
{
var elementHeight:Number = GOLDEN_RATIO * elementWidth;
var separation:Number = elementHeight * 0.5 + elementWidth * 0.5;
//gridWidth = stage.stageWidth;
gridWidth = 400;
var columns:int = Math.ceil(gridWidth / separation);
columns = columns % 2 ? columns + 1:columns;
//gridHeight = stage.stageHeight;
gridHeight = 400;
var rows:int = Math.ceil(gridHeight / separation);
rows++;
var totalElements:int = columns * rows;
if (!tejidoGrid)
{
tejidoGrid = new TejidoGrid(columns, totalElements, elementWidth, elementHeight, 0.2,[0x00,0x555555],isRandom);
}
else
{
tejidoGrid.colsAmount = columns;
tejidoGrid.totalAmount = totalElements;
tejidoGrid.eWidth = elementWidth;
tejidoGrid.eHeight = elementHeight;
tejidoGrid.draw(graphics,isTransforming)
}
}
private function clearGraphics():void
{
graphics.clear();
graphics.lineStyle(0);
}
}
import flash.display.BitmapData;
import flash.display.Graphics;
class TejidoGrid
{
private var _colsAmount:uint;
private var _totalAmount:uint;
private var _eWidth:Number;
private var _eHeight:Number;
private var separation:Number;
private var _ratio:Number;
private var colors:Array;
public var bitmapData:BitmapData;
private var _isRandomRatio:Boolean;
private var rowsAmount:uint;
public function TejidoGrid(colsAmount:uint, totalAmount:uint, width:Number, height:Number, ratio:Number, colors:Array,isRandomRatio:Boolean=false)
{
this.isRandomRatio = isRandomRatio;
this.colors = colors;
this.ratio = ratio;
this.eHeight = height;
this.eWidth = width;
this.totalAmount = totalAmount;
this.colsAmount = colsAmount;
setSeparation();
rowsAmount = totalAmount / colsAmount;
bitmapData = new BitmapData(colsAmount*separation, rowsAmount*separation);
bitmapData.perlinNoise(50,50,1,1,false,true,1,true)
}
public function draw(g:Graphics, isTransforming:Boolean = true):void
{
var orientation:Number;
var actualRatio:Number;
var yy:Number;
var xx:uint;
var fundamentalElement:FundamentalElement;
for (var i:int = 0; i <= totalAmount; i++)
{
yy = Math.floor(i / colsAmount);
xx = uint(i % colsAmount);
actualRatio = isTransforming?GaussianDistribution.getNormalizedValue(2 * xx / colsAmount - 1, 0, 0.25):ratio;
actualRatio = isTransforming?GaussianDistribution.getNormalizedValueBivariate(2 * xx / colsAmount - 1, 2 * yy / rowsAmount - 1, -0.5, 0.25, -0.5, 0.25, 0):ratio;
//actualRatio = isTransforming?SCMath.normalDistribution(2*xx / colsAmount-1, 0.5, 1):ratio;
//actualRatio = isTransforming?xx / colsAmount:ratio;
actualRatio = isRandomRatio?((bitmapData.getPixel(xx*separation, yy*separation) & 0xff) / 255):actualRatio;
fundamentalElement = new FundamentalElement(separation * xx, separation * yy, eHeight, eWidth, actualRatio);
orientation = (yy % 2 + i) % 2;
//g.beginFill(colors[orientation]);
//g.beginFill(0xcccccc);
fundamentalElement.draw(g, orientation);
}
g.beginFill(0, 0);
}
private function setSeparation():void
{
separation = _eWidth * 0.5 + _eHeight * 0.5;
}
public function get ratio():Number
{
return _ratio;
}
public function set ratio(value:Number):void
{
_ratio = value;
}
public function get colsAmount():uint
{
return _colsAmount;
}
public function set colsAmount(value:uint):void
{
_colsAmount = value;
setRows();
}
public function get totalAmount():uint
{
return _totalAmount;
}
public function set totalAmount(value:uint):void
{
_totalAmount = value;
setRows();
}
private function setRows():void
{
rowsAmount = _totalAmount / _colsAmount;
}
public function get eWidth():Number
{
return _eWidth;
}
public function set eWidth(value:Number):void
{
_eWidth = value;
setSeparation();
}
public function get eHeight():Number
{
return _eHeight;
}
public function set eHeight(value:Number):void
{
_eHeight = value;
setSeparation();
}
public function get isRandomRatio():Boolean
{
return _isRandomRatio;
}
public function set isRandomRatio(value:Boolean):void
{
_isRandomRatio = value;
}
}
import flash.display.Graphics;
import flash.geom.Matrix;
import flash.geom.Point;
class FundamentalElement
{
private var cx:Number;
private var cy:Number;
private var height:Number;
private var width:Number;
private var ratio:Number;
private var AA:Point;
private var BB:Point;
private var matrix:Matrix;
private var array:Array;
public function FundamentalElement(cx:Number, cy:Number, height:Number, width:Number, ratio:Number)
{
this.ratio = ratio;
this.width = width;
this.height = height;
this.cy = cy;
this.cx = cx;
AA = new Point;
BB = new Point;
matrix = new Matrix;
matrix.rotate(Math.PI * 0.5);
doSet();
}
private function doSet():void
{
AA.x = ratio * width * 0.5;
AA.y = 0.5 * height;
BB.x = 0.5 * width;
array = [AA,BB,new Point(AA.x,-AA.y),new Point(-AA.x,-AA.y),new Point(-BB.x,BB.y),new Point(-AA.x,AA.y)];
}
public function draw(g:Graphics,isRotated:uint=0):void
{
if (isRotated)
{
for (var i:int = 0; i < array.length; i++)
{
array[i] = matrix.transformPoint(array[i]);
}
}
g.moveTo(cx + array[array.length-1].x, cy + array[array.length-1].y);
for (var j:int = 0; j < array.length; j++)
{
g.lineTo(cx+array[j].x, cy+array[j].y);
}
}
}
class SCMath
{
static private var normalDistriutionFactor:Number = 1 / Math.sqrt(Math.PI * 2);
static public function normalDistribution(x:Number, mu:Number, sigma:Number):Number
{
var s:Number = 1 / sigma;
return s*normalDistriutionFactor*Math.pow(Math.E,-(x-mu)*(x-mu)*s*s*0.5);
}
}
class GaussianDistribution
{
private var mu:Number;
private var _sigma:Number;
private var factor:Number;
public function GaussianDistribution(mu:Number, sigma:Number)
{
this.sigma = sigma;
this.mu = mu;
}
public function getData():Array
{
var gaussian:Number;
var pow:Number;
var xx:Number;
var normal:Number;
var steps:int = 100;
var delta:Number = 1 / steps;
var data:Array = [];
var initxx:Number = -5;
var finalxx:Number = 5;
var size:Number = 10;
size = finalxx > initxx?finalxx - initxx:initxx - finalxx;
for (var i:int = 0; i < steps; i++)
{
normal = i * delta;
xx = size * (normal - 0.5);
pow = -(xx - mu) * (xx - mu)/(2*sigma*sigma);
gaussian = factor * Math.pow(Math.E, pow);
data[i] = gaussian;
}
return data;
}
public static function getNormalizedValue(xx:Number, mu:Number, sigma:Number):Number
{
return getValue(xx, mu, sigma) / getValue(mu, mu, sigma);
}
public static function getValue(xx:Number, mu:Number, sigma:Number):Number
{
var gaussian:Number;
var pow:Number;
var s:Number = 1 / sigma;
var factor:Number = s / Math.sqrt(2 * Math.PI);
pow = -(xx - mu) * (xx - mu)*s*s*0.5;
gaussian = factor * Math.pow(Math.E, pow);
return gaussian
}
public function get sigma():Number
{
return _sigma;
}
public function set sigma(value:Number):void
{
_sigma = value;
factor = 1 /( sigma * Math.sqrt(2 * Math.PI));
}
public static function getNormalizedValueBivariate(xx:Number, yy:Number, mux:Number, sigmax:Number, muy:Number, sigmay:Number, rho:Number):Number
{
return getBivariate(xx, yy, mux,sigmax,muy, sigmay, rho) / getBivariate(mux, muy, mux, sigmax, muy,sigmay, rho);
}
public static function getBivariate(xx:Number, yy:Number, mux:Number, sigmax:Number, muy:Number, sigmay:Number, rho:Number):Number
{
var s:Number = 1 / (sigmax * sigmay);
var r:Number = 1 - rho * rho;
var factor:Number = s / (2 * Math.PI * Math.sqrt(r));
var dx:Number = xx - mux;
var dy:Number = yy - muy;
var sxy:Number = sigmax * sigmay;
var squareBracket:Number = (dx * dx) / (sigmax * sigmax) + (dy * dy) / (sigmay * sigmay) - 2 * rho * (dx * dy) * s;
var gaussian:Number = 0.5*s/(Math.PI*Math.sqrt(r))*Math.pow(Math.E, -0.5*squareBracket/r);
return gaussian;
}
}