Перенос кнопки AS3 (стиль Windows 7) - PullRequest
2 голосов
/ 14 ноября 2011

ПРИМЕЧАНИЕ: Я решил сохранить историю темы, потому что думаю, что процесс поиска может быть кому-то полезен.Если вы хотите найти решение, перейдите к нижней части моего поста.

Я искал, но не нашел своего ответа ни в Google, ни в StackOverflow (даже ни одного учебника по нему).Я хотел бы создать подсветку ролловера на кнопке, например на панели задач Windows 7.Подсветка перемещается и является функцией от того, где находится кнопка мыши.Я не хочу, чтобы какое-либо изображение на моей кнопке (только цветовой градиент) содержало стандартный компонент.Как я могу применить этот эффект ролловера?

Назад, я пытался запустить этот код:

    <?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
             xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:mx="library://ns.adobe.com/flex/mx"
             minWidth="65" minHeight="22"
             creationComplete="GlassButtonSkin_creationCompleteHandler(event)"> 

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

    <fx:Declarations>

    </fx:Declarations>


    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            protected function GlassButtonSkin_creationCompleteHandler(event:FlexEvent):void{
                this.addEventListener(MouseEvent.MOUSE_OVER,mouseOverHandler);
                this.addEventListener(MouseEvent.CLICK,mouseClickHandler);
            }

            private function mouseOverHandler(event:MouseEvent):void{
                this.overEffectRadialGradient.y = event.stageY;
                this.labelDisplay.text = "your in";
                this.commitProperties();
            }
            private function mouseClickHandler(event:MouseEvent):void{
                this.labelDisplay.text = "your in";
            }
        ]]>
    </fx:Script>


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

    <s:transitions>
        <s:Transition fromState="up" toState="over" autoReverse="true">
            <s:Fade target="{overEffect}" alphaFrom="0" alphaTo="1" duration="500"/>
        </s:Transition>
    </s:transitions>




    <!-- inner border --> 
    <s:Rect left="0" right="0" top="0" bottom="0" id="innerBorder" radiusX="4" radiusY="4">
        <s:stroke>     
            <s:SolidColorStroke id="innerBorderStroke" weight="1" color="#ffffff" />
        </s:stroke>
    </s:Rect>

    <!-- outer border --> 
    <s:Rect left="1" right="1" top="1" bottom="1" id="outerBorder" radiusX="4" radiusY="4">
        <s:stroke>     
            <s:SolidColorStroke id="outerBorderStroke" weight="1" color="#000000"/>
        </s:stroke>
    </s:Rect>

    <!-- fill -->
    <!--- Defines the appearance of the Button component's background. -->
    <s:Rect id="background" left="1" right="1" top="1" bottom="1">
        <s:fill>
            <s:SolidColor alpha="0.5" color="#000000"/>
        </s:fill>
    </s:Rect>

    <s:Rect id="backgroundTopPart" left="1" right="1" top="1" height="50%"
            includeIn="up,over,disabled">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="#ffffff" alpha="0.6"/>
                <s:GradientEntry color="#ffffff" alpha="0.2"/>
            </s:LinearGradient>
        </s:fill>
    </s:Rect>

    <s:Rect id="overEffect" left="1" right="1" bottom="1" height="50%" radiusX="4" radiusY="4"
            includeIn="over,down">
        <s:fill>        
            <s:RadialGradient id="overEffectRadialGradient" x="{width*0.5}" y="{height*0.5}" scaleY="{height}" scaleX="{width/1.5}">
                <s:GradientEntry color="#8dbdff" alpha="0.7" />
                <s:GradientEntry color="#8dbdff" alpha="0"/>
            </s:RadialGradient>
        </s:fill>
    </s:Rect>


    <s:Label id="labelDisplay"
             text="Send"
             textAlign="center" 
             verticalAlign="middle" 
             color="#FFFFFF"
             horizontalCenter="0" verticalCenter="1" 
             left="10" right="10" top="2" bottom="2">
    </s:Label>



</s:SparkSkin>

Проблема в том, что ни одно событие не было захвачено.Я попытался изменить текст метки на событии щелчка, чтобы проверить, но он просто не работает вообще (без дескриптора события).Это действительно странно.Можете ли вы принести некоторую помощь, пожалуйста?

РЕДАКТИРОВАТЬ 15/11/11 Я обнаружил, что мой creationCompleteHandler нуждается в parent.mouseChildren = true;захватывать события мыши.Я положил его, и теперь я вижу, что события мыши фиксируются, но мой rollovereffect больше не отображается, даже если я удаляю переход состояний и играю с visible = true / false;эффекта в моем указателе мыши над обработчиком.

ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ Я наконец нашел решение моей проблемы, спасибо всем.Мое решение:

 <?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
             xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:mx="library://ns.adobe.com/flex/mx"
             minWidth="65" minHeight="22"
             creationComplete="GlassButtonSkin_creationCompleteHandler(event)"> 

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

    <fx:Declarations>

    </fx:Declarations>


    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            import mx.graphics.RadialGradient;

            import spark.effects.Fade;
            import spark.effects.animation.RepeatBehavior;

            [Bindable]
            private var rectRollOverEffect:Rect = new Rect();
            private var radialGradientRollOverEffect:RadialGradient = new RadialGradient();
            private var gradientEntryRollOverEffect1:GradientEntry = new GradientEntry(0x8dbdff,NaN,0.7);
            private var gradientEntryRollOverEffect2:GradientEntry = new GradientEntry(0x8dbdff,NaN,0);
            private var indexOfRollOverEffect:int;
            private var myFade:Fade;

            protected function GlassButtonSkin_creationCompleteHandler(event:FlexEvent):void{
                parent.mouseChildren = true;
                this.addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveHandler,true);
                this.addEventListener(MouseEvent.MOUSE_OUT,mouseOutHandler,true);
                this.addEventListener(MouseEvent.MOUSE_OVER,mouseOverHandler,true);

                this.addElement(rectRollOverEffect);
                indexOfRollOverEffect = this.getElementIndex(rectRollOverEffect);
                this.removeElementAt(indexOfRollOverEffect);
            }

            private function mouseOverHandler(event:MouseEvent):void{
                if(this.currentState == "disabled")
                    return;

                createRollOverEffect(event,0);

                myFade = new Fade(this.getElementAt(indexOfRollOverEffect));
                myFade.alphaFrom = 0;
                myFade.alphaTo = 1;
                myFade.duration = 200;
                myFade.end();
                myFade.play();
            }

            private function mouseMoveHandler(event:MouseEvent):void{
                if(this.currentState == "disabled")
                    return;

                this.removeElementAt(indexOfRollOverEffect);
                createRollOverEffect(event,1);
            }

            private function mouseOutHandler(event:MouseEvent):void{
                if(this.currentState == "disabled")
                    return;

                this.removeElementAt(indexOfRollOverEffect);
            }

            private function createRollOverEffect(event:MouseEvent,alpha:int):void{
                rectRollOverEffect.alpha = alpha;
                rectRollOverEffect.left = 2;
                rectRollOverEffect.right = 2;
                rectRollOverEffect.bottom = 2;
                rectRollOverEffect.top = 2;
                rectRollOverEffect.radiusX = 4;
                rectRollOverEffect.radiusY = 4;

                radialGradientRollOverEffect.entries = [gradientEntryRollOverEffect1,gradientEntryRollOverEffect2];
                radialGradientRollOverEffect.x = event.localX;
                radialGradientRollOverEffect.y = height-2;
                radialGradientRollOverEffect.scaleX = width/1.5;
                radialGradientRollOverEffect.scaleY = height;

                rectRollOverEffect.fill = radialGradientRollOverEffect;

                this.addElementAt(rectRollOverEffect,indexOfRollOverEffect);
            }
        ]]>
    </fx:Script>


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

    <s:transitions>
        <s:Transition fromState="over" toState="disabled">
            <s:CallAction target="{this}" functionName="removeElement" args="{[this.rectRollOverEffect]}"/>
        </s:Transition>
    </s:transitions>



    <!-- outer border --> 
    <s:Rect left="0" right="0" top="0" bottom="0" id="outerBorder" radiusX="4" radiusY="4">
        <s:stroke>     
            <s:SolidColorStroke id="outerBorderStroke" weight="1" color="#ffffff" />
        </s:stroke>
    </s:Rect>

    <!-- inner border --> 
    <s:Rect left="1" right="1" top="1" bottom="1" id="innerBorder" radiusX="4" radiusY="4">
        <s:stroke>     
            <s:SolidColorStroke id="innerBorderStroke" weight="1" color="#000000"/>
        </s:stroke>
    </s:Rect>

    <!-- fill -->
    <!--- Defines the appearance of the Button component's background. -->
    <s:Rect id="background" left="1" right="1" top="1" bottom="1">
        <s:fill>
            <s:SolidColor alpha="0.5" color="#000000"/>
        </s:fill>
    </s:Rect>

    <s:Rect id="backgroundTopPart" left="1" right="1" top="1" height="50%"
            includeIn="up,over,disabled">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="#ffffff" alpha="0.5" ratio="0.1"/>
                <s:GradientEntry color="#ffffff" alpha="0.1"/>
            </s:LinearGradient>
        </s:fill>
    </s:Rect>


    <s:Label id="labelDisplay"
             text="Send"
             textAlign="center" 
             verticalAlign="middle" 
             color="#FFFFFF"
             horizontalCenter="0" verticalCenter="1" 
             left="10" right="10" top="2" bottom="2">
    </s:Label>

    <s:Rect id="disableForeground" left="0" right="0" top="0" bottom="0"
            includeIn="disabled">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="#7B7B7B" alpha="0.6" ratio="0.1"/>
                <s:GradientEntry color="#aaaaaa" alpha="0.3"/>
            </s:LinearGradient>
        </s:fill>
    </s:Rect>


</s:SparkSkin>

1 Ответ

4 голосов
/ 14 ноября 2011

Вот несколько шагов для начала:

  1. Создание градиента.Может быть:
    • предопределенное изображение
    • круг, заполненный внешним градиентом цвета, установленным на прозрачный.Может быть, нужно преобразовать в эллипс.
  2. Маска градиента с областью кнопки.
  3. Прослушивание указатель мыши над и мышь событий в области кнопки.Обновите положение градиента до положения мыши (или только mouse.y) при перемещении мыши .

Я не могу обещать, что он будет выглядеть точно так же, как в окнах7 панель задач, так как она зависит от фона кнопки и формы градиента.Я не уверен, есть ли там дополнительные эффекты.Вы можете немного оживить вещи, добавив больше градиентов, которые изменяют их прозрачность в зависимости от расстояния до мыши, и поэкспериментировать с режимом умножения , который дает приятные эффекты. Обновление - Я думаю, this.overEffectRadialGradient.y = event.stageY; использует неправильные координаты.Это может работать, если кнопка в 0,0, хотя.Локальные координаты должны быть правильными: event.localY.

...