Rust动画与关键帧插值库keyframe的使用,高效实现平滑动画过渡和复杂曲线运动效果
Rust动画与关键帧插值库keyframe的使用,高效实现平滑动画过渡和复杂曲线运动效果
简介
keyframe是一个简单的Rust动画库,提供了以下功能:
- 多种缓动函数,包括用户定义的贝塞尔曲线(类似CSS的cubic-bezier)和可关键帧化的曲线
- 动画序列(类似CSS的@keyframes)
- 与mint库集成,支持2D/3D/4D数据结构(点、矩形、颜色等)
基本用法
补间动画
使用keyframe::ease(function, from, to, time)
在两个值之间进行补间动画:
use keyframe::{ease, functions::EaseInOut};
fn example() -> f64 {
let a = 0.0;
let b = 2.0;
let time = 0.5;
ease(EaseInOut, a, b, time)
}
动画序列
使用keyframe::AnimationSequence
创建更复杂的动画:
use keyframe::{keyframes, Keyframe, AnimationSequence};
fn example() {
// (value, time) 或 (value, time, function)
let mut sequence = keyframes![
(0.5, 0.0), // <-- 从0.0到0.3使用EaseInOut
(1.5, 0.3, Linear), // <-- 从0.3到1.0使用Linear
(2.5, 1.0) // <-- 这里的缓动函数不会使用,因为已经是最后了
];
sequence.advance_by(0.65);
assert_eq!(sequence.now(), 2.0);
assert_eq!(sequence.duration(), 1.0);
}
自定义结构
use keyframe::mint::Point2;
// 这个宏适用于任何只包含实现"CanTween"类型的结构体
use keyframe_derive::CanTween;
#[derive(CanTween)]
struct MySubStructure {
a: f32
}
#[derive(CanTween)]
struct MyStructure {
a: f64,
b: Point2<f64>,
c: f32,
d: [MySubStructure; N] // 数组长度由类型系统保证
}
// 也适用于无名结构体
#[derive(CanTween)]
struct UnnamedStructure(MyStructure, f64);
完整示例
下面是一个展示颜色渐变动画的完整示例:
use keyframe::{keyframes, AnimationSequence, functions::{EaseInOut, BounceOut}};
use keyframe::mint::Vector4;
fn main() {
// 创建一个颜色渐变的动画序列
let mut color_animation = keyframes![
// 从红色开始,使用EaseInOut缓动
(Vector4 { x: 1.0, y: 0.0, z: 0.0, w: 1.0 }, 0.0, EaseInOut),
// 过渡到绿色
(Vector4 { x: 0.0, y: 1.0, z: 0.0, w: 1.0 }, 0.3),
// 过渡到蓝色,使用BounceOut特效
(Vector4 { x: 0.0, y: 0.0, z: 1.0, w: 1.0 }, 0.7, BounceOut),
// 最后回到红色
(Vector4 { x: 1.0, y: 0.0, z: 0.0, w: 1.0 }, 1.0)
];
println!("颜色渐变动画示例:");
for i in 0..=10 {
let progress = i as f32 / 10.0;
color_animation.advance_to(progress);
let current_color = color_animation.now();
println!("进度: {:.1}, RGBA: ({:.2}, {:.2}, {:.2}, {:.2})",
progress, current_color.x, current_color.y, current_color.z, current_color.w);
}
}
注意事项
- 库提供了多种内置缓动函数,包括EaseIn、EaseOut、EaseInOut、Linear等
- 可以创建自定义的缓动函数来实现特殊的动画效果
- 动画序列可以包含任意数量的关键帧
- 支持各种数值类型和数据结构,包括mint库中的2D/3D/4D类型
通过合理使用keyframe库,可以轻松实现复杂的动画效果和平滑的过渡效果。
1 回复
Rust动画与关键帧插值库keyframe使用指南
keyframe
是一个轻量级的Rust动画库,专门用于处理关键帧动画和插值计算,能够高效实现平滑动画过渡和复杂曲线运动效果。
主要特性
- 支持多种插值方法:线性、缓入、缓出、贝塞尔曲线等
- 内置多种常用缓动函数
- 支持自定义插值器
- 类型安全的动画系统
- 零运行时成本抽象
安装
在Cargo.toml
中添加依赖:
[dependencies]
keyframe = "1.0"
基本用法
1. 创建简单动画
use keyframe::{keyframes, AnimationSequence};
use keyframe::functions::*;
fn main() {
// 创建关键帧序列
let mut sequence = keyframes![
(0.0, 0.0, Linear), // 时间0.0秒,值0.0
(1.0, 10.0, EaseInOut) // 时间1.0秒,值10.0
];
// 获取任意时间的插值
println!("Value at 0.5s: {}", sequence.now(0.5));
}
2. 使用内置缓动函数
use keyframe::functions::*;
let sequence = keyframes![
(0.0, 0.0, Linear),
(1.0, 100.0, EaseInOutCubic),
(2.0, 50.0, EaseOutElastic)
];
3. 复杂动画序列
use keyframe::{AnimationSequence, keyframes};
use keyframe::functions::*;
let mut sequence = AnimationSequence::new();
sequence.append(keyframes![
(0.0, 0.0, Linear),
(1.0, 100.0, EaseInOutQuad)
]);
sequence.append(keyframes![
(0.0, 100.0, Linear),
(1.0, 0.0, EaseOutBounce)
]);
// 前进到特定时间点
sequence.advance_to(1.5);
println!("Current value: {}", sequence.now());
高级功能
自定义插值器
use keyframe::{CanTween, Keyframe, AnimationSequence};
use std::ops::Mul;
#[derive(Clone, Debug)]
struct Color {
r: f64,
g: f64,
b: f64,
}
impl CanTween for Color {
fn ease(from: Self, to: Self, time: impl Mul<f64, Output = f64>) -> Self {
Color {
r: from.r + (to.r - from.r) * *time,
g: from.g + (to.g - from.g) * *time,
b: from.b + (to.b - from.b) * *time,
}
}
}
let mut color_animation = AnimationSequence::new();
color_animation.append(Keyframe::new(Color { r: 1.0, g: 0.0, b: 0.0 }, 0.0, Linear));
color_animation.append(Keyframe::new(Color { r: 0.0, g: 1.0, b: 0.0 }, 1.0, EaseInOut));
贝塞尔曲线插值
use keyframe::{keyframes, functions::BezierEasing};
let bezier = BezierEasing::new(0.42, 0.0, 0.58, 1.0);
let sequence = keyframes![
(0.极,值0.0
(1.0, 100.0, bezier)
];
性能建议
- 对于频繁调用的动画,考虑重用
AnimationSequence
而不是每次重新创建 - 使用
derive(CanTween)
为自定义类型自动实现插值 - 在游戏循环中,使用
advance_and_maybe_wrap
方法来处理循环动画
完整示例:2D物体动画
use keyframe::{keyframes, AnimationSequence};
use keyframe::functions::*;
struct GameObject {
x: f64,
y: f64,
scale: f64,
rotation: f64,
}
fn main() {
// 创建位置动画
let mut x_anim = keyframes![
(0.0, 0.0, Linear),
(2.0, 300.0, EaseOutElastic),
(4.0, 100.0, EaseInOutBack)
];
let mut y_anim = keyframes![
(0.0, 0.0, Linear),
(1.0, 200.0, EaseOutBounce),
(3.0, 50.0, EaseInQuad)
];
// 创建缩放动画
let mut scale_anim = keyframes![
(0.0, 1.0, Linear),
(1.5, 1.5, EaseOutElastic),
(3.0, 0.8, EaseInOutBack)
];
// 模拟游戏循环
let mut time = 0.0;
while time <= 4.0 {
let mut obj = GameObject {
x: x_anim.now(time),
y: y_anim.now(time),
scale: scale_anim.now(time),
rotation: 0.0,
};
println!(
"Time: {:.1}s | Position: ({:.1, {:.1}) | Scale: {:.2}",
time, obj.x, obj.y, obj.scale
);
time += 0.1;
}
}
keyframe
库提供了强大而灵活的工具来创建各种动画效果,从简单的线性过渡到复杂的弹性运动都可以轻松实现。通过组合不同的关键帧和缓动函数,你可以为你的Rust应用或游戏创建流畅的动画体验。