当前位置: 首页 > news >正文

Manim实现波浪形文字特效

本文将介绍如何使用Manim实现波浪形文字特效,通过自定义动画类让文字产生波浪般的动态效果。

1. 实现原理

波浪形文字特效的核心是通过自定义Animation类,对文本对象中的每个字符应用不同的位置偏移,从而形成波浪效果。

下面我们来分析具体实现:

1.1. 自定义Animation类

class WaveText(Animation):"""波浪形文字特效动画类"""def __init__(self, text_mobject, amplitude=0.2, frequency=2, phase=0, direction=UP, **kwargs):# 保存参数self.amplitude = amplitudeself.frequency = frequencyself.phase = phaseself.direction = direction# 获取文本对象中的所有子对象(每个字符)self.chars = text_mobject.submobjects# 记录每个字符的原始位置self.original_positions = [char.get_center() for char in self.chars]super().__init__(text_mobject, **kwargs)

WaveText类的初始化方法中,我们做了以下几件事:

  • 保存动画参数:振幅(amplitude)、频率(frequency)、初始相位(phase)和波动方向(direction
  • 获取文本对象中的所有子对象(每个字符)
  • 记录每个字符的原始位置,以便后续计算偏移量
  • 调用父类的初始化方法

1.2. 实现interpolate_mobject方法

    def interpolate_mobject(self, alpha):"""在动画过程中更新文本对象"""# 计算当前时间相位current_phase = self.phase + alpha * TAU * self.frequency# 更新每个字符的位置for i, char in enumerate(self.chars):# 获取字符原始位置original_pos = self.original_positions[i]# 计算波浪偏移量char_phase = 3 * original_pos[0]offset = self.amplitude * np.sin(char_phase + current_phase)# 计算新位置new_pos = original_pos + offset * self.direction# 更新字符位置char.move_to(new_pos)

interpolate_mobject方法是实现动画效果的关键,它在动画的每一帧都会被调用:

  • alpha参数表示动画进度,范围从0到1
  • 计算当前时间的相位,结合alphafrequency参数控制波浪的周期
  • 对每个字符应用不同的位置偏移,偏移量使用正弦函数计算
  • 字符的x坐标用于创建不同的相位,使每个字符有不同的波动
  • 最后,将计算得到的新位置应用到每个字符上

2. 使用示例

代码中提供了三个不同的场景示例,展示了波浪文字特效的各种用法:

2.1. 完整示例

class Example01(Scene):"""波浪文字特效完整示例场景"""def construct(self):# 创建多个文本对象,展示不同参数的效果text1 = Text("Hello Manim!", font_size=40).shift(UP * 2)text2 = Text("Large Amplitude", font_size=40).shift(UP * 0.5)text3 = Text("High Frequency", font_size=40).shift(DOWN * 0.5)text4 = Text("Horizontal Wave", font_size=40).shift(DOWN * 2)# 为每个文本创建不同参数的波浪动画wave_anim1 = WaveText(text1, amplitude=0.3, frequency=2, run_time=3, rate_func=linear)wave_anim2 = WaveText(text2, amplitude=0.5, frequency=1, run_time=3, rate_func=linear)wave_anim3 = WaveText(text3, amplitude=0.1, frequency=5, run_time=3, rate_func=linear)wave_anim4 = WaveText(text4, amplitude=0.3, frequency=3, direction=RIGHT, run_time=3, rate_func=linear)# 显示所有文本并同时播放动画self.play(FadeIn(text1), FadeIn(text2), FadeIn(text3), FadeIn(text4))self.play(wave_anim1, wave_anim2, wave_anim3, wave_anim4)self.wait()

这个示例展示了如何同时应用不同参数的波浪效果到多个文本对象上,包括不同的振幅、频率和方向。

2.2. 中文文本示例

class Example02(Scene):"""中文波浪文字特效简单示例场景"""def construct(self):# 创建中文文本text = Text("数学动画框架", font_size=60)# 显示文本并应用波浪动画self.play(Write(text))self.wait()# 应用垂直波浪效果wave_animation = WaveText(text, amplitude=0.2, frequency=2, run_time=2, rate_func=linear)self.play(wave_animation)self.wait()# 应用水平波浪效果wave_animation2 = WaveText(text, amplitude=0.4, frequency=1, direction=RIGHT, run_time=2, rate_func=linear)self.play(wave_animation2)self.wait()

这个示例展示了波浪特效在中文文本上的应用,先应用垂直方向的波浪,然后应用水平方向的波浪。

2.3. 数学公式示例

class Example03(Scene):"""数学公式文字特效简单示例场景"""def construct(self):# 创建数学公式文本text = MathTex("E", "=", "m", "c", "^2", font_size=60)# 显示公式并应用波浪动画self.play(Write(text))self.wait()# 应用垂直波浪效果wave_animation = WaveText(text, amplitude=0.2, frequency=2, run_time=2, rate_func=linear)self.play(wave_animation)self.wait()# 应用水平波浪效果wave_animation2 = WaveText(text, amplitude=0.4, frequency=1, direction=RIGHT, run_time=2, rate_func=linear)self.play(wave_animation2)self.wait()

这个示例展示了波浪特效在数学公式(使用MathTex创建)上的应用,同样分别应用了垂直和水平方向的波浪效果。

注意:这里数学公式中的每个元素要分开写,也就是:MathTex("E", "=", "m", "c", "^2")

如果写成一个整体的话(MathTex("E=mc^2")),整个公式会作为一个整体上下或左右摆动,不会有波浪效果。

3. 总结

3.1. 波浪文字特效的特点

  1. 高度可定制:通过调整振幅、频率、相位和方向等参数,可以创建各种不同风格的波浪效果
  2. 适用范围广:支持普通文本、中文字符和数学公式等多种文本类型
  3. 实现简洁:通过继承Animation类并重写interpolate_mobject方法,实现了核心的波浪效果
  4. 易于扩展:可以结合Manim的其他功能,如颜色变化、缩放等,创建更复杂的动画效果

3.2. 使用场景

  1. 视频片头/片尾:为标题或字幕添加波浪效果,增加视觉吸引力
  2. 教学视频:在讲解波浪、波动方程等概念时,可以用波浪文字特效直观地展示
  3. 数据可视化:为关键数据标签添加动态效果,突出重要信息
  4. 创意动画:结合其他动画效果,创建独特的视觉艺术作品

波浪文字特效是Manim中一个简单但非常实用的动画技巧,通过本文的介绍,相信你已经掌握了其实现原理和使用方法。

不妨动手尝试,为你的Manim动画增添更多动感和魅力!

http://www.hskmm.com/?act=detail&tid=21393

相关文章:

  • JUC: synchronized与锁升级
  • lang / philipino / feilvbin / taglog / tajialu
  • Windows上安装2个不同版本的MySQL5.7和8.4
  • cron表达式,每月1号凌晨3点执行和每周4凌晨3点半执行
  • 2025.9.30
  • C#/.NET/.NET Core技术前沿周刊 | 第 56 期(2025年9.22-9.28)
  • 反转链表
  • 天津港口海鲜之旅全攻略(2025最新版)
  • tomcat创建bat启动,结合任务计划实现自动重启tomcat服务 - 详解
  • 实用指南:【论文精读】Few-Shot Object Detection with Attention-RPN and Multi-Relation Detector
  • Chromium V8类型混淆漏洞CVE-2025-10585安全分析
  • Claude 4.5 刚刚发布,能连肝 30 多个小时,史上最卷 AI 诞生
  • 香橙派5pro驱动开发(一)
  • Python 脚本遇到 SSL 证书问题
  • sa-token开发时遇到的问题
  • HR如何摆脱入离职事务性内耗?组织管理系统助力聚焦人才价值挖掘
  • 基于SpringAI构建大模型应用
  • C# TCP - 串口转发 - 实践
  • 【研发规范】Git 提交(commit)、CodeReview规范
  • PCIE 各个管脚的作用是什么?
  • Windows 11 局域网打印机共享设置
  • DailyPaper-2025-9-29
  • gpd winmax2 fedora42 睡眠秒唤醒问题
  • 国企人力资源管理系统怎么选?内行人推荐这8款,功能、服务双保障
  • spring service注入命名规则
  • 完整教程:基于岗课赛证的中职物联网专业“综合布线课程”教学解决方案
  • tensorflow加载和预处理信息
  • linux查询磁盘空间,查询指定目录的空间 df命令
  • 轻松规划房贷:用好公积金贷款,让梦想之家触手可及
  • milvus使用的etcd空间整理