Category Archives: Graphics

Better BitmapData Brush

Actionscript:
  1. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0xCCCCCC);
  2. addChild(new Bitmap(canvas));
  3. var prevX:Number;
  4. var prevY:Number;
  5. var brush:Shape = new Shape();
  6.  
  7. stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
  8. stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  9. function onDown(evt:MouseEvent):void{
  10.     prevX = mouseX;
  11.     prevY = mouseY;
  12.     addEventListener(Event.ENTER_FRAME, onLoop);
  13. }
  14.  
  15. function onUp(evt:MouseEvent):void{
  16.     removeEventListener(Event.ENTER_FRAME, onLoop);
  17. }
  18.  
  19. function onLoop(evt:Event):void {
  20.       brush.x = mouseX;
  21.       brush.y = mouseY;
  22.       with (brush.graphics){
  23.           clear();
  24.           lineStyle(3, 0x000000);
  25.           lineTo(prevX-mouseX, prevY-mouseY);
  26.       }
  27.       canvas.draw(brush, brush.transform.matrix);
  28.       prevX = mouseX;
  29.       prevY = mouseY;
  30. }

If you write a drawing program with the Graphics class alone, you'll notice that eventually the flash player will start to slow down. This could take quite some time, but it will eventually happen. Because the Graphics class is entirely vector based, the flash player needs to keep track of every single point that makes up any line in your drawing. If you draw something and then erase it by drawing white vector lines over it, flash still needs to know about that thing that you erased.

The snippet I wrote yesterday reminded me of the technique used in the above snippet. In yesterdays post every line is drawn using the graphics class. As a result, eventually the flash player begins to choke.

Today's snippet draws a vector between the previous mouse location and the current mouse location - this vector is then drawn onto a BitmapData object and the vector is cleared. So rather than creating vector graphics that are continuously increasing in complexity, your just changing the color of pixels around on a BitmapData.

To see a visual explanation take a look at the below swf. I slowed it down to 5fps, I tinted the vector red and scaled up the stage so you can differentiate between what's vector and what's bitmap:


Click to see the swf...

Also posted in BitmapData | Tagged , , | 1 Comment

Gesture Capture

Actionscript:
  1. var canvas:Shape = Shape(addChild(new Shape()));
  2. var gestures:Array=[];
  3. var gestureNum:int = 0;
  4. var capGesture:Array;
  5. stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
  6. stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  7. function onDown(evt:MouseEvent):void{
  8.      capGesture=[];
  9.      addEventListener(Event.ENTER_FRAME, onCapture);
  10.    
  11.      canvas.graphics.lineStyle(3, 0xFF0000);
  12.      canvas.x = mouseX;
  13.      canvas.y = mouseY;
  14.      canvas.graphics.moveTo(0, 0);
  15. }
  16. function onUp(evt:MouseEvent):void{
  17.     gestures.push(capGesture.concat());
  18.     gestureNum++;
  19.      canvas.graphics.clear();
  20.     removeEventListener(Event.ENTER_FRAME, onCapture);
  21. }
  22. function onCapture(evt:Event):void{
  23.     capGesture.push(new Point(canvas.mouseX, canvas.mouseY));
  24.     canvas.graphics.lineTo(canvas.mouseX, canvas.mouseY);
  25. }
  26.  
  27. var currGesture:Array;
  28. var drawing:Boolean = false;
  29. var lineThickness:Number = 0;
  30. var lineColor:Number = 0x000000;
  31. var index:int = 0;
  32. var pnt:Point;
  33. var trans:Matrix = new Matrix();
  34. var i:int
  35. addEventListener(Event.ENTER_FRAME, onLoop);
  36. function onLoop(evt:Event):void{
  37.     if (gestureNum> 0){
  38.         if (!drawing){
  39.           currGesture = gestures[int(Math.random() * gestureNum)].concat();
  40.           trans.identity();
  41.           trans.rotate(Math.random()*6.28);
  42.           var scale:Number = Math.random() * 2 + .1;
  43.           trans.scale(scale, scale);
  44.           trans.tx = Math.random() * stage.stageWidth
  45.           trans.ty = Math.random() * stage.stageHeight
  46.           for (i = 0; i<currGesture.length; i++){
  47.              currGesture[i] = trans.transformPoint(currGesture[i]);  
  48.           }
  49.           lineThickness = Math.random() * Math.random() * 50;
  50.           if (int(Math.random()*10) ==1){
  51.              var col:uint = uint(Math.random()*255);
  52.              lineColor = col <<16 | col <<8 | col;
  53.           }
  54.           index = 0;
  55.           drawing = true;
  56.           graphics.lineStyle(lineThickness, lineColor);
  57.         }else{
  58.            for (i = 0; i<10; i++){
  59.                 if (drawing == true){
  60.                    pnt = currGesture[index];
  61.                    if (index == 0){
  62.                       graphics.moveTo(pnt.x, pnt.y);  
  63.                    }else{
  64.                       graphics.lineTo(pnt.x, pnt.y);
  65.                    }
  66.                    index++;
  67.                    if (index == currGesture.length){
  68.                        drawing = false;
  69.                    }
  70.                }
  71.            }
  72.         }
  73.     }
  74. }

This snippet is an idea I have been meaning to try for sometime. It's a mini-drawing program. You can draw single gestures (shapes, letters etc...) and the program then randomly scales, rotates, tints and translates these gestures repeatedly on the canvas. You can continue to draw as it does this, the more gestures you draw, the more the program will have to randomly choose from.


Have a look at the swf here...

Also posted in misc, motion | Tagged , , | Leave a comment

HSV Color Type

Actionscript:
  1. [SWF(width=560,height=300,backgroundColor=0x000000,frameRate=30)]
  2.  
  3. var key:Object = new Object();
  4. var alphabet:Array = "abcdefghijklmnopqrstuvwxyz".split("");
  5.  
  6. var num:Number = alphabet.length;
  7. var step:Number = 360 / num;
  8.  
  9. var colors:Object = new Object();
  10. for (var i:int  = 0; i<num; i++){
  11.     var index:String = alphabet[i];
  12.      key[index] = 65 + i;
  13.      var c:Array = hsv(i * step, 1, 1);
  14.      colors[index] = c[0] <<16 | c[1] <<8 | c[2];
  15. }
  16. alphabet.push("32");
  17. num++;
  18. key["32"] = 32;
  19. colors["32"]  = 0x333333;
  20. x = y = 10;
  21. var count:int = 0;
  22. var size:int = 20;
  23. stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPressed);
  24. function onKeyPressed(evt:KeyboardEvent):void{
  25.     for (var i:int= 0; i<num; i++){
  26.         var index:String = alphabet[i];
  27.          if (index == "32"){
  28.             trace("hi", evt.keyCode, key[index]);
  29.          }
  30.         if (evt.keyCode == key[index]){
  31.             graphics.beginFill(colors[index]);
  32.             var xp:int = count % num * size;
  33.             var yp:int = int(count / num) * size;
  34.             graphics.drawRect(xp, yp, size, size);
  35.             count++;
  36.         }
  37.     }
  38. }
  39. // ported from here:
  40. //http://www.cs.rit.edu/~ncs/color/t_convert.html
  41. function hsv(h:Number, s:Number, v:Number):Array{
  42.     var r:Number, g:Number, b:Number;
  43.     var i:int;
  44.     var f:Number, p:Number, q:Number, t:Number;
  45.     if (s == 0){
  46.         r = g = b = v;
  47.         return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
  48.     }
  49.     h /= 60;
  50.     i  = Math.floor(h);
  51.     f = h - i;
  52.     p = v *  (1 - s);
  53.     q = v * (1 - s * f);
  54.     t = v * (1 - s * (1 - f));
  55.     switch( i ) {
  56.         case 0:
  57.             r = v, g = t, b = p;
  58.             break;
  59.         case 1:
  60.             r = q, g = v, b = p;
  61.             break;
  62.         case 2:
  63.             r = p, g = v, b = t;
  64.             break;
  65.         case 3:
  66.             r = p, g = q, b = v;
  67.             break;
  68.         case 4:
  69.             r = t, g = p, b = v;
  70.             break;
  71.         default:        // case 5:
  72.             r = v, g = p, b = q;
  73.             break;
  74.     }
  75.     return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
  76. }

This snippet is a typing experiment - for every letter, you type a box filled with a specific color is drawn to the stage. The color associated with each letter is determined by moving through hsv color space - so typing an alphabet will end up with something resembling a spectrum.

Also posted in UI, color, keys | Tagged , , | Leave a comment

XML to ActionScript #3 (AsXML)

XML:
  1. <code>
  2.   <make reference="w" class="BasicView" args="stage.stageWidth, stage.stageHeight, false"/>
  3.   <call method="addChild" args="w"/>
  4.  
  5.   <make reference="wireMat" class="WireframeMaterial" args="0x000000" />
  6.  
  7.   <make reference="sphere" class="Sphere" args="wireMat, 100" />
  8.  
  9.   <call method="w.scene.addChild" args="sphere" />
  10.  
  11.   <make reference="animation" class="Object">
  12.     <set z="-500" rotationY="360"  rotationX="360" ease="Back.easeOut"/>
  13.   </make>
  14.  
  15.   <call method="TweenLite.to" args="sphere, 3, animation" />
  16.  
  17.   <call method="setInterval" args="w.singleRender, 32" />
  18.  
  19. </code>

This snippet shows XML that the mini-library AsXML can read and run - in this case AsXML is set up to run with Papervision

A few days ago I had the idea to write some code that would run ActionScript based on XML. I spent some time getting rid of a few bugs and setting up some demos with TweenLite, Papervision and QuickBox2D. I wrapped everything up into a mini-library called AsXML.

Check out the demos here.


Download AsXML and demo files here.

AsXML Features:
1) call methods of the main timeline
2) read and write properties on the main timeline
3) instantiate classes on the main timeline
4) call methods on these classes
5) read and write properties on these classes
6) store references to return values from functions

Also posted in Box2D, Math, QuickBox2D, XML, dynamic, external data, instantiation, misc, motion, return values, string manipulation, strings | Tagged , , | 11 Comments