manim 3.0
随着视频的深入,暴露的问题越来越多,其中主要的问题是自定义函数的混乱,我的解决方法是构造自己的完备的函数库
manim的主结构是mobject和animation,我想我的函数库大致也要这么分类:
1、mobject(以o开头,代表object)
2、操作mobject的函数(以d开头,代表Doframingo)
3、animation(以c开头,代表cartoon)
4、操作animation的函数
但是基于自己的能力和实用性,4可以暂时不做
具体如下:
1、预定义

if True: r = RIGHT;l = LEFT;d = DOWN;u = UP;du = DEGREES;rr = RED;bb = BLUE;gg = GREEN;gg2 = GOLD;pp = PINK;tt = TEAL;ww = WHITE
2、manim自带函数

if type('manim CE') == str: # self.play() def sp(*args, **kwargs): return self.play(*args, **kwargs) # self.wait() def sw(*args, **kwargs): return self.wait(*args, **kwargs) # self.add() def sa(*args, **kwargs): return self.add(*args, **kwargs) # self.clear() def sc(*args, **kwargs): return self.clear(*args, **kwargs) # self.remove() def sr(*args, **kwargs): return self.remove(*args, **kwargs) # Animation Transform() def at(a, b, *args, **kwargs): return ReplacementTransform(a, b, *args, **kwargs) # Animation Transform() def at0(a, b, *args, **kwargs): return Transform(a, b, *args, **kwargs) # Animation ReplacementTransform() def art(a, b, *args, **kwargs): return ReplacementTransform(a, b, *args, **kwargs) # Animation TransformMatchingShapes() def atm(a, b, *args, **kwargs): return TransformMatchingShapes(a, b, *args, **kwargs) # Animation ClockwiseTransform() def act(a, b, *args, **kwargs): return ClockwiseTransform(a, b, *args, **kwargs) # Animation CounterclockwiseTransform() def acct(a, b, *args, **kwargs): return CounterclockwiseTransform(a, b, *args, **kwargs) # Animation Write() def aw(a, *args, **kwargs): return Write(a, *args, **kwargs) # Animation LaggedStart() def als(a, *args, **kwargs): return LaggedStart(a, *args, **kwargs) # Animation Unwrite() def auw(a, *args, **kwargs): return Unwrite(a, *args, **kwargs) # Animation FadeOut() def afo(a, *args, **kwargs): return FadeOut(a, *args, **kwargs) # Animation FadeIn() def afi(a, *args, **kwargs): return FadeIn(a, *args, **kwargs) # Animation FadeOut() def afoo(a, *args, **kwargs): return FadeOut(a, *args, shift=DOWN, **kwargs) # Animation FadeIn() def afii(a, *args, **kwargs): return FadeIn(a, *args, shift=DOWN, **kwargs) # Animation Restore() def are(a, *args, **kwargs): return Restore(a, *args, **kwargs) # Animation Rotate() def aro(a, b, *args, **kwargs): return Rotate(a, about_point = b, *args, **kwargs) # 注意b有可能是坐标,有可能是物体 # return Rotate(a, about_point = b.get_center(), *args, **kwargs) # Animation DrawBorderThenFill() def adb(a, *args, **kwargs): return DrawBorderThenFill(a, *args, **kwargs) # Animation DrawBorderThenFill() reverse def adbr(a, *args, **kwargs): return DrawBorderThenFill(a, *args, **kwargs, reverse_rate_function = True) # Animation GrowFromCenter() def agf0(a, *args, **kwargs): return GrowFromCenter(a, *args, **kwargs) def agf(*args, **kwargs): li = [] for i in args: li.append(GrowFromCenter(i, **kwargs)) return AnimationGroup(*li) # Animation GrowFromEdge() def agfe(a, b, *args, **kwargs): return GrowFromEdge(a, b, *args, **kwargs) # Animation GrowFromPoint() def agfp(a, b, *args, **kwargs): return GrowFromPoint(a, b, *args, **kwargs) # Animation MoveAlongPath() def ama(a, b, *args, **kwargs): return MoveAlongPath(a, b, *args, **kwargs) # Animation SpinInFromNothing def asi(a, *args, **kwargs): return SpinInFromNothing(a, angle=2 * PI, *args, **kwargs) # Animation SpinInFromNothing reverse def asir(a, *args, **kwargs): return SpinInFromNothing(a, angle=2 * PI, *args, **kwargs, reverse_rate_function = True) # Animation ShrinkToCenter def ast0(a, *args, **kwargs): return ShrinkToCenter(a, *args, **kwargs) def ast(*args, **kwargs): li = [] for i in args: li.append(ShrinkToCenter(i, **kwargs)) return AnimationGroup(*li) # Animation Circumscribe def ac(a, *args, **kwargs): return Circumscribe(a, *args, **kwargs) # Animation Indicate def ai(a, *args, **kwargs): return Indicate(a, *args, **kwargs) # Animation Restore def ar(a, *args, **kwargs): return Restore(a, *args, **kwargs) # Animation Shift def ash(*args, **kwargs): li = [] i = 1 for a in args: if i % 2 != 0: li.append(ApplyMethod(a.shift, args[i], **kwargs)) i += 1 return AnimationGroup(*li) # Animation Succession def asu(*args): return Succession(*args) # Animation moveto def amt(*args, **kwargs): li = [] i = 1 for a in args: if i % 2 != 0: li.append(ApplyMethod(a.move_to, args[i], **kwargs)) i += 1 return AnimationGroup(*li) # Animation scale def asc(*args, **kwargs): li = [] i = 1 for a in args: if i % 2 != 0: li.append(ApplyMethod(a.scale, args[i], **kwargs)) i += 1 return AnimationGroup(*li) # Animation coloring def ac(*args, **kwargs): li = [] for i in range(len(args)): if i % 2 == 0: li.append(ApplyMethod(args[i].set_color, args[i+1], **kwargs)) return AnimationGroup(*li) # Animation set opacity def aso(*args, **kwargs): li = [] for i in range(len(args)): if i % 2 == 0: li.append(ApplyMethod(args[i].set_opacity, args[i+1], **kwargs)) return AnimationGroup(*li) # mobject Text def mt(text, *args, **kwargs): return Text(text, *args, **kwargs) # mobject SVGMobject def msm(name, *args, **kwargs): sm = SVGMobject(f'D:\\manimSVG\\{name}.svg') return sm # mobject SVGMobject constant def msmc(name, *args, **kwargs): sm = SVGMobject(f'D:\\manimSVG\\constants\\{name}.svg') return sm # mobject MathTex def mmt(text, *args, **kwargs): return MathTex(text, *args, **kwargs) # mobject VGroup def mvg(*args, **kwargs): return VGroup(*args, **kwargs) # mobject ArcBetweenPoints def mab(a, b, *args, **kwargs): return ArcBetweenPoints(a.get_center(), b.get_center(), angle = 120*DEGREES, *args, **kwargs) # mobject DashedLine def mdl(a, b, *args, **kwargs): return DashedLine(a, b, *args, **kwargs)
3、自定义物件

if type('object') == str: # object text flower def otf(a, judge=1): ''' a represents the text judge represents the type of text(normal or MarkupText(MathTex is inclined rather than upright)) ''' if judge == 1: at = Text(a, font = 'STZhongsong',stroke_width=2).set_color(color = ['#f3e9e0', '#fea8a9']) elif judge == 2: at = MarkupText(a, stroke_width=2).set_color(color = ['#f3e9e0', '#fea8a9']) fl = SVGMobject(r"D:\manimSource\svg\icon.svg")[8].rotate(PI/2).set_color(color = ['#fea8a9', '#f3e9e0']).scale(1.5) at.next_to(fl, RIGHT) vg = VGroup(fl, at) vg.set(height = 0.6).to_corner(UL) return vg # object text flower2 def otf2(a, judge=1): if judge == 1: at = Text(a, font = 'STFangsong',stroke_width=2).set_color(color = ['#f3e9e0', '#b1d85c']) elif judge == 2: at = MarkupText(a, stroke_width=2).set_color(color = ['#f3e9e0', '#b1d85c']) fl = SVGMobject(r"D:\manimSource\svg\icon.svg")[8].rotate(PI/2).set_color(color = ['#b1d85c', '#f3e9e0']).scale(1.5) at.next_to(fl, RIGHT) vg = VGroup(fl, at) vg.set(height = 0.6).to_corner(UL) return vg # object text flower3 def otf3(a, judge=1): if judge == 1: at = Text(a, font = 'STFangsong',stroke_width=2).set_color(color = ['#f3e9e0', '#6A5ACD']) elif judge == 2: at = MarkupText(a, stroke_width=2).set_color(color = ['#f3e9e0', '#6A5ACD']) fl = SVGMobject(r"D:\manimSource\svg\icon.svg")[8].rotate(PI/2).set_color(color = ['#6A5ACD', '#f3e9e0f']).scale(1.5) at.next_to(fl, RIGHT) vg = VGroup(fl, at) vg.set(height = 0.6).to_corner(UL).shift(2*DOWN) return vg # object narrator def on(a): text = Text(a, font='STZhongsong').to_edge(DOWN).scale(0.6) return text # object narrator 2 def on2(a): text = Text(a, font='STFangsong').scale(0.7).to_edge(DOWN) return text # object group def og(a, num, mess=True): vg = VGroup() for i in range(num): r = np.random.rand()*2.5 + 0.5 s = np.random.rand()*0.8 + 0.6 t = np.random.rand()*2*PI ro = np.random.rand()*2*PI if mess == True: vg.add(a.copy().shift(r*np.cos(t)*RIGHT+r*np.sin(t)*UP).scale(s).rotate(ro)) else: vg.add(a.copy()) return vg # object autograph introduction def oai(a,b,c): pic=ImageMobject(a).scale(1.3).shift(3.5*l+0.8*u) name=xn(b).next_to(pic,DOWN);name2=xn(c).scale(0.8).next_to(name,DOWN) return Group(pic,name,name2) # object my design def omd(a): return SVGMobject(f"D:\\manimSource\\svg\\{a}.svg") # object execute narrator def oen(a): for i in a: globals()[f't{str(i)}']=on(a[i]) # object execute narrator2 def oen2(a): for i in a: globals()[f'n{str(i)}']=on2(a[i]) # object execute object def oeo(a): for i in a: if type(a[i]) == str: globals()[f'o{str(i)}']=on2(a[i]) else: globals()[f'o{str(i)}']=a[i]
4、自定义对于物件的操作方法

if type('utilize') == str: # utilize move and scale def ums(a, n1, b, n2): scale = b[n2].width/a[n1].width a.scale(scale) vect = b[n2].get_center() - a[n1].get_center() a.shift(vect) # utilize color and opacity init def ucoi(*args): def xc2h(c): return rgb_to_hex(color_to_rgb(c)) for a in args: # 先缩放再设置透明度(否则会消失不见) a.set_opacity(1) for i in a: if xc2h(i.color) == '#ff0000': i.set_color(RED).set_sheen(0.1) elif xc2h(i.color) == '#ffff00': i.set_color(GOLD).set_sheen(0.1) elif xc2h(i.color) == '#00ff00': i.set_color(GREEN).set_sheen(0.1) elif xc2h(i.color) == '#00ffff': i.set_color(TEAL).set_sheen(0.1) elif xc2h(i.color) == '#0000ff': i.set_color(BLUE).set_sheen(0.1) elif xc2h(i.color) == '#ff00ff': i.set_color(PINK).set_sheen(0.1) # utilize opacity scale def uos(num, *args): ''' num represents the magnification of the 1st mobject args represent the mobjects ''' # 最好让透明度也一样 def premovescale(a, b): # x = VGroup() # y = VGroup() for i in a: # 设置get_fill_opacity() == 0.5会失效 if i.get_fill_opacity() < 1: x = i # x.add(i) for j in b: if j.get_fill_opacity() < 1: y = j # y.add(j) scale = y.height/x.height a.scale(scale) # 先缩放再移动 vector = y.get_center() - x.get_center() a.shift(vector) args[0].scale(num) for n in range(len(args) - 1): premovescale(args[n+1], args[n]) ucoi(*args) # utilize check def uc(*args): self.camera.background_color = WHITE for svg in args: if type(svg) == list: self.clear() for sss in svg: self.add(sss.set(color = RED)) for sss in svg: n = 0 for i in sss: num = Integer(number=n, stroke_width=2).set_color(BLACK).move_to(i) n += 1 self.add(num) self.wait() else: self.clear() self.add(svg.set(color = RED)) n = 0 for i in svg: num = Integer(number=n, stroke_width=2).set_color(BLACK).move_to(i) n += 1 self.add(num) self.wait() self.clear() # utilize place in grid def upg(buff1, buff2, *args): ''' such as upg(2,2,[a[0],a[1],a[2]],[a[3],a[4]]) ''' o = args[0][0] le = len(args[0]) n = 0 m = 0 vg = VGroup() for i in args: for j in i: j.move_to(o.get_center() + buff1*n*r + buff2*m*d) n += 1 n %= le vg.add(j) m += 1 vg.move_to(ORIGIN) return vg # utilize place in grid animation def upga(buff1, buff2, *args): ''' such as upg(2,2,[a[0],a[1],a[2]],[a[3],a[4]]) ''' o = args[0][0] le = len(args[0]) n = 0 m = 0 vg = VGroup() for i in args: for j in i: j.target.move_to(o.get_center() + buff1*n*r + buff2*m*d) n += 1 n %= le vg.add(j.copy().move_to(o.get_center() + buff1*n*r + buff2*m*d)) m += 1 distance = o.get_center() - vg[0].get_center() for i in args: for j in i: j.target.shift(distance) # utilize place in line def upl(buff,*args,direction=DOWN): o = args[0] n = 0 for i in args: i.move_to(o.get_center() + n*buff*direction) n += 1 vg = VGroup(*args) vg.move_to(ORIGIN) return vg # utilize place in line animation def upla(buff,*args,direction=DOWN): o = args[0] n = 0 vg = VGroup() for i in args: i.target.move_to(o.get_center() + n*buff*direction) vg.add(i.copy().move_to(o.get_center() + n*buff*direction)) n += 1 vg.move_to(ORIGIN) distance = vg[0].get_center() - o.get_center() for i in args: i.target.shift(distance) # utilize place in circle def upc(r, *args): n = 0 vg = VGroup() for i in args: i.move_to(ORIGIN) i.shift(r*np.cos(n*2*PI/len(args) + PI/2)*RIGHT + r*np.sin(n*2*PI/len(args) + PI/2)*UP) vg.add(i) n += 1 return vg # utilize place in circle animation def upca(r, *args): n = 0 for i in args: i.target.move_to(ORIGIN) i.target.shift(r*np.cos(n*2*PI/len(args) + PI/2)*RIGHT + r*np.sin(n*2*PI/len(args) + PI/2)*UP) n += 1 # utilize generate target def ugt(*args): for i in args: i.generate_target() # utilize forehead shift def ufsh(*args): i = 1 for a in args: if i % 2 != 0: a.shift(args[i]) i += 1 # utilize forehead scale def ufsc(*args): i = 1 for a in args: if i % 2 != 0: if type(a) == list: for j in a: j.scale(args[i]) else: a.scale(args[i]) i += 1 # utilize forehead coloring def ufc(*args): i = 1 for a in args: if i % 2 != 0: a.set_color(args[i]) i += 1 # utilize forehead next to def ufnt(*args): i = 0 for a in args: if i % 3 == 0: a.next_to(args[i+1], args[i+2]) i += 1
5、自定义动画

if type('cartoon') == str: # cartoon transform def ct(names, *args): ''' names: a list of mobjects args represent lists, such as [0,1,[0,0,1,1,2,2]], the 1st and 2nd numbers represent the index of mobject in the names list ''' def pretrans0(name, i): if type(i) == int: back = name + '[' + str(i) + ']' elif type(i) == str: m = i.find('.') n1 = i[0:m] n2 = i[m+1:] back = name + '[' + n1 + ':' + n2 + ']' return back def pretrans(name, i): if type(i) == int: back = name + '[' + str(i) + ']' elif type(i) == str: m = i.find('.') n1 = i[0:m] n2 = i[m+1:] back = name + '[' + n1 + ':' + n2 + ']' elif type(i) == list: back = 'VGroup(' for j in i: item = pretrans0(name, j) + ',' back += item back += ')' return back ag = 'AnimationGroup(' # range(0, n-1)是错的 itemli = [] for l in names: itemli.append(list(range(len(l)))) def countli0(name, i): if type(i) == int: name.remove(i) elif type(i) == str: m = i.find('.') n1 = int(i[0:m]) n2 = int(i[m+1:])-1 p1 = name.index(n1) p2 = name.index(n2) del name[p1:p2+1] def countli(name, i): if type(i) == int: name.remove(i) elif type(i) == str: m = i.find('.') n1 = int(i[0:m]) n2 = int(i[m+1:])-1 p1 = name.index(n1) p2 = name.index(n2) del name[p1:p2+1] elif type(i) == list: for j in i: item = countli0(name, j) set1 = set() set2 = set() for m in range(len(args)): n = 0 for i in args[m][2]: n += 1 if n % 2 != 0: u = pretrans(f'names[args[{str(m)}][0]]', i) countli(itemli[args[m][0]], i) set1.add(args[m][0]) else: v = pretrans(f'names[args[{str(m)}][1]]', i) item = f'ReplacementTransform({u}, {v}),' ag += item countli(itemli[args[m][1]], i) set2.add(args[m][1]) for i in set1: for ii in itemli[i]: # reverse GrowFromCenter不可用 ag += f'ShrinkToCenter(names[{str(i)}][{str(ii)}]), ' for j in set2: for jj in itemli[j]: ag += f'GrowFromCenter(names[{str(j)}][{str(jj)}]), ' ag += ')' agg = eval(ag) return agg # cartoon transform 2 def ct2(a, b, c): ''' a and b represent mobjects c represents the corresponding transform parts ''' def pretrans0(name, i): if type(i) == int: back = name + '[' + str(i) + ']' elif type(i) == str: m = i.find('.') n1 = i[0:m] n2 = i[m+1:] back = name + '[' + n1 + ':' + n2 + ']' return back def pretrans(name, i): if type(i) == int: back = name + '[' + str(i) + ']' elif type(i) == str: m = i.find('.') n1 = i[0:m] n2 = i[m+1:] back = name + '[' + n1 + ':' + n2 + ']' elif type(i) == list: back = 'VGroup(' for j in i: item = pretrans0(name, j) + ',' back += item back += ')' return back n = 0 ag = 'AnimationGroup(' # range(0, n-1)是错的 for i in c: n += 1 if n % 2 != 0: u = pretrans('a', i) else: v = pretrans('b', i) item = f'ReplacementTransform({u}, {v}),' ag += item ag += ')' agg = eval(ag) return agg # cartoon animations list def cal(t,*argss): args = [] for i in argss: args.append(i) # 不是args = args.reverse() args.reverse() n = 0 for a in args: if n == 1: ag = AnimationGroup(args[1],args[0],lag_ratio=t) elif n > 1: ag = AnimationGroup(a,ag,lag_ratio=t) n += 1 return ag # cartoon xxp play def cxp(*args): for a in args: if type(a) == list: self.wait(0.5) self.play(*a) self.wait(0.5) elif type(a) == tuple: self.clear() self.add(*a) # elif type(a) == tuple: # for i in a: # self.play(i) else: self.wait(0.5) self.play(a) self.wait(0.5) # cartoon move along arc def cmaa(a,b,c,s): ''' a represents the moving mobject b and c represent the starting and ending point s represents the direction ''' arc = ArcBetweenPoints(b.get_center(), c.get_center(), angle = s*120*DEGREES) return MoveAlongPath(a, arc) # cartoon release target def crt(*args): li = [] for i in args: li.append(MoveToTarget(i)) return AnimationGroup(*li) # cartoon move around def cma(*args,t=3): ag = [] for a in args: li = [] center = a.get_center() for i in range(t): x = np.random.rand()*0.3 y = np.random.rand()*2*PI li.append(amt(a,center+x*np.cos(y)*r+x*np.sin(y)*u,run_time=0.5,rate_func=rate_functions.smooth)) ag.append(asu(*li)) return AnimationGroup(*ag) # cartoon fade in def cfi(*args): li = [] for i in args: dots = og(Dot(),len(i)).set_color(WHITE).set_opacity(0) li.append(at(dots,i)) return AnimationGroup(*li) # cartoon fade out def cfo(*args): li = [] for i in args: dots = og(Dot(),len(i)).set_color(WHITE).set_opacity(0) li.append(at(i,dots)) return AnimationGroup(*li) # cartoon wait def cw(*args): return Wait(*args)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~