
今天我们来学习如何使用Manim实现漂亮的泡泡效果,本文将介绍如何使用Manim框架实现一个简单而实用的气泡特效,该特效可用于多种场景,如背景装饰、数据可视化过渡等。
1. 实现原理
气泡特效的核心在于BubbleEffect类,它继承自 Manim 的 Animation 类,通过重写关键方法来实现气泡的上升、变大和透明度变化效果。在代码用需要先引入Python的库文件:
1 2
| from manim import * import random
|
1.1. 核心类结构
BubbleEffect类的基本结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class BubbleEffect(Animation): """ 彩色气泡特效动画类 继承自Animation类,用于创建彩色气泡上升、变大、透明度变化的效果 """ def __init__( self, bubble_count=25, # 气泡数量 bubble_size_range=(0.1, 0.5), # 气泡大小范围 rise_speed_range=(0.6, 2.2), # 上升速度范围 growth_rate_range=(0.005, 0.015), # 生长速度范围 fade_rate_range=(0.02, 0.06), # 消失速度范围 colors=None, # 气泡颜色列表 **kwargs ):
|
1.2. 气泡创建机制
在__init__方法中,我们首先定义了一系列参数,如气泡数量、大小范围、上升速度等,然后创建一个VGroup来存放所有气泡:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| # 创建气泡组 self.bubbles = VGroup() self.bubble_count = bubble_count self.bubble_size_range = bubble_size_range self.rise_speed_range = rise_speed_range self.growth_rate_range = growth_rate_range self.fade_rate_range = fade_rate_range self.colors = colors or [RED, BLUE, GREEN, YELLOW, PURPLE, ORANGE]
# 保存运行时间,从kwargs中获取或使用默认值 self.run_time = kwargs.get("run_time", 5.0)
# 初始化气泡 for _ in range(bubble_count): bubble = self.create_bubble() self.bubbles.add(bubble)
# 调用父类初始化 super().__init__(self.bubbles, **kwargs)
|
每个气泡通过create_bubble方法创建,该方法随机设置气泡的大小、颜色和初始位置,并为每个气泡分配独立的上升速度、生长速度和消失速度:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| def create_bubble(self): """创建单个彩色气泡""" # 随机大小 size = random.uniform(*self.bubble_size_range) # 随机颜色 color = random.choice(self.colors) # 创建圆形气泡 bubble = Circle(radius=size, color=color, fill_opacity=0.4, stroke_width=2)
# 随机初始位置(底部区域) x_pos = random.uniform(-config.frame_width / 2 + 1, config.frame_width / 2 - 1) y_pos = random.uniform(-config.frame_height / 2, -config.frame_height / 2 + 2) bubble.move_to([x_pos, y_pos, 0])
# 存储气泡属性 bubble.rise_speed = random.uniform(*self.rise_speed_range) bubble.growth_rate = random.uniform(*self.growth_rate_range) bubble.fade_rate = random.uniform(*self.fade_rate_range) bubble.initial_radius = size
return bubble
|
1.3. 动画插值实现
动画的核心在于interpolate_mobject方法,它控制着每个气泡在每一帧的状态变化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| def interpolate_mobject(self, alpha): """插值函数,控制彩色气泡的动画效果""" dt = 1 / config.frame_rate # 每帧的时间间隔 for bubble in self.bubbles: # 1. 上升 bubble.shift(UP * bubble.rise_speed * dt)
# 2. 变大 bubble.scale(1 + bubble.growth_rate * dt)
# 3. 透明度变化 current_opacity = bubble.get_fill_opacity() new_opacity = current_opacity - bubble.fade_rate * dt
# 如果气泡超出屏幕顶部或透明度降到0以下,则重置 if new_opacity <= 0 or bubble.get_y() > config.frame_height / 2: # 重置气泡 x_pos = random.uniform( -config.frame_width / 2 + 1, config.frame_width / 2 - 1 ) y_pos = random.uniform( -config.frame_height / 2, -config.frame_height / 2 + 2 ) bubble.move_to([x_pos, y_pos, 0]) bubble.set_fill(opacity=0.4) bubble.set_stroke(opacity=0.4) else: bubble.set_fill(opacity=new_opacity) bubble.set_stroke(opacity=new_opacity)
|
这个方法实现了三个关键效果:
- 上升:每个气泡以自己的速度向上移动
- 变大:每个气泡以自己的速度缓慢变大
- 透明度变化:每个气泡逐渐变得透明
特别值得注意的是,当气泡超出屏幕顶部或透明度降到0以下时,代码会将气泡重置到底部,从而实现循环不断的气泡效果。
2. 使用示例
代码提供了两个使用示例,分别展示了普通气泡效果和彩色气泡效果。
2.1. 普通气泡效果
SimpleBubbleEffectExample类展示了如何创建灰度的气泡效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class SimpleBubbleEffectExample(Scene): """普通气泡特效示例场景"""
def construct(self): # 创建标题 title = Text("普通气泡特效演示", font_size=48) title.to_edge(UP) self.play(Write(title)) self.wait(0.5)
bubble_effect = BubbleEffect( bubble_count=25, colors=[GRAY], # 设置为灰色 bubble_size_range=(0.1, 0.5), rise_speed_range=(0.6, 2.2), growth_rate_range=(0.1, 0.5), fade_rate_range=(0.02, 0.06), run_time=2, # 使用run_time而不是duration )
# 播放气泡特效 self.play(bubble_effect) self.wait()
|
我们来看演示的视频效果:
2.2. 彩色气泡效果
ColorfulBubbleEffectExample类展示了如何创建彩色的气泡效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class ColorfulBubbleEffectExample(Scene): """彩色气泡特效示例场景"""
def construct(self): # 创建标题 title = Text("彩色气泡特效演示", font_size=48) title.to_edge(UP) self.play(Write(title)) self.wait(0.5)
# 创建彩色气泡特效动画 bubble_effect = BubbleEffect( bubble_count=25, bubble_size_range=(0.1, 0.5), rise_speed_range=(0.6, 2.2), growth_rate_range=(0.1, 0.5), fade_rate_range=(0.02, 0.06), run_time=2, # 使用run_time而不是duration )
# 播放彩色气泡特效 self.play(bubble_effect) self.wait()
|
两者的主要区别在于SimpleBubbleEffectExample显式指定了colors=[GRAY],而ColorfulBubbleEffectExample则使用了默认的彩色列表。我们来看视频的演示效果,还是非常不错的:
2.3. 自定义参数
BubbleEffect类提供了多个参数,可以根据需要进行调整:
| 参数名 |
类型 |
默认值 |
说明 |
| bubble_count |
int |
25 |
气泡数量 |
| bubble_size_range |
tuple |
(0.1, 0.5) |
气泡大小范围 |
| rise_speed_range |
tuple |
(0.6, 2.2) |
气泡上升速度范围 |
| growth_rate_range |
tuple |
(0.005, 0.015) |
气泡生长速度范围 |
| fade_rate_range |
tuple |
(0.02, 0.06) |
气泡透明度变化速度范围 |
| colors |
list |
[RED, BLUE, GREEN, YELLOW, PURPLE, ORANGE] |
气泡颜色列表 |
| run_time |
float |
5.0 |
动画运行时间 |
通过调整这些参数,可以创建各种不同风格的气泡效果。
3. 内容总结
3.1. 特效特点
- 可定制性强:通过调整多种参数,可以创建不同风格的气泡效果
- 性能优化:使用VGroup统一管理气泡,方便添加和删除
- 循环动画:气泡消失后会自动重置,实现循环不断的效果
- 随机性:每个气泡的大小、位置、速度等属性都是随机的,创建丰富多变的视觉效果
- 统一控制:作为Animation的子类,可以与Manim的其他动画无缝集成
3.2. 使用场景
- 背景装饰:为视频或演示添加动态背景
- 转场效果:在不同场景或章节之间作为过渡效果
- 数据可视化:与数据展示结合,增强视觉吸引力
- 节日氛围:通过调整颜色,可以创建适合不同节日的氛围效果
- 教学辅助:在物理课上演示浮力原理,或在化学课上模拟气泡反应
本文演示的代码,只需将上述代码复制粘贴到编辑器中,进行运行就可以,有问题可以在文章后留言。这个气泡特效实现简单但效果出色,可以为各种Manim动画项目增添生动的视觉元素。本文转自 https://www.cnblogs.com/wang_yb/p/19113551,如有侵权,请联系删除。