在动画制作中,轨迹特效常常用于增强视觉效果,而带有闪光效果的轨迹更是能够吸引观众的注意力。
本文将介绍如何使用Manim
动画库实现闪光轨迹特效。
1. 实现原理
下面的GlowingTracedPath
类参考了Manim
中的TracePath
类,增加了闪光和渐变色的效果。
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[ParsableManimColor] | None = None, #glow_speed: int = 2,**kwargs,):"""构造函数Parameters:traced_point_func - 回调函数,用于获取被追踪点的当前位置stroke_width - 轨迹的宽度,默认为 2stroke_color - 轨迹的基本颜色,默认为白色dissipating_time - 轨迹的消散时间gradient_colors - 颜色渐变列表glow_speed - 闪光速度,控制轨迹闪光效果的快慢**kwargs - 用于传递额外的关键字参数到父类VMobject的构造函数中"""super().__init__(stroke_color=stroke_color,stroke_width=stroke_width,**kwargs,)self.glow_speed = glow_speedif not gradient_colors is None:self.set_color_by_gradient(gradient_colors)self.set_stroke(opacity=0.2)self.traced_point_func = traced_point_funcself.dissipating_time = dissipating_timeself.time = 1self.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 += dtt = 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 > self.dissipating_time:nppcc = self.n_points_per_curveself.set_points(self.points[nppcc:])
初始化函数(__init__
)的参数,代码中已经有详细的注释,不再赘述。
至于更新轨迹的update_path
方法,它的关键逻辑有:
- 获取新点:通过
traced_point_func
获取被追踪点的当前位置,并将其添加到轨迹的末尾 - 动态调整透明度:使用正弦函数
np.sin
生成一个在0.5
到1
之间波动的强度值intensity
,并通过set_stroke
方法动态调整轨迹的透明度,从而实现闪烁效果 - 轨迹消散:如果设置了
dissipating_time
参数,当轨迹的持续时间超过该值时,会移除轨迹的起始部分,使轨迹逐渐消失
此外,GlowingTracedPath
类还会通过set_color_by_gradient
方法为轨迹设置颜色渐变效果。
2. 使用示例
接下来我们通过几个示例来看看如何使用这个特效。
2.1. 渐变色轨迹
基于上面我们实现的GlowingTracedPath
类,实现一个渐变色的轨迹非常简单。
a = Dot(RIGHT * 2)
b = GlowingTracedPath(a.get_center,gradient_colors=[BLUE, RED, YELLOW],
)
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)
代码中,轨迹b追踪点a的位置,形成一个由参数gradient_colors
指定的渐变色轨迹。
2.2. 轨迹逐渐消失
上面的示例中,轨迹不会消失,通过参数dissipating_time
,可以指定轨迹存在的时间(单位:秒)。
b = GlowingTracedPath(a.get_center,gradient_colors=[BLUE, RED, YELLOW],dissipating_time=0.5,
)
将轨迹b的dissipating_time
设置为0.5
,也就是新产生的轨迹会在0.5
秒后逐渐消失。
2.3. 轨迹闪烁
最后,来看看轨迹的闪光效果,下面的通过设置两种不同的glow_speed
(闪烁的速度),
来比较不同速度下的闪烁效果。
a1 = Dot()
a2 = Dot()
b1 = GlowingTracedPath(a1.get_center,gradient_colors=[BLUE, RED, YELLOW],glow_speed=8,
)
b2 = GlowingTracedPath(a2.get_center,gradient_colors=[BLUE, RED, YELLOW],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)
左边的心形glow_speed=8
,右边的心形glow_speed=16
,所以右边的闪烁速度会快一些。
3. 总结
通过GlowingTracedPath
类,我们可以轻松地在Manim
中实现带有闪光效果的轨迹。
这个类通过动态调整透明度和颜色渐变,结合轨迹的实时更新,创造出了引人注目的视觉效果。
无论是用于数学动画还是其他创意项目,这种特效都能为你的作品增添独特的魅力。