×
Namespaces

Variants
Actions

动画基础:Silverlight vs. QML

From Nokia Developer Wiki
Jump to: navigation, search
WP Metro Icon Porting.png
SignpostIcon WP7 70px.png
Article Metadata

代码示例
兼容于
文章
WS_YiLunLuo 在 12 Jan 2012 创建
最后由 hamishwillee 在 18 Jul 2013 编辑

QML动画示例可以在如下网址找到:http://doc.qt.nokia.com/4.7-snapshot/qdeclarativeanimation.html,Silverlight动画示例可以在如下网址找到:http://msdn.microsoft.com/en-us/library/ms608874.aspx。

在这两种情况下,动画的一般处理方式为应用动画来改变属性的值,在这篇文章中只是对有关基本动画处理方面的不同点和相同点进行讨论。 下面的代码显示了一个简单的QML动画如何定义。

NumberAnimation {
id: animateOpacity
target: flashingblob
properties: "opacity"
from: 0.09
to: 1.0
duration: 1000
loops: Animation.Infinite
}

这个动画可以通过调用一些命令处理程序中的animateOpacity.start()来启动。在Silverlight XAML(可扩展标记语言)中,一些相同的动画可以按如下的示例来定义:

<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName=" flashingblob"
Storyboard.TargetProperty="Opacity"
From="0.09" To="1.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>

再次重复,这儿动画可以通过调用一些命令处理程序中的myStoryboard.Begin();来启动。

这个简单的代码片段说明了一个重大的区别,基本上在QML中动画是作为我们自己的实例来定义的,但在Silverlight XAML中,我们是作为Storyboards来定义的。

使用这两种方法你可以定义目标和目标属性,也可以定义往返值,循环等。基本的区别在于所使用的语言格式。当然也有一些细微的区别,例如在QML中如果你有多个动画,你就需要使用SequentialAnimation或者ParallelAnimation将动画组合起来,在Silverlight中,你只需要在动画里定义相同的storyboard,并使用BeginTime在storyboard中定义每个动画的启动时间。

举例说明,如果你想要两个动画并行并这两个动画都拥有3个动画序列,那么你可以在QML中进行如下定义:

ParallelAnimation {
SequentialAnimation {
NumberAnimation { ...}
NumberAnimation { ...}
NumberAnimation { .. }
}
SequentialAnimation {
ColorAnimation { ...}
ColorAnimation { ... }
ColorAnimation { .. }
}
}

然后你可以在Silverlight试着进行如下的定义:

<Storyboard ...>    
<DoubleAnimation BeginTime="00:00:00" .../>
<DoubleAnimation BeginTime="00:00:02" .../>
<DoubleAnimation BeginTime="00:00:04" .../>
<ColorAnimation BeginTime="00:00:00" .../>
<ColorAnimation BeginTime="00:00:02" .../>
<ColorAnimation BeginTime="00:00:04" .../>
</Storyboard>

在Silverlight中可以使用另一个方法来实现上述功能,就是用KeyFrames-animations进行替换,然后你应该将它分成看起来简单的结构,如下:

<Storyboard x:Name="Grow">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00">
<LinearDoubleKeyFrame .../>
<DiscreteDoubleKeyFrame .../>
<SplineDoubleKeyFrame .. />
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00">
<LinearColorKeyFrame .../>
<DiscreteColorKeyFrame .../>
<SplineColorKeyFrame .../>
</ColorAnimationUsingKeyFrames>
</Storyboard>

这样设置两个组同时进行,组内不同的动画将按序列运行。

注意如果你没有在QML中利用easing,那么你应该在Silverlight中使用Linear-Frames,因为它也可以在使用中进行很好的匹配。Discrete-frame用来是为了代替PauseAnimation的,基本上它是简单的等待时间并作出改变。 Spline-frame也是一种在animation内自定义easing的方式,利用它你能够定义两个控制点来指定三次Bezier曲线,并定义进程的关键帧。注意你可以利用EasingFunction来定义Silverlight的easing,就像你在QML中定义的那样。Spline-frame只是提供了附加的方式来完成它。

独立动画

在QML中,你可以利用代码来控制动画的开启和关闭,你必需分别定义动画,给它一个id标签然后可以使用start()/stop()/pause()等来实现功能。举例来说你想在点击矩型框时实现透明度改变的动画,你可利用如下代码:

Rectangle {
id: flashingblob
width: 75; height: 75
color: "blue"
opacity: 1.0
 
MouseArea {
anchors.fill: parent
onClicked: {
animateOpacity.start()
}
}
 
NumberAnimation {
id: animateOpacity
target: flashingblob
properties: "opacity"
from: 0.09
to: 1.0
duration: 1000
loops: Animation.Infinite
}
}

在Silverlight中,如果你想使用canvas,可以使用下面的XAML代码。

<Canvas x:Name="LayoutRoot" Background="Transparent">
<Canvas.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="myrectanggle"
Storyboard.TargetProperty="Opacity"
From="0.09" To="1.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</Canvas.Resources>
 
<Rectangle Name="myrectanggle" Width="75" Height="75" Fill="Blue" MouseLeftButtonDown="myrectanggle_MouseLeftButtonDown"/>
 
</Canvas>

这里不利用动画作为变量,而是定义一个storyboard,并在storyboard中定义动画。为了开始这个动画你可以在c#代码中调用Begin(),,例如你可以按下鼠标来开始动画,代码如下:

private void myrectanggle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){
myStoryboard.Begin();
}

自动动画

在QML中,你可以在信号处理中自动执行动画,举例来说鼠标点击动画可以如下处理:

MouseArea {
anchors.fill: parent
onClicked: PropertyAnimation {…}
}

在Silverlight中,下面的代码将作出相似的行为,但必需使用事件触发来进行定义,示例代码如下所示:

<EventTrigger SourceName="stopButton" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation … />
</Storyboard>
</BeginStoryboard>
</EventTrigger>

当动画定义在对象本身之外,你必需为事件定义源对象,具体如上所示,如果在对象中定义了触发器,你就不需要定义源,因为在你的对象中已经拥有它。例如你可以在canvas中定义下面的代码在canvas的Loaded事件期间来开始动画。

<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard>
...
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>

通过Silverlight XAML,你还可以定义在一些事件发生时来执行动画,并且同时你也可以在样式定义里面定义触发器,实例代码如下所示:

<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
...
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
...
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>

QML也为动画定义了behavior,这是为了当属性值改变时开始动画。在Silverlight XAML中,相似的动画可以由DataTrigger进行处理。以下示例显示了在样式定义中如何实现该功能:

<Style.Triggers>
<DataTrigger Binding="{Binding MyValue[0].UpVisibility}" Value="1.0">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
...
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>

范例

简单的silverlite (WP 7.0)范例可在如下网站获得:File:Silver SimpleAnimation1.zip

This page was last modified on 18 July 2013, at 09:59.
143 page views in the last 30 days.