Tween

animate any property over time with easing.

▶ Run in browser

Tags: 2d animation tween

tween() smoothly drives a property from its current value to a target over a duration, optionally with an easing curve and repeats. It is a coroutine: hand it to start_coroutine() and the node’s lifecycle runs it. This example races a marker along each row using a different easing function so you can see how the curves differ; every marker covers the same distance in the same time.

What it demonstrates

  • tween(obj, prop, target, duration, easing=...) – interpolate a scalar or a Vec2 property (here, each marker’s position).

  • Easing functions (ease_linear, ease_in_quad, ease_out_quad, ease_in_out_cubic, …) shape the motion: slow-in, slow-out, both, or none.

  • repeat + repeat_mode="yoyo" to ping-pong the animation back and forth.

  • start_coroutine() to run a tween from a node.

Source

 1"""Tween: animate any property over time with easing.
 2
 3`tween()` smoothly drives a property from its current value to a target over a
 4duration, optionally with an easing curve and repeats. It is a coroutine: hand it
 5to `start_coroutine()` and the node's lifecycle runs it. This example races a
 6marker along each row using a different easing function so you can see how the
 7curves differ; every marker covers the same distance in the same time.
 8
 9# /// simvx
10# tags = ["2d", "animation", "tween"]
11# web = { root = "TweenDemo", width = 800, height = 600, responsive = true }
12# ///
13
14## What it demonstrates
15
16- `tween(obj, prop, target, duration, easing=...)` -- interpolate a scalar or a
17  `Vec2` property (here, each marker's `position`).
18- Easing functions (`ease_linear`, `ease_in_quad`, `ease_out_quad`,
19  `ease_in_out_cubic`, ...) shape the motion: slow-in, slow-out, both, or none.
20- `repeat` + `repeat_mode="yoyo"` to ping-pong the animation back and forth.
21- `start_coroutine()` to run a tween from a node.
22"""
23
24from simvx.core import Node2D, Vec2, tween
25from simvx.core.animation.tween import (
26    ease_in_cubic,
27    ease_in_out_cubic,
28    ease_in_quad,
29    ease_linear,
30    ease_out_cubic,
31    ease_out_quad,
32)
33from simvx.graphics import App
34
35WIDTH, HEIGHT = 800, 600
36LEFT_X, RIGHT_X = 210, WIDTH - 60
37CYCLES = 9999  # effectively endless for the demo's lifetime
38
39CURVES = [
40    ("linear", ease_linear),
41    ("ease_in_quad", ease_in_quad),
42    ("ease_out_quad", ease_out_quad),
43    ("ease_in_cubic", ease_in_cubic),
44    ("ease_out_cubic", ease_out_cubic),
45    ("ease_in_out_cubic", ease_in_out_cubic),
46]
47
48
49class Marker(Node2D):
50    def on_draw(self, renderer):
51        renderer.draw_circle(self.position, 14, colour=(0.4, 0.8, 1.0, 1.0), filled=True)
52
53
54class TweenDemo(Node2D):
55    def on_ready(self):
56        self.markers = []
57        for i, (name, easing) in enumerate(CURVES):
58            y = 90 + i * 80
59            marker = self.add_child(Marker(position=Vec2(LEFT_X, y)))
60            self.markers.append((name, y, marker))
61            # Animate position from the left edge to the right and back, forever,
62            # shaped by this row's easing curve.
63            self.start_coroutine(
64                tween(marker, "position", Vec2(RIGHT_X, y), duration=2.0,
65                      easing=easing, repeat=CYCLES, repeat_mode="yoyo")
66            )
67
68    def on_draw(self, renderer):
69        renderer.draw_text("Tween: easing curves", (20, 20), scale=2, colour=(1, 1, 1))
70        for name, y, _ in self.markers:
71            renderer.draw_text(name, (20, y - 8), scale=1, colour=(0.7, 0.7, 0.7))
72
73
74if __name__ == "__main__":
75    App(title="Tween", width=WIDTH, height=HEIGHT).run(TweenDemo())