Orbit Animation Example

Show how a simple orbit animation can be achieved via the trigonometry functions
This commit is contained in:
Nigel Breslaw 2024-09-30 21:47:46 +03:00 committed by GitHub
parent e41c2faaf3
commit bdf20488b0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 175 additions and 0 deletions

View file

@ -131,6 +131,10 @@ Files: examples/sprite-sheet/images/*.png
Copyright: Copyright © SixtyFPS GmbH <info@slint.dev>
License: MIT
Files: examples/orbit-animation/images/*.png examples/orbit-animation/images/*.svg
Copyright: Copyright © SixtyFPS GmbH <info@slint.dev>
License: MIT
Files: examples/weather-demo/index.html
Copyright: Copyright © SixtyFPS GmbH <info@slint.dev>
License: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0

View file

@ -0,0 +1,9 @@
<!-- Copyright © SixtyFPS GmbH <info@slint.dev> ; SPDX-License-Identifier: MIT -->
![Orbit Animation Screenshot](https://github.com/user-attachments/assets/a06bd1b3-fbb0-4b90-91c7-0a3fc181aae0)
# Orbit Animation Demo
Demonstrates how to fake orbit animations using Slint's trigonometric math functions.
[Online Preview](https://slint.dev/snapshots/master/editor/preview.html?load_url=https://raw.githubusercontent.com/slint-ui/slint/master/examples/orbit-animation/demo.slint)
[Online code editor](https://slint.dev/snapshots/master/editor/index.html?load_url=https://raw.githubusercontent.com/slint-ui/slint/master/examples/orbit-animation/demo.slint)

View file

@ -0,0 +1,122 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { ComboBox } from "std-widgets.slint";
import { Orbiter } from "orbiter.slint";
export component AppWindow inherits Window {
property <duration> orbitDuration: 5s;
// Animation drivers
property <angle> orbit-animation: (360deg * animation-tick() / orbitDuration).mod(360deg);
property <angle> attack-animation: (360deg * animation-tick() / 20s).mod(360deg);
// Demo data
property <[angle]> offSets: [0deg, 45deg, 90deg, 135deg, 180deg, 225deg, 270deg, 315deg];
property <[[angle]]> attacks: [[0deg, 0deg], [45deg, 45deg], [90deg, 90deg], [0deg, 180deg], [45deg, 225deg], [90deg, 270deg]];
property <image> slint-logo: @image-url("../../logo/slint-logo-small-dark.svg");
background: cb.current-value != "Demo 4" ? lightgrey : black;
animate background {
duration: 1000ms;
easing: ease-in-out-sine;
}
preferred-width: 600px;
preferred-height: 600px;
cb := ComboBox {
x: 10px;
y: 10px;
model: ["Demo 1", "Demo 2", "Demo 3", "Demo 4"];
current-value: "Demo 1";
}
if cb.current-value == "Demo 1": Rectangle {
Orbiter {
state: back;
orbit-rotation: orbit-animation;
orbit-attack: 45deg;
}
}
if cb.current-value == "Demo 2": Rectangle {
for offSet in offSets: Orbiter {
state: back;
orbit-rotation: orbit-animation;
offset: offSet;
orbit-attack: attack-animation;
}
}
if cb.current-value == "Demo 3": Rectangle {
for attack[index] in attacks: Orbiter {
state: back;
orbit-rotation: orbit-animation;
orbit-attack: attack[0];
offset: attack[1];
}
}
if cb.current-value == "Demo 4": Rectangle {
for offSet in offSets: Orbiter {
state: back;
orbit-rotation: orbit-animation;
offset: offSet;
orbit-attack: attack-animation;
source: slint-logo;
colorize: white.mix(black, self.scale);
}
}
if cb.current-value != "Demo 4":Image {
source: @image-url("images/sphere.png");
width: 200px;
}
if cb.current-value == "Demo 4": Image {
source: slint-logo;
width: 200px;
colorize: #1161FF;
}
if cb.current-value == "Demo 1": Rectangle {
Orbiter {
state: front;
orbit-rotation: orbit-animation;
orbit-attack: 45deg;
}
}
if cb.current-value == "Demo 2": Rectangle {
for offSet in offSets: Orbiter {
state: front;
orbit-rotation: orbit-animation;
offset: offSet;
orbit-attack: attack-animation;
}
}
if cb.current-value == "Demo 3": Rectangle {
for attack in attacks: Orbiter {
state: front;
orbit-rotation: orbit-animation;
orbit-attack: attack[0];
offset: attack[1];
}
}
if cb.current-value == "Demo 4": Rectangle {
for offSet in offSets: Orbiter {
state: front;
orbit-rotation: orbit-animation;
offset: offSet;
orbit-attack: attack-animation;
source: slint-logo;
colorize: white.mix(black, self.scale);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

View file

@ -0,0 +1,40 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
enum OrbiterState { front, back }
export component Orbiter {
in property <OrbiterState> state: OrbiterState.front;
in-out property source <=> img.source;
in-out property colorize <=> img.colorize;
in property <angle> orbit-rotation: 0deg;
in property <angle> offset: 45deg;
in property <length> radius: 220px;
property <angle> internal-rotation: orbit-rotation + offset;
in property <angle> orbit-attack: 180deg;
in property <length> ball-size: 60px;
property <length> zPos: sin(internal-rotation) * radius;
out property <float> scale: 0.3 + 0.7 * (zPos + radius) / (2 * radius);
property <bool> infront: internal-rotation.mod(360deg) < 180deg;
function isVisible() -> bool {
if (infront && state == OrbiterState.front) || (!infront && state == OrbiterState.back) {
return true;
} else {
return false;
}
}
visible: isVisible();
Rectangle {
x: cos(orbit-attack) * cos(internal-rotation) * radius;
y: sin(orbit-attack) * cos(internal-rotation) * radius;
img := Image {
width: root.ball-size * scale;
height: root.ball-size * scale;
source: @image-url("images/sphere-small.png");
}
}
}