Whenever there is a bitmap moving around that just doesn’t look “smooth” enough try this trick out:
1 | bitmap.scaleY = 1.001; |
Or this, either way:
1 | bitmap.scaleX = 0.999; |
Check a comparison between a normal bitmap (left) and the hacked one (right), you can clearly see the difference:
This movie requires Flash Player 9
Although both bitmaps set the smoothing property to true only the one in the left-hand side is a bit shaky. It turns out that only when its scale properties (scaleX or scaleY) are different than 1 it actually applies the smoothing – weird.
Here’s code of this example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | package { import caurina.transitions.Tweener; import flash.display.Bitmap; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.display.PixelSnapping; /** * @author Grifo.tv / Danilo Figueiredo - www.grifo.tv */ [SWF(width="700", height="100", frameRate="50", backgroundColor="#ffffff")] public class BitmapSmoothingTip extends Sprite { // ------------------------------------ // private, protected properties // ------------------------------------ protected var _arrows : Vector.<Bitmap>; protected var _arrowsX : Vector.<Number>; protected var _arrowsY : Vector.<Number>; // ------------------------------------ // public properties // ------------------------------------ // ------------------------------------ // constructor // ------------------------------------ public function BitmapSmoothingTip() { addEventListener(Event.ADDED_TO_STAGE, added, false, 0, true); } // // PRIVATE, PROTECTED // ______________________________________________________________ protected function added(e : Event) : void { removeEventListener(Event.ADDED_TO_STAGE, added, false); stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; init(); } protected function init() : void { // create vectors _arrows = new Vector.<Bitmap>(); _arrowsX = new Vector.<Number>(); _arrowsY = new Vector.<Number>(); // add normal bitmap addArrow(250.0, 25.0, false); // add smooth bitmap addArrow(380.0, 25.0, true); } protected function addArrow(posX : Number = 0.0, posY : Number = 0.0, hackSmoothing : Boolean = false) : void { // create bitmap var bitmap : Bitmap = new Bitmap(new Arrow(0.0, 0.0), PixelSnapping.NEVER); bitmap.x = posX; bitmap.y = posY; addChild(bitmap); // smoothing bitmap.smoothing = true; if (hackSmoothing) { bitmap.scaleY = 1.001; } // store bitmap properties _arrows.push(bitmap); _arrowsX.push(posX); _arrowsY.push(posY); // start animation animateArrow(_arrows.length - 1, Math.random()); } protected function animateArrow(index : uint, delay : Number = 0.0) : void { var time : Number = 1.5; // move up/right Tweener.addTween(_arrows[index], {x: _arrowsX[index] + 15, y: _arrowsY[index] - 15, time: time, transition: "easeInOutCirc", delay: delay}); // move down/left Tweener.addTween(_arrows[index], {x: _arrowsX[index], y: _arrowsY[index], time: time, transition: "easeInOutCirc", delay: delay + time, // and loop onComplete: animateArrow, onCompleteParams: [index]}); } // PUBLIC // ______________________________________________________________ } } |
Download the source of this example from here bitmap-smoothing-tip.zip (98KB, Flash CS4, Actionscript 3). With FLA file ready to be compiled.
4 Comments
You’re achieving a “smoothing” effect on your tween for a different reason then why you might think…
The reason the first is choppy is because by default a bitmap object has pixelSnapping set to “auto” which will snap to the nearest pixel when the bitmap isn’t being scaled or rotated; if you set the pixelSnapping property of your bitmap to PixelSnapping.NEVER you’ll see the same result and not have to scale your bitmap for no reason.
The smoothing property has to do with whether or not something will look overly pixelated if/when you do scale it. You indirectly turned off pixelSnapping by scaling the image slightly since it was still set to “auto”. You dig? =)
I have tried the PixelSnapping.NEVER but it does not seem to help much, that is why I had to workaround. I changed my example so it creates both bitmaps with PixelSnapping.NEVER, have a look.
very interesting point chrixian! ( :
Dan, amazing trick man! you are balls are giant!
cyasoon
This is a wonderful trick!
The AS3 doc is talking about that in the auto option (http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/PixelSnapping.html#AUTO):
A constant value used in the pixelSnapping property of a Bitmap object to specify that the bitmap image is snapped to the nearest pixel if it is drawn with no rotation or skew and it is drawn at a scale factor of 99.9% to 100.1%. If these conditions are satisfied, the image is drawn at 100% scale, snapped to the nearest pixel. Internally, this setting allows the image to be drawn as fast as possible by using the vector renderer.
But the auto option is actually not doing anything, or maybe you do need to select the auto option AND change the scale to 1.001?
Romu