Manim实现涟漪扩散特效
<p>在视频制作和数据可视化领域,涟漪扩散特效是一种常见且富有视觉吸引力的动画效果。</p><p>本文将详细介绍如何使用<code>Manim</code>数学动画引擎来实现这一效果,包括其实现原理、使用示例以及应用场景。</p>
<h1 id="1-实现原理">1. 实现原理</h1>
<p>涟漪扩散特效主要通过<code>RippleEffect</code>类来实现,该类继承自Manim的<code>Animation</code>基类。让我们深入了解其核心实现机制:</p>
<h2 id="11-核心设计思路">1.1. 核心设计思路</h2>
<pre><code class="language-python">class RippleEffect(Animation):
"""
涟漪扩散特效动画类
实现方法:使用Circle类创建多个同心圆,然后通过发光层实现发光效果,
再利用脉冲效果实现闪烁,从而模拟涟漪的扩散和闪烁。
"""
</code></pre>
<h2 id="12-参数设计">1.2. 参数设计</h2>
<p>该类提供了丰富的参数控制,使其具有高度可定制性:</p>
<pre><code class="language-python">def __init__(
self,
mobject: Mobject,
num_ripples: int = 5,
max_radius: float = 3.0,
min_radius: float = 0.1,
ripple_speed: float = 1.0,
color: ParsableManimColor = BLUE,
fade_out: bool = True,
glow_num: int = 3,
glow_width: float = 5,
pulse_frequency: float = 2.0,
**kwargs
):
# 存储参数
self.num_ripples = num_ripples
self.max_radius = max_radius
self.min_radius = min_radius
self.ripple_speed = ripple_speed
self.color = color
self.fade_out = fade_out
self.glow_num = glow_num
self.glow_width = glow_width
self.pulse_frequency = pulse_frequency
</code></pre>
<h2 id="13-多颜色支持实现">1.3. 多颜色支持实现</h2>
<p>代码巧妙地支持单色和多色两种模式:</p>
<pre><code class="language-python"># 处理颜色参数,支持单个颜色或多个颜色
if isinstance(color, (list, tuple)):
self.colors = list(color)
self.use_multiple_colors = True
else:
self.colors =
self.use_multiple_colors = False
</code></pre>
<h2 id="14-涟漪对象初始化">1.4. 涟漪对象初始化</h2>
<p>在构造函数中,代码预先创建了所有需要的涟漪圆环和对应的发光层:</p>
<pre><code class="language-python"># 创建涟漪圆环列表
self.ripples = []
self.glow_layers = []
# 创建多个同心圆环作为涟漪
for i in range(num_ripples):
# 确定当前涟漪的颜色
if self.use_multiple_colors:
ripple_color = self.colors
else:
ripple_color = self.colors
# 使用Circle创建圆环,初始半径为最小半径
circle = Circle(
radius=min_radius,
stroke_color=ripple_color,
stroke_width=2,
fill_opacity=0,
).move_to(mobject.get_center())
self.ripples.append(circle)
# 为每个涟漪创建发光层
glow_group = []
for j in range(glow_num):
glow = circle.copy()
glow_group.append(glow)
self.glow_layers.append(glow_group)
</code></pre>
<h2 id="15-动画插值实现">1.5. 动画插值实现</h2>
<p><code>interpolate_mobject</code>方法是实现动画效果的核心,它在每一帧都会被调用:</p>
<pre><code class="language-python">def interpolate_mobject(self, alpha: float):
"""
实现动画效果的核心方法
Parameters:
alpha - 是一个介于 0 和 1 之间的参数,表示动画的进度
"""
# 计算时间进度,考虑涟漪速度
time_alpha = alpha * self.ripple_speed
# 为每个涟漪计算不同的相位偏移,创建连续的涟漪效果
for i, (ripple, glow_group) in enumerate(zip(self.ripples, self.glow_layers)):
# 确定当前涟漪的颜色
if self.use_multiple_colors:
ripple_color = self.colors
else:
ripple_color = self.colors
# 计算每个涟漪的相位偏移
phase_offset = i / self.num_ripples
# 计算当前涟漪的时间进度
ripple_time = (time_alpha + phase_offset) % 1
# 计算当前半径,从最小半径到最大半径
current_radius = interpolate(self.min_radius, self.max_radius, ripple_time)
# 计算透明度,如果启用淡出效果
if self.fade_out:
# 使用正弦函数创建自然的淡出效果
opacity = np.sin(ripple_time * PI) * 0.8
else:
opacity = 0.8
# 确保透明度不为负数
opacity = max(0, opacity)
# 添加脉冲效果
pulse_effect = np.sin(ripple_time * self.pulse_frequency * 2 * PI) * 0.2
opacity = max(0, opacity + pulse_effect)
# 创建新的圆环并更新属性
new_ripple = Circle(
radius=current_radius,
stroke_color=ripple_color,
stroke_width=2,
stroke_opacity=opacity,
fill_opacity=0,
).move_to(self.mobject.get_center())
# 更新涟漪对象
ripple.become(new_ripple)
# 更新发光层
for j, glow in enumerate(glow_group):
phase = j / self.glow_num
# 设置发光层属性
glow.become(new_ripple.copy())
glow.set_stroke(
width=self.glow_width * (1 - phase) + 1,# 宽度递减
color=ripple_color,
opacity=opacity * 0.3 * (1 - phase),# 透明度递减
)
</code></pre>
<p>这个方法实现了几个关键的视觉效果:</p>
<ol>
<li><strong>涟漪扩散</strong>:通过计算当前半径,使圆环从中心向外扩散</li>
<li><strong>涟漪淡出</strong>:使用正弦函数创建自然的淡出效果</li>
<li><strong>脉冲效果</strong>:添加额外的正弦波动来模拟涟漪的脉冲闪烁</li>
<li><strong>发光效果</strong>:为每个涟漪添加多层发光效果,并使它们的宽度和透明度递减</li>
<li><strong>相位偏移</strong>:为不同的涟漪设置不同的相位偏移,创造连续的涟漪效果</li>
</ol>
<h1 id="2-使用示例">2. 使用示例</h1>
<p>代码提供了三种不同的使用示例,展示了涟漪效果的多样化应用:</p>
<h2 id="21-单颜色涟漪效果">2.1. 单颜色涟漪效果</h2>
<p>最简单的应用场景,从一个中心点向外扩散单色涟漪:</p>
<pre><code class="language-python">class RippleEffectExample(Scene):
"""
涟漪扩散特效示例场景
"""
def construct(self):
# 创建一个点作为涟漪的中心
center_dot = Dot(color=YELLOW)
self.add(center_dot)
# 创建涟漪扩散特效
ripple_effect = RippleEffect(
center_dot,
num_ripples=8,
max_radius=4.0,
min_radius=0.1,
ripple_speed=1.5,
color=BLUE,
glow_num=5,
glow_width=8,
pulse_frequency=3.0,
)
# 将所有涟漪和发光层添加到场景中
for ripple, glow_group in zip(ripple_effect.ripples, ripple_effect.glow_layers):
self.add(ripple)
for glow in glow_group:
self.add(glow)
# 播放动画
self.play(ripple_effect, run_time=5)
self.wait()
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/83005/202509/83005-20250925143841344-1037384150.gif" alt="" loading="lazy"></p>
<h2 id="22-双涟漪效果">2.2. 双涟漪效果</h2>
<p>展示两个同时扩散的涟漪效果,可以用于表现两个对象之间的交互:</p>
<pre><code class="language-python">class DualRippleEffectExample(Scene):
"""
双涟漪扩散特效示例场景
展示两个同时扩散的涟漪效果
"""
def construct(self):
# 创建两个点作为涟漪的中心
center_dot1 = Dot(color=YELLOW).shift(LEFT * 2)
center_dot2 = Dot(color=RED).shift(RIGHT * 2)
self.add(center_dot1, center_dot2)
# 创建两个涟漪扩散特效
ripple_effect1 = RippleEffect(
center_dot1,
num_ripples=6,
max_radius=1.5,
min_radius=0.1,
ripple_speed=1.2,
color=BLUE,
glow_num=4,
glow_width=6,
pulse_frequency=5.5,
)
ripple_effect2 = RippleEffect(
center_dot2,
num_ripples=6,
max_radius=1.5,
min_radius=0.1,
ripple_speed=1.2,
color=RED,
glow_num=8,
glow_width=4,
pulse_frequency=2.5,
)
# 将所有涟漪和发光层添加到场景中
for ripple, glow_group in zip(
ripple_effect1.ripples, ripple_effect1.glow_layers
):
self.add(ripple)
for glow in glow_group:
self.add(glow)
for ripple, glow_group in zip(
ripple_effect2.ripples, ripple_effect2.glow_layers
):
self.add(ripple)
for glow in glow_group:
self.add(glow)
# 同时播放两个动画
self.play(ripple_effect1, ripple_effect2, run_time=5)
self.wait()
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/83005/202509/83005-20250925143841808-1026433931.gif" alt="" loading="lazy"></p>
<h2 id="23-多颜色涟漪效果">2.3. 多颜色涟漪效果</h2>
<p>最具视觉冲击力的效果,从一个中心点向外扩散多种颜色的涟漪:</p>
<pre><code class="language-python">class MultiColorRippleEffectExample(Scene):
def construct(self):
# 创建一个点作为涟漪的中心
center_dot = Dot(color=YELLOW)
self.add(center_dot)
# 创建涟漪扩散特效
ripple_effect = RippleEffect(
center_dot,
num_ripples=8,
max_radius=4.0,
min_radius=0.1,
ripple_speed=1.5,
color=,
glow_num=5,
glow_width=8,
pulse_frequency=3.0,
)
# 将所有涟漪和发光层添加到场景中
for ripple, glow_group in zip(ripple_effect.ripples, ripple_effect.glow_layers):
self.add(ripple)
for glow in glow_group:
self.add(glow)
# 播放动画
self.play(ripple_effect, run_time=5)
self.wait()
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/83005/202509/83005-20250925143841076-1146974765.gif" alt="" loading="lazy"></p>
<h1 id="3-总结">3. 总结</h1>
<h2 id="31-特效特点">3.1. 特效特点</h2>
<ol>
<li><strong>高度可定制</strong>:提供了丰富的参数控制,包括涟漪数量、大小、速度、颜色、发光效果等</li>
<li><strong>视觉效果优美</strong>:通过多层发光、脉冲效果和相位偏移,创造出逼真而华丽的涟漪效果</li>
<li><strong>支持多颜色模式</strong>:可以实现单色涟漪或彩虹般的多色涟漪效果</li>
<li><strong>易于扩展</strong>:基于Manim的Animation类,易于与其他动画效果结合</li>
</ol>
<h2 id="32-使用场景">3.2. 使用场景</h2>
<p>涟漪扩散特效在以下场景中特别有用:</p>
<ol>
<li><strong>数据可视化</strong>:用于突出显示数据点或数据变化</li>
<li><strong>科学动画</strong>:模拟水面波纹、声波、电磁波等物理现象</li>
<li><strong>教育视频</strong>:在解释概念时吸引观众注意力,提高学习效果</li>
<li><strong>产品展示</strong>:为产品演示添加视觉亮点,增强吸引力</li>
<li><strong>片头片尾</strong>:作为视频过渡或装饰元素</li>
<li><strong>用户界面设计</strong>:在交互式应用中提供视觉反馈</li>
</ol>
<p>通过本文介绍的<code>RippleEffect</code>类,你可以轻松在自己的动画项目中实现这一效果,为你的作品增添视觉吸引力。</p><br><br>
来源:https://www.cnblogs.com/wang_yb/p/19111184
頁:
[1]