3

Flexコンテナ(絶対位置)にオブジェクトがあり、そのスケール値を非常に低く設定してから回転させると、スケールが減少するにつれて回転が「チョッパー」になります。問題を再現するコードを含めています。「上矢印」を押してオブジェクトを縮小し(「下」を押して拡大)、「ページアップ」を押してオブジェクトのサイズを大きくし、引き続きオブジェクトを表示できます。縮小した後、「左」と「右」を使用して回転させることができます。オブジェクトが縮小されていない場合、オブジェクトはきれいに回転しますが、オブジェクトを縮小すると(オブジェクトのサイズを大きくして、まだ表示できるように)、回転が途切れる場合があります。何か案は?

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:test="com.test.*"
                   resize="onResize()" addedToStage="onStart()" removedFromStage="onEnd()">
<fx:Script>
    <![CDATA[
        [Bindable]
        private var _rotation:Number = 0;

        [Bindable]
        private var _scale:Number = 1;

        [Bindable]
        private var _blockSize:Number = 100;

        protected function onStart():void {
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
        }

        protected function onEnd():void {
            stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
        }

        protected function onResize():void {
            if (Layer) {
                Layer.x = width/2
                Layer.y = height/2;
            }
        }

        protected function onKeyDown(event:KeyboardEvent):void {
            if (event.keyCode == Keyboard.LEFT) {
                Layer.rotation += -1;
            }
            if (event.keyCode == Keyboard.RIGHT) {
                Layer.rotation += 1;
            }
            if (event.keyCode == Keyboard.UP) {
                Layer.scaleX = Layer.scaleY = (Layer.scaleX / 2);
            }
            if (event.keyCode == Keyboard.DOWN) {
                Layer.scaleX = Layer.scaleY = (Layer.scaleX * 2);
            }
            if (event.keyCode == Keyboard.PAGE_UP) {
                _blockSize *=2;
            }
            if (event.keyCode == Keyboard.PAGE_DOWN) {
                _blockSize /=2;
            }
            this._rotation = Layer.rotation;
            this._scale = Layer.scaleX;
        }
    ]]>
</fx:Script>
<s:SkinnableContainer id="Layer">
    <test:RotatedComponent width="{_blockSize}" height="{_blockSize}"/>
</s:SkinnableContainer>
<s:Label x="10" y="10" text="Rotation: {_rotation}"/>
<s:Label x="10" y="30" text="Scale: {_scale}"/>
<s:Label x="10" y="50" text="Block: {_blockSize}"/>
</s:WindowedApplication>

RotatedComponent.mxmlのコード

package com.test {

import mx.core.UIComponent;

public class RotatedComponent extends UIComponent {

    public function RotatedComponent() {
        super();
    }

    override public function set width(value:Number):void {
        super.width = value;
        this.x = - (width/2);
    }

    override public function set height(value:Number):void {
        super.height = value;
        this.y = - (height/2);
    }

    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
        graphics.lineStyle(2, 0x333333);
        graphics.beginFill(0x660000);
        graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
        graphics.endFill();
        graphics.lineStyle(2, 0xffffff);
        graphics.drawCircle(unscaledWidth/2, unscaledHeight/2, 5);
    }
}
}

ありがとう!デレク

4

1 に答える 1

1

これは正式にはバグと呼べると思います。component.scale()とcomponent.rotation()を設定するのではなく、変換の行列を計算すると、結果は正しくなります。私の最善の推測は、Flexセッターの下のコードのどこかに丸め誤差があることです(私はすべてのFlexコードをステップスルーしましたが、奇妙なことは何も起こっていませんでした)。だから短い答え:

それ以外の:

component.scaleX = component.scaleY = _scale;
component.rotation = _rotation;

使用する

var matrix:Matrix = new Matrix();
matrix.scale(_scale, _scale);
matrix.rotate(_rotation * Math.PI / 180);
component.transform.matrix = matrix;

お役に立てば幸いです。デレク

于 2013-02-22T15:04:10.643 に答える