Tag Archives: actionsnippet

Circle Mouse Toy

Actionscript:
  1. var circles:Array = [];
  2. for (var i:int = 0; i<30; i++){
  3.     var c:Sprite = makeCircle();
  4.     c.x = stage.stageWidth / 2;
  5.     c.y = stage.stageHeight / 2;
  6.     c.scaleX = 1 + i/2;
  7.     c.scaleY = 0.5 + i/4;
  8.     addChild(c);
  9.     circles.push(c);
  10. }
  11. addEventListener(Event.ENTER_FRAME, onLoop);
  12. function onLoop(evt:Event):void {
  13.     circles[0].y += (mouseY - circles[0].y) / 4;
  14.     for (var i:int = 1; i<circles.length; i++){
  15.         var pre:Sprite = circles[i - 1];
  16.         circles[i].y += (pre.y - circles[i].y) / 4;
  17.     }
  18. }
  19. function makeCircle():Sprite{
  20.     var s:Sprite = new Sprite();
  21.     with(s.graphics){
  22.         lineStyle(0,0x000000);
  23.         drawCircle(0,0,10);
  24.     }
  25.     return s;
  26. }

This morning I woke up with a vision of this simple mouse toy in my head. I decided I might as well code it up... I may do more simple things like this in the next few days, it's relaxing.

Posted in Graphics, misc, motion | Also tagged , | 5 Comments

Polygon Problems

Lots of people have mentioned that they have problems with QuickBox2D Polygons. The simple solution is not to use the verts 2d array (which is more like how Box2D does polys). So when in doubt about polygons, simply use the points array which will nearly always work as long as the contour you define does not cross over itself. Here is a simple example on wonderfl:

Also... polygons are covered extensively in part two of the tutorial over at active tuts... more on that later.

Here is the timeline code:

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2.             /*
  3.                0
  4.               / \
  5.              0_0 0
  6.                | |
  7.                0-0
  8.             */
  9.             var sim:QuickBox2D = new QuickBox2D(this);
  10.             sim.createStageWalls();
  11.             // define the contour of your poly
  12.             // no limits as long as it doesn't cross over
  13.             // itself
  14.             sim.addPoly({x:10, y:5, points:[0.5,0,
  15.                                             1, 1,
  16.                                             1, 2,
  17.                                             0.5, 2,
  18.                                             0.5, 1,
  19.                                             0,1,
  20.                                             0.5,0],
  21.                                             wireframe:false});
  22.             sim.addCircle({x:11, y:10});
  23.             sim.start();
  24.             sim.mouseDrag();

Posted in Uncategorized | Also tagged , , | Leave a comment

Hide Browser Scrollbars

Actionscript:
  1. /*
  2. This snippet is by Mels le Noble
  3. www.melslenoble.nl
  4. It will hide the browser scrollbars.
  5. */
  6.  
  7. // see if we are testing locally
  8. if (stage.loaderInfo.url.split("/")[2])
  9. {
  10.  ExternalInterface.call("function(){document.body.style.overflow='hidden';document.html.style.overflow = 'hidden';}");
  11. }

This snippet by Mels le Noble will hide the browser scrollbars. The bulk of the snippet is the javascript inside the ExternalInterface.call() method. I like the trick that Mels uses to check if the swf is local.... snippet-worthy in itself.

Posted in UI | Also tagged , , , | Leave a comment

Matrix Zoom and Pan

Actionscript:
  1. [SWF(width=600, height=600, frameRate=30)]
  2. var sw:Number = stage.stageWidth;
  3. var sh:Number = stage.stageHeight;
  4.  
  5. var s:Shape = Shape(addChild(new Shape()));
  6.  
  7. var scale:Number = 1;
  8. var scaleDest:Number = 1;
  9. var down:Boolean = false;
  10. var dx:Number = 0, dy:Number = 0, time:Number = 0;
  11.  
  12. buttonMode = true;
  13.  
  14. addInstructions();
  15. vectorTexture();
  16.  
  17. stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
  18. stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  19. addEventListener(Event.ENTER_FRAME, onLoop);
  20.  
  21. function addInstructions():void{
  22.     var instruct:Sprite = Sprite(addChild(new Sprite()));
  23.     with (instruct.graphics) beginFill(0x666666), drawRect(0,0,270, 30);
  24.     instruct.x = instruct.y = 20;
  25.     var txt:TextField = TextField(instruct.addChild(new TextField()));
  26.     txt.defaultTextFormat = new TextFormat("Verdana", 11);
  27.     txt.x = txt.y = 5;
  28.     txt.selectable = false;
  29.     with (txt) textColor = 0xFFFFFF, autoSize = "left", text = "Click and hold to zoom, move mouse to pan";
  30. }
  31.  
  32. function vectorTexture():void{
  33.     var cols:Vector.<uint> = Vector.<uint>([0xFFFFFF, 0x000000]);
  34.     var rnd:Vector.<Number> = new Vector.<Number>(6, true);
  35.    
  36.     for(var i:int = 0 ; i<50; i++){
  37.         with(s.graphics){
  38.             lineStyle(Math.random() * 50 + 2, cols[int(Math.random()*cols.length)]);
  39.             drawCircle(Math.random() * sw, Math.random() * sh, 10 + Math.random() * Math.random() * 400);
  40.         }
  41.     }
  42.     s.graphics.lineStyle(20, 0xCCCCCC);
  43.     s.graphics.drawRect(0, 0,sw, sh);
  44. }
  45.  
  46. function onDown(evt:MouseEvent):void{ down = true; }
  47. function onUp(evt:MouseEvent):void{ down = false; }
  48. function onLoop(evt:Event):void {
  49.    if (down){
  50.      scaleDest *= 1.05;  
  51.      time = 0;
  52.    }else{
  53.      time++;
  54.      // zoom out after 30 iterations
  55.      if (time == 30){
  56.          scaleDest = 1;  
  57.      }
  58.    }
  59.    scale += (scaleDest - scale) / 4;
  60.    if (scale> 10) scale = scaleDest = 10;
  61.    
  62.    dx += (mouseX - dx) / 4;
  63.    dy += (mouseY - dy) / 4;
  64.    if (dx <0) dx = 0;
  65.    if (dy <0) dy = 0;
  66.    if (dx> sw) dx = sw;
  67.    if (dy> sh) dy = sh;
  68.    
  69.    // matrix zoom/pan
  70.    var m:Matrix = s.transform.matrix;
  71.    m.identity();
  72.    m.translate(-dx,-dy);
  73.    m.scale(scale, scale);
  74.    m.translate(dx,dy);
  75.    s.transform.matrix = m;
  76. }

I haven't been by the computer much these last two weeks - been traveling. Going back to nyc tomorrow so I'll go back to posting once a day.

This snippet uses a transformation matrix to zoom in and pan a Sprite instance. For demo purposes I filled the sprite with a few circles - but you'd likely be using this with a vector image of a map, a floor plan or some other graphic that warrants zooming and panning.

Back around flash 7 (I think) before the Matrix class was introduced we used to have to use MovieClip nesting to achieve this effect.


Have a look at the swf...


Posted in Graphics, matrix, motion | Also tagged , | Leave a comment

Distance Spring

Actionscript:
  1. [SWF(backgroundColor=0x222222, width=500, height=500)]
  2. var hsw:Number = stage.stageWidth / 2;
  3. var hsh:Number = stage.stageHeight / 2;
  4. var pointNum:int = 800
  5. var points3D:Vector.<Number> = new Vector.<Number>();
  6. var points3Dout:Vector.<Number> = new Vector.<Number>();
  7. var points2D:Vector.<Number> = new Vector.<Number>();
  8. var uvts:Vector.<Number> = new Vector.<Number>();
  9. var sorted:Array = [];
  10. var pnt:Point = new Point();
  11. var m:Matrix3D = new Matrix3D();
  12. var v:Vector3D = new Vector3D();
  13. for (var i:int = 0; i<pointNum; i++){
  14.     v.y = i * 0.7 - 300
  15.     var t =Math.random()*6.28;
  16.     v.x = 200 * Math.cos(i * 2 * Math.PI / 180);
  17.     v.z = 200 * Math.sin(i * 2 * Math.PI / 180);
  18.     v = m.transformVector(v);
  19.     points3D.push(v.x, v.y, v.z);
  20.     points2D.push(0,0);
  21.     uvts.push(0,0,0);
  22.     sorted.push(new Vector3D());
  23. }
  24. points3D.fixed = true;
  25. points2D.fixed = true;
  26. uvts.fixed = true;
  27. var p:PerspectiveProjection = new PerspectiveProjection();
  28. var proj:Matrix3D = p.toMatrix3D();
  29. var dx:Number = 0, dy:Number = 0;
  30. addEventListener(Event.ENTER_FRAME, onLoop);
  31. function onLoop(evt:Event):void {
  32.     var i:int, j:int;
  33.     dx += (mouseX - dx) / 4;
  34.     dy += (mouseY - dy) / 4;
  35.     m.identity();
  36.     m.appendRotation(getTimer() / 4, Vector3D.Y_AXIS);
  37.     m.transformVectors(points3D, points3Dout);
  38.    
  39.     m.identity();
  40.     m.appendRotation(dx, Vector3D.Z_AXIS);
  41.     m.appendRotation(dy, Vector3D.X_AXIS);
  42.     m.appendTranslation(0, 0, 1000);
  43.     m.append(proj);
  44.     Utils3D.projectVectors(m, points3Dout, points2D, uvts);
  45.     for (i = 0, j = 0; i<points2D.length; i+=2, j++){
  46.         sorted[j].x = points2D[i] + hsw;
  47.         sorted[j].y = points2D[i + 1] + hsh;
  48.         sorted[j].z = uvts[j * 3 + 2];
  49.     }
  50.     sorted.sortOn("z", Array.NUMERIC);
  51.     graphics.clear();
  52.     for(i = 0; i<sorted.length; i++){
  53.         var zpos:Number = sorted[i].z * 10000;
  54.         var c:int = zpos * 14;
  55.         graphics.beginFill(c <<16 | c <<8 | c);
  56.         graphics.drawCircle(sorted[i].x, sorted[i].y, zpos);
  57.         graphics.endFill();
  58.     }
  59. }

A variation on some recent posts... this snippet draws a rotating spring made up of 800 particles...

Have a look at the swf...


Posted in 3D, Graphics, Vector | Also tagged , | 3 Comments

Interesting Texture

Actionscript:
  1. var canvas:BitmapData = new BitmapData(1000,1000,false, 0x000000);
  2. addChild(new Bitmap(canvas));
  3. scaleX = scaleY = .5;
  4.  
  5. var w:int = canvas.width;
  6. var w10:int = w * 60;
  7. var size:int = canvas.width * canvas.height;
  8. for (var i:int = 0; i<size; i++){
  9.     var xp:int = i % w;
  10.      
  11.     var yp:int = int(i / w);
  12.     var c1:int = (255/8) * (Math.cos(xp* Math.PI/180 * 2) + Math.sin(yp*yp/w10));
  13.     if (c1 <0) c1 = 256 - c1;
  14.     c1 = (c1 <<1 | c1) ;
  15.     canvas.setPixel(xp, yp, c1 <<16 | c1 <<8 | c1 );
  16. }
  17. var m:Matrix = new Matrix();
  18. m.scale(1,-1);
  19. m.translate(0,canvas.height);
  20. var clone:BitmapData = canvas.clone();
  21. canvas.draw(clone, m, null, BlendMode.SUBTRACT);
  22. clone.draw(canvas);
  23. clone.applyFilter(clone, clone.rect, new Point(0,0), new BlurFilter(10,10,1));
  24. canvas.draw(clone, null, null, BlendMode.ADD);

Having one of those days where everything I code doesn't look right to me... took a little break from other work and created this very unoptimized abstract texture... no animation so here is a bitmap:

Posted in BitmapData, pixel manipulation, setPixel | 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

for loop Fun

Actionscript:
  1. var leng:int = 10;
  2. for (var i:int = 0, j:int = leng;  i <leng; i++, j = leng - i){
  3.     trace(i, j);
  4. }
  5.  
  6. /*outputs
  7. 0 10
  8. 1 9
  9. 2 8
  10. 3 7
  11. 4 6
  12. 5 5
  13. 6 4
  14. 7 3
  15. 8 2
  16. 9 1
  17. */

Looping backwards and forwards.

Posted in Math, misc, one-liners | Also tagged | Leave a comment

Slider Navigation

Actionscript:
  1. var thumbNum:Number = 20;
  2. var spacing:Number = 10;
  3. var thumbs:MovieClip = new MovieClip();
  4. addChild(thumbs);
  5. for (var i:int = 0; i<thumbNum; i++){
  6.     var t:MovieClip = new MovieClip();
  7.     with(t.graphics) beginFill(0x666666), drawRect(0,0,100,50);
  8.     t.x = i * (t.width + spacing);
  9.     t.y = 5;
  10.     t.buttonMode = true;
  11.     thumbs.addChild(t);
  12. }
  13. var minX:Number = stage.stageWidth - thumbs.width - spacing;
  14. var destX:Number = thumbs.x = spacing;
  15. var velX:Number = 10;
  16. var stageThird:Number =  stage.stageWidth / 3;
  17. var right:Number = stageThird * 2;
  18. var left:Number  = stageThird;
  19. addEventListener(Event.ENTER_FRAME, onLoop);
  20. function onLoop(evt:Event):void {
  21.     if (mouseX> right){
  22.        destX -= velX;
  23.     }
  24.     if (mouseX <left){
  25.         destX += velX;
  26.     }
  27.     if (destX <minX){
  28.         destX = minX;
  29.     }
  30.     if (destX> spacing){
  31.         destX = spacing;
  32.     }
  33.     thumbs.x += (destX - thumbs.x) /4;
  34. }

This snippet shows a technique for a common type of navigation.

Posted in UI, motion | Also tagged | Leave a comment

Slow Line Drawing

Actionscript:
  1. var canvas:BitmapData = Bitmap(addChild(new Bitmap(new BitmapData(400, 400, false, 0x000000)))).bitmapData;
  2.  
  3. function line(x1:Number, y1:Number, x2:Number, y2:Number, res:int=10):void{
  4.     var dx:Number = x2 - x1;
  5.     var dy:Number = y2 - y1;
  6.     var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
  7.     var step:Number = 1 / (dist / res);
  8.     for (var i:Number = 0; i<=1; i+= step){
  9.         // lerp : a  + (b - a) * f
  10.         canvas.setPixel(x1 + dx * i, y1 + dy * i, 0xFFFFFF);
  11.     }
  12. }
  13.  
  14. addEventListener(Event.ENTER_FRAME, onLoop);
  15. function onLoop(evt:Event):void {
  16.    canvas.fillRect(canvas.rect, 0x000000);
  17.   line(100 , 100, mouseX, mouseY,1);
  18.   line(100 + 50, 100, mouseX+ 50, mouseY,5);
  19. }

Yesterday I posted an implementation of the Bresenham Line Algorithm. Today I'm posting a comparatively slow way to draw a line with setPixel(). This snippet uses lerp and the Pythagorean theorem. It works nicely for small numbers of lines, its easy to draw dotted lines with it and its easy to explain. In a real app where you needed to use setPixel() to draw a line you should use one of the fast algorithms like Wu or Bresenham.

I didn't originally write this snippet to use set pixel... a few weeks ago I wrote something very similar to calculate a set of x y coords between two given points. In the program I used it in speed wasn't an issue (as I only needed to run the function one time). I've needed this kind of function many times before in games and small apps...

This was the original:

Actionscript:
  1. function calculatePoints(x1:Number, y1:Number, x2:Number, y2:Number, res:int=10):Array{
  2.     var points:Array = new Array();
  3.     var dx:Number = x2 - x1;
  4.     var dy:Number = y2 - y1;
  5.     var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
  6.     var step:Number = 1 / (dist / res);
  7.     for (var i:Number = 0; i<=1; i+= step){
  8.         points.push(new Point(x1 + dx * i, y1 + dy * i));
  9.     }
  10.     return points;
  11. }
  12.  
  13. trace(calculatePoints(0,0,100,0,10));
  14. /* outputs:
  15. (x=0, y=0),(x=10, y=0),(x=20, y=0),(x=30.000000000000004, y=0),(x=40, y=0),(x=50, y=0),(x=60, y=0),(x=70, y=0),(x=80, y=0),(x=89.99999999999999, y=0),(x=99.99999999999999, y=0)
  16. */

...and another version to allow you to specify the number of points to calculate rather than the pixel interval at which they should be calculated:

Actionscript:
  1. function calculatePoints(x1:Number, y1:Number, x2:Number, y2:Number, pointNum:int=10):Array{
  2.     var points:Array = new Array();
  3.     var step:Number = 1 / (pointNum + 1);
  4.     for (var i:Number = 0; i<=1; i+= step){
  5.         points.push(new Point(x1 + (x2 - x1) * i, y1 + (y2 - y1) * i));
  6.     }
  7.     return points;
  8. }
  9.  
  10. trace(calculatePoints(0,30,30,0,1));
  11. /* outputs:
  12. (x=0, y=30),(x=15, y=15),(x=30, y=0)
  13. */

This last version isn't perfect, sometimes the pointNum will be off by 1, I may fix that in a future post.

Posted in Math, graphics algorithms, misc, pixel manipulation, setPixel | Also tagged | Leave a comment