add system font loading

improve drawing
implement staggered text
begin refactor of drawing code
This commit is contained in:
2023-05-24 00:24:16 +02:00
parent 8523e44029
commit 330fa6a7f0
28 changed files with 844 additions and 207 deletions

View File

@@ -37,6 +37,11 @@ pub trait Animateable {
fn calculate(&mut self, timeline: &Timeline) -> Option<Entity>;
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Cache {
pub valid: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum AnimatedEntity {

View File

@@ -9,11 +9,13 @@ use crate::animation::{
timeline::Timeline,
};
use super::common::{Animateable, AnimationData, Drawable, Entity};
use super::common::{Animateable, AnimationData, Cache, Drawable, Entity};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnimatedEllipseEntity {
pub paint: Paint,
pub id: String,
pub cache: Cache,
pub radius: AnimatedFloatVec2,
pub origin: AnimatedFloatVec2,
pub position: AnimatedFloatVec2,
@@ -24,6 +26,8 @@ pub struct AnimatedEllipseEntity {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct EllipseEntity {
pub radius: (f32, f32),
pub cache: Cache,
pub id: String,
pub position: (f32, f32),
pub origin: (f32, f32),
pub paint: Paint,
@@ -62,9 +66,11 @@ impl Animateable for AnimatedEllipseEntity {
};
Some(Entity::Ellipse(EllipseEntity {
id: self.id.clone(),
radius,
position,
origin,
cache: self.cache.clone(),
paint: self.paint.clone(),
transform,
}))

View File

@@ -9,10 +9,12 @@ use crate::animation::{
timeline::Timeline,
};
use super::common::{Animateable, AnimationData, Drawable, Entity};
use super::common::{Animateable, AnimationData, Cache, Drawable, Entity};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnimatedRectEntity {
pub id: String,
pub cache: Cache,
pub position: AnimatedFloatVec2,
pub size: AnimatedFloatVec2,
pub origin: AnimatedFloatVec2,
@@ -23,6 +25,8 @@ pub struct AnimatedRectEntity {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RectEntity {
pub id: String,
pub cache: Cache,
pub position: (f32, f32),
pub size: (f32, f32),
pub origin: (f32, f32),
@@ -71,6 +75,8 @@ impl Animateable for AnimatedRectEntity {
};
Some(Entity::Rect(RectEntity {
id: self.id.clone(),
cache: self.cache.clone(),
position,
size,
origin,

View File

@@ -1,8 +1,9 @@
use super::common::{Animateable, AnimationData, Drawable, Entity};
use super::common::{Animateable, AnimationData, Cache, Drawable, Entity};
use crate::animation::{
primitives::{
paint::TextPaint,
transform::{AnimatedTransform, Transform},
values::{AnimatedFloatVec2, AnimatedValue},
},
timeline::Timeline,
};
@@ -16,14 +17,17 @@ pub struct AnimatedStaggeredTextLetter {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StaggeredTextLetter {
pub transform: Option<Transform>,
pub transform: Option<Vec<Transform>>,
pub paint: TextPaint,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnimatedStaggeredTextEntity {
pub id: String,
pub cache: Cache,
pub text: String,
pub stagger: f32,
pub origin: AnimatedFloatVec2,
pub animation_data: AnimationData,
pub transform: Option<AnimatedTransform>,
pub letter: AnimatedStaggeredTextLetter,
@@ -31,8 +35,11 @@ pub struct AnimatedStaggeredTextEntity {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StaggeredTextEntity {
pub id: String,
pub cache: Cache,
pub text: String,
pub stagger: f32,
pub origin: (f32, f32),
pub transform: Option<Transform>,
pub animation_data: AnimationData,
pub letter: StaggeredTextLetter,
@@ -51,14 +58,36 @@ impl Animateable for AnimatedStaggeredTextEntity {
None => None,
};
let letter_transform: Option<Transform> = match self.letter.transform.clone() {
Some(mut val) => Some(val.calculate(timeline, &self.animation_data)),
// Iterate over the chars of the string and calculate the animation with the staggered offset
let letter_transform: Option<Vec<Transform>> = match self.letter.transform.clone() {
Some(mut val) => {
let mut transforms: Vec<Transform> = Vec::new();
for c in self.text.chars().enumerate() {
let mut animation_data = self.animation_data.clone();
animation_data.offset += self.stagger * c.0 as f32;
let transform = val.calculate(timeline, &animation_data);
transforms.push(transform);
}
Some(transforms)
}
None => None,
};
let origin = self.origin.get_value_at_frame(
timeline.render_state.curr_frame,
&self.animation_data,
timeline.fps,
);
Some(Entity::StaggeredText(StaggeredTextEntity {
id: self.id.clone(),
transform,
cache: self.cache.clone(),
stagger: self.stagger,
origin,
text: self.text.clone(),
animation_data: self.animation_data.clone(),
letter: StaggeredTextLetter {

View File

@@ -8,10 +8,12 @@ use crate::animation::{
};
use serde::{Deserialize, Serialize};
use super::common::{Animateable, AnimationData, Drawable, Entity};
use super::common::{Animateable, AnimationData, Cache, Drawable, Entity};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TextEntity {
pub id: String,
pub cache: Cache,
pub text: String,
pub origin: (f32, f32),
pub paint: TextPaint,
@@ -20,6 +22,8 @@ pub struct TextEntity {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnimatedTextEntity {
pub id: String,
pub cache: Cache,
pub text: String,
pub origin: AnimatedFloatVec2,
pub paint: TextPaint,
@@ -45,6 +49,8 @@ impl AnimatedTextEntity {
};
TextEntity {
id: self.id.clone(),
cache: self.cache.clone(),
transform,
text: self.text.clone(),
origin,

View File

@@ -1,3 +1,5 @@
use std::str::FromStr;
use crate::animation::primitives::{
interpolations::{EasingFunction, InterpolationType, SpringProperties},
keyframe::{Keyframe, Keyframes},
@@ -7,7 +9,7 @@ use serde::{Deserialize, Serialize};
use super::primitives::{
entities::{
common::{AnimatedEntity, AnimationData, Entity},
common::{AnimatedEntity, AnimationData, Cache, Entity},
rect::AnimatedRectEntity,
text::AnimatedTextEntity,
},
@@ -52,12 +54,14 @@ impl Timeline {
fn build_bg(offset: f32, paint: Paint, size: (i32, i32)) -> AnimatedRectEntity {
let bg_box = AnimatedRectEntity {
id: String::from_str("1").unwrap(),
paint,
animation_data: AnimationData {
offset: 0.0 + offset,
duration: 5.0,
visible: true,
},
cache: Cache { valid: false },
transform: None,
origin: AnimatedFloatVec2::new(1280.0 / 2.0, 720.0 / 2.0),
position: AnimatedFloatVec2 {
@@ -171,7 +175,9 @@ pub fn test_timeline_entities_at_frame(
AnimatedEntity::Rect(build_bg(0.5, rect2_paint, size)),
AnimatedEntity::Rect(build_bg(1.0, rect3_paint, size)),
AnimatedEntity::Text(AnimatedTextEntity {
id: String::from_str("2").unwrap(),
paint: title_paint,
cache: Cache { valid: false },
text: input.title,
animation_data: AnimationData {
offset: 0.0,
@@ -216,8 +222,10 @@ pub fn test_timeline_entities_at_frame(
},
}),
AnimatedEntity::Text(AnimatedTextEntity {
id: String::from_str("3").unwrap(),
paint: sub_title_paint,
text: input.sub_title,
cache: Cache { valid: false },
animation_data: AnimationData {
offset: 0.5,
duration: 6.0,