manim边学边做--改变动画速度
ChangeSpeed类是Manim库中用于修改动画速度的类。
它提供了一种灵活的方式来控制动画的播放速度,使动画在不同时间段内以不同的速度播放,从而创造出更加丰富多样的动画效果。
比如,在创建包含多个元素动画的场景中,通过ChangeSpeed可以精确控制不同元素在不同时间点的移动速度,实现复杂的动画节奏编排。
1. 动画概述
与之前介绍的那些动画类不同,ChangeSpeed不是为元素实现某种具体的动画效果,
它的作用对象是动画本身,它的主要特点有:
- 灵活的速度调整:可以指定动画在不同时间对应的速度因子,也就是在动画的不同阶段设置不同的速度
- 与多种动画类型结合:不仅可以用于修改单个动画的速度,还能处理
AnimationGroup类型的动画,将多个动画组合成一个整体进行速度控制 - 支持速率函数覆盖:通过
rate_func参数可以覆盖传入动画的速率函数,从而进一步自定义动画的速度变化曲线
主要参数有:
| 参数名称 | 类型 | 说明 |
|---|---|---|
| anim | Animation | 需要修改速度的动画对象 |
| speedinfo | dict | 指定在不同时间点的动画速度 |
| rate_func | func | 覆盖传入动画的速率函数,在修改速度之前应用 |
| affects_speed_updaters | bool | 决定是否影响通过add_updater方法添加的更新器的速度 |
speedinfo参数是一个字典,
它的key是动画运行时间的百分比(0 到 1 之间的浮点数),value是对应的速度因子。
affects_speed_updaters参数一般在做联动动画时使用的,用来决定是否影响联动动画的速度。
ChangeSpeed还有一些方法,可以用于全面控制动画的执行流程、时间相关属性和相关对象的处理。
| 名称 | 说明 |
|---|---|
| add_updater | 用于将速度变化应用于更新器 |
| begin | 在动画开始时被调用时,进行初始化操作 |
| finish | 动画结束时被调用 |
| update_mobjects | 更新相关对象,如起始对象和(对于变换动画)目标对象 |
| clean_up_from_scene | 在动画结束后清理场景 |
| get_scaled_total_time | 返回动画所花费的时间 |
| interpolate | 在动画的每一帧被调用,用于设置动画的进度 |
2. 使用示例
下面通过示例来演示如何使用ChangeSpeed类来丰富动画的表现效果。
2.1. 变速移动的点
此示例在场景中创建了两个点,然后使用ChangeSpeed类来控制其移动动画。
通过speedinfo参数,设置第一个先减速移动,然后再加速移动,最后再次减速移动。
第二点与第一个点的速度变化正好相反,并且两个点在运动过程中都采用线性速率函数。
d1 = Dot(color=BLUE)
d2 = Dot(color=RED)
self.add(d1, d2)
# 先慢后快再慢
self.play(
ChangeSpeed(
d1.animate(run_time=2).shift(RIGHT * 5),
speedinfo={0.2: 0.5, 0.3: 2, 0.8: 0.5},
rate_func=linear,
),
)
# 先快后慢再快
self.play(
ChangeSpeed(
d2.animate(run_time=2).shift(LEFT * 5),
speedinfo={0.2: 2, 0.3: 0.5, 0.8: 2},
rate_func=linear,
),
)

2.2. 变速旋转的正方形
先添加了一个正方形,然后利用ChangeSpeed类来调整其旋转动画。
根据speedinfo设定,正方形在动画开始的前 30% 时间内慢速旋转(速度因子为 0.5),之后在 70%~100% 时间内快速旋转(速度因子为 2),
同时使用平滑的速率函数,产生了变速旋转的动画效果。
square = Square()
# 正方形先慢速旋转 然后快速旋转
self.play(
ChangeSpeed(
Rotate(square, angle=PI, run_time=3),
speedinfo={0.3: 0.5, 0.7: 2},
rate_func=smooth,
)
)

2.3. 结合更新器的变速缩放
首先创建了一个圆,并定义了一个更新器函数,使圆在每一帧渲染时按一定比例持续缩放。
接着通过ChangeSpeed类的静态方法add_updater将更新器应用到圆上,并根据speedinfo参数,使得更新器在动画中间部分速度变慢,从而实现了圆的变速缩放效果。
注意,这里要设置affects_speed_updaters=True,否则圆会匀速放大,使得speedinfo参数无效。
circle = Circle()
self.add(circle)
# 定义一个更新器函数,使圆持续缩放
def update_circle(circle, dt):
circle.scale(1 + 0.1 * dt)
# 将更新器添加到圆上,并使用ChangeSpeed控制更新器的速度
ChangeSpeed.add_updater(circle, update_circle)
self.play(
ChangeSpeed(
Wait(4),
speedinfo={0.3: 2, 0.4: 0.4, 0.7: 0.4, 1: 2},
affects_speed_updaters=True,
)
)

2.4. 动画组中元素的不同速度
在场景中添加了两条水平方向且一上一下的直线,通过ChangeSpeed类作用于AnimationGroup来实现不同速度的动画效果。
因为speedinfo参数只能设置一种速度因子,为了使两条直线的变色速度不一样,这里使用了一个技巧,设置两条直线变色的run_time不一样。
这样,即使它们的speedinfo参数一样,最终还是以不同节奏来变色。
l1 = Line(LEFT * 3, RIGHT * 3).shift(UP)
l2 = Line(LEFT * 3, RIGHT * 3).shift(DOWN)
self.add(l1, l2)
# 创建一个动画组,使两条线以不同的速度变色
self.play(
ChangeSpeed(
AnimationGroup(
l1.animate(run_time=2).set_color(RED),
l2.animate(run_time=4).set_color(BLUE),
),
speedinfo={
0.3: 1,
0.6: 0.5,
1: 1,
},
rate_func=linear,
)
)

3. 附件
文中的代码只是关键部分的截取,完整的代码共享在网盘中(change_speed.py),
下载地址: 完整代码 (访问密码: 6872)
manim边学边做--改变动画速度的更多相关文章
- 学EE做硬件找工作不如学CS做软件,为什么会这样?
学EE做硬件找工作不如学CS做软件,为什么会这样? 电子工程(EE)就业最好的方向居然是转计算机,也许让有的人觉得很不公平,EE也是很重要的学科,我们学习也很努力,为什么就业会不如CS?也有的人好奇, ...
- Android 中加载几百张图片做帧动画防止 OOM 的解决方案
Android 中加载几百张图片做帧动画防止 OOM 的解决方案 最近,项目中有个需求:就是要做一个帧动画,按理说这个是很简单的!但是我能说这个帧动画拥有几百张图片吗?...... 填坑一 ---帧动 ...
- 【30分钟学完】canvas动画|游戏基础(1):理论先行
前言 本文虽说是基础教程,但这是相对动画/游戏领域来说,在前端领域算是中级教程了,不适合前端小白或萌新.阅读前请确保自己对前端三大件(JavaScript+CSS+HTML)的基础已经十分熟悉,而且有 ...
- 牛腩学Kotlin做Android应用
牛腩学Kotlin做Android应用,蹭热度视频,边学边做, 01-kotlin插件安装及hello world 02-kotlin基础语法速览 哔哩哔哩观看地址:http://www.bilibi ...
- UIView封装动画--iOS利用系统提供方法来做关键帧动画
iOS利用系统提供方法来做关键帧动画 ios7以后才有用. /*关键帧动画 options:UIViewKeyframeAnimationOptions类型 */ [UIView animateKey ...
- php实现记忆化递归--以斐波那契数列为例(还是以边学边做为主,注重练习)
php实现记忆化递归--以斐波那契数列为例(还是以边学边做为主,注重练习) 一.总结 1.递归不优化的话,30层开外就有点吃力了 2.php因为定义变量的时候不用定义变量类型,所以数组里面的类型也是p ...
- html5-3 html5标签(热点地图如何实现)(边学边做)
html5-3 html5标签(热点地图如何实现)(边学边做) 一.总结 一句话总结:热点地图用绝对定位实现. 1.自定义列表怎么弄? dl 自定义列表dt 自定义标题dd 自定义列表内容 2. ...
- 【30分钟学完】canvas动画|游戏基础(7):动量守恒与多物体碰撞
前言 一路沿着本系列教程学习的朋友可能会发现,前面教程中都尽量避免提及质量的概念,很多运动概念也时刻提醒大家这不是真实的物体运动.因为真实的物体运动其实跟质量都是密不可分的,而且质量的引入自然必须提及 ...
- 【30分钟学完】canvas动画|游戏基础(2):从零开始画画
前言 上篇主要是理论的概述,本篇会多些实践,来讲讲canvas的基础用法,并包含一些基础三角函数的应用,推荐没有canvas基础的朋友阅读,熟悉的朋友可以跳过. 本人能力有限,欢迎牛人共同讨论,批评指 ...
- 【30分钟学完】canvas动画|游戏基础(4):边界与碰撞
前言 本系列前几篇中常出现物体跑到画布外的情况,本篇就是为了解决这个问题. 阅读本篇前请先打好前面的基础. 本人能力有限,欢迎牛人共同讨论,批评指正. 越界检测 假定物体是个圆形,如图其圆心坐标即是物 ...
随机推荐
- es之增删改查
查询 index: GET task_results/_search/ 普通查询: {"query":{"bool":{"must":[{& ...
- Python实现摇号系统
1.引言 摇号系统在现代社会中有广泛的应用,特别是在车牌摇号.房屋摇号等公共资源分配领域.摇号系统的主要目的是通过随机分配的方式,确保资源的公平.公正分配.本文将详细介绍如何使用Python实现一个简 ...
- 题解: CF768D Jon and Orbs
题解:CF768D Jon and Orbs 一句话题面:有k种不同的物品,每天等概率任取一种(不一定是新的种类).q组询问,每组给出一个p,问取完这k件物品的概率不小于\(\frac{p}{2000 ...
- 基于sqli-labs Less-5 sql报错注入详解
按照之前的思路发现,是正常的'闭合的字符型,但是在联合注入0' union select 1,2,3--+没有回显注入点,只是回显You are in,因此无法使用联合注入,考虑使用报错注入或者盲注. ...
- 使用 JuiceFS 快照功能实现数据库发布与端到端测试
今天的博客来自 JuiceFS 云服务用户 Jerry,他们通过使用 JuiceFS snapshot 功能,创新性地实现了数据的版本控制.Jerry,是一家位于北美的科技公司,利用人工智能和机器学习 ...
- 服务器cli模式下的定时器
有时候需要一部分后台业务异步的处理,比如处理redis队列啊,处理mysql统计啊,数据同步啊,这种长时间任务,但是又需要每段时间去看看的,发现linux cron最小只能支持每分钟的任务 分 时 天 ...
- MySQL 主从复制之多线程复制
目录 一.MySQL 多线程复制的背景 二.MySQL 5.5 主从复制 1.原理 2.部署主从复制 2.1.主节点安装配置MySQL 5.5 2.2.从节点安装配置MySQL 5.5 3.检查主从库 ...
- VUE3刷新页面报错:Uncaught SyntaxError: Unexpected token ‘<‘
今天用vue3配置嵌套路由时,发现刷新页面后,页面变为空白,打开控制台发现报错: Uncaught SyntaxError: Unexpected token '<' 解决方法: 修改vue.c ...
- 从架构到成本,SQL Server 和 PostgreSQL 四大区别全方位解析!
从架构到成本,SQL Server 和 PostgreSQL 四大区别全方位解析! 今天我想分享 SQL Server 和 PostgreSQL 之间的四大关键区别. 在比较 SQL Server 和 ...
- Collections Framework中的算法(之二)
从本篇开始我们讲述Collections中的一些算法的源代码!本篇主要讲述与排序相关的一些方法,如:排序.反序.反序比较器.乱序.最大值和最小值等. 一.头及一些与算法相关的属性 package ja ...