Manim实现渐变填充特效

作者:databook日期:2025/10/2

本文将介绍如何使用Manim框架实现动态渐变填充特效,通过自定义动画类来控制物体的颜色随时间平滑变化。

1. 实现原理

1.1. 自定义动画类设计

Manim中,所有动画效果都是通过继承Animation基类并实现相应的方法来创建的。

我们设计了一个名为GradientFillAnimation的类,专门用于实现颜色渐变填充效果:

1class GradientFillAnimation(Animation):
2    """动态渐变填充动画类"""
3    
4    def __init__(self, mobject, colors, run_time=5, **kwargs):
5        """
6        初始化渐变填充动画
7        
8        Parameters:
9        mobject: 要应用动画的物体
10        colors: 颜色列表,动画将在这些颜色之间进行渐变
11        run_time: 动画运行时间
12        """
13        self.mobject = mobject
14        self.colors = colors
15        self.color_count = len(colors)
16        super().__init__(mobject, run_time=run_time, **kwargs)
17

这个类接受三个主要参数:

  1. 要应用动画的物体(mobject
  2. 颜色序列(colors
  3. 动画运行时间(run_time)。

颜色序列是一个包含多个颜色的列表,动画会在这些颜色之间按顺序进行渐变。

1.2. 颜色插值实现

动画的核心在于interpolate_mobject方法的实现,该方法根据动画进度(alpha值,范围从0到1)计算并更新物体的颜色。

1def interpolate_mobject(self, alpha):
2    """根据动画进度alpha更新物体的颜色"""
3    # 计算当前应该显示的颜色
4    total_segments = self.color_count - 1
5    segment_progress = alpha * total_segments
6    segment_index = int(segment_progress)
7    
8    # 确保索引在有效范围内
9    if segment_index >= total_segments:
10        segment_index = total_segments - 1
11        
12    # 计算在当前段中的进度
13    local_progress = segment_progress - segment_index
14    
15    # 获取当前段的起始和结束颜色
16    start_color = self.colors[segment_index]
17    end_color = self.colors[segment_index + 1]
18    
19    # 插值计算当前颜色
20    current_color = interpolate_color(start_color, end_color, local_progress)
21    
22    # 应用颜色到物体
23    self.mobject.set_fill(current_color)
24

这段代码的工作原理如下:

  1. 首先计算颜色渐变的总段数(颜色数量减1)
  2. 根据当前动画进度(alpha)确定应该处于哪个颜色渐变段
  3. 计算在当前渐变段内的进度比例
  4. 获取当前渐变段的起始颜色和结束颜色
  5. 使用interpolate_color函数在两种颜色之间进行插值计算,得到当前应该显示的颜色
  6. 最后通过set_fill方法将计算得到的颜色应用到物体上

通过这种方式,我们可以实现物体在多个颜色之间的平滑过渡效果,创造出生动的视觉体验。

2. 使用示例

下面通过两个具体的场景示例来演示如何使用GradientFillAnimation类实现动态渐变填充效果。

2.1. 单个物体的渐变效果

Example01场景展示了如何为单个物体应用渐变填充动画:

1class Example01(Scene):
2    """演示动态渐变填充特效的场景"""
3    
4    def construct(self):
5        # 创建一个圆形
6        circle = Circle(radius=2, fill_opacity=1)
7        
8        # 定义渐变颜色序列:红->蓝->绿->红(形成循环)
9        gradient_colors = [RED, BLUE, GREEN, RED]
10        
11        # 添加圆形到场景
12        self.add(circle)
13        
14        # 应用渐变填充动画
15        self.play(GradientFillAnimation(circle, gradient_colors, run_time=4))
16        
17        # 停留片刻以展示最终效果
18        self.wait()
19

在这个示例中:

  1. 我们创建了一个半径为2、填充不透明度为1的圆形
  2. 定义了一个包含四种颜色的渐变序列:红->蓝->绿->红,形成一个颜色循环
  3. 将圆形添加到场景中
  4. 应用GradientFillAnimation动画,设置运行时间为4秒
  5. 动画播放结束后,停留片刻以展示最终效果

运行这段代码,你将看到一个圆形在4秒内从红色平滑过渡到蓝色,再过渡到绿色,最后回到红色的动画效果。

2.2. 多个物体同时应用渐变效果

Example02场景展示了如何为多个物体同时应用不同的渐变填充动画:

1class Example02(Scene):
2    """演示多个物体同时使用渐变填充特效的场景"""
3    
4    def construct(self):
5        # 创建多个形状
6        circle = Circle(radius=1, fill_opacity=1)
7        square = Square(side_length=2, fill_opacity=1)
8        triangle = Triangle(fill_opacity=1).scale(1.5)
9        
10        # 排列形状
11        circle.shift(LEFT * 2 + DOWN)
12        square.shift(RIGHT * 2 + DOWN)
13        triangle.shift(UP)
14        
15        # 定义不同的颜色序列
16        colors1 = [RED, YELLOW, BLUE, RED]
17        colors2 = [GREEN, PURPLE, ORANGE, GREEN]
18        colors3 = [PINK, GOLD, TEAL, PINK]
19        
20        # 添加形状到场景
21        self.add(circle, square, triangle)
22        
23        # 同时对所有形状应用不同的渐变动画
24        self.play(
25            GradientFillAnimation(circle, colors1, run_time=2),
26            GradientFillAnimation(square, colors2, run_time=2),
27            GradientFillAnimation(triangle, colors3, run_time=2),
28        )
29        
30        # 停留片刻以展示最终效果
31        self.wait()
32

在这个示例中:

  1. 我们创建了三种不同的形状:圆形、正方形和三角形,并设置了它们的位置
  2. 为每个形状定义了不同的颜色渐变序列
  3. 同时对三个形状应用GradientFillAnimation动画,设置相同的运行时间(2秒)

运行这段代码,你将看到三个形状同时进行颜色渐变,但各自遵循不同的颜色变化路径,创造出丰富多彩的视觉效果。

3. 总结

3.1. 特效特点

通过上面的实现和示例,我们可以总结出这个动态渐变填充特效的几个主要特点:

  1. 高度可定制:可以自由定义颜色渐变序列、动画运行时间等参数
  2. 平滑过渡:使用颜色插值算法实现颜色之间的平滑过渡
  3. 灵活性强:可以同时应用于多个物体,并为每个物体设置不同的渐变效果
  4. 易于集成:作为ManimCE的自定义动画类,可以轻松集成到任何Manim项目中

3.2. 使用场景

这个动态渐变填充特效在以下场景中特别有用:

  1. 教学视频:用于突出显示重要概念或流程变化
  2. 数据可视化:通过颜色变化展示数据的变化趋势
  3. 品牌宣传视频:根据品牌色调创建特色动画效果
  4. 艺术创作:用于创建富有表现力的视觉效果
  5. 演示文稿:增强幻灯片的视觉吸引力

3.3. 技术要点

实现这个特效的关键技术要点包括:

  1. 继承Manim的Animation基类并实现interpolate_mobject方法
  2. 使用interpolate_color函数进行颜色插值计算
  3. 根据动画进度动态更新物体的填充颜色
  4. 合理组织颜色序列以实现所需的渐变效果

通过掌握这些技术,你可以在Manim中创建出更加生动、有趣的动画效果,为你的视频作品增添独特的视觉魅力。


Manim实现渐变填充特效》 是转载文章,点击查看原文


相关推荐


15:00开始面试,15:06就出来了,问的问题有点变态。。。
测试界晓晓2025/10/2

从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到8月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%,这下搞的饭都吃不起了。 还在有个朋友内推我去了一家互联网公司,兴冲冲见面试官,没想到一道题把我给问死了: 如果模块请求http改为了https,测试方案应该如何制定,修改? 感觉好简单的题,硬是没有答出来,早知道好好看看一大佬软件测试面试宝典了。 通过大数据总结发现,其实软件测试岗的面试都是差不多


分布式架构初识:为什么需要分布式
湮酒10/2/2025

分布式架构初识:从单体到分布式演进 本文系统介绍了从单体架构到分布式架构的演进过程。单体架构虽具有开发简单、部署方便等优点,但随着业务增长面临扩展性差、可靠性低等局限。通过电商秒杀、金融支付、弹性扩展三个典型场景,文章展示了分布式架构在高并发、高可用和弹性扩展方面的优势。分布式架构可通过水平拆分(分库分表)和服务化(微服务)两种基本形态实现,能有效解决性能瓶颈、单点故障等问题,满足现代互联网应用的高并发、高可用需求。


SpringSecurity自定义认证成功、失败、登出成功处理器
三口吃掉你9/30/2025

AuthenticationSuccessHandler的方法进行认证成功后的处理的。AuthenticationFailureHandler的方法进行认证失败后的处理的。实际上在UsernamePasswordAuthenticationFilter进行登录认证的时候,如果登录成功了是会调用。实际上在UsernamePasswordAuthenticationFilter进行登录认证的时候,如果认证失败了是会调用。我们也可以自己去自定义成功处理器进行成功后的相应处理。


【Linux操作系统】基础开发工具
ZLRRLZ9/30/2025

本文介绍了Linux开发中的常用工具链,包括软件包管理(yum/apt)、文本编辑器(Vim)、编译器(gcc/g++)、构建工具(make/Makefile)、进度条实现、版本控制(Git)和调试器(gdb/cgdb)。重点讲解了Vim的多模式编辑、gcc的编译流程与动静态链接区别、Makefile的自动化构建原理,以及Git的版本控制三板斧操作。这些工具构成了Linux环境下高效开发的完整工作流,帮助开发者完成从代码编写、编译构建到版本管理的全流程工作。


从汇编角度看C++优化:编译器真正做了什么
oioihoii2025/10/3

我们写的C++代码,对人类来说是清晰的逻辑表达,但对机器来说,只是一串抽象的字符。编译器,特别是像GCC、Clang这样的现代编译器,扮演着“翻译官”兼“优化大师”的角色。它们将高级代码转化为机器指令,并在此过程中,对代码进行脱胎换骨般的重塑,以求达到极致的性能。 今天,我们将深入汇编层面,揭开编译器优化的神秘面纱,看看我们的代码在编译器的“熔炉”中究竟经历了什么。 为什么选择汇编语言? 汇编是机器指令的人类可读形式,是连接高级语言与硬件执行的最直接桥梁。通过查看编译器生成的汇编代码,我们可以:


零基础从头教学Linux(Day 45)
小白银子2025/10/4

OpenResty介绍与实战 一、概述 OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web应用、Web服务和动态网关。 简单地说 OpenResty 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Me


纯电汽车emc整改:设计缺陷到合规达标的系统方案|深圳南柯电子
深圳南柯电子2025/10/5

在新能源汽车产业迈入智能化、电动化深水区的当下,电磁兼容性(EMC)已成为决定产品安全与市场竞争力的核心指标。某头部车企曾因电机控制器辐射超标导致整车上市延迟,直接损失超3亿元;某新势力品牌因车载充电机传导骚扰超标引发用户投诉,召回成本高达1.2亿元。这些案例揭示了一个残酷现实:EMC整改不再是产品上市前的“补救措施”,而是贯穿研发、生产、运维全生命周期的系统工程。 一、纯电汽车emc整改的标准为纲:构建EMC合规的“法律底线” 纯电汽车EMC整改需严格遵循国内外双重标准体系。国内以GB/T


SpringBoot安全进阶:利用门限算法加固密钥与敏感配置
风象南2025/10/7

一、背景:单点密钥的隐患 在企业信息系统中,密钥是最核心的安全资产。无论是数据库加密、支付签名,还是用户隐私保护,背后都依赖一把"超级钥匙"。 然而,现实中我们常常遇到这些场景: 单点保管风险:某个核心密钥仅由一个运维人员或系统服务持有,一旦泄露或者丢失,整个系统可能崩盘。 操作合规问题:金融或政府系统中,法规往往要求多方共同参与,才能执行高风险操作。 分布式架构挑战:在云环境或多数据中心下,如何既能保证数据安全,又能防止任何一个节点"作恶"? 一句话总结: 👉 一个人掌握所有密钥 = 系统安


Rust语言简介
xqlily2025/10/8

Rust是一种现代的系统编程语言,由Mozilla基金会开发,并于2010年首次发布。它旨在解决传统语言(如C和C++)中的常见问题,如内存安全错误和并发性挑战,同时保持高性能。Rust强调安全性、速度和并发性,使其在系统开发、嵌入式系统和WebAssembly等领域广受欢迎。下面,我将从核心特点、优势和应用场景入手,逐步介绍Rust,并附上一个简单示例。 核心特点 内存安全:Rust通过独特的“所有权系统”避免空指针解引用、缓冲区溢出等常见错误。例如,编译器在编译时检查内存访问,确保


HTML 元素帮助手册
hubenchang05152025/10/9

#HTML 元素帮助手册 转载自 MDN #主根元素 元素描述<html>表示一个 HTML 文档的根(顶级元素),所以它也被称为根元素。所有其它元素必须是此元素的后代。 #文档元数据 元素描述<base>指定用于一个文档中包含的所有相对 URL 的根 URL。一份中只能有一个该元素。<head>包含文档相关的配置信息(元数据),包括文档的标题、脚本和样式表等。<link>指定当前文档与外部资源的关系。该元素最常用于链接 CSS,此外也可以被用来创建站点图标(比如“favicon”样式图标和

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0