在 Flex 4 中创建动画皮肤很困难

发布于 2024-10-27 18:51:38 字数 4998 浏览 5 评论 0原文

我的任务是创建此页面上按钮图形样式的等效 Flex 4 实现: http://h.dwighthouse.com/temp/UDOP/2011-3- 25_themeDevGlowing/

即按钮上的动画发光效果。我已经得到了我认为合适的基于程序的渐变皮肤基础,但我有两个问题。

第一,我无法在皮肤中响应任何鼠标事件。我似乎找不到其他人遇到这个问题。在下面的代码中,当鼠标悬停时,startAnimation 永远不会被调用,但该事件显然已被注册。要测试此代码,只需将 skinClass="ButtonSkin" 添加到主应用程序中的按钮声明中,下面的代码是 ButtonSkin.mxml 文件。

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx"
        initialize="init()"
        mouseEnabled="true">

    <fx:Metadata>
        [HostComponent("spark.components.Button")]
    </fx:Metadata>

    <fx:Script>
        <![CDATA[
            import flash.events.Event;

            [Bindable]
            private var animatedAlpha:Number = 0.8;
            private var animationDirection:Number = -1;

            private function backAndForth(value:Number, max:Number, min:Number, increment:Number):Number {
                value += (animationDirection * increment);
                if (value < min || value > max)
                {
                    animationDirection *= -1;
                    value += (animationDirection * increment * 2);
                }
                return value;
            }

            private function startAnimation(e:MouseEvent):void {
                animatedAlpha = backAndForth(animatedAlpha, 0.8, 0.3, 0.1); // Or something
                systemManager.addEventListener(MouseEvent.MOUSE_OUT, endAnimation);
            }

            private function endAnimation(e:MouseEvent):void {
                animatedAlpha = backAndForth(animatedAlpha, 0.8, 0.3, 0.1); // Or something
                systemManager.removeEventListener(MouseEvent.MOUSE_OUT, endAnimation);
            }

            private function init():void {
                parent.mouseChildren = true; // Otherwise mouse events don't fire in the skin
                clickableArea.addEventListener(MouseEvent.MOUSE_OVER, startAnimation);
            }
        ]]>
    </fx:Script>


    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>

    <s:Group top="0" bottom="0" left="0" right="0" id="clickableArea">
        <s:Rect top="0" bottom="0" left="0" right="0" radiusX="8" radiusY="8">
            <s:fill>
                <s:LinearGradient rotation="90">
                    <s:GradientEntry color="#000000" color.down="#bb0000" color.disabled="#3b3b3b" ratio="0" />
                    <s:GradientEntry color="#353535" color.down="#ff0000" color.disabled="#555555" ratio="1" />
                </s:LinearGradient>
            </s:fill>
        </s:Rect>

        <s:Rect top="0" bottom="0" left="0" right="0" radiusX="8" radiusY="8">
            <s:fill>
                <s:LinearGradient rotation="90">
                    <s:GradientEntry color.over="#8f1b1b" alpha="0" ratio="0" />
                    <s:GradientEntry color.over="#8f1b1b" alpha="0" ratio="0.4" />
                    <s:GradientEntry color.over="#8f1b1b" alpha="{animatedAlpha}" alpha.down="0" ratio="1" />
                </s:LinearGradient>
            </s:fill>
        </s:Rect>

        <s:Rect top="0" bottom="0" left="0" right="0" radiusX="8" radiusY="8">
            <s:stroke>
                <s:SolidColorStroke color="#000000" color.disabled="#333333" weight="1" />
            </s:stroke>
            <s:fill>
                <s:LinearGradient rotation="90">
                    <s:GradientEntry color="#ffffff" color.disabled="#9e9e9e" alpha="0.6" alpha.down="0.7" ratio="0" />
                    <s:GradientEntry color="#ffffff" color.disabled="#848484" alpha="0.2" alpha.down="0.4" ratio="0.45" />
                    <s:GradientEntry color="#ffffff" alpha="0" ratio="0.46" />
                </s:LinearGradient>
            </s:fill>
        </s:Rect>

        <s:Label id="labelDisplay" color="#ffffff" color.disabled="#aaaaaa" textAlign="center" baseline="center" paddingTop="7" paddingBottom="5" paddingLeft="10" paddingRight="10">
            <s:filters>
                <s:DropShadowFilter distance="0" angle="45" blurX="5" blurY="5" />
            </s:filters>
        </s:Label>
    </s:Group>

编辑我发现了为什么鼠标事件没有触发。该按钮显然默认将 mouseChildren 设置为 false,这专门防止事件触发低于其自身的值。在构造函数中使用 parent.mouseChildren = true; 可以修复此问题。继续问题的下一部分:连续动画。

除此之外,我希望获得一些帮助或为我指出每帧调用函数的正确方向,以及使用鼠标事件打开和关闭所述增量调用的能力。 (如果这不是您在 Flex 中制作动画的方式,请原谅我,我对基于 Flash 的动画一无所知。)谢谢!

I have been tasked with creating the equivalent Flex 4 implementation of graphical style of the buttons found on this page:
http://h.dwighthouse.com/temp/UDOP/2011-3-25_themeDevGlowing/

Namely, the animated glowing effect on the buttons. I've gotten what I think is the appropriate programmatic gradient-based skin basis, but I have two problems.

One, I can't get any mouse events to respond in the skin. I can't seem to find others with this problem. In the below code, startAnimation is never getting called when a mouse over occurs, but the event is apparently getting registered. To test this code, simply add skinClass="ButtonSkin" to a button declaration in your main application, the code below being the ButtonSkin.mxml file.

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx"
        initialize="init()"
        mouseEnabled="true">

    <fx:Metadata>
        [HostComponent("spark.components.Button")]
    </fx:Metadata>

    <fx:Script>
        <![CDATA[
            import flash.events.Event;

            [Bindable]
            private var animatedAlpha:Number = 0.8;
            private var animationDirection:Number = -1;

            private function backAndForth(value:Number, max:Number, min:Number, increment:Number):Number {
                value += (animationDirection * increment);
                if (value < min || value > max)
                {
                    animationDirection *= -1;
                    value += (animationDirection * increment * 2);
                }
                return value;
            }

            private function startAnimation(e:MouseEvent):void {
                animatedAlpha = backAndForth(animatedAlpha, 0.8, 0.3, 0.1); // Or something
                systemManager.addEventListener(MouseEvent.MOUSE_OUT, endAnimation);
            }

            private function endAnimation(e:MouseEvent):void {
                animatedAlpha = backAndForth(animatedAlpha, 0.8, 0.3, 0.1); // Or something
                systemManager.removeEventListener(MouseEvent.MOUSE_OUT, endAnimation);
            }

            private function init():void {
                parent.mouseChildren = true; // Otherwise mouse events don't fire in the skin
                clickableArea.addEventListener(MouseEvent.MOUSE_OVER, startAnimation);
            }
        ]]>
    </fx:Script>


    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>

    <s:Group top="0" bottom="0" left="0" right="0" id="clickableArea">
        <s:Rect top="0" bottom="0" left="0" right="0" radiusX="8" radiusY="8">
            <s:fill>
                <s:LinearGradient rotation="90">
                    <s:GradientEntry color="#000000" color.down="#bb0000" color.disabled="#3b3b3b" ratio="0" />
                    <s:GradientEntry color="#353535" color.down="#ff0000" color.disabled="#555555" ratio="1" />
                </s:LinearGradient>
            </s:fill>
        </s:Rect>

        <s:Rect top="0" bottom="0" left="0" right="0" radiusX="8" radiusY="8">
            <s:fill>
                <s:LinearGradient rotation="90">
                    <s:GradientEntry color.over="#8f1b1b" alpha="0" ratio="0" />
                    <s:GradientEntry color.over="#8f1b1b" alpha="0" ratio="0.4" />
                    <s:GradientEntry color.over="#8f1b1b" alpha="{animatedAlpha}" alpha.down="0" ratio="1" />
                </s:LinearGradient>
            </s:fill>
        </s:Rect>

        <s:Rect top="0" bottom="0" left="0" right="0" radiusX="8" radiusY="8">
            <s:stroke>
                <s:SolidColorStroke color="#000000" color.disabled="#333333" weight="1" />
            </s:stroke>
            <s:fill>
                <s:LinearGradient rotation="90">
                    <s:GradientEntry color="#ffffff" color.disabled="#9e9e9e" alpha="0.6" alpha.down="0.7" ratio="0" />
                    <s:GradientEntry color="#ffffff" color.disabled="#848484" alpha="0.2" alpha.down="0.4" ratio="0.45" />
                    <s:GradientEntry color="#ffffff" alpha="0" ratio="0.46" />
                </s:LinearGradient>
            </s:fill>
        </s:Rect>

        <s:Label id="labelDisplay" color="#ffffff" color.disabled="#aaaaaa" textAlign="center" baseline="center" paddingTop="7" paddingBottom="5" paddingLeft="10" paddingRight="10">
            <s:filters>
                <s:DropShadowFilter distance="0" angle="45" blurX="5" blurY="5" />
            </s:filters>
        </s:Label>
    </s:Group>

EDIT I found out why mouse events weren't firing. The button apparently has mouseChildren false by default, which specifically prevents events from firing lower than itself. Using parent.mouseChildren = true; in the constructor fixes this issue. On to the next part of the question: continuous animation.

Other than that, I'd appreciate some help or point me in the right direction of calling a function every frame, and the ability to turn said incremental call on and off using mouse events. (If that's not how you animate in Flex, forgive me, I know nothing about Flash-based animation.) Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南街女流氓 2024-11-03 18:51:38

这两个问题的答案都已找到:

  1. 按钮会阻止其子级(包括外观)接收鼠标事件。通过在皮肤的初始化函数中设置parent.mouseChildren = true;,可以正常接收鼠标事件。

  2. 事实证明,您可以像在 Javascript 中设置动画一样在 Flex (Actionscript) 中设置动画:setInterval 和clearInterval。

Answers to both questions have been found:

  1. Buttons prevent their children (including Skins) from receiving mouse events. By setting parent.mouseChildren = true; in the skin's initializing function, mouse events are received normally.

  2. Turns out you can animate in Flex (Actionscript) the same way you animate in Javascript: setInterval and clearInterval.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文