Анимировать круглый прямоугольник в ActionScript 3 - PullRequest
1 голос
/ 20 мая 2009

Я пытаюсь анимировать круглый прямоугольник в ActionScript 3.

Я хочу, чтобы он появился в центре экрана, а затем быстро вырос во всех четырех направлениях. Начальный размер должен быть около 30x10 пикселей, а конечный размер около 300x100 пикселей. Анимация должна занять от 500 до 1000 миллисекунд. Мне бы хотелось, чтобы окно немного переросло эти размеры в последних нескольких кадрах, а затем вернулось к нужному размеру.

Я сейчас использую анимацию Back easeOut и гамму scale9Grid, благодаря предложению TypeOneError, однако я все еще не в лесу. Я могу заставить коробку отскочить вправо и вниз, и анимация выглядит правильно, за исключением того, что я хотел бы, чтобы прямоугольник оставался по центру. Функция ScaleFromCenterConstant почти правильная, так как поле остается центрированным, однако, если я отправлю через шкалу, рассчитанную анимацией движения, окно взрывается за пределами экрана.

Должен ли я использовать Matrix.scale () или я должен настраивать Matrix.a .d .tx и .ty по отдельности?

Вот мой код:

package {

import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.*;

import flash.display.*;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.setTimeout;

public class Scaling extends Sprite
{

    private var startWidth:int = 50;
    private var startHeight:int = 30;
    private var startLineWidth:int = 5;
    private var startEllipse:int = 15;
    private var startCenter:Point = new Point(400, 300);

    public var mySprite:Sprite = new Sprite();
    public var myTween:Tween;

    public function Scaling() {
        this.stage.scaleMode = StageScaleMode.NO_SCALE;
        this.stage.align = StageAlign.TOP_LEFT;

        graphics.beginFill(0x000000);
        graphics.drawRect(0, 0, 800, 600);
        mySprite.graphics.endFill();

        mySprite.graphics.beginFill(0xF7F3DC);
        mySprite.graphics.lineStyle(startLineWidth, 0xD35F72);
        mySprite.graphics.drawRoundRect(0, 0, startWidth, startHeight, startEllipse, startEllipse);
        mySprite.graphics.endFill();

        mySprite.x = startCenter.x - startWidth / 2;
        mySprite.y = startCenter.y - startHeight / 2;
        mySprite.width = startWidth;
        mySprite.height = startHeight;

        mySprite.scale9Grid = new Rectangle(10, 10, 30, 10);

        setTimeout(GoGoGadgetScaling, 1000);
    }

    private function GoGoGadgetScaling():void {
        addChild(mySprite);

        var o:Object = new Object();
        o["scale"] = 1;

        myTween = new Tween(o, "scale", Back.easeOut, 1, 5, 0.3, true);

        myTween.addEventListener(TweenEvent.MOTION_CHANGE, function(evt:TweenEvent):void {
            //ScaleRightAndDown(mySprite, o["scale"] * 2, o["scale"], startCenter);
            //ScaleFromCenterConstant(mySprite, 1.2, 1.1, startCenter);
            ScaleFromCenter(mySprite, o["scale"], o["scale"], startCenter);
        });

        myTween.addEventListener(TweenEvent.MOTION_FINISH, function(evt:TweenEvent):void {
            setTimeout(function():void {
                var tf:TextField = new TextField();
                tf.autoSize = TextFieldAutoSize.LEFT;
                tf.text = "Finished...";
                mySprite.addChild(tf);
            }, 100);
        });
    }

    private function ScaleRightAndDown(ob:*, sx:Number, sy:Number, ptScalePoint:Point):void {
        var m:Matrix = ob.transform.matrix;
        m.a = sx;
        m.d = sy;
        mySprite.transform.matrix = m;
    }

    private function ScaleFromCenterConstant(ob:*, sx:Number, sy:Number, ptScalePoint:Point):void {
        var m:Matrix = ob.transform.matrix;
        m.ty -= ptScalePoint.y;
        m.tx -= ptScalePoint.x;
        m.scale(sx, sy);
        m.tx += ptScalePoint.x;
        m.ty += ptScalePoint.y;
        ob.transform.matrix = m;
    }

    // This does not work
    private function ScaleFromCenter(ob:*, sx:Number, sy:Number, ptScalePoint:Point):void {
        var m:Matrix = ob.transform.matrix;
        m.ty -= ptScalePoint.y;
        m.tx -= ptScalePoint.x;
        m.scale(sx, sy);
        m.a = sx;
        m.d = sy;
        m.tx += ptScalePoint.x;
        m.ty += ptScalePoint.y;
        ob.transform.matrix = m;
    }

}   
}

ОБНОВЛЕНИЕ:

Да, спасибо Нико Найману, у меня все получилось. Вот окончательный код для немногих заинтересованных:

package {

import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.*;
import flash.display.*;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.*;
import flash.utils.setTimeout;

public class Scaling extends Sprite
{

    private var startWidth:int = 400;
    private var startHeight:int = 150;
    private var startLineWidth:int = 5;
    private var startEllipse:int = 15;
    private var startCenter:Point = new Point(400, 300);

    public var mySprite:Sprite = new Sprite();
    public var myTween:Tween;

    public function Scaling() {
        this.stage.scaleMode = StageScaleMode.NO_SCALE;
        this.stage.align = StageAlign.TOP_LEFT;

        mySprite.graphics.beginFill(0xF7F3DC);
        mySprite.graphics.lineStyle(startLineWidth, 0xD35F72);
        mySprite.graphics.drawRoundRect(-startWidth/2, -startHeight/2, startWidth, startHeight, startEllipse, startEllipse);
        mySprite.graphics.endFill();

        mySprite.x = startCenter.x;
        mySprite.y = startCenter.y;

        mySprite.scale9Grid = new Rectangle(-startWidth/2 + startEllipse/2, -startHeight/2 + startEllipse/2, startWidth - startEllipse, startHeight - startEllipse);

        mySprite.scaleX = 0;
        mySprite.scaleY = 0;

        addChild(mySprite);

        setTimeout(GoGoGadgetScaling, 1000);
    }

    private function GoGoGadgetScaling():void {

        var o:Object = new Object();
        o["scale"] = 1;

        myTween = new Tween(o, "scale", Back.easeOut, 0.1, 1, 0.5, true);

        myTween.addEventListener(TweenEvent.MOTION_CHANGE, function(evt:TweenEvent):void {
            mySprite.scaleX = o["scale"];
            mySprite.scaleY = o["scale"];
        });

        myTween.addEventListener(TweenEvent.MOTION_FINISH, function(evt:TweenEvent):void {
            setTimeout(function():void {
                var tf:TextField = new TextField();
                tf.autoSize = TextFieldAutoSize.LEFT;
                tf.text = "Finished...";
                mySprite.addChild(tf);
            }, 100);
        });
    }

}   
}

Ответы [ 3 ]

0 голосов
/ 22 мая 2009

Если вы хотите «перерасти» и вернуться, вам нужен переход Back.easeOut. Могу ли я также предложить вам использовать Flash Authoring tool для ускорения создания графики? Вы можете использовать инструмент Rectangle Primitive, чтобы создать прямоугольник с закругленными углами, преобразовать его в MovieClip или Sprite и выбрать 9-фрагментное масштабирование. Если вы отрегулируете срезы так, чтобы они начинались и заканчивались там, где начинается кривая, он будет только увеличивать центр, а углы будут оставаться круглыми.

0 голосов
/ 26 мая 2009

Не могли бы вы просто нарисовать графику по центру (т.е. поставить верхний левый угол на x = -startWidth/2 и y = -startHeight/2 вместо 0, 0), а затем сделать простую анимацию масштаба на mySprite? Таким образом, вы можете избавиться от всех расчетов матрицы ...

0 голосов
/ 20 мая 2009

Вы пытались использовать easyOut?

myTween = new Tween(o, "scale", Elastic.easeOut, 1, 1.5, 0.75, true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...