Help with cycle animation

Hi,

I have the following code based in the login button example:

<App>
	<JavaScript>
		var Observable = require("FuseJS/Observable");

		function LoadButton(){
		    this.activeState = Observable("defaultState");

		    this.doneLoading = function(result){
		        this.activeState.value = result;
		    }.bind(this);
		    
		    this.startLoading = function(){

		    	this.activeState.value = "loadingState"
		    	self = this;
		    
      			setTimeout( function() { 
              		self.doneLoading("success");
        		}, 3500)

		    }.bind(this);
		}

		button = Observable(new LoadButton());

    	module.exports = {
    		button: button
    	}
	</JavaScript>

	<Panel Background="#f0f">
		<Each Items="{button}">
			<LoadButton Alignment="VerticalCenter"/>
		</Each>
	</Panel>

	<Panel ux:Class="LoadButton" Width="150" Height="60">
	    <Text ux:Name="text" Alignment="Center" Value="Load" Color="#090" FontSize="16" Opacity="1"/>
	    <Panel>
	        <WhileTrue ux:Name="showCross">
	            <CrossIcon ux:Name="crossIcon" Opacity="0"/>
	            <Change crossIcon.Opacity="1" Duration="0.05"/>
	        </WhileTrue>
	    </Panel>
	    <Panel>
	        <WhileTrue ux:Name="showCheck">
	            <CheckIcon ux:Name="checkIcon" Opacity="0"/>
	            <Change checkIcon.Opacity="1" Duration="0.05"/>
	        </WhileTrue>
	    </Panel>

	    <Circle ux:Name="circle" StartAngleDegrees="-90" EndAngleDegrees="-90" Width="56" Height="56">
	        <Stroke Width="4" Alignment="Center">
	            <SolidColor ux:Name="circleStrokeColor" Color="#090"/>
	        </Stroke>
	    </Circle>

	    <Rectangle ux:Name="rect" CornerRadius="30" Width="146" Height="56">
	        <SolidColor ux:Name="rectColor" Color="#fff" />
	        <Stroke ux:Name="rectStroke" Width="4" Alignment="Center">
	            <SolidColor ux:Name="rectStrokeColor" Color="#090"/>
	        </Stroke>
	    </Rectangle>

	    <WhilePressed>
	        <Scale Target="text" Factor="0.9" Duration="0.05"/>
	    </WhilePressed>
	    <Clicked>
	        <Callback Handler="{startLoading}"/>
	    </Clicked>


	    <StateGroup Active="{activeState}" Rest="defaultState" Transition="Exclusive">
	        <State ux:Name="defaultState"/>
	        <State ux:Name="loadingState">
	            <Change DurationBack="0" rectStrokeColor.Color="#ddd" Duration="0.3" />
	            <Change DurationBack="0" text.Opacity="0" Duration="0.15"/>
	            <Change DurationBack="0" rect.Width="56" Duration="0.4" Easing="CircularInOut"/>
	            <Change DurationBack="0" rectColor.Color="#fff" Duration=".3"/>
	            <Change DurationBack="0" circle.EndAngleDegrees="269.9" Delay="0.4" Duration="1"/>

	        	<!--Cycle Target="circle.EndAngleDegrees" Low="-90" High="270" Waveform="Sawtooth" Delay="0.4" Frequency="1" Easing="QuadraticInOut"/-->

	        </State>
	        <State ux:Name="success">
	            <Change text.Opacity="0" DurationBack="0.2" DelayBack="0.3"/>
	            <Change rect.Width="56" Duration="0" DurationBack="0.4" Easing="CircularInOut"/>
	            <Change rectStrokeColor.Color="#090" Duration=".3"/>
	            <Change rectColor.Color="#090" Duration=".3"/>
	            <Change showCheck.Value="true"/>
	        </State>
	        <State ux:Name="error">
	            <Change text.Opacity="0" DurationBack="0.2" DelayBack="0.3"/>
	            <Change rect.Width="56" Duration="0" DurationBack="0.4" Easing="CircularInOut"/>
	            <Change circleStrokeColor.Color="#900" Duration=".3"/>
	            <Change rectStrokeColor.Color="#900" Duration=".3"/>
	            <Change rectColor.Color="#900" Duration=".3"/>
	            <Change showCross.Value="true"/>
	        </State>
	    </StateGroup>
	</Panel>

	<Panel ux:Class="CheckIcon" ux:Name="self" Width="25" Height="25">
	    <Panel Offset="-10%,30%">
	        <Panel Width="100%" Height="100%">
	            <Rotation Degrees="45" />
	            <Rectangle ux:Name="checkRect1" Alignment="Left" TransformOrigin="Anchor" Anchor="0%,50%" Width="50%" Height="10%" Color="White"/>
	        </Panel>
	        <Rectangle ux:Name="checkRect2" Offset="-5%,0%" TransformOrigin="Anchor" Anchor="100%,50%" Width="100%" Height="10%" Color="White">

	            <Rotation Degrees="135"/>
	        </Rectangle>
	        <AddingAnimation>
	            <Change checkRect2.Width="0" Duration="0.5" Easing="BounceIn"/>
	            <Change checkRect1.Width="0" Duration="0.15" Delay="0.5" Easing="QuadraticOut"/>
	        </AddingAnimation>
	        <RemovingAnimation>
	            <Change self.Opacity="0" Duration="0.1"/>
	        </RemovingAnimation>
	    </Panel>
	</Panel>

	<Panel Width="30" Height="30" ux:Class="CrossIcon" ux:Name="self">
	    <Rectangle ux:Name="crossRect1" Width="100%" Height="10%" Color="White">
	        <Rotation Degrees="-45"/>
	    </Rectangle>
	    <Rectangle ux:Name="crossRect2" Width="100%" Height="10%" Color="White">
	        <Rotation Degrees="45"/>
	    </Rectangle>
	    <AddingAnimation>
	        <Change crossRect1.Width="15" Duration="0" DurationBack="0.5" Easing="BounceIn"/>
	        <Change crossRect2.Width="15" Duration="0" DurationBack="0.5" Easing="BounceIn"/>
	    </AddingAnimation>
	    <RemovingAnimation>
	        <Change self.Opacity="0" Duration="0.1"/>
	    </RemovingAnimation>
	</Panel>
</App>

when you click on the login button the animation works but as the login action takes 3.5 seconds the circle stops wheeling after 1 second:

  <Change DurationBack="0" circle.EndAngleDegrees="269.9" Delay="0.4" Duration="1"/>

I want the circle to keep spinning till the loading has ended so i changed it to:

    <Cycle Target="circle.EndAngleDegrees" Low="-90" High="270" Waveform="Sawtooth" Delay="0.4" Frequency="1" Easing="QuadraticInOut"/>

now it keeps spinning (that’s perfect) BUT when the loading state is finished it shows back the default state for a second before doing the success state animation.

How should i do it ? and… why adding a cycle to the circle affects how the states are shown? (if i remove the cycle the default state is not shown after loading)

thnx.

How can you solve this?

Here you have:

I added an animation at the end that makes the circle expand (you can remove it easily). The trick was to call the successCallBack from the success state.

Note: this was developed using 0.35 as the new versions does not work on my processor.

<App>
    <JavaScript>
        var Observable  = require("FuseJS/Observable");

        var uxLoginBtn = Observable(new LoginButton());

        function LoginButton(){
            this.activeState = Observable("defaultState");
            this.errorMsg = Observable("");

            this.successCallBack = function() {
                //do whatever u want to do when success
            }.bind(this);

            this.doneLoading = function(result, errorMsg){

                if (errorMsg!="") {
                  this.errorMsg.value = errorMsg;
                }
                
                this.activeState.value = result;
            }.bind(this);

          this.startLoading = function(){

            if (this.activeState.value=="error") {
                this.activeState.value="defaultState";
                return "";
            }

            this.activeState.value = "loadingState";
              
            self = this;

            setTimeout( function() { self.doneLoading("success", "") }, 3000)
                

          }.bind(this);
        }
        module.exports = {
            uxLoginBtn: uxLoginBtn
        }

    </JavaScript>
    
    <Panel Background="#00000033">
        <Each Items="{uxLoginBtn}">
            <LoginButton/>
        </Each>
    </Panel>

    <Panel ux:Class="LoginButton" Width="150" Height="36">
        <Text ux:Name="text" Alignment="Center" Value="Login" TextColor="#fff" FontSize="16" Opacity="1"/>
        <Panel>
            <WhileTrue ux:Name="showCross">
                <CrossIcon ux:Name="crossIcon" Opacity="0"/>
                <Text ux:Name="errorMsg" Value="{errorMsg}" Opacity="0"  Alignment="BottomCenter" TextColor="#fff" FontSize="14" Margin="0,15,0,0"/> 

                <Change crossIcon.Opacity="1" Duration="0.05"/>
                
            </WhileTrue>
        </Panel>

        <Panel ux:Name="checkIconPanel">
            <CheckIcon ux:Name="checkIcon" Opacity="0"/>
        </Panel>

        <Panel ux:Name="loadingCirclePanel">
            <Circle ux:Name="loadingCircle" Width="70%" Height="70%" Opacity="0" StartAngleDegrees="0" LengthAngleDegrees="90">
                <Stroke Width="1" Brush="#fff" />
            </Circle>
        </Panel>

        <WhileTrue ux:Name="loadCircle">
            <Change text.Opacity="0" Duration="0.2" DurationBack="0"/>
            <Change loadingCircle.Opacity="1" Duration="0.3" Delay="0.2" DelayBack="0" DurationBack="0"/>
            <Spin Target="loadingCircle" Frequency="2"/>
            <Cycle Target="loadingCircle.LengthAngleDegrees" Low="30" High="300" Frequency="0.7" />
        </WhileTrue>

        <Circle ux:Name="circle" StartAngleDegrees="-90" EndAngleDegrees="-90" Width="36" Height="36" Fill="#96281B">
            <Stroke Width="2">
                <SolidColor ux:Name="circleStrokeColor" Color="#96281B"/>
            </Stroke>
        </Circle>

        <Panel ux:Name="loadingButton" Opacity="0" Width="1320" Height="1320" Alignment="Center">
            <Circle Fill="#96281B"/>
                <Scaling ux:Name="loginButtonScaling" Factor="0.02" />
        </Panel>

        <Rectangle ux:Name="rect" CornerRadius="30" Width="80" Height="36">
            <SolidColor ux:Name="rectColor" Color="#96281B" />
            <Stroke ux:Name="rectStroke" Width="2">
                <SolidColor ux:Name="rectStrokeColor" Color="#96281B"/>
            </Stroke>
        </Rectangle>

        <WhilePressed>
            <Scale Target="text" Factor="0.9" Duration="0.05"/>
        </WhilePressed>
        <Clicked>
            <Callback Handler="{startLoading}"/>
            <ReleaseFocus />
        </Clicked>


        <StateGroup Active="{activeState}" Rest="defaultState" Transition="Exclusive">
            <State ux:Name="defaultState">
                <Change errorMsg.Opacity="0" Duration="0.2" Delay="0"/>
                
            </State>
            <State ux:Name="loadingState">
                <Change DurationBack="0" text.Opacity="0" Duration="0.15"/>
                <Change DurationBack="0" rect.Width="36" Duration="0.4" Easing="CircularInOut"/>

                <Change loadCircle.Value="true" />

            </State>

            <State ux:Name="success">
                <Change loadCircle.Value="false" />

                <Change text.Opacity="0" DurationBack="0.2" DelayBack="0.3"/>
                <Change rect.Width="36" Duration="0" DurationBack="0.4" Easing="CircularInOut"/>
                <Change rectStrokeColor.Color="#96281B" Duration=".3"/>
                <Change rectColor.Color="#96281B" Duration=".3"/>

                <Change checkIcon.Opacity="1" Duration="0.5"/>
                <Change checkIconPanel.Opacity="0" Delay="0.5" Duration="0.1"/>

                <Change loadingButton.Opacity="1" Duration="0.01" />
                <Change loginButtonScaling.Factor="1" Delay="0.3" Duration="0.8" DurationBack="0" Easing="ExponentialInOut"/>

                <Callback Handler="{successCallBack}" Delay="0.9"/>
            </State>
            <State ux:Name="error">
                <Change loadCircle.Value="false" />

                <Change text.Opacity="0" DurationBack="0.2" DelayBack="0.3"/>
                <Change rect.Width="36" Duration="0" DurationBack="0.4" Easing="CircularInOut"/>
                
                <Change circleStrokeColor.Color="#fff" Duration=".3"/>
                <Change rectStrokeColor.Color="#fff" Duration=".3"/>
                <Change rectColor.Color="#900" Duration=".3"/>
                <Change showCross.Value="true"/>

                <Scale Target="rect" Factor="0.7" Duration="0.4" Delay="0.3" DurationBack="0"/>
                <Scale Target="circle" Factor="0.7" Duration="0.4" Delay="0.3" DurationBack="0"/>
                <Scale Target="crossIcon" Factor="0.7" Duration="0.4" Delay="0.3" DurationBack="0"/>

                <Move Target="rect" Y="-15" Duration="0.3" Delay="0.7" DurationBack="0"/>
                <Move Target="circle" Y="-15" Duration="0.3" Delay="0.7" DurationBack="0"/>
                <Move Target="crossIcon" Y="-15" Duration="0.3" Delay="0.7" DurationBack="0"/>

                <Change errorMsg.Opacity="1" Duration="0.2" Delay="0.9" DurationBack="0" DelayBack="0"/>
            </State>
        </StateGroup>
    </Panel>

        <Panel Width="18" Height="18" ux:Class="CrossIcon" ux:Name="self">
        <Rectangle ux:Name="crossRect1" Width="100%" Height="10%" Fill="White">
            <Rotation Degrees="-45"/>
        </Rectangle>
        <Rectangle ux:Name="crossRect2" Width="100%" Height="10%" Fill="White">
            <Rotation Degrees="45"/>
        </Rectangle>
        <AddingAnimation>
            <Change crossRect1.Width="15" Duration="0" DurationBack="0.5" Easing="BounceIn"/>
            <Change crossRect2.Width="15" Duration="0" DurationBack="0.5" Easing="BounceIn"/>
        </AddingAnimation>
        <RemovingAnimation>
            <Change self.Opacity="0" Duration="0.1"/>
        </RemovingAnimation>
    </Panel>

    <Panel ux:Class="CheckIcon" ux:Name="self" Width="16" Height="16">
        <Panel Offset="-10%,30%">
            <Panel Width="100%" Height="100%">
                <Rotation Degrees="45" />
                <Rectangle ux:Name="checkRect1" Alignment="Left" TransformOrigin="Anchor" Anchor="0%,50%" Width="50%" Height="10%" Fill="White"/>
            </Panel>
            <Rectangle ux:Name="checkRect2" Offset="-5%,0%" TransformOrigin="Anchor" Anchor="100%,50%" Width="100%" Height="10%" Fill="White">

                <Rotation Degrees="135"/>
            </Rectangle>
            <AddingAnimation>
                <Change checkRect2.Width="0" Duration="0.5" Easing="BounceIn"/>
                <Change checkRect1.Width="0" Duration="0.15" Delay="0.5" Easing="QuadraticOut"/>
            </AddingAnimation>
            <RemovingAnimation>
                <Change self.Opacity="0" Duration="0.1"/>
            </RemovingAnimation>
        </Panel>
    </Panel>
</App>