一键导入
component-design
Reusable component patterns including VGroup subclasses, helper methods, encapsulated visualizations, and always_redraw patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Reusable component patterns including VGroup subclasses, helper methods, encapsulated visualizations, and always_redraw patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Core Manim concepts including Scene lifecycle, Mobject hierarchy, coordinate systems, animation lifecycle, and rate functions.
Mathematical rendering with MathTex, Tex, tex_to_color_map, custom equation classes, and formula animation patterns.
Production animation patterns including reveal, transform, progressive reveal, emphasis, and cleanup patterns.
Camera manipulation including zoom, pan, save/restore state, line width compensation, and focus transitions.
3Blue1Brown-style production standards including color palettes, timing guidelines, positioning rules, cleanup patterns, and typography standards.
| name | component-design |
| description | Reusable component patterns including VGroup subclasses, helper methods, encapsulated visualizations, and always_redraw patterns. |
Patterns for creating reusable, well-structured Manim components.
class MyComponent(VGroup):
"""Reusable visualization component"""
def __init__(self, param1, param2, **kwargs):
super().__init__(**kwargs)
# Store parameters
self.param1 = param1
self.param2 = param2
# Build component
self._build()
def _build(self):
"""Construct the component's mobjects"""
# Create child mobjects
self.part_a = Circle(radius=self.param1)
self.part_b = Square(side_length=self.param2)
# Position relative to each other
self.part_b.next_to(self.part_a, RIGHT)
# Add to self (VGroup)
self.add(self.part_a, self.part_b)
# Create instance
component = MyComponent(1.0, 0.5)
# It's a VGroup, so all VGroup methods work
component.scale(0.5)
component.move_to(LEFT * 2)
component.set_color(BLUE)
# Animate
self.play(Create(component))
self.play(component.animate.shift(RIGHT * 3))
from scipy.stats import norm
class DistributionPlot(VGroup):
"""Self-contained probability distribution visualization"""
def __init__(
self,
func, # Distribution function
x_range=(-3, 3), # Domain
color=BLUE,
show_axes=True,
**kwargs
):
super().__init__(**kwargs)
self.func = func
self.x_min, self.x_max = x_range
self.color = color
self._build(show_axes)
def _build(self, show_axes):
# Calculate y range from function
x_vals = np.linspace(self.x_min, self.x_max, 100)
y_vals = [self.func(x) for x in x_vals]
y_max = max(y_vals) * 1.1
# Create axes
self.axes = Axes(
x_range=[self.x_min, self.x_max, 1],
y_range=[0, y_max, y_max/4],
x_length=6,
y_length=4,
tips=False
)
# Create plot
self.curve = self.axes.plot(self.func, color=self.color)
# Add to component
if show_axes:
self.add(self.axes)
self.add(self.curve)
# Helper methods
def get_point(self, x):
"""Get point on curve at x value"""
return self.axes.c2p(x, self.func(x))
def get_area(self, x_start, x_end, color=None):
"""Get shaded area under curve"""
return self.axes.get_area(
self.curve,
x_range=[x_start, x_end],
color=color or self.color
)
def get_vertical_line(self, x, color=RED):
"""Get vertical line from x-axis to curve"""
return DashedLine(
start=self.axes.c2p(x, 0),
end=self.get_point(x),
color=color
)
class DemoScene(Scene):
def construct(self):
# Create distribution
dist = DistributionPlot(
func=lambda x: norm.pdf(x, 0, 1),
x_range=(-3, 3),
color=BLUE
)
self.play(Create(dist))
# Use helper methods
area = dist.get_area(-1, 1, color=YELLOW)
self.play(FadeIn(area))
line = dist.get_vertical_line(0)
self.play(Create(line))
class DynamicPlot(VGroup):
"""Plot with dynamic parameter"""
def __init__(self, initial_value=1.0, **kwargs):
super().__init__(**kwargs)
# Create tracker
self.value_tracker = ValueTracker(initial_value)
# Build static parts
self.axes = Axes(x_range=[-3, 3], y_range=[0, 1])
self.add(self.axes)
# Build dynamic parts
self.curve = always_redraw(self._build_curve)
self.add(self.curve)
def _build_curve(self):
"""Rebuild curve based on current tracker value"""
sigma = self.value_tracker.get_value()
return self.axes.plot(
lambda x: norm.pdf(x, 0, sigma),
color=BLUE
)
def set_value(self, value, **kwargs):
"""Animate value change"""
return self.value_tracker.animate.set_value(value, **kwargs)
@property
def value(self):
return self.value_tracker.get_value()
class DynamicScene(Scene):
def construct(self):
plot = DynamicPlot(initial_value=1.0)
self.add(plot)
# Animate parameter change
self.play(plot.set_value(0.5), run_time=2)
self.play(plot.set_value(2.0), run_time=2)
class PlotSystem(VGroup):
"""Coordinate system with encapsulated plotting"""
def __init__(self, x_range, y_range, **kwargs):
super().__init__(**kwargs)
self.axes = Axes(
x_range=x_range,
y_range=y_range,
tips=False
)
self.add(self.axes)
self.plots = VGroup()
self.add(self.plots)
def c2p(self, x, y):
"""Convert coordinates to point"""
return self.axes.c2p(x, y)
def p2c(self, point):
"""Convert point to coordinates"""
return self.axes.p2c(point)
def plot(self, func, x_range=None, **kwargs):
"""Add a plot to the system"""
plot = self.axes.plot(func, x_range=x_range, **kwargs)
self.plots.add(plot)
return plot
def add_point(self, x, y, **kwargs):
"""Add a point to the system"""
point = Dot(self.c2p(x, y), **kwargs)
self.add(point)
return point
def add_data(self, data, **kwargs):
"""Add scatter points from data"""
points = VGroup(*[
Dot(self.c2p(x, y), **kwargs)
for x, y in data
])
self.add(points)
return points
class ComponentFactory:
"""Factory for creating styled components"""
# Shared configuration
COLORS = {
"primary": BLUE,
"secondary": ORANGE,
"accent": PURPLE
}
@classmethod
def create_labeled_circle(cls, label_text, radius=0.5, color="primary"):
"""Create a circle with centered label"""
group = VGroup()
circle = Circle(radius=radius, color=cls.COLORS[color])
label = Text(label_text, font_size=24)
label.move_to(circle)
group.add(circle, label)
return group
@classmethod
def create_labeled_box(cls, title, content, width=3, color="primary"):
"""Create a box with title and content"""
group = VGroup()
box = Rectangle(width=width, height=2, color=cls.COLORS[color])
title_text = Text(title, font_size=20, weight=BOLD)
content_text = Text(content, font_size=16)
title_text.next_to(box, UP, buff=0.1, aligned_edge=LEFT)
content_text.move_to(box)
group.add(box, title_text, content_text)
return group
class NeuralNetworkLayer(VGroup):
"""Single layer of neurons"""
def __init__(self, n_neurons, radius=0.3, **kwargs):
super().__init__(**kwargs)
self.neurons = VGroup(*[
Circle(radius=radius, color=WHITE)
for _ in range(n_neurons)
]).arrange(DOWN, buff=0.5)
self.add(self.neurons)
def get_neuron(self, index):
return self.neurons[index]
class NeuralNetwork(VGroup):
"""Complete neural network visualization"""
def __init__(self, layer_sizes, **kwargs):
super().__init__(**kwargs)
# Create layers
self.layers = VGroup(*[
NeuralNetworkLayer(size)
for size in layer_sizes
]).arrange(RIGHT, buff=2)
# Create connections
self.connections = VGroup()
for i in range(len(self.layers) - 1):
layer_connections = self._connect_layers(
self.layers[i],
self.layers[i + 1]
)
self.connections.add(layer_connections)
self.add(self.connections, self.layers)
def _connect_layers(self, layer1, layer2):
"""Create arrows between all neurons in adjacent layers"""
arrows = VGroup()
for n1 in layer1.neurons:
for n2 in layer2.neurons:
arrow = Arrow(
n1.get_right(),
n2.get_left(),
buff=0.05,
stroke_width=1
)
arrows.add(arrow)
return arrows
Each component should do one thing well:
# Good: Focused component
class AxisLabels(VGroup):
"""Just handles axis labels"""
pass
# Bad: Doing too much
class PlotWithLabelsAndLegendAndTitle(VGroup):
pass
class FlexibleComponent(VGroup):
DEFAULT_COLOR = BLUE
DEFAULT_SIZE = 1.0
def __init__(self, color=None, size=None, **kwargs):
super().__init__(**kwargs)
self.color = color or self.DEFAULT_COLOR
self.size = size or self.DEFAULT_SIZE
class PlotComponent(VGroup):
def get_point_at(self, x):
"""Get point on plot at x value"""
pass
def highlight_region(self, x1, x2):
"""Highlight a region of the plot"""
pass
def add_annotation(self, x, text):
"""Add text annotation at x"""
pass
# Public attributes: no underscore
self.axes
self.curve
# Private/internal: leading underscore
self._temp_points
self._cached_values
# Methods: verbs for actions
def get_area(self, ...):
def create_label(self, ...):
def update_curve(self, ...):
class WellDocumentedComponent(VGroup):
"""Brief description of component.
Longer description explaining use case and behavior.
Args:
param1: Description of param1
param2: Description of param2
Attributes:
axes: The underlying Axes object
curve: The plotted curve
Example:
>>> comp = WellDocumentedComponent(1.0, "label")
>>> self.play(Create(comp))
"""