2

我在补间时尝试围绕外部点旋转矩形没有成功。我试图将红色矩形的顶部锁定到线,同时它从左到右补间并从 0º 旋转到 90º。

替代文字 http://www.freeimagehosting.net/uploads/0b937c92e6.png

上图显示了补间的 3 种状态。状态 1 显示直线开头的红色矩形,没有角度。状态 2 显示红色矩形沿线的一半补间,角度为 45º,也是总角度 90º 的一半。状态 3 显示补间的最终位置,其中红色矩形的角度为 90º,并位于线条的边缘。

我遇到的问题似乎是在补间时,旋转导致红色矩形的顶部与黑线失去同步。

这是我的代码不起作用,但希望能让您更清楚地了解我正在尝试的内容。

var angle:Number = 90;
var previousAngle:Number = 0;

var distanceObject:Object = new Object();
distanceObject.distance = line.width;

distanceTween = new Tween(distanceObject, "distance", None.easeNone, 0, distanceObject.distance, 5, true);
distanceTween.addEventListener(TweenEvent.MOTION_CHANGE, tweenHandler);

function tweenHandler(evt:TweenEvent):void
    {
    var angleShift:Number = (angle / distance) * distanceObject.distance;

    //1:tween RedBox position
    redBox.x = line.x + line.width * distanceObject.distance;

    //2:tween RedBox angle
    var externalPointMatrix:Matrix = redBox.transform.matrix;
    MatrixTransformer.rotateAroundExternalPoint(externalPointMatrix, 0 + redBox.width * distanceObject.distance, 0, angleShift - previousAngle);
    redBox.transform.matrix = externalPointMatrix;

    previousAngle = angleShift;
    }
4

1 回答 1

2

我认为您没有很好地为通用解决方案指定问题。这里有 3 个变化:x、y 和旋转。这些中的每一个都是根据矩形上的一个点(图中的蓝色“x”)随时间变化而计算出来的。这意味着您首先需要关注的是矩形上随时间变化的点。接下来,您需要知道可以使用该点以及旋转来计算 x 和 y。

所以把它分解成几个步骤。

  1. 找到线上“x”点的位置
  2. 旋转对象
  3. 找到矩形的“x”点的位置
  4. 根据旋转角度和“x”点的已知位置计算矩形的 x 和 y 位置(SOHCHAHTOA

这里有一些代码来说明:

package
{

import com.greensock.TweenNano;

import flash.display.Sprite;
import flash.events.Event;

[SWF(width='500', height='300', backgroundColor='#ffffff', frameRate='30')]
public class BoxAnim extends Sprite
{
    private static const LINE_WIDTH:int = 350;
    private static const RECT_WIDTH:int = 150;
    private static const RECT_HEIGHT:int = 100;
    private static const FINAL_ROTATION:Number = Math.PI/2;

    public var point:Number;

    private var line:Sprite;
    private var rect:Sprite;
    private var cross:Sprite;

    public function BoxAnim()
    {
        addEventListener(Event.ADDED_TO_STAGE, addedToStage);
    }

    private function addedToStage(event:Event):void
    {
        line = new Sprite();
        addChild(line);
        line.graphics.lineStyle(10, 0x0);
        line.graphics.lineTo(LINE_WIDTH, 0);
        line.x = 50;
        line.y = 175;

        rect = new Sprite();
        addChild(rect);
        rect.graphics.lineStyle(4, 0xFF0000);
        rect.graphics.beginFill(0xFF0000, 0.5);
        rect.graphics.drawRect(0, 0, RECT_WIDTH, RECT_HEIGHT);
        rect.x = 50;
        rect.y = 175;

        cross = new Sprite();
        addChild(cross);
        cross.graphics.lineStyle(5, 0x41a9f4);
        cross.graphics.moveTo(-5, -5);
        cross.graphics.lineTo(5, 5);
        cross.graphics.moveTo(5, -5);
        cross.graphics.lineTo(-5, 5);
        cross.x = 50;
        cross.y = 175;

        point = 0;
        TweenNano.to(this, 3, {point: 1, onUpdate: tick});
    }

    private function tick():void
    {
        // first calculate where the point should be on the line
        cross.x = (point * LINE_WIDTH) + line.x;

        // calculate the angle of rotation
        var rotationRadians:Number = (point * FINAL_ROTATION);
        rect.rotation = rotationRadians*180/Math.PI;

        // calculate where on the rectangle the point would be
        var rectCrossX:Number = (point * RECT_WIDTH);
        // use trig to find the x & y points
        rect.x = cross.x - Math.cos(rotationRadians)*rectCrossX;
        rect.y = cross.y - Math.sin(rotationRadians)*rectCrossX;
    }
}

}

我只是将变量point用作从 0 到 1 的百分比。然后我对其进行缩放以找到线上“x”点的位置。再次缩放以计算旋转。再次缩放它以找到它位于矩形顶部的位置。然后 trig 求解该点的矩形角的位置。

于 2010-06-22T01:36:22.967 回答