灰行人饿杀鬼 發表於 2025-10-2 16:43:00

Manim实现渐变填充特效

<p>本文将介绍如何使用<code>Manim</code>框架实现<strong>动态渐变填充特效</strong>,通过自定义动画类来控制物体的颜色随时间平滑变化。</p>
<h1 id="1-实现原理">1. 实现原理</h1>
<h2 id="11-自定义动画类设计">1.1. 自定义动画类设计</h2>
<p>在<code>Manim</code>中,所有动画效果都是通过继承<code>Animation</code>基类并实现相应的方法来创建的。</p>
<p>我们设计了一个名为<code>GradientFillAnimation</code>的类,专门用于实现颜色渐变填充效果:</p>
<pre><code class="language-python">class GradientFillAnimation(Animation):
    """动态渐变填充动画类"""
   
    def __init__(self, mobject, colors, run_time=5, **kwargs):
      """
      初始化渐变填充动画
      
      Parameters:
      mobject: 要应用动画的物体
      colors: 颜色列表,动画将在这些颜色之间进行渐变
      run_time: 动画运行时间
      """
      self.mobject = mobject
      self.colors = colors
      self.color_count = len(colors)
      super().__init__(mobject, run_time=run_time, **kwargs)
</code></pre>
<p>这个类接受三个主要参数:</p>
<ol>
<li>要应用动画的物体(<code>mobject</code>)</li>
<li>颜色序列(<code>colors</code>)</li>
<li>动画运行时间(<code>run_time</code>)。</li>
</ol>
<p><strong>颜色序列</strong>是一个包含多个颜色的列表,动画会在这些颜色之间按顺序进行渐变。</p>
<h2 id="12-颜色插值实现">1.2. 颜色插值实现</h2>
<p>动画的核心在于<code>interpolate_mobject</code>方法的实现,该方法根据动画进度(<code>alpha</code>值,范围从0到1)计算并更新物体的颜色。</p>
<pre><code class="language-python">def interpolate_mobject(self, alpha):
    """根据动画进度alpha更新物体的颜色"""
    # 计算当前应该显示的颜色
    total_segments = self.color_count - 1
    segment_progress = alpha * total_segments
    segment_index = int(segment_progress)
   
    # 确保索引在有效范围内
    if segment_index &gt;= total_segments:
      segment_index = total_segments - 1
      
    # 计算在当前段中的进度
    local_progress = segment_progress - segment_index
   
    # 获取当前段的起始和结束颜色
    start_color = self.colors
    end_color = self.colors
   
    # 插值计算当前颜色
    current_color = interpolate_color(start_color, end_color, local_progress)
   
    # 应用颜色到物体
    self.mobject.set_fill(current_color)
</code></pre>
<p>这段代码的工作原理如下:</p>
<ol>
<li>首先计算颜色渐变的总段数(颜色数量减1)</li>
<li>根据当前动画进度(<code>alpha</code>)确定应该处于哪个颜色渐变段</li>
<li>计算在当前渐变段内的进度比例</li>
<li>获取当前渐变段的起始颜色和结束颜色</li>
<li>使用<code>interpolate_color</code>函数在两种颜色之间进行插值计算,得到当前应该显示的颜色</li>
<li>最后通过<code>set_fill</code>方法将计算得到的颜色应用到物体上</li>
</ol>
<p>通过这种方式,我们可以实现物体在多个颜色之间的平滑过渡效果,创造出生动的视觉体验。</p>
<h1 id="2-使用示例">2. 使用示例</h1>
<p>下面通过两个具体的场景示例来演示如何使用<code>GradientFillAnimation</code>类实现动态渐变填充效果。</p>
<h2 id="21-单个物体的渐变效果">2.1. 单个物体的渐变效果</h2>
<p><code>Example01</code>场景展示了如何为单个物体应用渐变填充动画:</p>
<pre><code class="language-python">class Example01(Scene):
    """演示动态渐变填充特效的场景"""
   
    def construct(self):
      # 创建一个圆形
      circle = Circle(radius=2, fill_opacity=1)
      
      # 定义渐变颜色序列:红-&gt;蓝-&gt;绿-&gt;红(形成循环)
      gradient_colors =
      
      # 添加圆形到场景
      self.add(circle)
      
      # 应用渐变填充动画
      self.play(GradientFillAnimation(circle, gradient_colors, run_time=4))
      
      # 停留片刻以展示最终效果
      self.wait()
</code></pre>
<p>在这个示例中:</p>
<ol>
<li>我们创建了一个半径为2、填充不透明度为1的圆形</li>
<li>定义了一个包含四种颜色的渐变序列:红-&gt;蓝-&gt;绿-&gt;红,形成一个颜色循环</li>
<li>将圆形添加到场景中</li>
<li>应用<code>GradientFillAnimation</code>动画,设置运行时间为4秒</li>
<li>动画播放结束后,停留片刻以展示最终效果</li>
</ol>
<p>运行这段代码,你将看到一个圆形在4秒内从红色平滑过渡到蓝色,再过渡到绿色,最后回到红色的动画效果。</p>
<p><img src="https://img2024.cnblogs.com/blog/83005/202510/83005-20251002162758087-417574608.gif" alt="" loading="lazy"></p>
<h2 id="22-多个物体同时应用渐变效果">2.2. 多个物体同时应用渐变效果</h2>
<p><code>Example02</code>场景展示了如何为多个物体同时应用不同的渐变填充动画:</p>
<pre><code class="language-python">class Example02(Scene):
    """演示多个物体同时使用渐变填充特效的场景"""
   
    def construct(self):
      # 创建多个形状
      circle = Circle(radius=1, fill_opacity=1)
      square = Square(side_length=2, fill_opacity=1)
      triangle = Triangle(fill_opacity=1).scale(1.5)
      
      # 排列形状
      circle.shift(LEFT * 2 + DOWN)
      square.shift(RIGHT * 2 + DOWN)
      triangle.shift(UP)
      
      # 定义不同的颜色序列
      colors1 =
      colors2 =
      colors3 =
      
      # 添加形状到场景
      self.add(circle, square, triangle)
      
      # 同时对所有形状应用不同的渐变动画
      self.play(
            GradientFillAnimation(circle, colors1, run_time=2),
            GradientFillAnimation(square, colors2, run_time=2),
            GradientFillAnimation(triangle, colors3, run_time=2),
      )
      
      # 停留片刻以展示最终效果
      self.wait()
</code></pre>
<p>在这个示例中:</p>
<ol>
<li>我们创建了三种不同的形状:圆形、正方形和三角形,并设置了它们的位置</li>
<li>为每个形状定义了不同的颜色渐变序列</li>
<li>同时对三个形状应用<code>GradientFillAnimation</code>动画,设置相同的运行时间(2秒)</li>
</ol>
<p>运行这段代码,你将看到三个形状同时进行颜色渐变,但各自遵循不同的颜色变化路径,创造出丰富多彩的视觉效果。</p>
<p><img src="https://img2024.cnblogs.com/blog/83005/202510/83005-20251002162758022-2100138745.gif" alt="" loading="lazy"></p>
<h1 id="3-总结">3. 总结</h1>
<h2 id="31-特效特点">3.1. 特效特点</h2>
<p>通过上面的实现和示例,我们可以总结出这个动态渐变填充特效的几个主要特点:</p>
<ol>
<li><strong>高度可定制</strong>:可以自由定义颜色渐变序列、动画运行时间等参数</li>
<li><strong>平滑过渡</strong>:使用颜色插值算法实现颜色之间的平滑过渡</li>
<li><strong>灵活性强</strong>:可以同时应用于多个物体,并为每个物体设置不同的渐变效果</li>
<li><strong>易于集成</strong>:作为ManimCE的自定义动画类,可以轻松集成到任何Manim项目中</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>
</ol>
<h2 id="33-技术要点">3.3. 技术要点</h2>
<p>实现这个特效的关键技术要点包括:</p>
<ol>
<li>继承Manim的<code>Animation</code>基类并实现<code>interpolate_mobject</code>方法</li>
<li>使用<code>interpolate_color</code>函数进行颜色插值计算</li>
<li>根据动画进度动态更新物体的填充颜色</li>
<li>合理组织颜色序列以实现所需的渐变效果</li>
</ol>
<p>通过掌握这些技术,你可以在<code>Manim</code>中创建出更加生动、有趣的动画效果,为你的视频作品增添独特的视觉魅力。</p><br><br>
来源:https://www.cnblogs.com/wang_yb/p/19123732
頁: [1]
查看完整版本: Manim实现渐变填充特效