Manim实现气泡特效

news/2025/9/26 15:16:53/文章来源:https://www.cnblogs.com/wang_yb/p/19113551

本文将介绍如何使用Manim框架实现一个简单而实用的气泡特效,该特效可用于多种场景,如背景装饰、数据可视化过渡等。

1. 实现原理

气泡特效的核心在于BubbleEffect类,它继承自Manim的Animation类,通过重写关键方法来实现气泡的上升、变大和透明度变化效果。

1.1. 核心类结构

BubbleEffect类的基本结构如下:

class BubbleEffect(Animation):"""彩色气泡特效动画类继承自Animation类,用于创建彩色气泡上升、变大、透明度变化的效果"""def __init__(self,bubble_count=25,  # 气泡数量bubble_size_range=(0.1, 0.5),  # 气泡大小范围rise_speed_range=(0.6, 2.2),  # 上升速度范围growth_rate_range=(0.005, 0.015),  # 生长速度范围fade_rate_range=(0.02, 0.06),  # 消失速度范围colors=None,  # 气泡颜色列表**kwargs):# 初始化代码...def create_bubble(self):# 创建单个气泡的代码...def interpolate_mobject(self, alpha):# 控制气泡动画效果的核心代码...

1.2. 气泡创建机制

__init__方法中,我们首先定义了一系列参数,如气泡数量、大小范围、上升速度等,然后创建一个VGroup来存放所有气泡:

# 创建气泡组
self.bubbles = VGroup()
self.bubble_count = bubble_count
self.bubble_size_range = bubble_size_range
self.rise_speed_range = rise_speed_range
self.growth_rate_range = growth_rate_range
self.fade_rate_range = fade_rate_range
self.colors = colors or [RED, BLUE, GREEN, YELLOW, PURPLE, ORANGE]# 保存运行时间,从kwargs中获取或使用默认值
self.run_time = kwargs.get("run_time", 5.0)# 初始化气泡
for _ in range(bubble_count):bubble = self.create_bubble()self.bubbles.add(bubble)# 调用父类初始化
super().__init__(self.bubbles, **kwargs)

每个气泡通过create_bubble方法创建,该方法随机设置气泡的大小、颜色和初始位置,并为每个气泡分配独立的上升速度、生长速度和消失速度:

def create_bubble(self):"""创建单个彩色气泡"""# 随机大小size = random.uniform(*self.bubble_size_range)# 随机颜色color = random.choice(self.colors)# 创建圆形气泡bubble = Circle(radius=size, color=color, fill_opacity=0.4, stroke_width=2)# 随机初始位置(底部区域)x_pos = random.uniform(-config.frame_width / 2 + 1, config.frame_width / 2 - 1)y_pos = random.uniform(-config.frame_height / 2, -config.frame_height / 2 + 2)bubble.move_to([x_pos, y_pos, 0])# 存储气泡属性bubble.rise_speed = random.uniform(*self.rise_speed_range)bubble.growth_rate = random.uniform(*self.growth_rate_range)bubble.fade_rate = random.uniform(*self.fade_rate_range)bubble.initial_radius = sizereturn bubble

1.3. 动画插值实现

动画的核心在于interpolate_mobject方法,它控制着每个气泡在每一帧的状态变化:

def interpolate_mobject(self, alpha):"""插值函数,控制彩色气泡的动画效果"""dt = 1 / config.frame_rate  # 每帧的时间间隔for bubble in self.bubbles:# 上升bubble.shift(UP * bubble.rise_speed * dt)# 变大bubble.scale(1 + bubble.growth_rate * dt)# 透明度变化current_opacity = bubble.get_fill_opacity()new_opacity = current_opacity - bubble.fade_rate * dt# 如果气泡超出屏幕顶部或透明度降到0以下,则重置if new_opacity <= 0 or bubble.get_y() > config.frame_height / 2:# 重置气泡x_pos = random.uniform(-config.frame_width / 2 + 1, config.frame_width / 2 - 1)y_pos = random.uniform(-config.frame_height / 2, -config.frame_height / 2 + 2)bubble.move_to([x_pos, y_pos, 0])bubble.set_fill(opacity=0.4)bubble.set_stroke(opacity=0.4)else:bubble.set_fill(opacity=new_opacity)bubble.set_stroke(opacity=new_opacity)

这个方法实现了三个关键效果:

  1. 上升:每个气泡以自己的速度向上移动
  2. 变大:每个气泡以自己的速度缓慢变大
  3. 透明度变化:每个气泡逐渐变得透明

特别值得注意的是,当气泡超出屏幕顶部或透明度降到0以下时,代码会将气泡重置到底部,从而实现循环不断的气泡效果。

2. 使用示例

代码提供了两个使用示例,分别展示了普通气泡效果和彩色气泡效果。

2.1. 普通气泡效果

SimpleBubbleEffectExample类展示了如何创建灰度的气泡效果:

class SimpleBubbleEffectExample(Scene):"""普通气泡特效示例场景"""def construct(self):# 创建标题title = Text("普通气泡特效演示", font_size=48)title.to_edge(UP)self.play(Write(title))self.wait(0.5)bubble_effect = BubbleEffect(bubble_count=25,colors=[GRAY],  # 设置为灰色bubble_size_range=(0.1, 0.5),rise_speed_range=(0.6, 2.2),growth_rate_range=(0.1, 0.5),fade_rate_range=(0.02, 0.06),run_time=2,  # 使用run_time而不是duration)# 播放气泡特效self.play(bubble_effect)self.wait()

2.2. 彩色气泡效果

ColorfulBubbleEffectExample类展示了如何创建彩色的气泡效果:

class ColorfulBubbleEffectExample(Scene):"""彩色气泡特效示例场景"""def construct(self):# 创建标题title = Text("彩色气泡特效演示", font_size=48)title.to_edge(UP)self.play(Write(title))self.wait(0.5)# 创建彩色气泡特效动画bubble_effect = BubbleEffect(bubble_count=25,bubble_size_range=(0.1, 0.5),rise_speed_range=(0.6, 2.2),growth_rate_range=(0.1, 0.5),fade_rate_range=(0.02, 0.06),run_time=2,  # 使用run_time而不是duration)# 播放彩色气泡特效self.play(bubble_effect)self.wait()

两者的主要区别在于SimpleBubbleEffectExample显式指定了colors=[GRAY],而ColorfulBubbleEffectExample则使用了默认的彩色列表。

2.3. 自定义参数

BubbleEffect类提供了多个参数,可以根据需要进行调整:

参数名 类型 默认值 说明
bubble_count int 25 气泡数量
bubble_size_range tuple (0.1, 0.5) 气泡大小范围
rise_speed_range tuple (0.6, 2.2) 气泡上升速度范围
growth_rate_range tuple (0.005, 0.015) 气泡生长速度范围
fade_rate_range tuple (0.02, 0.06) 气泡透明度变化速度范围
colors list [RED, BLUE, GREEN, YELLOW, PURPLE, ORANGE] 气泡颜色列表
run_time float 5.0 动画运行时间

通过调整这些参数,可以创建各种不同风格的气泡效果。

3. 总结

3.1. 特效特点

  1. 可定制性强:通过调整多种参数,可以创建不同风格的气泡效果
  2. 性能优化:使用VGroup统一管理气泡,方便添加和删除
  3. 循环动画:气泡消失后会自动重置,实现循环不断的效果
  4. 随机性:每个气泡的大小、位置、速度等属性都是随机的,创建丰富多变的视觉效果
  5. 统一控制:作为Animation的子类,可以与Manim的其他动画无缝集成

3.2. 使用场景

  1. 背景装饰:为视频或演示添加动态背景
  2. 转场效果:在不同场景或章节之间作为过渡效果
  3. 数据可视化:与数据展示结合,增强视觉吸引力
  4. 节日氛围:通过调整颜色,可以创建适合不同节日的氛围效果
  5. 教学辅助:在物理课上演示浮力原理,或在化学课上模拟气泡反应

这个气泡特效实现简单但效果出色,可以为各种Manim动画项目增添生动的视觉元素。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/918440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

石家庄商标设计小黄人seo

#停止原有工程 ps -ef | grep demo | grep -v grep | awk {print $2} | xargs kill#删除原有工程 rm -rf /opt/app/demo.jar#解压压缩包指定文件&#xff0c;并存入指定路径 #tar -zxf 压缩包 -C 解压到的路径 压缩包中指定文件名 tar -zxf /opt/app/demo.tgz -C /opt/app .…

完整教程:决策树(Decision Tree)

完整教程:决策树(Decision Tree)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco&q…

C# Inno Setup

1.安装 inno Setup 2.参考博客 Inno Setup编译器巨详细使用教程-CSDN博客

CF2139虚拟游记

前言 CF2139 \(Div.2\) 难度。 由于刚上大学,开学有很多活动,连参加 vp 的时间都挤不出来。 A.Maple and Multiplication 题面 共 \(t\) 组数据,每组数据: 给定两个数 \(a,b\) ,你可以进行任意次操作:选择一个整…

新方向 - MKT

新方向 1 国防科技大学 语义 2 美团 毛一年 机器人研究院 120m 200-300米 无人机基本参数 老版本 新版本2.4kg (1)视觉卫星图定位 (2)动态重新规划路径 (3)夜间场景 多视角相机的夜间视觉导航下视觉 3…

网站 框架wordpress 换页面

十一章&#xff1a;Java 集合 一、集合框架的概述 1、集合&#xff1a;就像一个容器&#xff0c;可以动态的把多个对象的引用放入容器中。简称 Java 容器 ​ 说明&#xff1a;此时的存储&#xff0c;主要指的是内存层面的存储&#xff0c;不涉及到持续化的存储&#xff08;.t…

用h5做简易网站代码wordpress视频弹窗

diannao1xiejiandeMacBook-Air ~ % su Password: su: Sorry输入 sudo passwd 命令重置密码即可。

融合多元定位技术,帮助应用破解精准定位难题

从查阅天气到记录运动轨迹,从打车到路径规划等,移动终端已深入人们日常生活的方方面面,看似简单的操作背后,都依赖于精准的定位技术。对于应用开发者,位置数据的实时性与准确性直接决定用户体验。当前主流定位技术…

PP-OCRv5 C++ 基准测试工具:打造高性能OCR评测标杆 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

自定义中间件进入管道中执行队列的流程

自定义中间件进入管道中执行队列的流程 1. 自定义中间件类的标准写法 public class CustomLoggingMiddleware {private readonly RequestDelegate _next;// 1. 构造函数必须包含 RequestDelegate next 参数public Cust…

网站推广的常用途径有哪些网站ftp需要关闭

一、集成测试和系统测试的区别 &#xff08;一&#xff09;测试的目的 • 集成测试&#xff1a;主要目的是验证各个模块组合在一起后&#xff0c;它们之间的接口和交互是否正确&#xff0c;是否能够按照设计要求协同工作&#xff0c;以确保系统的稳定性和可靠性&#xff0c;重…

做一个回收网站怎么做免费网站建

当人用眼睛看事物的时候&#xff0c;会感觉到近处的东西是比远处的东西要大一些的&#xff0c;通俗的说&#xff0c;这就是透视。 总的来说。透视变换是将3D的世界转换到2D图像上的一种手段&#xff0c;人的视觉系统和摄像头视觉系统也是基于这一工作原理。 对透视变化的研究&a…

ps做产品的网站怎么做免费的产品图片网站

大家好&#xff0c;今天来聊聊论文降重隐藏字符怎么识别&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 论文降重隐藏字符的识别方法 一、引言 在论文降重过程中&#xff…

翻斗幼儿园历险记-CTF-WP

翻斗幼儿园历险记 一、搭建: docker-compose up -d 运行那个docker-compose.yml文件即可打开127.0.0.1:32777就运行好了2、打法 文件上传前端过滤,bp抓包改后缀即可盲猜一波,上传的目录是/uploads下面 哥斯拉连上马…

.net8+winform+Antdui 制作 LOL 小助手

.net8+winform+Antdui 制作 LOL 小助手 .net8+winform+Antdui 制作 LOL 小助手 一、事件起因 二、筹备工作 三、查看效果 四、后期拓展想法 一、事件起因 本人 lol 菜鸡一枚,最近天天玩排位模式,有时候自己分路有优势…

深入解析:【Git】Git 简介及基本操作

深入解析:【Git】Git 简介及基本操作pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mona…

hutool主要内容list

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅 Hutool = Hu + tool,是原公司项目底层代码剥离后的开源库,“Hu”是公司名称的表示,too…

做图赚钱的网站有哪些中国能源建设集团有限公司是央企

QDomDocument类代表了一个XML文件 QDomDocument类代表整个的XML文件。概念上讲&#xff1a;它是文档树的根节点&#xff0c;并提供了文档数据的基本访问方法。由于元素、文本节点、注释、指令执行等等不可能脱离一个文档的上下文&#xff0c;所以文档类也包含了需要用来创建这些…

Kurt-Blender零基础教程:第2章:建模篇——第3节:陈列/父子级/蒙皮/置换修改器与小狐狸角色建模 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

网站建设的目标客户分析建做网站

使用 Yelp 数据集进行用户画像&#xff08;User Profiling&#xff09;是一项有趣的任务&#xff0c;可以理解用户的偏好、行为和特征。以下是总结的一个基本的步骤&#xff0c;帮助构建用户画像 pandas 加载数据&#xff1a; import pandas as pd# 加载数据 users pd.read_…