Неустойчивая анимация Flex 4.5.1 при использовании события MOUSE_MOVE для запускаанимация TileGroup внутри холста - PullRequest
0 голосов
/ 01 сентября 2011

По сути, я пытаюсь изменить атрибуты horizontalCenter и verticalCenter компонента TileGroup, измененные обратно пропорционально движению мыши, и использовать эффект искрового движения, чтобы сделать это движение плавным. TileGroup - это потомок mx: Canvas, ширина которого 100%, а высота 100%. Их около 20 или около того BorderContainers внутри TileGroup.

Для примера того, как это должно работать, посмотрите на http://gallery.artofgregmartin.com/

Моя версия движется так же, как и та, но она не такая гладкая. Глядя на загрузку процессора и мой, и его использование примерно одинаково (80-90%, когда идет движение), но мы различаемся в использовании GPU. Мой использует только около 4%, а его около 10%.

Вот мой код движения:

private function onMouseMove(event:MouseEvent):void{
    var stageCenterX:Number = this.stage.stageWidth/2;
    var stageCenterY:Number = this.stage.stageHeight/2;
    var sliderPanelCenterX:Number = sliderPanel.width/2;
    var sliderPanelCenterY:Number = sliderPanel.height/2;
    var mouseX:Number = event.stageX;
    var mouseY:Number = event.stageY;
    var offsetX:Number = 0;
    var offsetY:Number = 0;
    var padding:Number = 400;

    var multX:Number = (stageCenterX - mouseX)/stageCenterX;
    offsetX = (multX * sliderPanelCenterX);

    if(mouseX <= stageCenterX){
        offsetX = offsetX - Math.abs(multX * stageCenterX) + Math.abs(multX * padding);
    }
    else {
        offsetX = offsetX + Math.abs(multX * stageCenterX) - Math.abs(multX * padding);
    }

    var multY:Number = (stageCenterY - mouseY)/stageCenterY;
    offsetY = (multY * sliderPanelCenterY);

    if(mouseY <= stageCenterY){
        offsetY = offsetY - Math.abs(multY * stageCenterY) + Math.abs(multY * padding); 
    }
    else {
        offsetY = offsetY + Math.abs(multY * stageCenterY) - Math.abs(multY * padding);
    }

    panelHC = Math.round(offsetX);
    panelVC = Math.round(offsetY);

    movePanel.captureStartValues();
    sliderPanel.verticalCenter = panelVC;   //sliderPanel is the id for the TileGroup
    sliderPanel.horizontalCenter = panelHC;
    movePanel.play();
}

А вот почтительный mxml-код:

<fx:Declarations>
    <s:Move id="movePanel" target="{sliderPanel}" />
</fx:Declarations>
<mx:Canvas width="100%" height="100%" backgroundColor="#111111" 
    horizontalScrollPolicy="off" 
    verticalScrollPolicy="off">
    <s:TileGroup id="sliderPanel" horizontalGap="2" verticalGap="2" width="2010" 
       horizontalCenter="0" verticalCenter="0" z="1" />
</mx:Canvas>

Ответы [ 3 ]

0 голосов
/ 01 сентября 2011

Возможно ли, что ваш эффект никогда не будет применен?

Внутри обработчика событий вы напрямую устанавливаете свойства verticalCenter и horizontalCenter для панели.Насколько я понимаю, панель здесь не смещена, а жестко установлена ​​на новую позицию.

Держу пари, что комментирование:

// movePanel.captureStartValues();
sliderPanel.verticalCenter = panelVC;   //sliderPanel is the id for the TileGroup
sliderPanel.horizontalCenter = panelHC;
// movePanel.play();

не повлияет на вашу анимацию.

Нет значений анимации, установленных на movePanel.Вы должны сделать что-то вроде:

movePanel.xBy = ...
movePanel.xTo = ...
movePanel.yBy = ...
movePanel.yTo = ...
...

Документы: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/effects/Move.html

0 голосов
/ 01 сентября 2011

Может показаться, что встроенные процедуры анимации не совсем оптимизированы.Я отключил все методы твининга для TweenMax (http://www.greensock.com/tweenmax/), а также следовал некоторым советам по оптимизации на этом сайте, и теперь он работает гладко, как масло.

Спасибо за все полезные ответы!

-Nigel

Метод TweenMax:

Replaced

movePanel.captureStartValues();
movePanel.easer = powerEasing;
sliderPanel.verticalCenter = panelVC;
sliderPanel.horizontalCenter = panelHC;
movePanel.stop();
movePanel.play();

With

TweenMax.to(sliderPanel,2.5,
  {verticalCenter:panelVC,horizontalCenter:panelHC, ease:Back.easeOut});
0 голосов
/ 01 сентября 2011

Это может произойти:

Flash по умолчанию обновляет экран кадр за кадром - после кадра.События мыши могут отправляться несколько раз за кадр.Обновление экрана использует только значения из последнего отправленного события мыши.

Вы можете убедить экран обновить немедленно, вызвав метод updateAfterEvent() события.Если вы это сделаете, Flash вставит дополнительное обновление экрана прямо в ваш кадр.

Вы можете отслеживать обновления экрана, прослушивая событие RENDER любого экранного объекта.Вот тестовый класс, который показывает updateAfterEvent в действии.Есть 2 поля, которые вы можете навести мышкой.Левое поле использует updateAfterEvent().Правая ячейка обновляется обычным обновлением экрана.Вы увидите, что левый ящик сразу же обновляется.Вместо этого правое поле обновляется после завершения фрейма.Поскольку частота кадров составляет 0,5, это может занять до 2 секунд.Также попробуйте переместить мышь в оба поля.Левое поле обновится сразу, а правое только кадр за кадром.

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.utils.getTimer;

    public class UpdateAfterEvent2 extends Sprite {
        public var box1 : Sprite;
        public var box2 : Sprite;

        public function UpdateAfterEvent2() {
            stage.frameRate = .5;

            box1 = new Sprite();
            box1.name = "box1";
            box1.x = 10;
            box1.y = 10;
            colorize(box1, 0xFF0000);
            box1.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
            box1.addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
            box1.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
            addChild(box1);

            box2 = new Sprite();
            box2.name = "box2";
            box2.x = 70;
            box2.y = 10;
            colorize(box2, 0xFF0000);
            box2.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
            box2.addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
            box2.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
            addChild(box2);

            addEventListener(Event.ENTER_FRAME, enterFrame);
            addEventListener(Event.EXIT_FRAME, exitFrame);
            addEventListener(Event.RENDER, render);
        }

        private function enterFrame(event : Event) : void {
            trace ("----------------enterFrame", getTimer());
        }

        private function exitFrame(event : Event) : void {
            trace ("----------------exitFrame", getTimer());
        }

        private function mouseMove(event : MouseEvent) : void {
            var box : Sprite = event.currentTarget as Sprite;
            trace ("move", box.name, getTimer());
            if (box == box1) {
                trace ("--------UPDATE_AFTER_EVENT");
                event.updateAfterEvent();
            }

            box.alpha = box.alpha == 1 ? .5 : 1;

            stage.invalidate();
        }

        private function mouseOut(event : MouseEvent) : void {
            var box : Sprite = event.currentTarget as Sprite;
            trace ("out", box.name, getTimer());
            if (box == box1) {
                trace ("--------UPDATE_AFTER_EVENT");
                event.updateAfterEvent();
            }
            colorize(box, 0xFF0000);

            stage.invalidate();
        }

        private function mouseOver(event : MouseEvent) : void {
            var box : Sprite = event.currentTarget as Sprite;
            trace ("over", box.name, getTimer());
            if (box == box1) {
                trace ("--------UPDATE_AFTER_EVENT");
                event.updateAfterEvent();
            }
            colorize(box, 0x0000FF);

            stage.invalidate();
        }

        private function render(event : Event) : void {
            trace ("--------RENDER", getTimer());
        }

        private function colorize(box : Sprite, color : uint) : void {
            with (box.graphics) {
                clear();
                beginFill(color);
                drawRect(0, 0, 50, 50);
            }
        }
    }
}
...