Composition

Combining animations in sequence, in parallel and with a lag; reusable clips; easing.

Contents:

  • k.seq: Composes animations in sequence: each one starts when the previous one ends.
  • k.par: Composes animations in parallel: they all start together and the group lasts as long as the longest one.
  • k.stagger: Staggers a list of animations: each one starts lag seconds after the previous one.
  • k.clip: Decorator that turns a function def name(s: k.Scene, ...) into a reusable sequence with its own cursor.
  • k.Animation: Immutable: only has an effect when passed to s.play or s.start.
  • k.ease: Easing curves.

Methods in this area:

  • anim.with_: Returns a copy of the animation with a different duration, easing or delay.

Back to the reference index.

k.seq (function)

k.seq(*anims: Animation) -> Animation

Composes animations in sequence: each one starts when the previous one ends. The result is an Animation like any other and can be rescaled with duration=.

Parameters:

Name Type Default Description
*anims Animation variadic

Example:

@k.scene
def sequence(s: k.Scene):
    box = k.Square(2).place(at="center")
    label = k.Text("box").place(inside=box)
    s.play(k.seq(k.draw(box), k.write(label)), duration=2)
    s.wait(0.5)

See also: k.par, k.stagger, s.play.

k.par (function)

k.par(*anims: Animation) -> Animation

Composes animations in parallel: they all start together and the group lasts as long as the longest one. s.play(a, b) is defined as s.play(k.par(a, b)); use k.par when the parallel group is part of another composition.

Parameters:

Name Type Default Description
*anims Animation variadic

Example:

@k.scene
def parallel(s: k.Scene):
    a = k.Circle(r=0.7).place(at="left", margin=3)
    b = k.Circle(r=0.7).place(at="right", margin=3)
    title = k.Text("Together").place(at="top", margin=0.8)
    s.play(k.seq(k.par(k.draw(a), k.draw(b)), k.write(title)))
    s.wait(0.5)

See also: k.seq, k.stagger, s.play.

k.stagger (function)

k.stagger(
    anims: Sequence[Animation],
    lag: float = 0.1,
    order: StaggerOrder = "sequence",
) -> Animation

Staggers a list of animations: each one starts lag seconds after the previous one. order= changes the order: "sequence" (default), "reverse", "center" or "random(seed)".

Parameters:

Name Type Default Description
anims Sequence[Animation] required
lag float 0.1 Staggers a list of animations: each one starts lag seconds after the previous one.
order StaggerOrder "sequence" order= changes the order: "sequence" (default), "reverse", "center" or "random(seed)".

Example:

@k.scene
def cascade(s: k.Scene):
    bars = [k.Bar(v) for v in [3, 5, 2, 6, 4]]
    row = k.Row(*bars, gap=0.3, align="bottom").place(at="center")
    s.play(k.stagger([k.grow(b, from_="bottom") for b in row], lag=0.1))
    s.wait(0.5)

See also: k.seq, k.par, k.grow.

k.clip (function)

k.clip(fn: Callable[Concatenate[Scene, P], None]) -> ClipFunction[P]
k.clip(fn: Callable[Concatenate[Owner, Scene, P], None]) -> ClipMethod[Owner, P]

Written as: @k.clip

Decorator that turns a function def name(s: k.Scene, ...) into a reusable sequence with its own cursor. Calling the clip returns an Animation, which composes with s.play, k.seq and k.par and can be rescaled with duration=.

Parameters:

Name Type Default Description
fn Callable[Concatenate[Scene, P], None] required

Example:

@k.clip
def present(s: k.Scene, obj: k.Node) -> None:
    s.play(k.draw(obj))
    s.play(k.indicate(obj))

@k.scene
def with_clip(s: k.Scene):
    a = k.Circle(r=0.8).place(at="left", margin=3)
    b = k.Square(1.6).place(at="right", margin=3)
    s.play(present(a), present(b))

See also: k.seq, s.play, k.Component.

k.Animation (class)

k.Animation(
    duration: float | None = None,
    ease: EaseLike | None = None,
    delay: float = 0.0,
    span: Span | None = None,
)

Immutable: only has an effect when passed to s.play or s.start.

Documented together with anim.with_.

Parameters:

Name Type Default Description
duration float | None None
ease EaseLike | None None
delay float 0.0
span Span | None None

Attributes:

Attribute Type Description
anim.delay
anim.duration
anim.ease Ease
anim.span

Members:

  • total: Natural length including the delay, before any rescaling.
  • with_: Returns a copy of the animation with a different duration, easing or delay.
  • emit: Schedule into the scene starting at t0, with every duration multiplied by k.
  • describe: Short human description for kinemo check timelines.
  • split_for_during: (apply, revert) pair for s.during, computed before applying.

k.Animation.total (property)

anim.total: float  # read-only

Natural length including the delay, before any rescaling.

k.Animation.with_ (method)

anim.with_(
    *,
    duration: float | None = None,
    ease: EaseLike | None = None,
    delay: float | None = None,
) -> Animation

Returns a copy of the animation with a different duration, easing or delay. Animations are immutable values: the original does not change.

Parameters:

Name Type Default Description
duration float | None None
ease EaseLike | None None
delay float | None None

Example:

@k.scene
def variation(s: k.Scene):
    dot = k.Dot(r=0.25, x=-4)
    s.add(dot)
    move = dot.to(x=4)
    s.play(move.with_(duration=2, ease=k.ease.out_back, delay=0.2))

See also: k.ease, obj.to.

k.Animation.emit (method)

anim.emit(s: Scene, t0: float, k: float, ease: Ease | None) -> float

Schedule into the scene starting at t0, with every duration multiplied by k. Returns the time the animation actually ends.

Parameters:

Name Type Default Description
s Scene required
t0 float required Schedule into the scene starting at t0, with every duration multiplied by k.
k float required Schedule into the scene starting at t0, with every duration multiplied by k.
ease Ease | None required

k.Animation.describe (method)

anim.describe() -> str

Short human description for kinemo check timelines.

k.Animation.split_for_during (method)

anim.split_for_during(s: Scene) -> tuple[Animation, Animation]

(apply, revert) pair for s.during, computed before applying. Only state changes and emphasis can be reverted; everything else is K0204.

Parameters:

Name Type Default Description
s Scene required

k.ease (namespace)

k.ease  # namespace

Easing curves. Every verb and every .to() uses k.ease.smooth (cubic in-out) by default. Also: linear, in_, out, in_out, out_back, out_elastic, spring(stiffness, damping), steps(n) and custom(fn) for any f: [0, 1] → ℝ.

Members:

Member Description or type
k.ease.linear Ease
k.ease.smooth Ease
k.ease.in_ Ease
k.ease.out Ease
k.ease.in_out Ease
k.ease.out_back Ease
k.ease.out_elastic Ease
k.ease.spring(stiffness: float = 100.0, damping: float = 10.0) -> Ease
k.ease.steps(n: int) -> Ease
k.ease.custom(fn: Callable[[float], float], samples: int = 256) -> Ease Any f: [0, 1] → ℝ, sampled into a table evaluated natively.
k.ease.reverse(e: Ease) -> Ease

Example:

@k.scene
def easing(s: k.Scene):
    a = k.Dot(r=0.2, x=-4, y=1)
    b = k.Dot(r=0.2, x=-4, y=-1)
    s.add(a, b)
    s.play(a.to(x=4, ease=k.ease.linear), b.to(x=4, ease=k.ease.out_elastic), duration=2)

See also: anim.with_, s.play.