Object state
Changing objects: animated state changes (.to()), instant writes (.set()), copies.
Contents:
k.Node: Objects are values: creating one does not put it in the scene (uses.addor a verb).k.reparent: Moves an object to another group at the scheduled time, keeping its world position (inside a container, it takes its place in the flow).
Methods in this area:
obj.to: Animated state change: interpolates each prop from its value at the cursor to the target.obj.set: Instant change at the cursor.obj.unbind: Removes reactive bindings (all props when no name is given), keeping the current value.obj.copy: Creates a new identity with the same props.
Back to the reference index.
k.Node (class)#
k.Node(*, name: str | None = None, key: str | None = None, **props: object)
Objects are values: creating one does not put it in the scene (use s.add or a verb).
Documented together with obj.to.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
name |
str | None |
None |
|
key |
str | None |
None |
|
**props |
object |
variadic |
Props (animatable with .to(), settable with .set() or in the constructor):
| Prop | Kind | Default | Interpolation |
|---|---|---|---|
x |
float | 0.0 |
linear |
y |
float | 0.0 |
linear |
rotate |
float | 0.0 |
linear |
scale |
float | 1.0 |
linear |
scale_x |
float | 1.0 |
linear |
scale_y |
float | 1.0 |
linear |
anchor |
vec2 | (0.0, 0.0) |
linear |
opacity |
float | 1.0 |
linear |
z |
float | 0.0 |
linear |
visible |
bool | True |
step_end |
Layout-derived props (read-only, reactive, in the parent's coordinates): obj.width, obj.height, obj.left, obj.right, obj.top, obj.bottom, obj.center, obj.bbox, obj.position; obj.world.position and obj.world.center give global coordinates.
Members:
set: Instant change at the cursor.to: Animated state change: interpolates each prop from its value at the cursor to the target.unbind: Removes reactive bindings (all props when no name is given), keeping the current value.edge: Point of the object's box named by an anchor ("right", "top-left", ...), in its parent's coordinates, reactive:k.Arrow(start=a.edge("right"), end=b.edge("left")).age: Seconds since the object (or its nearest present ancestor) last entered the scene.entered: Event at each entry of the object into the scene.exited: Event at each exit of the object from the scene.copy: Creates a new identity with the same props.place: Declares where the object sits, relative to the frame (at="top",margin=) or to another object (above=,below=,left_of=,right_of=,inside=withpad=), withgap=(accepts a signal) andalign=.to_place: Animated change of placement: the.toof.place.unpin: Releases the position constraint at the cursor: the object keeps its current position and is free to animatex/y.
k.Node.set (method)
obj.set(**props: Unpack[PropChanges]) -> Node
Instant change at the cursor. Passing a signal or a lambda creates a reactive binding from the cursor on (there are no updaters); obj.unbind("x") removes the binding.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
**props |
Unpack[PropChanges] |
variadic |
Example:
@k.scene
def binding(s: k.Scene):
leader = k.Dot(r=0.25, x=-4, y=1)
follower = k.Dot(r=0.15, fill=k.RED)
s.add(leader, follower)
follower.set(x=leader.x, y=leader.y - 2)
s.play(leader.to(x=4), duration=2)
See also: obj.to, obj.unbind, k.signal.
k.Node.to (method)
obj.to(
*,
duration: float | None = None,
ease: EaseLike | None = None,
delay: float = 0.0,
blend: Blend = "replace",
place: PlaceKeywords | Mapping[str, object] | None = None,
unpin: bool = False,
**props: Unpack[PropChanges],
) -> Animation
Animated state change: interpolates each prop from its value at the cursor to the target. Accepts any public prop (x, y, scale, rotate, color, opacity...) plus duration=, ease=, delay=, blend="add", and unpin=True to release a .place constraint where the animation starts (to switch constraints instead, use obj.to_place(...)). Colors interpolate in OKLab.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
duration |
float | None |
None |
Accepts any public prop (x, y, scale, rotate, color, opacity...) plus duration=, ease=, delay=, blend="add", and unpin=True to release a .place constraint where the animation starts (to switch constraints instead, use obj.to_place(...)). |
ease |
EaseLike | None |
None |
Accepts any public prop (x, y, scale, rotate, color, opacity...) plus duration=, ease=, delay=, blend="add", and unpin=True to release a .place constraint where the animation starts (to switch constraints instead, use obj.to_place(...)). |
delay |
float |
0.0 |
Accepts any public prop (x, y, scale, rotate, color, opacity...) plus duration=, ease=, delay=, blend="add", and unpin=True to release a .place constraint where the animation starts (to switch constraints instead, use obj.to_place(...)). |
blend |
Blend |
"replace" |
Accepts any public prop (x, y, scale, rotate, color, opacity...) plus duration=, ease=, delay=, blend="add", and unpin=True to release a .place constraint where the animation starts (to switch constraints instead, use obj.to_place(...)). |
place |
PlaceKeywords | Mapping[str, object] | None |
None |
|
unpin |
bool |
False |
Accepts any public prop (x, y, scale, rotate, color, opacity...) plus duration=, ease=, delay=, blend="add", and unpin=True to release a .place constraint where the animation starts (to switch constraints instead, use obj.to_place(...)). |
**props |
Unpack[PropChanges] |
variadic |
Example:
@k.scene
def state(s: k.Scene):
square = k.Square(1.5).place(at="center")
s.play(k.draw(square))
s.play(square.to(color=k.RED, rotate=45, scale=1.5), duration=1.5)
s.wait(0.5)
See also: obj.set, anim.with_, s.during.
k.Node.unbind (method)
obj.unbind(*names: str)
Removes reactive bindings (all props when no name is given), keeping the current value. Required before animating a bound prop (error K0401).
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
*names |
str |
variadic |
Example:
@k.scene
def unbind(s: k.Scene):
a = k.Dot(r=0.25, x=-3)
b = k.Dot(r=0.25, x=-3, y=-1, fill=k.RED)
s.add(a, b)
b.set(x=a.x)
s.play(a.to(x=3))
b.unbind("x")
s.play(b.to(x=-3))
k.Node.edge (method)
obj.edge(name: Anchor = "center") -> Expr[Vec]
Point of the object's box named by an anchor ("right", "top-left", ...), in its parent's coordinates, reactive: k.Arrow(start=a.edge("right"), end=b.edge("left")).
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
name |
Anchor |
"center" |
k.Node.age (property)
obj.age: Expr[float] # read-only
Seconds since the object (or its nearest present ancestor) last entered the scene.
k.Node.entered (property)
obj.entered: EventSource[None] # read-only
Event at each entry of the object into the scene.
k.Node.exited (property)
obj.exited: EventSource[None] # read-only
Event at each exit of the object from the scene.
k.Node.copy (method)
obj.copy(frozen: bool = False) -> Node
Creates a new identity with the same props. By default the copy follows the original's reactive bindings; frozen=True copies only the values at the cursor. Use it to show the same visual in two places (an object has a single parent).
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
frozen |
bool |
False |
By default the copy follows the original's reactive bindings; frozen=True copies only the values at the cursor. |
Example:
@k.scene
def copy(s: k.Scene):
original = k.Circle(r=0.8, fill=k.TEAL, fill_opacity=0.5).place(at="left", margin=3)
s.play(k.draw(original))
twin = original.copy(frozen=True).place(at="right", margin=3)
s.play(k.fade_in(twin))
See also: k.Group, k.reparent.
k.Node.place (method)
obj.place(**kw: Unpack[PlaceKeywords]) -> Node
Written as: obj.place(at=, above=, below=, left_of=, right_of=, inside=, gap=, margin=, align=, pad=, clamp=False, weak=False)
Declares where the object sits, relative to the frame (at="top", margin=) or to another object (above=, below=, left_of=, right_of=, inside= with pad=), with gap= (accepts a signal) and align=. The relation keeps holding while the objects move. Returns the object itself, so it chains with the constructor.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
**kw |
Unpack[PlaceKeywords] |
variadic | Keyword arguments (PlaceKeywords): at: Anchor | VecVal, above: Node, below: Node, left_of: Node, right_of: Node, inside: Node, gap: FloatVal, margin: FloatVal, pad: FloatVal, align: Align, clamp: bool, weak: bool, by: str. |
Example:
@k.scene
def positions(s: k.Scene):
box = k.Square(2).place(at="center")
title = k.Text("Title").place(at="top", margin=0.6)
label = k.Text("box", size=0.4).place(below=box, gap=0.3)
s.add(box, title, label)
s.play(box.to(scale=1.5))
See also: obj.to_place, obj.unpin, k.Row, obj.to.
k.Node.to_place (method)
obj.to_place(
*,
duration: float | None = None,
ease: EaseLike | None = None,
delay: float = 0.0,
**place: Unpack[PlaceKeywords],
) -> Animation
Written as: obj.to_place(at=, above=, below=, left_of=, right_of=, inside=, gap=, margin=, align=, pad=, clamp=False, weak=False, duration=None, ease=None, delay=0.0)
Animated change of placement: the .to of .place. Takes the same keywords as .place(...) plus duration=, ease= and delay=, and moves the object from its current placement to the new one. The new constraint keeps holding afterwards.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
duration |
float | None |
None |
Takes the same keywords as .place(...) plus duration=, ease= and delay=, and moves the object from its current placement to the new one. |
ease |
EaseLike | None |
None |
Takes the same keywords as .place(...) plus duration=, ease= and delay=, and moves the object from its current placement to the new one. |
delay |
float |
0.0 |
Takes the same keywords as .place(...) plus duration=, ease= and delay=, and moves the object from its current placement to the new one. |
**place |
Unpack[PlaceKeywords] |
variadic | Keyword arguments (PlaceKeywords): at: Anchor | VecVal, above: Node, below: Node, left_of: Node, right_of: Node, inside: Node, gap: FloatVal, margin: FloatVal, pad: FloatVal, align: Align, clamp: bool, weak: bool, by: str. |
Example:
@k.scene
def replace(s: k.Scene):
tri = k.Triangle().place(at="center")
title = k.Text("title", size=0.5).place(above=tri, gap=0.4)
s.add(tri, title)
s.play(title.to_place(right_of=tri, gap=0.4))
s.play(tri.to_place(at="left", margin=2)) # the title follows
See also: obj.place, obj.unpin, obj.to.
k.Node.unpin (method)
obj.unpin()
Releases the position constraint at the cursor: the object keeps its current position and is free to animate x/y. Inside an animation, obj.to(x=..., unpin=True) does the same where the animation starts. To switch constraints instead, use obj.to_place(...).
Example:
@k.scene
def release(s: k.Scene):
tri = k.Triangle().place(at="center")
title = k.Text("free").place(above=tri, gap=0.4)
s.add(tri, title)
s.play(title.to(x=3, unpin=True))
title.unpin() # the instant form, at the cursor
See also: obj.place, obj.to_place, obj.to.
k.reparent (function)#
k.reparent(obj: Node, new_parent: Group) -> Animation
Moves an object to another group at the scheduled time, keeping its world position (inside a container, it takes its place in the flow). This is how you change parents: an object has exactly one (error K0103).
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
obj |
Node |
required | Instant move of obj into new_parent at the scheduled instant, keeping its world position (inside a container it takes its slot in the flow). |
new_parent |
Group |
required | Instant move of obj into new_parent at the scheduled instant, keeping its world position (inside a container it takes its slot in the flow). |
Example:
@k.scene
def change_group(s: k.Scene):
dot = k.Dot(r=0.25)
left = k.Row(dot, k.Square(0.8), gap=0.3).place(at="left", margin=2)
right = k.Row(k.Square(0.8), gap=0.3).place(at="right", margin=2)
s.add(left, right)
s.play(k.reparent(dot, right))
s.wait(0.5)