在ActionScript 3中为圆形矩形设置动画

时间:2022-06-10 23:40:22

I'm trying to animate a round rectangle in ActionScript 3.

我正在尝试在ActionScript 3中为圆形矩形设置动画。

I want it to appear in the centre of the screen, and then grow out quickly in all four directions. Initial size should be about 30x10 pixels and final size about 300x100 pixels. The animation should take somewhere between 500 and 1000 milliseconds. I'd like the box to slightly outgrow these dimensions in the last few frames and then bounce back to the right size.

我希望它出现在屏幕的*,然后在所有四个方向快速生长。初始大小应为约30x10像素,最终大小约为300x100像素。动画应该占用500到1000毫秒之间的某个时间。我希望盒子在最后几帧中略微超过这些尺寸,然后弹回到合适的尺寸。

I'm now using a Back easeOut tween and a scale9Grid, thanks to TypeOneError's suggestion, however I'm still not out of the woods. I can get the box to bounce out right and downwards, and the animation looks right, except I would like the box to remain centered. The function ScaleFromCenterConstant is almost right, as the box remains centered, however if I send through the scale calculated by the tween the box explodes off the screen.

我现在正在使用Back easeOut补间和scale9Grid,感谢TypeOneError的建议,但是我仍然没有走出困境。我可以让盒子向右和向下反弹,动画看起来正确,除了我希望盒子保持居中。函数ScaleFromCenterConstant几乎是正确的,因为框保持居中,但是如果我通过补间计算的比例发送,则框会从屏幕上爆炸。

Should I be using Matrix.scale() or should I be setting Matrix.a .d .tx and .ty individually?

我应该使用Matrix.scale()还是应该单独设置Matrix.a .d .tx和.ty?

Here's my code thus far :

到目前为止,这是我的代码:

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;
    }

}   
}

UPDATE :

Yay, thanks to Niko Nyman, I got it working. Here is the final code for the interested few :

是的,感谢Niko Nyman,我明白了。以下是感兴趣的少数人的最终代码:

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 个解决方案

#1


Could you just draw the graphics centered (ie. put the top-left corner at x = -startWidth/2 and y = -startHeight/2 instead of 0, 0), then do a simple tween of scale on mySprite? This way you could get rid of all the matrix calculations...

你能不能画出居中的图形(即把左上角放在x = -startWidth / 2而y = -startHeight / 2而不是0,0),然后在mySprite上做一个简单的缩放补间?这样你就可以摆脱所有的矩阵计算......

#2


Have you tried to use easeOut?

你试过使用easeOut吗?

myTween = new Tween(o, "scale", Elastic.easeOut, 1, 1.5, 0.75, true);

#3


If you're looking to "outgrow" and come back, you want the Back.easeOut transition. Might I also suggest that you use the Flash Authoring tool to speed up the creation of the graphics as well? You could use the Rectangle Primitive tool to create a rounded rectangle, convert it to a MovieClip or Sprite and select 9-slice-scaling. If you adjust the slices so they start and end where the curve starts, it will only scale the center up and the corners will stay round.

如果你想要“超长”并回来,你需要Back.easeOut过渡。我是否也建议您使用Flash创作工具来加速图形的创建?您可以使用Rectangle Primitive工具创建圆角矩形,将其转换为MovieClip或Sprite并选择9切片缩放。如果您调整切片使它们开始和结束曲线开始的位置,它只会向上缩放中心并且角落将保持圆形。

#1


Could you just draw the graphics centered (ie. put the top-left corner at x = -startWidth/2 and y = -startHeight/2 instead of 0, 0), then do a simple tween of scale on mySprite? This way you could get rid of all the matrix calculations...

你能不能画出居中的图形(即把左上角放在x = -startWidth / 2而y = -startHeight / 2而不是0,0),然后在mySprite上做一个简单的缩放补间?这样你就可以摆脱所有的矩阵计算......

#2


Have you tried to use easeOut?

你试过使用easeOut吗?

myTween = new Tween(o, "scale", Elastic.easeOut, 1, 1.5, 0.75, true);

#3


If you're looking to "outgrow" and come back, you want the Back.easeOut transition. Might I also suggest that you use the Flash Authoring tool to speed up the creation of the graphics as well? You could use the Rectangle Primitive tool to create a rounded rectangle, convert it to a MovieClip or Sprite and select 9-slice-scaling. If you adjust the slices so they start and end where the curve starts, it will only scale the center up and the corners will stay round.

如果你想要“超长”并回来,你需要Back.easeOut过渡。我是否也建议您使用Flash创作工具来加速图形的创建?您可以使用Rectangle Primitive工具创建圆角矩形,将其转换为MovieClip或Sprite并选择9切片缩放。如果您调整切片使它们开始和结束曲线开始的位置,它只会向上缩放中心并且角落将保持圆形。