你知道我是谁了 發表於 2025-9-18 19:25:00

Manim实现闪光轨迹特效

<p>在动画制作中,轨迹特效常常用于增强视觉效果,而带有闪光效果的轨迹更是能够吸引观众的注意力。</p>
<p>本文将介绍如何使用<code>Manim</code>动画库实现闪光轨迹特效。</p>
<h1 id="1-实现原理">1. 实现原理</h1>
<p>下面的<code>GlowingTracedPath</code>类参考了<code>Manim</code>中的<code>TracePath</code>类,增加了闪光和渐变色的效果。</p>
<pre><code class="language-python">class GlowingTracedPath(VMobject):
    def __init__(
      self,
      traced_point_func: Callable,
      stroke_width: float = 2,
      stroke_color: ParsableManimColor | None = WHITE,
      dissipating_time: float | None = None,
      gradient_colors: list | None = None,#
      glow_speed: int = 2,
      **kwargs,
    ):
      """
      构造函数

      Parameters:
            traced_point_func - 回调函数,用于获取被追踪点的当前位置
            stroke_width - 轨迹的宽度,默认为 2
            stroke_color - 轨迹的基本颜色,默认为白色
            dissipating_time - 轨迹的消散时间
            gradient_colors - 颜色渐变列表
            glow_speed - 闪光速度,控制轨迹闪光效果的快慢
            **kwargs - 用于传递额外的关键字参数到父类VMobject的构造函数中
      """
      super().__init__(
            stroke_color=stroke_color,
            stroke_width=stroke_width,
            **kwargs,
      )
      self.glow_speed = glow_speed

      if not gradient_colors is None:
            self.set_color_by_gradient(gradient_colors)

      self.set_stroke(opacity=0.2)

      self.traced_point_func = traced_point_func
      self.dissipating_time = dissipating_time
      self.time = 1

      self.add_updater(self.update_path)

    def update_path(self, mob, dt):
      # 更新轨迹中的点
      new_point = self.traced_point_func()
      if not self.has_points():
            self.start_new_path(new_point)

      self.time += dt
      t = self.time * self.glow_speed# 控制脉冲速度
      intensity = 0.25 * np.sin(t) + 0.75# 0.5-1之间波动
      # 动态调整透明度
      self.set_stroke(
            opacity=intensity,# 透明度波动
      )

      self.add_line_to(new_point)
      # 轨迹消散
      if self.dissipating_time:
            if self.time - 1 &gt; self.dissipating_time:
                nppcc = self.n_points_per_curve
                self.set_points(self.points)
</code></pre>
<p>初始化函数(<code>__init__</code>)的参数,代码中已经有详细的注释,不再赘述。</p>
<p>至于更新轨迹的<code>update_path</code>方法,它的关键逻辑有:</p>
<ul>
<li><strong>获取新点</strong>:通过<code>traced_point_func</code>获取被追踪点的当前位置,并将其添加到轨迹的末尾</li>
<li><strong>动态调整透明度</strong>:使用正弦函数<code>np.sin</code>生成一个在<code>0.5</code>到<code>1</code>之间波动的强度值<code>intensity</code>,并通过<code>set_stroke</code>方法动态调整轨迹的透明度,从而实现闪烁效果</li>
<li><strong>轨迹消散</strong>:如果设置了<code>dissipating_time</code>参数,当轨迹的持续时间超过该值时,会移除轨迹的起始部分,使轨迹逐渐消失</li>
</ul>
<p>此外,<code>GlowingTracedPath</code>类还会通过<code>set_color_by_gradient</code>方法为轨迹设置颜色渐变效果。</p>
<h1 id="2-使用示例">2. 使用示例</h1>
<p>接下来我们通过几个示例来看看如何使用这个特效。</p>
<h2 id="21-渐变色轨迹">2.1. 渐变色轨迹</h2>
<p>基于上面我们实现的<code>GlowingTracedPath</code>类,实现一个渐变色的轨迹非常简单。</p>
<pre><code class="language-python">a = Dot(RIGHT * 2)
b = GlowingTracedPath(
    a.get_center,
    gradient_colors=,
)
self.add(a, b)
self.play(a.animate(path_arc=PI / 2).shift(LEFT * 2), run_time=2)
self.play(a.animate(path_arc=-PI / 2).shift(LEFT * 2), run_time=2)
</code></pre>
<p>代码中,<strong>轨迹b</strong>追踪<strong>点a</strong>的位置,形成一个由参数<code>gradient_colors</code>指定的渐变色轨迹。</p>
<p><img src="https://img2024.cnblogs.com/blog/83005/202509/83005-20250918192423063-356779301.gif" alt="" loading="lazy"></p>
<h2 id="22-轨迹逐渐消失">2.2. 轨迹逐渐消失</h2>
<p>上面的示例中,轨迹不会消失,通过参数<code>dissipating_time</code>,可以指定轨迹存在的时间(单位:秒)。</p>
<pre><code class="language-python">b = GlowingTracedPath(
    a.get_center,
    gradient_colors=,
    dissipating_time=0.5,
)
</code></pre>
<p>将<strong>轨迹b</strong>的<code>dissipating_time</code>设置为<code>0.5</code>,也就是新产生的轨迹会在<code>0.5</code>秒后逐渐消失。</p>
<p><img src="https://img2024.cnblogs.com/blog/83005/202509/83005-20250918192423051-905866457.gif" alt="" loading="lazy"></p>
<h2 id="23-轨迹闪烁">2.3. 轨迹闪烁</h2>
<p>最后,来看看轨迹的闪光效果,下面的通过设置两种不同的<code>glow_speed</code>(闪烁的速度),</p>
<p>来比较不同速度下的闪烁效果。</p>
<pre><code class="language-python">a1 = Dot()
a2 = Dot()
b1 = GlowingTracedPath(
    a1.get_center,
    gradient_colors=,
    glow_speed=8,
)
b2 = GlowingTracedPath(
    a2.get_center,
    gradient_colors=,
    glow_speed=16,
)
self.add(a1, b1, a2, b2)

heart1 = ImplicitFunction(
    lambda x, y: (x**2 + y**2 - 1) ** 3 - x**2 * y**3,
    color=PINK,
    x_range=[-1.5, 1.5],
    y_range=[-1.2, 1.8],
).shift(LEFT * 1.5)
heart2 = ImplicitFunction(
    lambda x, y: (x**2 + y**2 - 1) ** 3 - x**2 * y**3,
    color=PINK,
    x_range=[-1.5, 1.5],
    y_range=[-1.2, 1.8],
).shift(RIGHT * 1.5)

self.play(MoveAlongPath(a1, heart1), MoveAlongPath(a2, heart2), run_time=4)
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/83005/202509/83005-20250918192423094-552193029.gif" alt="" loading="lazy"></p>
<p><strong>左边</strong>的心形<code>glow_speed=8</code>,<strong>右边</strong>的心形<code>glow_speed=16</code>,所以右边的闪烁速度会快一些。</p>
<h1 id="3-总结">3. 总结</h1>
<p>通过<code>GlowingTracedPath</code>类,我们可以轻松地在<code>Manim</code>中实现带有闪光效果的轨迹。</p>
<p>这个类通过动态调整透明度和颜色渐变,结合轨迹的实时更新,创造出了引人注目的视觉效果。</p>
<p>无论是用于数学动画还是其他创意项目,这种特效都能为你的作品增添独特的魅力。</p><br><br>
来源:https://www.cnblogs.com/wang_yb/p/19099538
頁: [1]
查看完整版本: Manim实现闪光轨迹特效