mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-03-27 01:23:05 +08:00
5.6 KiB
5.6 KiB
Animation (continuation)
Goal
- Provide XML-defined interpolation function
- Provide new animation API
Demo
- Download with round progress bar
- First X seconds the animation fill the progress bar
- After that if the downloading is not finished, show a rolling animation
- When the downloading is finished, show a ending animation
- Downloaded text fade in
- Progress bar fly out
Feature
Interpolation function
A new xml tag will be added in to write a function:
func <NAME>(start: T, end: T, target: T): IGuiGraphicsAnimationInterpolation^;func <NAME>(start: T, end: T, target: U): IGuiGraphicsAnimationInterpolation^;- if T is a value type so it has to be change a property of type T in U
interface IGuiGraphicsAnimationInterpolation
{
func Interpolate(position: double):void;
}
API
- A group of new overloading functions are added in
GuiInstanceRootObjectwhich do- Add animation to
root->GetControlHostInternal()->GetGraphicsHost()->GetAnimationManager(), whereGetControlHostInternalis a new protected abstract function. - If the control host is not ready (e.g. the control has not been added to a window), then all animations will be kept and attach to the window later
- When the root object is deleted, all animations are stopped (set the internal flag so that the animation manager will remove them later)
- And has the following options:
- interpolation object
- timed or infinite
- for timed animation
- a function to convert passed total time to a double value
- default:
passed total time / total time
- default:
- a fomular function to convert a double value from
[0..1]to[0..1]to control the animation behavior
- a function to convert passed total time to a double value
- for infinite animation
- a function to convert passed total time to a double value
- default:
passed total time
- default:
- a function to convert passed total time to a double value
- for timed animation
- end of animation notification
- Stop an
IAsyncobject - Call a callback function
- Stop an
- Add animation to
Workflow
- Author calls animation APIs themselves to start an animation
- State machine or async coroutine is supported by "end of animation notification"
- Add
$Await GetApplication().DoEvents();
Proposal (2)
<TimedAnimation Progress="progress"> <!-- Progress's default value is "progress" -->
<Interpolation> <!-- Interpolation's default value is "{ return progress; }" -->
<!CData[
{
var pi = 2 * Math::ASin(1);
return (Math::Sin((progress - 0.5) * pi) + 1) / 2;
}
]]>
</Interpolation>
<Data Name="Color" Type="Color"/>
<Data Name="Distance" Type="int"/> <!-- Data has its own Interpolation child element -->
<States Default="A">
<State Name="A">
<Data Name="Color" Value="#FF0000"/>
<Data Name="Distance" Value="0"/>
</State>
<State Name="B">
<Data Name="Color" Value="#FFFFFF"/>
<Data Name="Distance" Value="100"/>
</State>
</States>
<!--
Generate component:
class State{ /* all properties */ }
property Current : State^ {const, not observe}
property Source : State^ {const, not observe}
property Target : State^ {const, not observe}
property A : State^ {const, not observe}
property B : State^ {const, not observe}
func CreateAnimation(source:State^, target:State^, length:int):IGuiGraphicsAnimation^;
func ContinueAnimation(source:State^, target:State^, length:int):IGuiGraphicsAnimation^;
func GetAnimationLengthScale(source:State^, target:State^, current:State^):double;
func Interpolate(source:State^, target:State^, current:State^, progress:double):void;
-->
</TimedAnimation>
<InfiniteAnimation>
</InfiniteAnimation>
Proposal (3)
- Remove
<InfiniteAnimation> - Add
Type="Once|Repeat"to<TimedAnimation> - All
<State>should set exactly the same set of properties - All properties that are not set in
<State>should have aValueproperty, which is similar toInterpolationProperty Value=Value(Interpolation((CurrentTime-StartTime) %Length/ cast doubleLength))
- (optional) Syntax for
$switchto wait for callbacks caused from some actions in the$initblock - (optional) Syntax for
$switchto raise a specified exception for wrong inputs
try
{
$switch(raise "Sad!")
{
$init
{
DownloadAsync().Execute([$1; this.Cancel(); ], null);
}
case A():{}
case B():{}
}
}
catch(ex)
{
if (ex.Message == "Sad!") { return; }
raise;
}
Proposal (4)
- Use XML to compose gradient timed animations as building blocks
- Use coroutine to compose complex animation
- $AwaitTask: await a task
- $Play: initiate and await an animation
- $PlayInGroup: initiate an animation but not wait, a group object (maybe just a number) should be provided
- $AwaitGroup: await all animations in a group
- $Pause: wait for several milliseconds
- If an animation is cancelled, all animations initiated by this animation are cancelled
- Animation manager object in the control host becomes a animation timer callback
- When a root object begins an animation, it attaches the callback object to the manager
- When a root object finishes an animation, it detaches the callback object from the manager
- When a root object is removed from a control host, it detaches the callback object from the manager, and create a new callback object when it is added to a control host later. Durint the moment, the animation is paused.
- Detach an callback object by setting the return value of function "Run" to false, and let the animation manager remove this object later.