使用 Kanzi Engine API 创建动画和时间轴。¶
Kanzi 动画系统由动画和时间线组成。动画定义特定类型的值如何随时间变化,而时间线将动画映射到您想要动画化的对象属性。
您可以使用 Kanzi Engine API 创建动画和时间轴:
From-to 动画定义了属性值从哪个值更改到哪个值。您可以省略这些值中的任意一个,以便从当前值或到属性的当前值进行动画。From-to 动画使用一个缓动曲线来定义动画的变化速率。您可以使用 Kanzi 提供的缓动曲线之一,或定义您自己的缓动曲线。
要使用 Kanzi Engine API 创建 from-to 动画,请参阅 使用 Kanzi Engine API 创建 from-to 动画。
关键帧动画使用的关键帧定义了属性值以及动画要在何时达到值。在 Kanzi 中,您可以创建线性、阶梯和贝塞尔样条关键帧。
要使用 Kanzi Engine API 创建关键帧动画,请参阅 使用 Kanzi Engine API 创建关键帧动画。
属性时间线将动画应用于对象的属性。例如,要更改 Image 节点的布局大小,使用属性时间线来为该节点的 Layout Width 和 Layout Height 属性设置动画。
要使用 Kanzi Engine API 创建属性时间线,请参阅 使用 Kanzi Engine API 创建属性时间线。
属性字段时间轴将动画应用于对象的一个或多个属性字段。例如,您可以为每个颜色通道使用单独的动画来更改 Text Block 节点中文本的颜色。
要使用 Kanzi Engine API 创建属性字段时间线,请参阅 使用 Kanzi Engine API 创建属性字段时间线。
并行时间轴允许您将 Kanzi 同时播放的时间轴分组。并行时间轴在最后一个子时间轴中的动画结束时结束。使用此时间轴来组织时间轴集合并创建时间轴的组合。
要使用 Kanzi Engine API 创建并行时间线,请参阅 使用 Kanzi Engine API 创建并行时间线。
时间轴播放属性允许您定义 Kanzi 如何播放时间轴内容。例如,您可以设置动画的速度、重复次数和播放方向。请参阅 使用 Kanzi Engine API 配置时间线。
使用 Kanzi Engine API 创建 from-to 动画¶
From-to 动画定义了属性值从哪个值更改到哪个值。您可以省略这些值中的任意一个,以便从当前值或到属性的当前值进行动画。From-to 动画使用一个缓动曲线来定义动画的变化速率。您可以使用 Kanzi 提供的缓动曲线之一,或定义您自己的缓动曲线。
要创建从-至动画:
// Create a from-to animation that uses the linear easing function and is two seconds long.
// As a starting value, the animation takes the current value of the property in the node you want to animate.
// The animation sets the final value of the property in the node you animate to 200.
// You set which node this animation animates in the timeline.
FloatLinearFromToAnimationSharedPtr linearAnimation = FloatLinearFromToAnimation::create(domain, chrono::seconds(2), nullopt, 200.0f);
要使用从-至动画动画化节点中的某个属性值:
// Create a property timeline and apply the linearAnimation from-to animation to the Layout Width property
// to animate the width of the current node.
PropertyAnimationTimelineSharedPtr propertyTimeline = PropertyAnimationTimeline::create(domain, ".", Node::WidthProperty, linearAnimation);
要使用从-至动画动画化节点中的某个属性字段值:
// Create a property field animation timeline and apply it to the Render Transformation property of the current node.
PropertyFieldAnimationTimelineSharedPtr propertyFieldTimeline = PropertyFieldAnimationTimeline::create(domain, ".", Node2D::RenderTransformationProperty);
// Scale the current node on the x axis by animating the Scale X property field of the Render Transformation property
// with the linearAnimation from-to animation.
propertyFieldTimeline->addEntry(PropertyFieldScaleX, linearAnimation);
要创建使用向后缓动曲线和缓出模式的浮点从-至动画:
// Define the FloatBackFromToAnimation to use float values and Back easing function.
typedef FromToAnimation<float, BackEasingFunction> FloatBackFromToAnimation;
typedef shared_ptr<FloatBackFromToAnimation> FloatBackFromToAnimationSharedPtr;
// Create a from-to animation that uses the back easing function and is 5000 milliseconds long.
// The animation sets the starting value of the property in the node you want to animate to 100,
// and the final value of that property to 300.
FloatBackFromToAnimationSharedPtr backAnimation = FloatBackFromToAnimation::create(domain, chrono::milliseconds(5000), nullopt, 300.0f);
// Set the easing mode of the backAnimation from-to animation to Ease out.
backAnimation->setEasingMode(AnimationEaseOut);
要播放动画而不管时间线类型如何:
// Create the playback context and the timeline playback for the node defined in the item2d.
SceneGraphTimelinePlaybackContext context(*item2d);
// Create the playback for the timeline defined in the propertyFieldTimeline.
TimelinePlaybackSharedPtr playback = propertyFieldTimeline->createPlayback(context);
// Start the animation.
domain->getRootTimelineClock()->addTimelinePlayback(playback);
有关详细信息,请参阅 FromToAnimation 类。
使用 Kanzi Engine API 创建关键帧动画¶
关键帧动画使用的关键帧定义了属性值以及动画要在何时达到值。在 Kanzi 中,您可以创建线性、阶梯和贝塞尔样条关键帧。
要创建关键帧动画:
// Create a float keyframe animation.
FloatKeyframeAnimationSharedPtr keyframeAnimation = FloatKeyframeAnimation::create(domain);
// Create and add keyframes to the keyframe animation. This keyframe animation contains two linear keyframes.
// Create a linear keyframe at second 0 with the value 0.
keyframeAnimation->addLinearKeyframe(chrono::seconds::zero(), 0.0f);
// Create a linear keyframe at second 1 with the value 100.
keyframeAnimation->addLinearKeyframe(chrono::seconds(1), 100.0f);
要使用关键帧动画动画化节点中的某个属性值:
// Create a property timeline and apply the keyframeAnimation keyframe animation to the Layout Width property
// to animate the width of the current node.
PropertyAnimationTimelineSharedPtr propertyTimeline = PropertyAnimationTimeline::create(domain, ".", Node2D::WidthProperty, keyframeAnimation);
要使用关键帧动画动画化节点中的某个属性字段值:
// Create a property field animation timeline and apply it to the Render Transformation property of the current node.
PropertyFieldAnimationTimelineSharedPtr propertyFieldTimeline = PropertyFieldAnimationTimeline::create(domain, ".", Node2D::RenderTransformationProperty);
// Rotate the current node by animating the Rotation Z property field of the Render Transformation property
// with the keyframeAnimation keyframe animation.
propertyFieldTimeline->addEntry(PropertyFieldRotationZ, keyframeAnimation);
要创建一个使用贝塞尔曲线关键帧在 8 字形路径上移动对象的关键帧动画:
// Create two float keyframe animations: one to animate the object on the x axis,
// the other to animate the object on the y axis.
// Create float keyframe animation keyframeAnimationX that uses linear keyframes
// to animate the movement of the object on the x axis.
FloatKeyframeAnimationSharedPtr keyframeAnimationX = FloatKeyframeAnimation::create(domain);
// Create a linear keyframe at second 0 with the value 0.
keyframeAnimationX->addLinearKeyframe(chrono::seconds::zero(), 0.0f);
// Create a linear keyframe at second 4 with the value 4.
// At this keyframe the object reaches the furthest point on the x axis.
keyframeAnimationX->addLinearKeyframe(chrono::seconds(4), 4.0f);
// Create a linear keyframe at second 8 with the value 0.
// At this keyframe the object returns to the same position it had at the first keyframe.
keyframeAnimationX->addLinearKeyframe(chrono::seconds(8), 0.0f);
// Create float keyframe animation keyframeAnimationY that uses Bezier keyframes
// to animate the movement of the object on the y axis.
FloatKeyframeAnimationSharedPtr keyframeAnimationY = FloatKeyframeAnimation::create(domain);
// Create a linear keyframe at second 0 with the value 0. When you use Bezier keyframes,
// you can use any type of keyframe for the first keyframe, because you need this keyframe
// only to provide the information for the starting position.
keyframeAnimationY->addLinearKeyframe(chrono::seconds::zero(), 0.0f);
// Create a Bezier keyframe at second 4 with the value 0 and two control points.
// You use the control points to set the position of the keyframe.
keyframeAnimationY->addBezierKeyframe(chrono::seconds(4), 0.0f, Vector2(0.5f, 4.0f), Vector2(0.5f, -4.0f));
// Create a Bezier keyframe at second 8 with the value 0 and two control points.
// This keyframe uses the same control points, but because the keyframeAnimationX
// animation moves the object on the x axis back to its starting position, this keyframe
// is a mirror image of the previous keyframe.
keyframeAnimationY->addBezierKeyframe(chrono::seconds(8), 0.0f, Vector2(0.5f, 4.0f), Vector2(0.5f, -4.0f));
// Create a property field animation timeline and apply it to the Render Transformation property of the current node.
PropertyFieldAnimationTimelineSharedPtr timeline = PropertyFieldAnimationTimeline::create(domain, ".", Node3D::RenderTransformationProperty);
// Move the current node on the x axis by animating the Translation X property field of the Render Transformation property
// with the keyframeAnimationX keyframe animation.
timeline->addEntry(PropertyFieldTranslationX, keyframeAnimationX);
// Move the current node on the y axis by animating the Translation Y property field of the Render Transformation property
// with the keyframeAnimationY keyframe animation.
timeline->addEntry(PropertyFieldTranslationY, keyframeAnimationY);
要播放动画而不管时间线类型如何:
// Create the playback context and the timeline playback for the node defined in the item2d.
SceneGraphTimelinePlaybackContext context(*item2d);
// Create the playback for the timeline defined in the propertyFieldTimeline.
TimelinePlaybackSharedPtr playback = propertyFieldTimeline->createPlayback(context);
// Start the animation.
domain->getRootTimelineClock()->addTimelinePlayback(playback);
有关详细信息,请参阅 KeyframeAnimation 类。
使用 Kanzi Engine API 创建属性时间线¶
属性时间线将动画应用于对象的属性。例如,要更改 Image 节点的布局大小,使用属性时间线来为该节点的 Layout Width 和 Layout Height 属性设置动画。
要创建属性时间线:
// Create a property timeline and apply the linearAnimation animation to the Layout Width property
// to animate the width of the current node.
PropertyAnimationTimelineSharedPtr propertyTimeline = PropertyAnimationTimeline::create(domain, ".", Node::WidthProperty, linearAnimation);
要播放动画而不管时间线类型如何:
// Create the playback context and the timeline playback for the node defined in the item2d.
SceneGraphTimelinePlaybackContext context(*item2d);
// Create the playback for the timeline defined in the propertyFieldTimeline.
TimelinePlaybackSharedPtr playback = propertyFieldTimeline->createPlayback(context);
// Start the animation.
domain->getRootTimelineClock()->addTimelinePlayback(playback);
有关详细信息,请参阅 PropertyAnimationTimeline 类。
使用 Kanzi Engine API 创建属性字段时间线¶
属性字段时间轴将动画应用于对象的一个或多个属性字段。例如,您可以为每个颜色通道使用单独的动画来更改 Text Block 节点中文本的颜色。
要创建属性字段时间线:
// Create a property field timeline and apply it to the Render Transformation property of the current node.
PropertyFieldAnimationTimelineSharedPtr propertyFieldTimeline = PropertyFieldAnimationTimeline::create(domain, ".", Node2D::RenderTransformationProperty);
// Scale the current node on the x axis by animating the Scale X property field of the Render Transformation property
// with the linearAnimation animation.
propertyFieldTimeline->addEntry(PropertyFieldScaleX, linearAnimation);
要播放动画而不管时间线类型如何:
// Create the playback context and the timeline playback for the node defined in the item2d.
SceneGraphTimelinePlaybackContext context(*item2d);
// Create the playback for the timeline defined in the propertyFieldTimeline.
TimelinePlaybackSharedPtr playback = propertyFieldTimeline->createPlayback(context);
// Start the animation.
domain->getRootTimelineClock()->addTimelinePlayback(playback);
有关详细信息,请参阅 PropertyFieldAnimationTimeline 类。
使用 Kanzi Engine API 创建并行时间线¶
并行时间轴允许您将 Kanzi 同时播放的时间轴分组。并行时间轴在最后一个子时间轴中的动画结束时结束。使用此时间轴来组织时间轴集合并创建时间轴的组合。
将子时间线添加到并行时间线时,子时间线的集合体将构成并行时间线的内容。这意味着并行时间线的所有播放属性都应用于其子时间线。
要创建并行时间线:
// Create a parallel timeline.
ParallelTimelineSharedPtr parallelTimeline = ParallelTimeline::create(domain);
// Add propertyTimeline and propertyFieldTimeline timelines to the parallel timeline. Parallel timeline plays
// both timelines at the same time.
parallelTimeline->addChild(propertyTimeline);
parallelTimeline->addChild(propertyFieldTimeline);
要播放动画而不管时间线类型如何:
// Create the playback context and the timeline playback for the node defined in the item2d.
SceneGraphTimelinePlaybackContext context(*item2d);
// Create the playback for the timeline defined in the propertyFieldTimeline.
TimelinePlaybackSharedPtr playback = propertyFieldTimeline->createPlayback(context);
// Start the animation.
domain->getRootTimelineClock()->addTimelinePlayback(playback);
有关详细信息,请参阅 ParallelTimeline 类。
使用 Kanzi Engine API 配置时间线¶
时间轴由一系列连续播放的迭代组成,从指定的开始时间开始。每个迭代是时间轴内容的连续部分,Kanzi 以特定方式播放。时间轴内容可以由一个或多个动画或子时间轴组成。
时间轴播放属性允许您定义 Kanzi 如何播放时间轴内容。例如,您可以设置动画的速度、重复次数和播放方向。Kanzi 按以下顺序应用时间轴属性:
剪辑属性用于设置要在迭代中播放的时间线内容的部分:
剪辑开始时间用于设置时间线内容从开头跳过的时长。
剪辑持续时间用于设置时间线内容的持续时间。
持续时间标度用于设置(构成剪辑的)时间线内容的播放时长。
例如,如果将持续时间标度设置为 2,时间线内容会花费比时间线内容中定义的时长多一倍的时间进行播放。
构成剪辑并设置了持续时间标度的时间线内容会显示迭代的内容。
方向行为用于设置迭代内容在哪个方向进行播放。将方向行为设置为:
正常 (Normal) 将正常播放迭代内容
反向 (Reverse) 将反向播放迭代内容
往复 (PingPong) 将正常播放迭代内容直到结束,然后按相反方向播放到开头。
重复计数用于设置迭代内容的重复次数。将重复计数设置为 0 以使迭代无限期重复,或直到它被停止。
开始时间用于设置何时开始播放时间线的第一个迭代。将开始时间设置为:
0 将立即开始播放第一个迭代。这是开始时间的默认值。
正值将在开始时间所设置的时长之后开始播放第一个迭代。
负值使 Kanzi 按开始时间设置的时间长度剪辑时间线的开头。这使得时间线看起来像是在过去的某个时间开始的。
时间轴仅在其全局时间超过时间轴的开始时间属性后才应用其内容。在 Kanzi 播放时间轴直到结束后,时间轴会从结束处无限期地应用其内容,直到被移除。如果您有一个重复计数设置为多次重复的并行时间轴,并且您向其中添加了一个具有非零正开始时间的时间轴,则子时间轴仅在其全局时间超过其开始时间后才在并行时间轴的每次迭代开始时播放。
请注意,并非所有时间轴播放属性的组合都是有效的。例如,如果您将时间轴的重复次数设置为无限,并将该时间轴作为子时间轴添加到并行时间轴中,则并行时间轴的内容持续时间将变为无限。在这种情况下,不允许将并行时间轴的方向行为设置为反向,因为反转无限内容没有意义。如果您确实将方向行为设置为反向,Kanzi Engine 会在内部将其恢复为正常,并在日志中打印警告消息。
要开始播放时间轴:
// Create playback context.
SceneGraphTimelinePlaybackContext context(*nodeToAnimate);
// Create playback for timeline.
TimelinePlaybackSharedPtr timelinePlayback = timeline->createPlayback(context);
// Add playback to the clock.
timelineClock->addTimelinePlayback(timelinePlayback);
要停止时间轴的播放:
// Remove playback from the clock.
timelineClock->removeTimelinePlayback(*timelinePlayback);
要获取时间轴的开始时间:
// Get start time of timeline.
chrono::milliseconds startTime = timeline->getStartTime();
要设置时间线的开始时间:
// Set start time of timeline to 100 milliseconds.
// Playback of timeline will start to perform its first iteration after its global time reaches 100 milliseconds.
timeline->setStartTime(chrono::milliseconds(100));
要获取时间轴的裁剪:
// Get clip start time of timeline.
chrono::milliseconds clipStartTime = timeline->getClipStartTime();
// Get clip duration of timeline.
optional<chrono::milliseconds> clipDuration = timeline->getClipDuration();
要设置时间线剪辑:
// Set clip start time of timeline to 100 milliseconds.
// Playback of timeline will perform playback of timeline content starting from 100 milliseconds in each iteration.
timeline->setClipStartTime(chrono::milliseconds(100));
// Set clip duration of timeline to 200 milliseconds.
// Playback of timeline will perform playback of timeline content for 200 milliseconds in each iteration.
timeline->setClipDuration(chrono::milliseconds(200));
要获取时间轴的重复次数:
// Get repeat count of timeline.
unsigned int repeatCount = timeline->getRepeatCount();
要设置时间线的重复次数:
// Set repeat count of Timeline to 10.
// Playback of timeline will perform 10 iterations of timeline content.
timeline->setRepeatCount(10);
// Set repeat count of Timeline to 0.
// Playback of timeline will perform infinite amount of iterations.
timeline->setRepeatCount(0);
要获取时间轴的持续时间比例:
// Get duration scale of timeline.
float durationScale = timeline->getDurationScale();
要设置时间线的持续时间比例:
// Set scale of timeline to 4.
// Playback of timeline will be 4 times slower compared to default playback speed and each iteration
// will be 4 times longer compared to iteration duration with default scale.
timeline->setDurationScale(4.0f);
要获取时间轴播放的方向:
// Get direction behavior of timeline.
enum Timeline::DirectionBehavior directionBehavior = timeline->getDirectionBehavior();
要设置时间线播放的方向:
// Set direction behavior of timeline to pingpong.
// Each odd iteration of timeline will play its content normally
// and each even iteration will play it in reverse manner.
timeline->setDirectionBehavior(Timeline::DirectionBehaviorPingPong);
有关详细信息,请参阅 Timeline 类。