Improvements and additions to animation control and operations based on Manim.
For basic Manim knowledge, please refer to manim
- Configure the LaTeX environment first
- For detailed instructions, refer to texlive
Warning
WARNING: Be sure to configure the LaTeX environment variables properly.
- Install dependencies
- Developed with
Python 3.10, the minimum required version isPython 3.8.
git clone https://github.com/rainbowyuyu/manim_extend_rainbow.git
cd ./manim_extend_rainbow
pip install -r requirements.txtyty_manim
├── examples.ipynb
├── disposition
│ ├── speed_rate_fuc.py
│ ├── speed_rate_fuc.md
│ └── fonts_and_colors.py
├── basic_unit
│ ├── squ_tex.py
│ ├── dec_bin.py
│ ├── screen_cycle.py
│ ├── threed_vgp.py
│ ├── code_step.py
│ ├── shapes.py
│ ├── cs2_arena.py
│ ├── cs2_damage.py
│ └── cs2_map.py
├── application
│ ├── matrix_yty.py
│ ├── page_replacement.py
│ ├── title_animate.py
│ └── s.py
└── tools
└── map_editor
video_project
└── cs2_c4
├── manim
├── cs2_c4_data
├── cs2_c4_edit
└── cs2_c4_footage
Collection of Manim rate_func easing curves (polynomial / sine·expo·circ / back·elastic·bounce / there-and-back, etc.).
Full guide, usage tips, and a GIF demo for each curve:
→ speed_rate_fuc.md
from yty_manim.disposition.speed_rate_fuc import ease_in_out_cubic, rate_presets
self.play(mob.animate.shift(RIGHT), rate_func=ease_in_out_cubic)
self.play(..., rate_func=rate_presets["ease_out_back"])Regenerate demo GIFs:
python examples/render_speed_rate_gifs.pyFont list, gradient palettes, typedict shape styles, and CS2-related defaults (cs2_arena_3d / cs2_damage / cs2_mirage_map, etc.).
Contains classes SquTex, SquTexSlide, and Stack
A data block, inheriting from :class:~.VGroup,
- Commonly used for demonstrations of data structures and binary encoding,
- Combines squares and numbers together, supporting unified and individual animations,
- The
distancemember records the gap between data when first constructed, - Single animations can be created using :method:
animate_one_by_oneto group animations, - When creating the data block, all modifiable parameters are passed to the :class:
~.Squareclass, - To modify other parameters, use :method:
change_squareand :method:change_text, - Be cautious when using :method:
change_text, as it will change the hierarchy of the original object, - Use :method:
add_bracketto add brackets to all negative numbers in the data block.
Usage example:
from manim import *
from yty_manim.basic_unit.squ_tex import SquTex
class SquTexCreate(Scene):
def construct(self):
t = SquTex("rainbow")
self.play(t.animate_one_by_one(FadeIn , scale=1.5))
self.wait()A slid
6DB7
ing data block, inheriting from :class:~.SquTex,
- Adds sliding animation to the data block,
- Use :method:
slidefor basic positional sliding, - Use :method:
slide_fadefor internal or external sliding with smooth fade-in and fade-out for the data block.
Usage example:
from manim import *
from yty_manim.basic_unit.squ_tex import SquTexSlide
class SquTexSlideBasic(Scene):
def construct(self):
s = SquTexSlide("rainbow")
self.add(s)
self.wait()
for i in range(len(s)):
self.play(*s.slide(-1))
self.wait()A stack-oriented data block, inheriting from :class:~.SquTexSlide,
- Adds structure transforms on top of sliding blocks: swap, reverse, and a following pointer,
- Use :method:
move_pointerto move the pointer to an index, - Use :method:
swap/ :method:reverse(unpack the returned animation group inplay), - :method:
pop/ :method:pushare extended to keep the pointer in sync.
Usage example:
from manim import *
from yty_manim.basic_unit.squ_tex import Stack
from yty_manim.disposition.fonts_and_colors import gradient_dict, typedict
class StackClass(Scene):
def construct(self):
lst = [1, 2, 3, 4, 5]
s = Stack(lst, pointer_direction=UP, need_pointer=True, **typedict["default_st_type"])
for i in range(len(lst)):
s[i].set_color(gradient_dict["rainbow_color"][i % 7])
self.play(Create(s))
self.play(s.animate.move_pointer(2))
self.play(*s.swap(0, 3))
self.play(*s.reverse())
self.wait()Contains classes BinNumber and Bin4SquTex
BinNumberhandles binary numeric logic;Bin4SquTexis planned to connect binary display toSquTexanimations (still being improved).
A data block for binary numbers,
-
Records the sign bit, integer part, and fractional part of a binary number,
-
Converts decimal numbers to an ideal binary format,
-
Can perform operations on binary numbers.
-
Initialize with empty values for the object, then use :method:
bin2decto convert the binary object to a decimal number, -
Use :method:
standardizeto standardize the binary number format, -
Use :method:
ex_oneto convert to its one's complement, -
Use :method:
ex_twoto convert to its two's complement, -
Use :method:
informationto display all parameter information, -
Use :method:
cal_checkto check if precision will be exceeded during calculations, -
Operator overloading methods follow the format of the first operand.
Usage example:
from yty_manim.basic_unit.dec_bin import BinNumber
# Define decimal number and convert it to binary
test_bin = BinNumber(-0.2, 8, 1, True)
print(test_bin)
print(test_bin.ex_one())
print(test_bin.ex_two())Contains classes ScreenCycle and Directory
A title-screen carousel, inheriting from :class:~.VGroup,
- Commonly used for intro title rotation and parking the active title in a corner,
- Construct with a list of title strings; optionally set font, gradient, spacing, and magnification,
- Use :method:
step_forwardto advance (highlight current, fade others), - Use :method:
set_to_edge/ :method:set_backto move the title to a corner or restore the carousel.
Usage example:
from manim import *
from yty_manim.basic_unit.screen_cycle import ScreenCycle
class ScreenTest(Scene):
def construct(self):
text_list = [
"Hello World",
"Hell Worl",
"Hel Wor",
"He Wo",
]
s = ScreenCycle(text_list)
self.add(s)
for i in range(len(text_list)):
self.play(s.animate.step_forward())
self.play(s.animate.set_to_edge(UL))
self.play(s.animate.set_back())A table-of-contents visual, inheriting from :class:~.VGroup,
- Left-side dotted timeline plus chapter titles on the right,
- Use :method:
step_forwardto light up the next item in sync with narration.
Usage example:
from manim import *
from yty_manim.basic_unit.screen_cycle import Directory
from yty_manim.disposition.fonts_and_colors import text_font
class DirectoryPage(Scene):
def construct(self):
title = [
"Pages & replacement",
"Thrashing & Belady",
"Replacement algorithms",
"Stack structure",
"Code walkthrough",
]
d = Directory(title, font=text_font[0])
d[1].set_color(GRAY)
self.play(Write(d[0:2]), run_time=2)
for i in range(len(title)):
d.step_forward(self)Contains class ThreeDVgp
A layered 3D object group, inheriting from :class:~.VGroup,
- Copies any 2D mobject along
OUTto create extruded thickness, - Use :method:
set_depth_gradient_colorfor a depth color ramp, - Use :method:
set_depth_gradient_opacityfor a depth opacity ramp, - Use :method:
animate_togetherto apply the same animation to every layer, - Use :method:
set_shadeto offset a bottom shadow layer.
Usage example:
from manim import *
from yty_manim.basic_unit.threed_vgp import ThreeDVgp
from yty_manim.disposition.fonts_and_colors import color_dict
class PictureShow(ThreeDScene):
def construct(self):
self.camera.background_color = color_dict["bg"]
t2d = Text("rainbow")
t3d = ThreeDVgp(t2d, layer_depth=20)
self.set_camera_orientation(0.25 * PI, -0.25 * PI, 0.25 * PI)
t3d.set_depth_gradient_opacity([0, 1])
t3d.set_depth_gradient_color(WHITE, BLUE_D)
self.add(t3d)Contains class CodeStep
Stepwise code writing, inheriting from :class:~.Code,
- Tracks how many lines h 9E09 ave already been revealed,
- Use :method:
write_codeto write the nextlines; withis_auto_runtime=True, duration scales with character count, - Useful when walking through pseudocode in sync with narration.
Usage example:
from manim import *
from yty_manim.basic_unit.code_step import CodeStep
class CodeShow(Scene):
def construct(self):
c1 = CodeStep(
code_string="a = 1\nb = 2\nprint(a + b)",
language="python",
)
self.add(c1)
for i in range(len(c1[2])):
c1.write_code(self, 1, is_auto_runtime=True)
self.wait(0.3)Contains class Book
A book-shaped decoration, inheriting from :class:~.VGroup,
- Built from a cover rectangle, side thickness, top cut, and vertical title,
indexsetsz_indexfor stacking order,fill_color/stroke_colorcontrol the cover fill and stroke,- Handy for intros, shelves, and chapter decorations.
Usage example:
from manim import *
from yty_manim.basic_unit.shapes import Book
class BookShape(Scene):
def construct(self):
b1 = Book("...", 0, BLUE, BLUE_E)
b2 = Book("CV", 1, GREEN, GREEN_E)
self.add(b1.shift(LEFT * 0.5), b2)
self.wait()Contains Arena3D, GridMap2D, AlgoSpec, and shared toy-map constants GRID, BOMB_IJ, SURVIVOR_IJ
- The 3D arena and 2D pathfinding grid share the same topology for sphere-blast vs path-wave comparisons.
A CS2 C4–style 3D arena, inheriting from :class:~.VGroup,
- Builds floor plates, merged walls, bomb and survivor markers from
GRID, - Often paired with shockwave / sphere-blast
ThreeDScenes, - Helpers such as
_bfs_dist/_bfs_pathand damage coloring live in the same module.
Usage example:
from manim import *
from yty_manim.basic_unit.cs2_arena import Arena3D
class ArenaShow(ThreeDScene):
def construct(self):
self.set_camera_orientation(phi=58 * DEGREES, theta=-55 * DEGREES, zoom=0.72)
arena = Arena3D()
self.play(FadeIn(arena), run_time=1.2)
self.wait()A 2D grid map for pathfinding visuals, inheriting from :class:~.VGroup,
- Shares
GRID/BOMB_IJ/SURVIVOR_IJwithArena3D, - Supports layered coloring, path polylines, and endpoint markers,
- Use :method:
apply_map_transformto scale/shift for side-panel layouts.
Usage example:
from manim import *
from yty_manim.basic_unit.cs2_arena import (
BOMB_IJ,
SURVIVOR_IJ,
MAP_SCALE,
MAP_SHIFT,
GridMap2D,
)
class GridShow(Scene):
def construct(self):
m = GridMap2D(BOMB_IJ, SURVIVOR_IJ)
m.apply_map_transform(MAP_SCALE, MAP_SHIFT)
self.add(m, m.markers)
self.wait()Contains ExplosionMarker, PlayerMarker, DamageGrid, HealthBar, DamageHill3D,
plus helpers such as bake_damage_field / bilinear_sample / make_demo_walls
- Used to explain distance falloff × occlusion → grid bake → runtime sample → HP preview.
A teaching explosion marker, inheriting from :class:~.VGroup,
- Draws a core, glow, and radius ring (visual only),
- Different from the
ExplosionSourcedata class intools.map_editor; aliasExplosionSource = ExplosionMarkeris kept here.
Usage example:
from manim import *
from yty_manim.basic_unit.cs2_damage import ExplosionMarker, RADIUS
class MarkerShow(Scene):
def construct(self):
src = ExplosionMarker(ORIGIN, RADIUS)
self.play(FadeIn(src))
self.wait()A prebaked damage heat grid, inheriting from :class:~.Group (avoids empty-anchor zip issues),
- Takes a world-point lattice and a damage field, then colors each sample by intensity,
- Works with :func:
make_grid_points/ :func:bake_damage_field/ :func:bilinear_sample.
Usage example:
from manim import *
import numpy as np
from yty_manim.basic_unit.cs2_damage import (
D_MAX,
DamageGrid,
ExplosionMarker,
RADIUS,
bake_damage_field,
make_demo_walls,
make_grid_points,
)
class DamageGridShow(Scene):
def construct(self):
walls = make_demo_walls()
pts, *_ = make_grid_points()
e = np.array([-2.2, 0.6, 0.0])
field = bake_damage_field(pts, e, RADIUS, D_MAX, walls)
grid = DamageGrid(pts, field)
self.add(grid, ExplosionMarker(e, RADIUS))
self.wait()A 3D damage-hill helper (teaching model, not an engine port),
- :method:
heightreturns surface height; :method:color_surfacecolors faces by height, - :method:
curved_descent_pathreturns a ground-following Bézier sample path, - Full production scene:
video_project/cs2_c4/manim/damage_field_3d.py.
Usage example:
from manim import *
from yty_manim.basic_unit.cs2_damage import DamageHill3D, X_MIN, X_MAX, Y_MIN, Y_MAX
class HillShow(ThreeDScene):
def construct(self):
hill = DamageHill3D()
surface = Surface(
lambda u, v: np.array([u, v, hill.height(u, v)]),
u_range=[X_MIN, X_MAX],
v_range=[Y_MIN, Y_MAX],
resolution=(24, 20),
)
hill.color_surface(surface)
self.set_camera_orientation(phi=70 * DEGREES, theta=-40 * DEGREES)
self.add(surface)
self.wait()Contains MirageVectorMap, GridMapView, MirageOverview, plus Mirage walkability, site constants, and engine snippets
- Data:
WALKABLE,WAVE_SPEED_M_S,dijkstra_wave_field,arrival_time_seconds - Rendering: vector heat map, MapBundle view, shockwave tracker binding
A Mirage top-down vector map with a fluid shockwave front, inheriting from :class:~.VGroup,
- Draws floor and heat layers from the 128×96 walkable grid,
- Use :func:
bind_fluid_wave_trackerto sync aValueTrackerradius to the contour front.
Usage example:
from manim import *
import numpy as np
from yty_manim.basic_unit.cs2_map import (
BOMB_SITE_A,
MirageVectorMap,
bind_fluid_wave_tracker,
dijkstra_wave_field,
)
class MirageMapShow(Scene):
def construct(self):
dist, _ = dijkstra_wave_field(BOMB_SITE_A.norm)
m = MirageVectorMap(dist=dist)
r = ValueTracker(0.0)
bind_fluid_wave_tracker(m, r)
self.add(m)
self.play(r.animate.set_value(float(np.nanmax(dist[np.isfinite(dist)]))), run_time=4)
self.wait()A generic MapBundle grid view, inheriting from :class:~.VGroup,
- Loads a bundle from
tools.map_editorand draws walkable cells plus shockwave heat, - Assemble with :func:
build_map_view_from_bundle/ :func:bind_wave_tracker.
Usage example:
from manim import *
from yty_manim.basic_unit.cs2_map import bind_wave_tracker, build_map_view_from_bundle
from yty_manim.tools.map_editor.map_bundle import MapBundle, default_maps_dir
class BundleMapShow(Scene):
def construct(self):
bundle = MapBundle.load(default_maps_dir() / "your_map")
view = build_map_view_from_bundle(bundle)
r = ValueTracker(0.0)
bind_wave_tracker(view, r)
self.add(view)
self.play(r.animate.set_value(40), run_time=3)Contains base class MatrixCal and computation classes MatrixDet and MatrixMath
A matrix class for absolute control of matrix elements, inheriting from :class:~.VGroup,
- Commonly used for demonstrating matrix computations; each row is a
SquTex, - Supports generating matrices with negative numbers and brackets using :method:
neg_with_brackets, - Get matrix rows using :method:
get_row, - Get matrix columns using :method:
get_column.
Usage example:
from manim import *
from yty_manim.application.matrix_yty import MatrixCal
class MatrixCalShow(Scene):
def construct(self):
m = MatrixCal([[1, -2], [3, 4]])
self.play(FadeIn(m))
self.play(Indicate(m.get_row(0)))
self.wait()Determinant calculation, inheriting from :class:~.MatrixCal,
- Commonly used for demonstrating determinant calculations,
- Supports extended determinant calculation demonstrations using :method:
det_mat, - Automatically adjusts size using :method:
set_scale_fitness, - Get calculation process information using :method:
get_process_inform, - Get result information using :method:
get_result_inform, - Generate calculation steps using :method:
cal_progress_times, - Generate result steps using :method:
cal_result_addition.
Usage example:
from manim import *
from yty_manim.application.matrix_yty import MatrixDet, matrix_3
class MatrixDetCal(Scene):
def construct(self):
mat_mob = MatrixDet(matrix_3)
mat_mob_det = mat_mob.det_mat()
vgp, vgp_brackets, num_lst = mat_mob_det.get_process_inform(1)
self.add(mat_mob_det)
self.play(FadeIn(vgp), FadeIn(vgp_brackets))
self.wait()Matrix operations, inheriting from :class:~.MatrixCal,
- Used for demonstrating matrix addition / multiplication style workflows,
- API style mirrors
MatrixDetfor stepwise intermediate results.
Usage example:
from manim import *
from yty_manim.application.matrix_yty import MatrixMath
class MatrixMathShow(Scene):
def construct(self):
a = MatrixMath([[1, 2], [3, 4]])
self.play(FadeIn(a))
self.wait()Contains base classes Page / PageReplacement, plus
OptPageReplacement, LruPageReplacement, FifoPageReplacement, and ClockPageReplacement
- Shared stack, frame table, and step interfaces make it easy to plug in more algorithms.
OS page-replacement algorithm animation, inheriting from :class:~.Page,
- Access sequence on top, page frames in the middle, optional stack and miss-rate HUD,
- Use :method:
step_onto advance; subclasses override :method:cal_funcfor eviction policy, - Commonly used to compare OPT / LRU / FIFO / Clock.
Usage example:
from manim import *
from yty_manim.application.page_replacement import OptPageReplacement
class PageOPT(Scene):
def construct(self):
input_lst = [7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1, " "]
p = OptPageReplacement(input_lst, page_frame_num=3)
self.add(p)
self.wait()
for i in range(len(input_lst) - 1):
p.step_on(self, i)Contains class TitleAnimate
Title animation, inheriting from :class:~.SquTexSlide,
- Extends sliding blocks into a title intro: push blocks in, then pop them away,
- Use :method:
generateto build the title; use :method:disappearto tear it down, force_center/force_colorcontrol centering and coloring during pushes.
Usage example:
from manim import *
from yty_manim.application.title_animate import TitleAnimate
from yty_manim.disposition.fonts_and_colors import text_font
class TitleIntroduction(Scene):
def construct(self):
ta = TitleAnimate(
"rainbow",
font=text_font[0],
side_length=1.5,
fill_opacity=0.5,
stroke_opacity=0.8,
)
self.wait()
ta.generate(self, run_time=0.5)
self.wait(1)
ta.disappear(self, run_time=0.2, force_center=False)
self.wait()Contains classes CalculusStep, DerivativeVisualizer, and IntegralVisualizer
Base class for calculus step visuals, inheriting from :class:~.VGroup,
- Used for teaching derivatives and integrals: plots, tangents, Riemann sums,
- Use :method:
show_derivative_stepsto get playable derivative steps, - Use :method:
show_integral_stepsfor integral steps, - Use :method:
animate_riemann_sumto show Riemann-sum convergence, DerivativeVisualizer/IntegralVisualizerare more specialized wrappers.
Usage example:
from manim import *
from yty_manim.application.s import CalculusStep
class DerivativeShow(Scene):
def construct(self):
calc = CalculusStep(lambda x: x ** 2, x_range=[-3, 3])
self.add(calc)
for step in calc.show_derivative_steps(x_point=1):
self.play(*step)
self.wait(0.5)Map editor and shockwave data utilities,
MapBundle/ExplosionSource/MapMarkerpack walkability, markers, and blast sources,map_wave.shockwave_fieldbuilds intensity from a Dijkstra / BFS distance field,map_radar_importimports walkability from radar images,- The Tk GUI can be launched from the repo root.
Usage example:
python -m yty_manim.tools.map_editorfrom yty_manim.tools.map_editor import MapBundle, default_maps_dir, shockwave_field
bundle = MapBundle.load(default_maps_dir() / "your_map")
dist, intensity, damage = shockwave_field(bundle)Production projects.
- Reusable units live in
yty_manim/basic_unit - Final Manim scenes live under each project's
manimfolder - Footage, narration, and edit scripts live under
cs2_c4_footage/cs2_c4_edit, etc.
CS2 C4 shockwave production scenes. Each file is one or more independently renderable Scenes:
| File | Content |
|---|---|
| titles.py | TOC + chapter title cards |
| shockwave.py | Shockwave algorithm + 3D contrast |
| pathfinding.py | Pathfinding / distance fields |
| prebake.py | Prebake algorithm |
| damage_field_3d.py | 3D damage hill |
| mirage.py | Mirage multi-shot scenes |
Usage example:
python -m manim -qh video_project/cs2_c4/manim/titles.py ContentsPageScene
python -m manim -qh video_project/cs2_c4/manim/shockwave.py ShockwaveAlgorithmScene
python -m manim -qh video_project/cs2_c4/manim/pathfinding.py PathfindingAlgorithmsScene
python -m manim -qh video_project/cs2_c4/manim/prebake.py PrebakeAlgorithmScene
python -m manim -qh video_project/cs2_c4/manim/mirage.py MirageShockwaveScene
python -m manim -qh --disable_caching video_project/cs2_c4/manim/damage_field_3d.py ExplosionDamageField3DRendered clips are typically copied to cs2_c4_edit/manim; see render_all.bat.