Tag Archives: as3

Smudge Tool #1

Actionscript:
  1. [SWF(backgroundColor = 0xCCCCCC)]
  2. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,true, 0xFFFFFFFF);
  3. addChild(new Bitmap(canvas));
  4.  
  5. var loader:Loader = new Loader();
  6. loader.load(new URLRequest("http://actionsnippet.com/wp-content/chair.jpg"));
  7. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
  8. function onComplete(evt:Event):void{
  9.     canvas.draw(loader);
  10. }
  11.  
  12. var brush:Shape = new Shape();
  13. var diameter:Number = 120;
  14. var radius:Number = diameter / 2;
  15. var matrix:Matrix = new Matrix();
  16.  
  17. var brushAlpha:BitmapData = new BitmapData(diameter, diameter, true, 0x00000000);
  18. drawRadial();
  19. brushAlpha.draw(brush);
  20.  
  21. var xp:Number = 0, yp:Number = 0, px:Number = 0, py:Number = 0;
  22. var dx:Number, dy:Number;
  23.  
  24. stage.addEventListener(MouseEvent.MOUSE_MOVE, onLoop);
  25. function onLoop(evt:Event):void {
  26.     xp = mouseX - radius;
  27.     yp = mouseY - radius;
  28.     dx = xp - px;
  29.     dy = yp - py;
  30.     canvas.copyPixels(canvas,
  31.                     new Rectangle(px, py, diameter, diameter),
  32.                     new Point(xp, yp), brushAlpha, new Point(0,0), true);
  33.     px = xp;
  34.     py = yp
  35. }
  36.  
  37. function drawRadial():void{
  38.     matrix.createGradientBox(diameter, diameter, 0, 0, 0);
  39.     with (brush.graphics){
  40.         beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0xFFFFFF], [1,0], [0, 255], matrix, SpreadMethod.PAD);
  41.         drawCircle(radius, radius, radius);
  42.     }
  43. }

This is a quick snippet I wrote while thinking about how to create a smudge tool using BitmapData... it isn't perfect, but it's a good first step. It still needs some linear interpolation and I may need to do some pixel pushing to prevent a strange alpha anomaly that causes the brush to get darker than expected....


Here is the swf...

Posted in BitmapData | Also tagged , | 1 Comment

Isometric Cones (spikes)

Actionscript:
  1. [SWF(width = 600, height = 500, backgroundColor=0xFFFFFF)]
  2.  
  3. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0xFFFFFF);
  4. addChild(new Bitmap(canvas));
  5.  
  6. var matrix:Matrix = new Matrix();
  7. var grid:Sprite =   new Sprite();
  8. grid.filters = [new DropShadowFilter(4, 0, 0, 0.05, 20, 10)];
  9. matrix.rotate(Math.PI / 4);
  10. matrix.scale(1, 0.6);
  11. matrix.translate(stage.stageWidth / 2, stage.stageHeight / 2 + 50);
  12. grid.transform.matrix = matrix;
  13.  
  14. var rowCol:int = 9;
  15. var spikeNum:Number = rowCol * rowCol;
  16. var diameter:Number = 30;
  17. var space:Number  = diameter + 10;
  18. var halfGridSize:Number  = rowCol * space / 2;
  19. var radius:Number;
  20. addEventListener(Event.ENTER_FRAME, onLoop);
  21. function onLoop(evt:Event):void {
  22.     radius  = diameter / 2;
  23.     grid.y -= 0.9;
  24.     grid.graphics.clear();
  25.     for (var i:Number = 0; i<spikeNum; i++){
  26.        var xp:Number = i % rowCol;
  27.        var yp:Number = int(i / rowCol);
  28.        drawSpike(xp * space - halfGridSize, yp * space - halfGridSize, (xp + yp) / 4, 0, -yp);
  29.     }
  30.     canvas.draw(grid, grid.transform.matrix);
  31.     diameter -= 0.5;
  32.     if (diameter <3){
  33.         removeEventListener(Event.ENTER_FRAME, onLoop);
  34.     }
  35. }
  36. function drawSpike(xp:Number, yp:Number, rot:Number = 0, xOff:Number=0, yOff:Number = 0):void{
  37.     matrix.createGradientBox(diameter, diameter, rot, xp - radius + yOff, yp - radius + xOff);
  38.     with (grid.graphics){
  39.         beginGradientFill(GradientType.LINEAR, [0xFFFFFF, 0x999999], [1,1], [0, 255], matrix, SpreadMethod.PAD);
  40.         drawCircle(xp, yp, radius);
  41.     }
  42. }

This snippet draws some isometric cones. Here are some images created by tweaking a few of the values:

Posted in 3D, BitmapData, misc | Also tagged , | Leave a comment

BlendModes & Blur

Actionscript:
  1. [SWF(width = 750, height = 750)]
  2. var canvas:BitmapData = new BitmapData(750,1000,false, 0x000000);
  3. addChild(new Bitmap(canvas));
  4.  
  5. var loader:Loader = new Loader();
  6. loader.load(new URLRequest("http://actionsnippet.com/imgs/paint.jpg"));
  7. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
  8. var bit:BitmapData
  9. var blurred:BitmapData;
  10. function onLoaded(evt:Event):void{
  11.     bit = Bitmap(evt.target.content).bitmapData;
  12.     blurred = bit.clone();
  13.     blurred.applyFilter(blurred, blurred.rect, new Point(0,0), new BlurFilter(4, 4, 6));
  14.     var blends:Array = [BlendMode.NORMAL,BlendMode.ADD, BlendMode.DARKEN,BlendMode.HARDLIGHT,BlendMode.LIGHTEN, BlendMode.MULTIPLY, BlendMode.OVERLAY,BlendMode.SCREEN, BlendMode.DIFFERENCE];
  15.     var m:Matrix = new Matrix();
  16.     for (var i:int = 0; i<blends.length; i++){
  17.         m.tx = i % 3 * 250;
  18.         m.ty = int(i / 3) * 250;
  19.         canvas.draw(bit, m);
  20.         if (i> 0){
  21.         canvas.draw(blurred, m, null, blends[i]);
  22.         }
  23.     }
  24. }

When I used to use photoshop for more than just the most basic of things, I would use a simple technique that employed layer modes (blend modes in flash) and blur. Sometimes, if I had a low quality image that I wanted to make look a little better, or just wanted to give an image a subtle effect, I would duplicate the layer the image was on, blur it and then go through all the layer modes on that duplicate layer until I found something I liked.

This snippet does the same thing with a few select blend modes:

This isn't the greatest image to illustrate the effect, but I didn't feel like digging something better up. Two notable swatches are the upper right (darken) and the lower middle (screen).

Posted in BitmapData, misc | Also tagged , | 6 Comments

Cut Image into Squares (copyPixels)

Actionscript:
  1. [SWF(width=650, height=650)]
  2. var loader:Loader = new Loader();
  3. loader.load(new URLRequest("http://actionsnippet.com/wp-content/chair.jpg"));
  4. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
  5.  
  6. var w:Number;
  7. var h:Number;
  8. var rows:Number = 20;
  9. var cols:Number = 20;
  10. var tiles:Vector.<BitmapData> = new Vector.<BitmapData>();
  11. var locX:Vector.<Number> = new Vector.<Number>();
  12. var locY:Vector.<Number> = new Vector.<Number>();
  13. var rX:Vector.<Number> = new Vector.<Number>();
  14. var rY:Vector.<Number> = new Vector.<Number>();
  15. var sX:Vector.<Number> = new Vector.<Number>();
  16. var sY:Vector.<Number> = new Vector.<Number>();
  17. function onLoaded(evt:Event):void{
  18.     w = evt.target.width;
  19.     h = evt.target.height;
  20.     var image:BitmapData = Bitmap(evt.target.content).bitmapData;
  21.     var tileWidth:Number = w / cols;
  22.     var tileHeight:Number = h / rows;
  23.     var inc:int = 0;
  24.     var pnt:Point = new Point();
  25.     var rect:Rectangle = new Rectangle(0,0,tileWidth,tileHeight);
  26.     for (var i:int = 0; i<rows; i++){
  27.         for (var j:int = 0; j<cols; j ++){
  28.              var currTile:BitmapData= new BitmapData(tileWidth, tileHeight, true, 0x00000000);
  29.              rect.x = j * tileWidth;
  30.              rect.y = i * tileHeight;
  31.              currTile.copyPixels(image, rect, pnt, null, null, true);
  32.              tiles[inc] = currTile;
  33.              rect.x += 25;
  34.              rect.y += 25;
  35.              sX[inc] = rect.x;
  36.              sY[inc] = rect.y;
  37.              locX[inc] = rX[inc] = -rect.width * 2
  38.              locY[inc] = rY[inc] =  Math.random() * stage.stageHeight;
  39.              setTimeout(startAnimation, inc *4 + 100, inc, rect.x, rect.y);
  40.              inc++;
  41.         }
  42.     }
  43. }
  44.  
  45. function startAnimation(index:int, dx:Number, dy:Number):void{
  46.     var interval:Number;
  47.     var animate:Function = function(index:int):void{
  48.         locX[index] += (dx - locX[index]) / 4;
  49.         locY[index] += (dy - locY[index]) / 4;
  50.         if (Math.abs(locX[index] - dx) <1 && Math.abs(locY[index] - dy)<1){
  51.             locX[index] = dx;
  52.             locY[index] = dy;
  53.             clearInterval(interval);
  54.         }
  55.     }
  56.    interval = setInterval(animate, 32, index);
  57. }
  58.  
  59. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0xFFFFFF);
  60. addChild(new Bitmap(canvas));
  61.  
  62. var loc:Point = new Point();
  63. addEventListener(Event.ENTER_FRAME, onLoop);
  64. function onLoop(evt:Event):void {
  65.       canvas.fillRect(canvas.rect, 0xFFFFFF);
  66.       for (var i:int = 0; i<tiles.length; i++){
  67.             var tile:BitmapData= tiles[i];
  68.             loc.x = locX[i];
  69.             loc.y = locY[i];
  70.             canvas.copyPixels(tile, tile.rect, loc, null, null, true);
  71.       }
  72. }

This snippet cuts a dynamically loaded image into a series of smaller BitmapData instances. These BitmapData instances are then drawn to a canvas BitmapData using copyPixels. The BitmapData.copyPixels() method is extremely fast - so this has some advantages over yesterdays post (which did basically the same thing with Sprites). I used setInterval and setTimeout to do a simple demo animation, but I recommend using TweenLite on a real project.

Posted in BitmapData, Vector | Also tagged , | 10 Comments