as3 tween position relative to current position - actionscript-3

I have a tween set on a timer:
var manTimer:Timer = new Timer(1000,14);
manTimer.addEventListener(TimerEvent.TIMER, moveMan);
function moveMan(e:TimerEvent):void {
var manX:Tween = new Tween(man, "x", Regular.easeOut, 0, -40, 1, true);
}
I just need to make the tween's position relative to it's current position, as opposed to starting at the stage's 0 position then moving the the stage's -40 position. It needs to start at its current position the move -40 from that position.
Thanks,
Wade

var manX:Tween = new Tween(man, "x", Regular.easeOut, man.x, man.x - 40, 1, true);

Related

Tween functions for series of menus wont work after the 1st

I am having a problem with a series of drop down menus i'm trying to make. I have 3 buttons, each of which when hovered over, drops down a sub menu with options. The problem I'm running into is that the first menu works, it drops down as it should. The second and third menus however do not work, and I don't understand why. I'm not getting an error code, and some googling directed me to people who were having similar problems suggesting flash garbage collection might be what is causing my issue. i'm not sure how to structure it so that this wont happen. I should also add that this is my first time posting so I apologize for any format issues in the post, and I'm very new to coding so any help will be much appreciated, I don't really know the questions to ask to get me going in the right direction.
Thankyou for your time
The code I have so far is as follows
import fl.transitions.Tween;
import fl.transitions.easing.Regular;
stop();
menu_cont.paint_rect.alpha = 0;
menu_cont.trim_rect.alpha = 0;
menu_cont.wheels_rect.alpha = 0;
menu_cont.paint_btn.addEventListener(MouseEvent.ROLL_OVER, paintRollOver);
menu_cont.paint_rect.addEventListener(MouseEvent.MOUSE_OUT, paintMouseOut);
menu_cont.trim_btn.addEventListener(MouseEvent.ROLL_OVER, trimRollOver);
menu_cont.trim_rect.addEventListener(MouseEvent.MOUSE_OUT, trimMouseOut);
menu_cont.wheels_btn.addEventListener(MouseEvent.ROLL_OVER, wheelsRollOver);
menu_cont.wheels_rect.addEventListener(MouseEvent.MOUSE_OUT, wheelsMouseOut);
var paintMenuTween:Tween = new Tween (menu_cont.paint_menu, "y",
Regular.easeOut,menu_cont.paint_menu.y, 50, .5, true);
var paintMenuTween2:Tween = new Tween (menu_cont.paint_menu, "y",
Regular.easeOut,menu_cont.paint_menu.y, -15, .5, true);
var trimMenuTween:Tween = new Tween (menu_cont.trim_menu, "y",
Regular.easeOut,menu_cont.trim_menu.y, 50, .5, true);
var trimMenuTween2:Tween = new Tween (menu_cont.trim_menu, "y",
Regular.easeOut,menu_cont.trim_menu.y, -15, .5, true);
var wheelsMenuTween:Tween = new Tween (menu_cont.wheels_menu, "y",
Regular.easeOut,menu_cont.wheels_menu.y, 50, .5, true);
var wheelsMenuTween2:Tween = new Tween (menu_cont.wheels_menu, "y",
Regular.easeOut,menu_cont.wheels_menu.y, -15, .5, true);
function paintRollOver (event:MouseEvent):void {
paintMenuTween = new Tween (menu_cont.paint_menu, "y",
Regular.easeOut,menu_cont.paint_menu.y, 50, .5, true);
trace ("paint over")
}
function paintMouseOut (event:MouseEvent):void {
paintMenuTween2 = new Tween (menu_cont.paint_menu, "y",
Regular.easeOut,menu_cont.paint_menu.y, -15, .5, true);
trace ("paint out")
}
function trimRollOver (event:MouseEvent):void {
trimMenuTween = new Tween (menu_cont.trim_menu, "y", Regular.easeOut,menu_cont.trim_menu.y, 50, .5, true);
trace("trim over")
}
function trimMouseOut (event:MouseEvent):void {
trimMenuTween2 = new Tween (menu_cont.trim_menu, "y", Regular.easeOut,menu_cont.trim_menu.y, -15, .5, true);
trace("trim out")
}
function wheelsRollOver (event:MouseEvent):void {
wheelsMenuTween = new Tween (menu_cont.wheels_menu, "y", Regular.easeOut,menu_cont.wheels_menu.y, 50, .5, true);
trace ("wheels over")
}
function wheelsMouseOut (event:MouseEvent):void {
wheelsMenuTween2 = new Tween (menu_cont.wheels_menu, "y", Regular.easeOut,menu_cont.wheels_menu.y, -15, .5, true);
trace ("wheels out")
}

Start Tween when other Tween reaches certain position AS3

I'm trying to create a simple slideshow of 3 images going from left to right.
I want to check if the last image is on stage ( so the image3.x = 0 ) in order to start the new Tween.
I thought it would be something a simple as the following code, but that doesn't seem to work.
function Start() {
if(image3.x == 0){
var myTween:Tween = new Tween(image, "x", None.easeNone, -140, 640, 10, true);
}
}
stage.addEventListener(Event.ENTER_FRAME, Start);
Split the original Tween in two parts, from -140 to 0 and from 0 to 640.
var tween:Tween = new Tween(image, "x", None.easeNone, -140, 0, 10, true);
Wait for it to finish:
tween.addEventListener(TweenEvent.MOTION_FINISH, onZeroReached);
Then do the second part plus whatever else you want to do:
function onZeroReached(te:TweenEvent):void
{
tween = new Tween(image, "x", None.easeNone, 0, 640, 10, true);
// do additional stuff here
}
code untested

As3 draw bitmap + copyPixel around mouseX and mouseY

I am doing a magnifying glass effect?
I have a working version. However the performance is not good enough on the tablet.
What i have done so far:
I had a ENTERFRAME event on a mouseDown
So it start capture the screen when the mouse click down, and follow the mouseX and mouseY
It works, but the only problem it keep draw the whole stage rather than maybe (300px * 300px) around the mouseX and mosueY. is there a way i can make the draw area according to your mouseX and mouseY. I guess that would help the performance as well. :)
e.target.removeEventListener(Event.ENTER_FRAME, startCapture);
function startCapture(e:Event):void{
var glassWidth:uint=80;
var glassHeight:int=80;
var curBd:BitmapData;
var curBmp:Bitmap;
var posX:int = _parentStage.mouseX - 40;
var posY:int = _parentStage.mouseY - 40;
//-------------------------------------------------------------
//var subArea:Rectangle = new Rectangle(0,0,500,500);
//var newBmp:Bitmap = new BitmapData(500,500);
//var cutoutBmp:Bitmap = new Bitmap( newBmp, PixelSnapping.ALWAYS, true );
//cutoutBmp.bitmapData.draw( jpgSource, new Matrix(1, 0, 0, 1, -357, -341) , null, null, subArea, true );
//-------------------------------------------------------------
bd = new BitmapData(1024, 768, true, 0);
var subArea:Rectangle = new Rectangle(_parentStage.mouseX, _parentStage.mouseY, 500, 500);
// bd = new BitmapData(500, 500);
bd.draw(_parentStage.mc_mainContainer);
// bd.draw(_parentStage.mc_mainContainer);
curBmp=new Bitmap(new BitmapData(glassWidth,glassHeight), PixelSnapping.ALWAYS);
curBmp.bitmapData.copyPixels(bd,new Rectangle(posX,posY,_parentStage.mouseX,_parentStage.mouseY),new Point(0,0));
curBd=curBmp.bitmapData;
var ma:Matrix = new Matrix(1, 0, 0, 1, -40, -40);
glass.name = 'glass';
glass.alpha = 1;
glass.graphics.clear();
glass.graphics.beginBitmapFill(curBd, ma);
glass.graphics.drawCircle(0, 0, 35);
//glass.graphics.drawCircle(0, 0, 35);
glass.graphics.endFill();
//var imageCircle:Bitmap = new _magGlass();
//trace(_magGlass);
//glass.addChild(_magGlass);
if(!_parentStage.contains(glass))_parentStage.addChildAt(glass, _parentStage.numChildren - 2);
glass.x = _parentStage.mouseX;
glass.y = _parentStage.mouseY - 75;
}
Where your performance problem is coming from is where you're creating new bitmaps and bitmapdatas and rectangles on every frame. Instead, just create one or two in the constructor or on click and then reuse them. Since you already have a BitmapData, you can probably just put that on the stage and mask it, rather than using the graphics object in glass. At least pick one approach or the other. Doing both is killing you, performance wise.

set zoom on mouse click target to center of stage

I'm having toruble with an image that I zoom into in flash. I got everything to work, only I want the clicked X and Y coordinats to center to the stage. ( so that the area clicked on always zooms in and position the area clicked to the middle of the stage)
the image is a movieclip and it zooms with a tween, but i tried everything but the image wont center the stage..
does anyone have a clue for wich actionscript 3 code I can use to do this?
my code is:
const TWEEN_IN:String = "tweenIn";
const TWEEN_OUT:String = "tweenOut";
var tweenDirection:String;
var internalPoint:Point;
var externalPoint:Point;
var tw:Tween;
square.x = stage.stageWidth - square.width/2;
square.y = stage.stageHeight - square.height/2;
square.addEventListener(MouseEvent.CLICK, zoomIn);
function zoomIn($e:MouseEvent):void
{
square.removeEventListener(MouseEvent.CLICK, zoomIn);
//internalPoint = new Point(stage.width/2, stage.height/2);
internalPoint = new Point(square.mouseX, square.mouseY);
//externalPoint = new Point(500, 350);
externalPoint = new Point(stage.mouseX, stage.mouseY);
tweenDirection = TWEEN_IN;
tw = new Tween(null, "", Strong.easeOut, square.scaleX, 3, 1, true);
tw.addEventListener(TweenEvent.MOTION_CHANGE, _syncScale);
tw.addEventListener(TweenEvent.MOTION_FINISH, _cleanTween);
}
function _syncScale($e:TweenEvent):void
{
square.scaleX = square.scaleY = tw.position;
var matrix:Matrix = square.transform.matrix;
MatrixTransformer.matchInternalPointWithExternal(matrix, internalPoint, externalPoint);
square.transform.matrix = matrix;
}
function _cleanTween($e:TweenEvent):void
{
tw.removeEventListener(TweenEvent.MOTION_CHANGE, _syncScale);
tw.removeEventListener(TweenEvent.MOTION_FINISH, _cleanTween);
tw = null;
if(tweenDirection == TWEEN_IN)
stage.addEventListener(MouseEvent.CLICK, zoomOut);
else if(tweenDirection == TWEEN_OUT)
square.addEventListener(MouseEvent.CLICK, zoomIn);
}
function zoomOut($e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.CLICK, zoomOut);
//internalPoint = new Point(0, 0);
//externalPoint = new Point(0, 0);
externalPoint = square.localToGlobal(internalPoint);
internalPoint = square.globalToLocal(externalPoint);
tweenDirection = TWEEN_OUT;
tw = new Tween(null, "", Strong.easeOut, square.scaleX, 1, 1, true);
tw.addEventListener(TweenEvent.MOTION_CHANGE, _syncScale);
tw.addEventListener(TweenEvent.MOTION_FINISH, _cleanTween);
}
Just do this as you're zooming in:
square.x = externalPoint.x - (internalPoint.x * square.scaleX);
square.y = externalPoint.y - (internalPoint.y * square.scaleY);
This assumes that the square has it's origin/registration point in the top left, and works by taking the distance between registration point and click (internalPoint) and then making sure that the same distance is kept, albeit scaled, after the scale is complete.
Explained in another way, it stores the center of the click in internalPoint (which is relevant to the top left of the square), and the stage position of that same point in externalPoint (which is absolute). This means that were you to instantly (before zooming) do the following, it would have no effect:
square.x = externalPoint.x - internalPoint.x;
After the scale however, the internalPoint no longer gives an accurate measurement of the absolute distance between the top left corner and the mouse click. Instead, you need to scale it the same amount that the square has been scaled, for that to be accurate, which is why my suggestion above should work.

Actionscript 3: How to remove all black pixels from BitmapData?

Let say I have a BitmapData with different pixels representing an object, and some black pixels around it that I want to remove.
I would like to obtain a new BitmapData, with width and height of the object represented by non-black pixels.
For example, let say I have a BitmapData 400x400px, but the object represented by non-black pixels occupies the rect: x=100, y=100, width=200, height=200. I want to get new BitmapData representing that rect, all black pixels should be removed. Of course, i have no coordinates for that rectangle, i need somehow to make difference between a full black bitmapdata and the original one, and construct a new bitmapdata (different width and height).
Any idea on how to do this please ?
You can use getColorBoundsRect to find the dimensions of the differently-colored-pixels inside your BitmapData:
//some fake data
var yourBigBmd:BitmapData = new BitmapData( 300, 300, false, 0 );
yourBigBmd.fillRect( new Rectangle( 10, 10, 30, 60 ), 0xFF0000 );
//a little notch
yourBigBmd.fillRect( new Rectangle( 10, 10, 10, 10), 0x00000 );
var blackColor:uint = 0x000000;
var littleBmdBounds:Rectangle = yourBigBmd.getColorBoundsRect( 0xFFFFFF, blackColor, false );
trace( "littleBmdBounds: " + littleBmdBounds );
This will trace littleBmdBounds: (x=10, y=10, w=30, h=60)
Next, we need to copy what's in those bounds into a new BitmapData:
var littleBmd:BitmapData = new BitmapData( littleBmdBounds.width, littleBmdBounds.height, true, 0 );
var mx:Matrix = new Matrix();
mx.translate( -littleBmdBounds.x, -littleBmdBounds.y );
littleBmd.draw( yourBigBmd, mx );
Finally, use threshold to remove any remaining black and make it transparent:
var blackAlphaColor:uint = 0xFF000000;
var transparentColor:uint = 0x00000000;
littleBmd.threshold( littleBmd, littleBmd.rect, littleBmd.rect.topLeft, "==", blackAlphaColor, transparentColor )