Skip to content

Fixed animation reset bug - #12683

Open
R-Cramer4 wants to merge 2 commits into
slint-ui:masterfrom
R-Cramer4:kms-animation-fix
Open

Fixed animation reset bug#12683
R-Cramer4 wants to merge 2 commits into
slint-ui:masterfrom
R-Cramer4:kms-animation-fix

Conversation

@R-Cramer4

Copy link
Copy Markdown
Contributor

An animation could be reset or not run if the dependencies of a binding are changed without actually changing the animation values. This is most notable on embedded hardware as you can force things to change at the frame rate therefore pausing the animation. On desktop it is noticeable as a jitter, and a reproducible example is:

AppWindow.slint

export struct Row { counter: int, active: bool }

export component AppWindow inherits Window {
    in property <[Row]> model;
    width: 300px;
    height: 100px;

    for row[i] in model : Rectangle {
        background: red;
        width: 50px;
        height: 50px;
        x: row.active ? 200px : 0px;
        animate x { duration: 3000ms; }
    }

    Text { text: model[0].counter; }
}

main.rs:

use slint::{Timer, TimerMode, VecModel, Model};
use std::rc::Rc;

slint::include_modules!();

fn main() {
    let app = AppWindow::new().unwrap();
    let rows = Rc::new(VecModel::from(vec![Row { counter: 0, active: false }]));
    app.set_model(rows.clone().into());

    // Spurious per-frame dirty: rewrites `counter` every ~16ms, `active` untouched.
    let timer = Timer::default();
    let rows_clone = rows.clone();
    timer.start(TimerMode::Repeated, std::time::Duration::from_millis(16), move || {
        let mut row = rows_clone.row_data(0).unwrap();
        row.counter += 1;
        rows_clone.set_row_data(0, row); // rewrites whole row -> marks dependents dirty every frame
    });

    // After 500ms, flip `active` once - this is the genuine change that should animate.
    let rows_clone2 = rows.clone();
    Timer::single_shot(std::time::Duration::from_millis(500), move || {
        let mut row = rows_clone2.row_data(0).unwrap();
        row.active = true;
        rows_clone2.set_row_data(0, row);
    });

    app.run().unwrap();
}

- If a binding's dependencies changed it would cause the animation to
  restart even if it didn't update the animation target

@tronical tronical left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks generally good. This seems sensible behaviour.

Comment thread internal/core/properties/properties_animations.rs Outdated
Comment thread internal/core/properties/properties_animations.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants