Tween¶
animate any property over time with easing.
▶ Run in browserTags: 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 aVec2property (here, each marker’sposition).The
easingmodule (easing.ease_linear,easing.ease_in_quad,easing.ease_out_quad,easing.ease_in_out_cubic, …) shapes the motion: slow-in, slow-out, both, or none.repeat+repeat_mode="yoyo"to ping-pong the animation back and forth.yield from tween(...)inside your own coroutine to sequence or loop tweens.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- The `easing` module (`easing.ease_linear`, `easing.ease_in_quad`,
19 `easing.ease_out_quad`, `easing.ease_in_out_cubic`, ...) shapes the motion:
20 slow-in, slow-out, both, or none.
21- `repeat` + `repeat_mode="yoyo"` to ping-pong the animation back and forth.
22- `yield from tween(...)` inside your own coroutine to sequence or loop tweens.
23- `start_coroutine()` to run a tween from a node.
24"""
25
26from simvx.core import Node2D, Vec2, easing, tween
27from simvx.graphics import App
28
29WIDTH, HEIGHT = 800, 600
30LEFT_X, RIGHT_X = 210, WIDTH - 60
31
32CURVES = [
33 ("linear", easing.ease_linear),
34 ("ease_in_quad", easing.ease_in_quad),
35 ("ease_out_quad", easing.ease_out_quad),
36 ("ease_in_cubic", easing.ease_in_cubic),
37 ("ease_out_cubic", easing.ease_out_cubic),
38 ("ease_in_out_cubic", easing.ease_in_out_cubic),
39]
40
41
42def ping_pong(marker, target, curve):
43 """Run a there-and-back tween over and over.
44
45 A tween is an ordinary coroutine, so it composes: `yield from` runs one
46 two-leg yoyo (out and back), and the loop starts the next one.
47 """
48 while True:
49 yield from tween(marker, "position", target, duration=2.0, easing=curve, repeat=2, repeat_mode="yoyo")
50
51
52class Marker(Node2D):
53 def on_draw(self, renderer):
54 renderer.draw_circle(self.position, 14, colour=(0.4, 0.8, 1.0, 1.0), filled=True)
55
56
57class TweenDemo(Node2D):
58 def on_ready(self):
59 self.markers = []
60 for i, (name, curve) in enumerate(CURVES):
61 y = 90 + i * 80
62 marker = self.add_child(Marker(position=Vec2(LEFT_X, y)))
63 self.markers.append((name, y, marker))
64 # Animate position from the left edge to the right and back, forever,
65 # shaped by this row's easing curve.
66 self.start_coroutine(ping_pong(marker, Vec2(RIGHT_X, y), curve))
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())