transform¶
备注
使用 Transform 进行不同文字间的变换可能不会有足够好的效果,在使用时请多加斟酌
- class janim.anims.transform.Transform(src_item: Item, target_item: Item, *, path_arc: float = 0, path_arc_axis: Vect = array([0., 0., 1.]), path_func: PathFunc | None = None, flatten: bool = False, root_only: bool = False, hide_src: bool = True, show_target: bool = True, src_fade: float = 0, target_fade: float = 0, **kwargs)¶
基类:
Animation创建从
src_item到target_item的插值动画作用机制:在开始时隐藏源物件,在动画过程中播放“插值效果”,在结束后显示目标物件
- 参数:
src_item -- 变换的起始物件
target_item -- 变换的目标物件
路径与插值
- 参数:
path_arc -- 插值路径的圆弧角度;为
0时按直线插值path_arc_axis -- 当使用圆弧路径时的旋转轴。
path_func -- 自定义路径函数;传入后会覆盖
path_arc与path_arc_axis的默认路径行为
对齐策略
- 参数:
flatten -- 是否忽略子物件层级并直接按顺序展平对齐;默认
False,要求源与目标子结构可对齐root_only -- 是否仅对根物件进行插值而不递归子物件
显隐与淡入淡出
- 参数:
hide_src -- 动画开始时是否自动隐藏源物件
show_target -- 动画结束时是否自动显示目标物件
src_fade -- 仅当
hide_src=False时生效;表示源物件在动画开头淡入的时长比例target_fade -- 表示目标物件在动画末尾淡出的时长比例
src_fade与target_fade对半透明物件较为实用,可规避开始/结束时重叠导致的透明度突变
基本示例:
TransformExample ¶
from janim.imports import * class TransformExample(Timeline): def construct(self): A = Text('Text-A', font_size=72) B = Text('Text-B', font_size=72) C = Text('C-Text', font_size=72) A.show() self.forward() self.play(Transform(A, B)) self.forward() self.play(Transform(B, C)) self.forward()
对
hide_src和show_target参数的演示:TransformHideShowExample ¶
from janim.imports import * class TransformHideShowExample(Timeline): def construct(self): squares = Square(color=GREEN) * 3 squares.points.arrange(DOWN).shift(LEFT * 3) circles = Circle(color=BLUE) * 3 circles.points.arrange(DOWN).shift(RIGHT * 3) txts = Text('default\nhide_src=False\nshow_target=False') txts.points.arrange(DOWN, buff=2) self.show(txts, squares) self.forward() self.play( Transform(squares[0], circles[0]), Transform(squares[1], circles[1], hide_src=False), Transform(squares[2], circles[2], show_target=False), duration=3 ) self.forward()
对
src_fade和target_fade参数的演示:TransformFadeExample ¶
from janim.imports import * class TransformFadeExample(Timeline): def construct(self): squares = Square(color=GREEN, fill_alpha=0.4) * 3 squares.points.arrange(DOWN).shift(LEFT * 3) circles = Circle(color=BLUE, fill_alpha=0.4) * 3 circles.points.arrange(DOWN).shift(RIGHT * 3) txts = Text('fade=0\nfade=0.2\nfade=0.4') txts.points.arrange(DOWN, buff=2) self.show(txts, squares) self.forward() self.play( Transform(squares[0], circles[0], hide_src=False), Transform(squares[1], circles[1], hide_src=False, src_fade=0.2), Transform(squares[2], circles[2], hide_src=False, src_fade=0.4), duration=3 ) self.forward() self.play( Transform(squares[0], circles[0]), Transform(squares[1], circles[1], target_fade=0.2), Transform(squares[2], circles[2], target_fade=0.4), duration=3 ) self.forward()
- class janim.anims.transform.MoveToTarget(item: Item, **kwargs)¶
基类:
TransformMoveToTargetExample ¶
from janim.imports import * class MoveToTargetExample(Timeline): def construct(self): txt = Text('A Matrix') mat = TypstMatrix([ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]) self.play(Write(txt)) Group(txt.generate_target(), mat).points.arrange(DOWN) self.play( MoveToTarget(txt), FadeIn(mat, UP) ) self.forward()
- class janim.anims.transform.TransformInSegments(src: Item, src_segments: Iterable[Iterable[int]] | Iterable[int], target: Item, target_segments: Iterable[Iterable[int]] | Iterable[int] | EllipsisType, *, trs_kwargs: dict = {}, **kwargs)¶
基类:
AnimGroup依照切片列表进行
src与target之间的变换
基本用法
TransformInSegments(a, [[0,3], [5,7]], b, [[1,3], [5,7]])
相当于
AnimGroup(Transform(a[0:3], b[1:3]), Transform(a[5:7], b[5:7]))
省略变换目标的切片
使用
...表示与变换来源的切片相同TransformInSegments(a, [[0,3], [5,7]], b, ...)
相当于
TransformInSegments(a, [[0,3], [5,7]], b, [[0,3], [5,7]])
连续切片
TransformInSegments(a, [[0,3], [5,7,9]], b, [[1,3], [4,7], [10,14]])
相当于
TransformInSegments(a, [[0,3], [5,7], [7,9]], b, [[1,3], [4,7], [10,14]])
切片简写
如果总共只有一个切片,可以省略一层嵌套
TransformInSegments(a, [0, 4, 6, 8], b, ...)
相当于
TransformInSegments(a, [[0, 4, 6, 8]], b, ...)
连续切片倒序
倒过来写即可使切片倒序
TransformInSegments(a, [8, 6, 4, 0], b, ...)
相当于
TransformInSegments(a, [[6,8], [4,6], [0,4]], b, ...)
请留意 Python 切片中左闭右开的原则,对于倒序序列
[8, 6, 4, 0]来说则是左开右闭TransformInSegmentsExample ¶
from janim.imports import * class TransformInSegmentsExample(Timeline): def construct(self): typ1 = TypstMath('sin x + cos x') typ2 = TypstMath('cos y + sin y') typ2.match_pattern(typ1, '+') Group(typ1, typ2).points.scale(3) self.show(typ1) self.forward(0.5) self.play(TransformInSegments(typ1, [[0,3,4], [5,8,9]], typ2, ..., lag_ratio=0.5)) self.forward(0.5)
- class janim.anims.transform.MethodTransform(item: Item, obj: Item | _AsTypeWrapper, show_at_begin: bool = True, hide_at_end: bool = False, **kwargs)¶
基类:
Transform依据物件的变换而创建的补间过程
具体参考
anim()MethodTransformExample ¶
from janim.imports import * class MethodTransformExample(Timeline): def construct(self): A = Text("Text-A") A.points.to_border(LEFT) A.show() self.forward() self.play( A.anim.points.scale(3).shift(RIGHT * 7 + UP * 2) ) self.play( A.anim.color.set(BLUE) ) self.forward()
- class janim.anims.transform.FadeTransform(src: Item, target: Item, *, hide_src: bool = True, show_target: bool = True, path_arc: float = 0, path_arc_axis: Vect = array([0., 0., 1.]), path_func: PathFunc | None = None, src_root_only: bool = False, target_root_only: bool = False, collapse: bool = True, **kwargs)¶
基类:
AnimGroup
- class janim.anims.transform.TransformMatchingShapes(src: ~janim.items.item.Item, target: ~janim.items.item.Item, *, match: MatchHandler = <function TransformMatchingShapes.<lambda>>, mismatch: tuple[MismatchHandler, MismatchHandler] = (<function TransformMatchingShapes.<lambda>>, <function TransformMatchingShapes.<lambda>>), duration: float = 2, lag_ratio: float = 0, collapse: bool = True, **kwargs)¶
基类:
AnimGroup匹配形状进行变换
match表示对于匹配的形状的处理mismatch表示对于不匹配的形状的处理注:所有传入该动画类的额外参数(
**kwargs)都会被传入match和mismatch的方法中
TransformMatchingShapesExample ¶
from janim.imports import * class TransformMatchingShapesExample(Timeline): def construct(self): a = Text("the morse code", font_size=48).show() b = Text("here come dots", font_size=48) self.forward() self.play(TransformMatchingShapes(a, b, path_arc=PI/2)) self.forward() self.play(TransformMatchingShapes(b, a, path_arc=PI/2)) self.forward()
- class janim.anims.transform.TransformMatchingDiff(src: ~janim.items.item.Item, target: ~janim.items.item.Item, *, match: MatchHandler = <function TransformMatchingDiff.<lambda>>, mismatch: tuple[MismatchHandler, MismatchHandler] = (<function TransformMatchingDiff.<lambda>>, <function TransformMatchingDiff.<lambda>>), duration: float = 2, lag_ratio: float = 0, collapse: bool = True, **kwargs)¶
基类:
AnimGroup匹配 diff 进行变换
对于一般物件,使用形状匹配 diff;对于
Text使用TextChar的字符匹配 diffmatch表示对于匹配的形状的处理mismatch表示对于不匹配的形状的处理注:所有传入该动画类的额外参数(
**kwargs)都会被传入match和mismatch的方法中
TransformMatchingDiffExample ¶
from janim.imports import * typ1_src = R""" ```python subtitle_group = Group( SurroundingRect(subtitle, color=surrounding_color, stroke_alpha=0, fill_alpha=surrounding_alpha), subtitle ).fix_in_frame() subtitle_group.depth.set(depth) if not self.hide_subtitles: self.schedule(range.at, subtitle_group.show) self.schedule(range.end, subtitle_group.hide) ``` """ typ2_src = R""" ```python if surrounding_alpha == 0: subtitle_display = subtitle else: subtitle_display = Group( SurroundingRect(subtitle, color=surrounding_color, stroke_alpha=0, fill_alpha=surrounding_alpha), subtitle ) subtitle_display.fix_in_frame().depth.set(depth) if not self.hide_subtitles: self.schedule(range.at, subtitle_display.show) self.schedule(range.end, subtitle_display.hide) ``` """ class TransformMatchingDiffExample(Timeline): CONFIG = Config( typst_shared_preamble=t_( R''' #set text(black) #show: box.with(inset: 8pt, fill: white, stroke: gray + 2pt, radius: 4pt) ''' ) ) def construct(self): typ1 = TypstDoc(typ1_src).show() typ2 = TypstDoc(typ2_src) # 设置背景框的深度 for typ in [typ1, typ2]: typ[:2].set(depth=1) self.forward() self.play( Transform(typ1[:2], typ2[:2], duration=2), TransformMatchingDiff(typ1[2:], typ2[2:]) ) self.forward() typ1 = TypstDoc(typ1_src).show() typ2 = TypstDoc(typ2_src)