醇的化学反应

s1

        t1 = mt('醇的化学反应', font='STZhongsong')
        al1 = msm('general')
        al20 = msm('general2').scale(2)
        xs(al1, 0, al20, 0)
        xm(al1, 0, al20, 0)
        al1.save_state()
        al20.save_state()
        vgfo1 = mvg(al20[0], al20[2], al20[7], al20[8])
        vgcen1 = mvg(al20[1], al20[3:7], al20[9:])
        vgcen1.save_state()
        vd1 = al20[9:11]
        vd2 = al20[11:13]
        hyp = msm('hyp').scale(0.95)
        hyp1 = xcc(hyp, '#00c1ff')
        hyp2 = xcc(hyp, '#4792a9')
        hyp1.set_color([BLUE_C, BLUE_E]).set_sheen(0.3).set_opacity(0.8)
        hyp2.set_color([BLUE_C, BLUE_E]).set_sheen(0.3).set_opacity(0.8)
        p0 = xcc(msm('p0'), '#323dc0').scale(0.45).set_color([BLUE_C, BLUE_E]).set_sheen(0.3).set_opacity(0.8)
        p00 = xcc(msm('p0'), '#323dc0').scale(0.45).set_color([RED_C, RED_E]).set_sheen(0.3).set_opacity(0.8).rotate(PI)
        p1 = xcc(msm('p1'), '#d55656').scale(0.8).set_color([BLUE_C, BLUE_E]).set_sheen(0.3).set_opacity(0.8)
        sorb = msm('sorb').scale(1.7).set_color([RED_C, RED_E]).set_sheen(0.3).set_opacity(0.8)
        al2 = mvg(al20, hyp)
        t2 = xun('醇的结构特点')
        t3 = xn('饱和醇羟基的氧为sp³杂化')
        t3[8:11].set_color([BLUE_C, BLUE_E]).set_sheen(0.3).set_opacity(0.8)

        
#         xc([al20])
        sp(adb(t1))
        sp(afo(t1))
        sp(agf(al1))
        sp(adb(t2))
        sp(adb(t3))
        sp(xt(al1, al20, [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12]))
        sc()
        al1.restore()
        sa(t2, t3, al20)
        sp(afo(vgfo1))
        sp(vgcen1.animate.move_to(ORIGIN).scale(1.6))
        p0.move_to(al20[3]).shift(1.4*LEFT)
        p0.move_to(al20[3]).shift(1.4*LEFT)
        p00.move_to(al20[1]).shift(1.4*RIGHT)
        hyp.move_to(al20[3]).shift(1.2*UR)
        p1.move_to(al20[3]).shift(1.05*DR)
        sorb.move_to(al20[5])
        sp(al20[4].animate.set_sheen(0.3).set_opacity(0.8), al20[6].animate.set_sheen(0.3).set_opacity(0.8), al20[9:13].animate.set_sheen(0.3).set_opacity(0.8), run_time=0.5)
        sp(al20[4].animate.set_color(BLUE_C), al20[6].animate.set_color(BLUE_C), al20[9:13].animate.set_color(BLUE_C))
        sw()
        al20[6].set_z_index(-1)
        sp(at(al20[4], VGroup(p0, p00)), at(al20[6], VGroup(p1, sorb)))
        sw()
        sp(al20[9:11].animate.move_to(hyp1), al20[11:13].animate.move_to(hyp2))
        sp(at(al20[9:11], hyp1), at(al20[11:13], hyp2))
        sw(2)
        sp(ar(vgcen1), afo(t3))
        sp(afi(vgfo1))
        sc()
        sa(t2, al20)
        sp(xt(al20, al1, [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12]))
        sc()
        sa(t2, al1)
        sw(0.5)
View Code

 s2

        al1 = msm('general')
        al20 = msm('general2').scale(2)
        ohdot = msm('ohdot')
        xms(al1, 0, al20, 0)
        xms(ohdot, 0, al1, 3)
        al1.save_state()
        al20.save_state()
        t2 = xun('醇的结构特点')
        t3 = xn('在醇羟基中,氧的电负性比氢大,它们的公用电子对偏向氧')
        xf(t3, '公用电子对').set_color(RED).set_sheen(0.3)
        t4 = xn('氢表现出一定的活性,所以醇具有酸性')
        acid = xf(t4, '酸性').copy()
        acidt = xtb('酸性', RED)
        
#         sa(xx)
#         sw()
        
        
        sa(t2, al1)
        sw(0.5)
        sp(adb(t3))
        sw()
        sp(xt(al1, ohdot, [3,0,6,'1.3',5,3]))
        sp(al1[6].animate.set_sheen(0.3), run_time=0.3)
        sp(al1[6].animate.set_color(RED))
        sp(al1[6].animate.shift(0.2*LEFT))
        sp(at(t3,t4))
        sw()
        sp(al1[5].animate.rotate(about_point=al1[1].get_center(), angle=10*DEGREES), run_time=0.6)
        sp(al1[5].animate.rotate(about_point=al1[1].get_center(), angle=-20*DEGREES), run_time=0.6)
        sp(al1[5].animate.rotate(about_point=al1[1].get_center(), angle=10*DEGREES), run_time=0.6)
        sp(adb(acidt), afo(t3, t2, al1))
        sw(0.5)
View Code

 s3

        acidt = xtf('酸性')
        baset = xtf('碱性')
        table = xtf('亲核性')
        t1 = xn('由于醇羟基具有酸性,因此醇可以和金属钠反应')
        t2 = xn('醇的酸性比水弱,醇和钠的反应要温和得多')
        t3 = xn('醇也可以和其他活泼金属发生反应,例如K、Mg和Al')
        eq1 = msm('eqa').scale(0.27)
        mo1 = eq1[1:7].copy().scale(1.5)
        mo2 = eq1[9:11].copy().scale(1.5)
        vgmo = VGroup(mo1, mo2).move_to(ORIGIN).arrange(buff=2)
        mo3 = eq1[12:19].copy()
        xms(mo3,0,mo1,0)
        mo4 = eq1[20:22].copy().move_to(mo2)
        xs(mo4,0,mo1,5)
        mo11 = mo1.copy().set_opacity(0)
        mo22 = mo2.copy().set_opacity(0)
        no1 = xn('').scale(1.3)
        no2 = xn('').scale(1.3)
        novg = mvg(no1,no2).arrange(buff=3).shift(1.3*DOWN)
        n1 = Text('16~18').scale(0.8)
        n2 = Text('15.7').scale(0.8)
        nvg = mvg(n1,n2).shift(2*DOWN)
        xa(nvg, novg)
        mno = mmt('pK_a').next_to(n1, 3*LEFT).shift(0.05*DOWN)
        vgaci = mvg(no1,no2,n1,n2,mno)
        t4 = xn('不同类型的醇的酸性强弱顺序为:')
        t5 = xn('这是因为体积较小的烷氧负离子的溶剂化程度较大,稳定性较高')
        t6 = xn('那么其对应的共轭酸(醇)的酸性就越强')
        k1 = xn('酸性强弱顺序').shift(6*UP).scale(1.3)
        k2 = xn('溶剂化大小顺序').shift(6*UP).scale(1.3)
        l1 = msm('yi').scale(0.25)
        l2 = msm('bin')
        l3 = msm('ding')
        xms(l2,0,l1,0)
        xms(l3,0,l1,3)
        l2.shift(0.7*LEFT)
        l1.shift(5*LEFT)
        l3.shift(4.5*RIGHT)
        j1 = Text('>').shift(2.8*LEFT)
        j2 = Text('>').shift(1.5*RIGHT)
        o1 = msm('yi2')
        o2 = msm('bin2')
        o3 = msm('ding2')
        xms(o1,0,l1,0)
        xms(o2,0,l2,0)
        xms(o3,0,l3,0)
        l1.save_state()
        l2.save_state()
        l3.save_state()
        al1 = msm('general')
        al20 = msm('general2').scale(2)
        xms(al1, 0, al20, 0)
        t7 = xn('醇羟基上的氧可利用孤对电子与氢结合形成氧鎓盐')
        t9 = xn('氧的孤对电子也可以进攻带正电荷的离子或基团')
        xf(t7, '孤对电子').set_color(RED).set_sheen(0.3)
        xf(t9, '孤对电子').set_color(RED).set_sheen(0.3)
        t8 = xn('故醇具有碱性')
        t10 = xn('故醇具有亲核性')
        ywy = msm('ywy')
        oz = msm('oz')
        xms(ywy, 0, al1, 3)
        xms(oz, 0, al1, 3)
        ywh = ywy[5:].copy().shift(UP)

        
#         xc([ywh, al1, oz])
#         sw()
        
        sa(acidt)
        sw(0.5)
        sp(adb(t1), adb(mo1), adb(mo2))
        sw()
        sp(act(mo1[5], mo4), acct(mo2, mo3[5:7]), run_time=2)
        sw()
        sr(mo1,mo2)
        sa(mo3,mo4)
        sp(at(mo11,eq1[1:7]), at(mo22, eq1[9:11]), at(mo3, eq1[12:19]), at(mo4, eq1[20:22]))
        sp(agf(eq1[0]), agf(eq1[7]), agf(eq1[8]), agf(eq1[22:]), agf(eq1[11]), agf(eq1[19]))
        sw(2)
        sc()
        sa(acidt, t1, eq1)
        sp(at(t1, t2))
        sp(aw(vgaci))
        sw(1.5)
        sp(at(t1, t3))
        sw(2)
        sp(afo(vgaci, eq1))
        sp(at(t1, t4))
        sp(adb(l1), adb(l2), adb(l3))
        sp(agf(j1), agf(j2), agf(k1))
        sw(2)
        sp(at(t1, t5))
        sp(at(l1, o1), at(l2[9], o2[10]), at(l3[14], o3[15]))
        sp(FadeOut(k1), run_time=0.7)
        sp(FadeIn(k2), run_time=0.7)
        sw(2)
        sp(at(t1, t6))
        sp(FadeOut(k2), run_time=0.7)
        sp(FadeIn(k1), run_time=0.7)
        sp(ar(l1), ar(l2), ar(l3))
        sw(2)
        sp(afo(k1,t1,l1,l2,l3,j1,j2))
        sp(afi(al1))
        sp(acidt.animate.move_to([-5.4,2,0]).scale(1.3))
        sp(adb(t7))
        sp(agf(ywh))
        sp(al1[9:11].animate.set_sheen(0.3), run_time=0.5)
        sp(al1[9:11].animate.set_color(RED))
        al1.save_state()
        sp(ywh.animate.shift(DOWN))
        sw()
        al1[5].save_state()
        sp(afo(al1[9:13], al1[6]), al1[5].animate.move_to(oz[1]), at(ywh[0], oz[2]), ywh[1:].animate.move_to(oz[3:]))
        sw()
        sp(at(t7,t8))
        sp(adb(baset))
        sw()
        sp(baset.animate.move_to([-5.4,0,0]).scale(1.3))
        sp(at(t7, t9), afi(al1[9:13], al1[6]), afo(ywh), ar(al1[5]))
        sw(1.5)
        sp(adb(table))
        sp(at(t7,t10), afo(al1, baset, acidt))
        sw(0.5)
View Code

 s4

        acidt = xtf('酸性').move_to([-5.4,2,0]).scale(1.3)
        baset = xtf('碱性').move_to([-5.4,0,0]).scale(1.3)
        nut = xtf('亲核性')
        t1 = xn('故醇具有亲核性')
        t2 = xn('例如甲醇和硝酸的反应过程如下:')
        jia0 = msm('jia0')
        jia1 = msm('jia1')
        xiao0 = msm('xiao0')
        xiao1 = msm('xiao1')
        tran1 = msm('tran1')
        tran2 = msm('tran2')
        tran3 = msm('tran3')
        tran4 = msm('tran4')
        condi = msm('condi').to_edge(UP).shift(0.5*UP + 2*LEFT)
        n = mt('N', font='Times New Roman')
        xms(xiao0, 2, n, 0)
        xms(xiao1, 0, n, 0)
        xms(tran1, 0, n, 0)
        xms(tran2, 0, n, 0)
        xms(tran3, 0, n, 0)
        xms(tran4, 0, n, 0)
        xs(jia0, 3, n, 0)
        xs(condi, 0, tran2, 2)
        condi.scale(0.8)
        jia0.shift(4*LEFT)
        xms(jia1, 0, jia0, 3)
        tran1[4].set_color(BLUE).set_sheen(0.3)
        tran1[16].set_color(RED).set_sheen(0.3)
        u1 = xun('H转移')
        h2o = msm('h2o').shift(2*DOWN + 4*RIGHT).set_color(BLUE).set_sheen(0.3)
        h = msm('h+').shift(2*UP + 4*RIGHT).set_color(RED).set_sheen(0.3)
        xs(h2o, 0, tran4, 3)
        xs(h, 0, tran4, 3)
        tran4[11].set_color(GREEN).set_sheen(0.3)
        name = xn('硝酸甲酯').shift(1.5*UP)
        p1 = xn('利用醇羟基氧的亲核性,醇可以和含氧无机酸、有机酸成酯')
        al1 = msm('general')
        al20 = msm('general2').scale(2)
        xms(al1, 0, al20, 0)
        


#         xc([tran1, tran2])
#         sw()
        
        
        sa(nut, t1)
        sw(0.5)
        sp(at(t1,t2), adb(jia0), adb(xiao0))
        sp(xt(jia0, jia1, [0,5,1,3,2,4,3,0,4,1]), agf(jia1[6]), agf(jia1[2]), agf(jia1[7:]), xt(xiao0, xiao1, [0,8,1,6,2,0,3,1,4,4]),
          agf(xiao1[9]),agf(xiao1[7]),agf(xiao1[5]),agf(xiao1[10:12]),agf(xiao1[12]),agf(xiao1[2:4]))
        sc()
        sa(jia1, xiao1,nut,t1)
        sp(jia1[7:].animate.set_sheen(0.3), xiao1[2].animate.set_sheen(0.3), run_time=0.5)
        sp(jia1[7:].animate.set_color(BLUE), xiao1[2].animate.set_color(RED))
        sw(1.5)
        sp(xt(jia1, tran1, [3,12,4,13,5,14,6,15,0,3,2,11,1,10,'7.9',4]), xt(xiao1, tran1, [8,8,6,7,7,9,0,0,'10.12','18.20',2,16,3,2,1,1,5,6,4,5,12,17]),
           agf(xiao1[9], reverse_rate_function = True), agf(tran1[20:22]))
        sw(1.5)
        sp(jia1.animate.set_sheen(0), xiao1.animate.set_sheen(0), run_time=0.5)
        sp(jia1.animate.set_color(WHITE), xiao1.animate.set_color(WHITE))
        sr(jia1,xiao1)
        tran1.set_color(WHITE).set_sheen(0)
        sa(tran1)
        sp(afi(u1))
        sp(tran1[10].animate.set_sheen(0.3), run_time=0.5)
        sp(tran1[10].animate.set_color(BLUE))
        sw()
        tran2[2].set_color(BLUE).set_sheen(0.3)
        sp(xt(tran1,tran2,[10,2]), agf(tran1[11], reverse_rate_function = True), agf(tran1[20:22], reverse_rate_function = True), agf(tran1[16], reverse_rate_function = True))
        sw()
        sc()
        sa(tran2, nut, t2, u1)
        sp(tran2.animate.set_sheen(0), run_time=0.5)
        sp(tran2.animate.set_color(WHITE))
        sp(afo(u1))
        sw(0.5)
        sp(afi(condi))
        sp(xt(tran2, tran3, [9,20,2,16]), at(condi[0].copy(), tran3[18]), agf(tran3[21]), agf(tran3[17]), agf(tran3[19]), agf(tran3[22:24]))
        sc()
        sa(tran3, nut, t2)
        sp(afo(condi))
        sp(tran3[20].animate.set_sheen(0.3), tran3[1:3].animate.set_sheen(0.3), tran3[16:20].animate.set_sheen(0.3), tran3[22:24].animate.set_sheen(0.3), tran3[21].animate.set_sheen(0.3), run_time=0.5)
        sp(tran3[20].animate.set_color(RED), tran3[1:3].animate.set_color(BLUE), tran3[16:20].animate.set_color(BLUE), tran3[22:24].animate.set_color(BLUE), tran3[21].animate.set_color(GREEN))
        sw(1.5)
        sp(xt(tran3, tran4, ['14.16','12.14',7,9,8,10,6,8,5,7,13,14,21,11]), xt(tran3, h, [20,0]), agf(h[1:3]), xt(tran3, h2o, [16,0,18,1,1,2]),
          agf(tran3[17], reverse_rate_function = True), agf(tran3[19], reverse_rate_function = True), agf(tran3[2], reverse_rate_function = True), agf(tran3[22:24], reverse_rate_function = True))
        sp(adb(name))
        sp(at(t2, p1))
        sw(2)
        sp(afo(t2, tran3, name, h))
        sp(afi(al1, acidt, baset))
        sp(nut.animate.move_to([-5.4,-2,0]).scale(1.3))
        sw(0.5)
View Code

 s5

        acidt = xtf('酸性').move_to([-5.4,2,0]).scale(1.3)
        baset = xtf('碱性').move_to([-5.4,0,0]).scale(1.3)
        nut = xtf('亲核性').move_to([-5.4,-2,0]).scale(1.3)
        xtable = xtf('取代')
        al1 = msm('general')
        yilie = msm('yilie')
        nufu = msm('nufu')
        nu = msm('nu')
        yilie[11:13].set_color(RED).set_sheen(0.3)
        al20 = msm('general2').scale(2)
        xms(al1, 0, al20, 0)
        xms(yilie, 0, al1, 1)
        al1.save_state()
        t0 = xn('醇中的碳氧键是极性共价键,氧的电负性大于碳')
        xf(t0, '碳氧键').set_color(RED).set_sheen(0.3)
        t1 = xn('共用电子对偏向氧')
        xf(t1, '共用电子对').set_color(RED).set_sheen(0.3)
        t2 = xn('当亲核试剂进攻正电性碳时,羟基被亲核试剂取代')
        t3 = xn('其中最重要的反应是羟基被卤原子取代')
        del1 = MathTex(r'\delta + ').scale(0.8).move_to(al1[1]).shift(0.6*UR)
        del2 = MathTex(r'\delta - ').scale(0.8).move_to(yilie[1]).shift(0.6*UR)
        del3 = MathTex(r'\delta - ').scale(0.8).move_to(al1[3]).shift(0.6*UR)
        nufu.set(height = al1[3].height).move_to(al1[1]).shift(2.3*DOWN + 0.2*RIGHT)
        xms(nu, 0, al1, 1)
        x = Text('X', font = 'STZhongsong')
        xms(x, 0, al1, 3)

#         nufu.shift(1.5*UP)
#         sa(al1, x)
#         xc([al1])
#         sw()
        
        
        sa(nut, acidt, baset, al1)
        sw(0.5)
        sp(adb(t0))
        sp(al1[4].animate.set_sheen(0.3), run_time=0.5)
        sp(al1[4].animate.set_color(RED))
        sw()
        sp(at(t0,t1))
        sp(xt(al1, yilie, [4,'11.13',3,1,6,10,5,9,'9.11','2.4','11.13','4.6']))
        sp(al1[4].animate.shift(0.2*RIGHT))
        sp(adb(del1), adb(del2))
        sp(Restore(al1), at(del2,del3))
        sp(at(t0, t2))
        sp(agf(nufu))
        sp(al1[7:9].animate.set_opacity(0.3))
        sp(nufu.animate.shift(1.3*UP))
        sp(afo(al1[3:7], al1[9:13], del1, del2), xt(nufu, nu, ['0.2', '1.3', 2, 3]))
        al1[3:7].set_opacity(0)
        al1[9:13].set_opacity(0)
        sp(al1[7:9].animate.set_opacity(1))
        sp(at(t0, t3))
        sp(at(nufu[0:2], x))
        sw()
        sp(adb(xtable))
        sp(afo(nut, acidt, baset, al1, nufu, t0))
        sw(0.5)
View Code

 s6

        xtable = xtf('取代')
        s1 = msm('s1')
        s2 = msm('s2')
        m1 = s1[0:4].move_to([-3,0,0])
        m2 = s1[4:6].move_to([3,0,0])
        m3 = s2[0:3]
        m4 = s2[3:6].move_to([3,0,0])
        xms(m3,0,m1,0)
        t1 = MarkupText('<span font="STZhongsong">醇羟基不是一个好的离去基团,因为</span>OH<sup><b>—</b></sup><span font="STZhongsong">是强碱</span>').to_edge(DOWN).scale(0.6)
        t2 = xn('也就是说,一般醇分子中的C—O键很难断裂')
        xf(t2, 'C—O').set_color(BLUE).set_sheen(0.3)
        t3 = xn('只有将羟基转变为弱碱性的基团,亲核取代反应才能发生')
        t1[18].shift(0.1*UP)
        t2[13].shift(0.02*UP)
        cross = msm('cross').scale(0.7).shift(0.4*LEFT).set_color(RED).set_sheen(0.3)
        m1.save_state()
        m2.save_state()
        


#         xc([m3])

        
        def playscene():
            sa(xtable) 
            sw(0.5)
            sp(adb(t1), adb(m1), adb(m2))
            sp(xt(m1,m3,[0,0,3,2]), act(m1[1:3], m4[0:2]), agf(m4[2]), acct(m2[0],m3[1]), agf(m2[1], reverse_rate_function = True), run_time=2)
            sc()
            sa(xtable,t1,m3,m4)
            m1.restore()
            m2.restore()
            sp(aw(cross))
            sw()
            sp(xt(m3,m1,[0,0,2,3]), acct(m4[0:2], m1[1:3]), agf(m4[2], reverse_rate_function = True), act(m3[1],m2[0]), agf(m2[1]), auw(cross), at(t1,t2), run_time=2)
            sp(VGroup(m1[0:2], m1[3]).animate.set_sheen(0.3), run_time = 0.5)
            sp(VGroup(m1[0:2], m1[3]).animate.set_color(BLUE))
            sw(1.5)
            sc()
            sa(m1,m2,xtable,t1)
            sp(at(t1,t3), Restore(m1))
            sw(2)
            sp(afo(m1,m2,t1))
            
        playscene()
View Code

废弃

#         xxp
        if type('xxp') == str:
    #         xxp transform
            def xt(a, b, c):
                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'Transform({u}, {v}),'
                        ag += item
                ag += ')'
                agg = eval(ag)
                return agg
    #         xxp color to hex
            def xc2h(c):
                return rgb_to_hex(color_to_rgb(c))
    #         xxp opacity scale
            def xos(inter, *args):
#             最好让透明度也一样
                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)
                if inter == 1:
                    for n in range(len(args)):
                        if n == 0:
                            premovescale(args[n], Text('H', font='Times New Roman', fill_opacity=0.5))
                        else:
                            premovescale(args[n], args[n-1])
                if inter == 2:
                    for n in range(len(args) - 1):
                        premovescale(args[n], args[n+1])
#             xxp color and opacity init
            def xcoi(*args):
                for a in args:
#                     先缩放再设置透明度(否则会消失不见)
                    a.set_opacity(1)
                    for i in a:
                        if xc2h(i.color) == '#ff0000':
                            i.set_color(RED).set_sheen(0.3)
                        elif xc2h(i.color) == '#ffff00':
                            i.set_color(GOLD).set_sheen(0.3)
                        elif xc2h(i.color) == '#00ff00':
                            i.set_color(GREEN).set_sheen(0.3)
                        elif xc2h(i.color) == '#00ffff':
                            i.set_color(TEAL).set_sheen(0.3)
                        elif xc2h(i.color) == '#0000ff':
                            i.set_color(BLUE).set_sheen(0.3)
                        elif xc2h(i.color) == '#ff00ff':
                            i.set_color(PINK).set_sheen(0.3)
    #         xxp color transform
            def xct(u, v):
                def normalxct(u, v):
                    a = u.copy()
                    b = v.copy()
                    def discard(co):
                        co.discard('#ffffff')
                        co.discard('#ff0000')
                        co.discard('#ffff00')
                        co.discard('#00ff00')
                        co.discard('#00ffff')
                        co.discard('#ff00ff')
                        co.discard('#0000ff')
                    ag = 'AnimationGroup('
                    colorlist1 = set()
                    colorlist2 = set()
                    for i in a:
                        colorlist1.add(xc2h(i.color))
                    discard(colorlist1)
                    for j in b:
                        colorlist2.add(xc2h(j.color))
                    discard(colorlist2)
        #             共同颜色
                    colorlist = colorlist1.intersection(colorlist2)
                    for i in range(len(a)):
                        if xc2h(a[i].color) == WHITE:
                            ag += f'GrowFromCenter(a[{i}], reverse_rate_function = True), '
                    for j in range(len(b)):
                        if xc2h(b[j].color) not in colorlist:
                            b[j].set_color(BLUE)
                            ag += f'DrawBorderThenFill(b[{j}]), '
                    for c in colorlist:
                        x = 'VGroup('
                        y = 'VGroup('
                        for m in range(len(a)):
                            if xc2h(a[m].color) == c:
                                x += f'a[{m}], '
                                a[m].set_color(WHITE)
                        for n in range(len(b)):
                            if xc2h(b[n].color) == c:
                                y += f'b[{n}], '
                                b[n].set_color(WHITE)
                        x += ')'
                        y += ')'
                        ag += f'Transform({x}, {y}), '
                    ag += ')'
                    return eval(ag)
                if type(u) == list and type(v) == list:
#                     s = ''不可行
                    s = 'AnimationGroup('
                    for m in range(len(u)):
                        for n in range(len(v)):
                            s += f'normalxct(u[{m}], v[{n}]), '
                    s += ')'
                    return eval(s)
                if type(v) == list:
#                     s = ''不可行
                    s = 'AnimationGroup('
                    for l in range(len(v)):
                        s += f'normalxct(u, v[{l}]), '
                    s += ')'
                    return eval(s)
                elif type(u) == list:
#                     s = ''不可行
                    s = 'AnimationGroup('
                    for l in range(len(v)):
                        s += f'normalxct(u[{l}], v), '
                    s += ')'
                    return eval(s)
                else:
                    return normalxct(u, v)
    #         xxp check
            def xc(*args):
                self.camera.background_color = WHITE
                for svg in args:
                    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)
                    for i in range(51):
    #                 eval()无法使用,显示undefined
                        if mobjectdict[f'v{i}'] in self.mobjects:
                            name = Text(f'm{i}').set(color = GREEN).move_to(mobjectdict[f'v{i}'].get_top())
                            self.add(name)
                    self.wait()
                self.clear()
    #         xxp check all
            def xca():
                self.camera.background_color = WHITE
                for svg in self.mobjects:
                    n = 0
                    for i in svg:
                        num = Integer(number=n, stroke_width=2).set(color = BLACK).move_to(i)
                        n += 1
                        self.add(num)
                    svg.set(color = RED)
                for i in range(51):
    #                 eval()无法使用,显示undefined
                    if mobjectdict[f'v{i}'] in self.mobjects:
                        name = Text(f'm{i}').set(color = GREEN).move_to(mobjectdict[f'v{i}'].get_top())
                        self.add(name)
                for i in range(21):
    #                 eval()无法使用,显示undefined
                    if narratordict[f'v{i}'] in self.mobjects:
                        name = Text(f't{i}').set(color = GREEN).move_to(narratordict[f'v{i}'].get_top())
                        self.add(name)
                self.wait(2)
                self.clear()
    #         xxp align
            def xa(b, a):
                l = len(a)
                for i in range(0, l):
                    b[i].set_x(a[i].get_x())
                    if i > 0:
                        b[i].set_y(b[0].get_y())
    #         xxp find
            def xf(a, b):
                n1 = str.find(a.text, b)
                n2 = n1 + len(b)
                return a[n1:n2]
    #         xxp narrator
            def xn(a):
                text = Text(a, font='STZhongsong').to_edge(DOWN).scale(0.6)
                return text
    #         xxp upnarrator
            def xun(a):
                text = Text(a, font='STZhongsong').to_edge(UP).scale(0.8)
                return text
    #         xxp para
            def xp(x, y):
                a = Text(y, font="STZhongsong").to_edge(DOWN).scale(0.6)
                b = Text(x, font="STZhongsong").to_edge(1.8*DOWN).scale(0.6)
                return VGroup(a, b)
    #         xxp scale
            def xs(a, n1, b, n2):
                scale = b[n2].width/a[n1].width
                a.scale(scale)
    #         xxp move and scale
            def xms(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)
    #         xxp choose color
            def xcc(a, b):
                for i in a:
                    if rgb_to_hex(color_to_rgb(i.color)) == b:
                        return i
    #         xxp narrator wait
            def xnw(a):
                self.wait(0.1*len(a))
    #         xxp text flower
            def xtf(a):
                at = Text(a, font = 'STZhongsong',stroke_width=2).set_color(color = ['#f3e9e0', '#fea8a9'])
    #             at[0].set_color(color = ['#f3e9e0', '#fea8a9'])
    #             at[1].set_color(color = ['#f3e9e0', '#fea8a9'])
                fl = msm('icon')[8].rotate(PI/2).set_color(color = ['#fea8a9', '#f3e9e0']).scale(1.5).set(width = at.width)
                at.next_to(fl, RIGHT)
                vg = VGroup(fl, at)
                vg.set(width = 1.8).to_corner(UL)
                return vg
    #         xxp text flower2
            def xtf2(a):
                at = Text(a, font = 'STZhongsong',stroke_width=2).set_color(color = ['#f3e9e0', '#b1d85c'])
    #             at[0].set_color(color = ['#f3e9e0', '#fea8a9'])
    #             at[1].set_color(color = ['#f3e9e0', '#fea8a9'])
                fl = msm('icon')[8].rotate(PI/2).set_color(color = ['#b1d85c', '#f3e9e0']).scale(1.5).set(width = at.width)
                at.next_to(fl, RIGHT)
                vg = VGroup(fl, at)
                vg.set(width = 1.8).to_corner(UL).shift(2*RIGHT)
                return vg
    #         xxp color move and scale
            def xcms(a, b):
                x = VGroup()
                y = VGroup()
                for i in a:
                    if rgb_to_hex(color_to_rgb(i.color)) == '#000000':
                        x.add(i)
                for j in b:
                    if rgb_to_hex(color_to_rgb(j.color)) == '#000000':
                        y.add(j)
                scale = y.width/x.width
                vect = y.get_center() - x.get_center()
                a.shift(vect)
                a.scale(scale)
    #         xxp single scale
            def xss(a, n):
                x = Text('C', font="Times New Roman")
                y = a[n]
                scale = x.width/y.width
                a.scale(scale)
    #         xxp pre postion
            def xpp(a, pos):
                d1 = Dot().to_corner(UL)
                d2 = Dot().to_edge(UP)
                d3 = Dot().to_corner(UR)
                d4 = Dot().to_edge(LEFT)
                d5 = Dot()
                d6 = Dot().to_edge(RIGHT)
                d7 = Dot().to_corner(DL)
                d8 = Dot().to_edge(DOWN)
                d9 = Dot().to_corner(DR)
                if pos == 'ul':
                    a.move_to((d1.get_center() + d5.get_center())/2)
                elif pos == 'u':
                    a.move_to((d2.get_center() + d5.get_center())/2)
                elif pos == 'ur':
                    a.move_to((d3.get_center() + d5.get_center())/2)
                elif pos == 'l':
                    a.move_to((d4.get_center() + d5.get_center())/2)
                elif pos == 'o':
                    a.move_to(d5.get_center())
                elif pos == 'r':
                    a.move_to((d6.get_center() + d5.get_center())/2)
                elif pos == 'dl':
                    a.move_to((d7.get_center() + d5.get_center())/2)
                elif pos == 'd':
                    a.move_to((d8.get_center() + d5.get_center())/2)
                elif pos == 'dr':
                    a.move_to((d9.get_center() + d5.get_center())/2)
#             xxp arrange and align
            def xaa(mobs, b, d):
                vg = VGroup()
                for m in mobs:
                    vg.add(m)
                vg.arrange(buff=b)
                if d == 'u':
                    dire = UP
                elif d == 'd':
                    dire = DOWN
                for i in mobs:
                    if i != mobs[0]:
                        i.align_to(mobs[0], dire)
#             xxp add other
            def xao(*args):
                if len(args) == 2:
                    sa(args[0].to_corner(UR), args[1].to_corner(DL))
                if len(args) == 3:
                    sa(args[0].to_corner(UR), args[1].to_corner(DL), args[2].to_corner(DR))
#             xxp grow from center
            def xgf(a, li):
                avg = 'AnimationGroup('
                def pregrow(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
                for j in li:
                    partani = pregrow('a', j)
                    avg += f'GrowFromCenter({partani}), '
                avg += ')'
                return eval(avg)
#             xxp reverse grow from center
            def xrgf(a, li):
                avg = 'AnimationGroup('
                def pregrow(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
                for j in li:
                    partani = pregrow('a', j)
                    avg += f'GrowFromCenter({partani}, reverse_rate_function = True), '
                avg += ')'
                return eval(avg)
#             xxp sheen and color
            def xsc(a, b):
                self.play(a.animate.set_sheen(0.3), run_time=0.5)
                self.play(a.animate.set_color(b))
#             xxp place in line
            def xpl(*args):
                vg = VGroup()
                frame = FullScreenRectangle()
                wid = frame.width
                for i in args:
                    vg.add(i.copy())
                    wid -= i.width
                mybuff = wid/(len(args)+1)
                vg.arrange(buff=mybuff)
                for j in range(len(args)):
                    args[j].match_x(vg[j])
                
#         manim CE
        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 Transform(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 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 Restore()
            def ar(a, *args, **kwargs):
                return Restore(a, *args, **kwargs)
    #         Animation DrawBorderThenFill()
            def adb(a, *args, **kwargs):
                return DrawBorderThenFill(a, *args, **kwargs)
    #         Animation GrowFromCenter()
            def agf(a, *args, **kwargs):
                return GrowFromCenter(a, *args, **kwargs)
    #         Animation MoveAlongPath()
            def ama(a, b, *args, **kwargs):
                return MoveAlongPath(a, b, *args, **kwargs)

    #         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 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(), *args, **kwargs)
#         other function
        if type('other function') == str:
    #         refresh
            def refresh(*args, **kwargs):
                sc()
                sa(*args, **kwargs)
                sw()
    #         color refresh
            def crefresh(*args, **kwargs):
                sc()
                for i in args:
                    xcoi(i)
                sa(*args, **kwargs)
View Code
            self.next_section()
            sa(m0)
            sw(0.5)
            sp(adb(t0), adb(m1))
            sp(adb(m2), adb(m3))
            sp(at(t0,t1))
            sw(1.5)
            sp(afo(t0))
            sp(xt(m2,m6,[0,0,1,1,2,2,3,3,4,4,5,5]), agf(m6[6]),agf(m6[8:10]), agf(m6[10:12]), xt(m3,m6,[0,7]), agf(m5[1]), xt(m3,m5,[1,0]), afi(t2))
            refresh(m0,m1,m6,m5,t2)
            sp(m6[4:].animate.set_sheen(0.3),run_time=0.5)
            sp(m6[4:].animate.set_color(BLUE))
            sp(xt(m6,m4,[0,1,1,2,2,3,3,4,4,5,5,6,7,7,'10.12',0]),agf(m6[6],reverse_rate_function = True),agf(m6[8:10], reverse_rate_function = True))
            refresh(m0,m1,m4,m5,t2)
            
            sp(ama(m5,m7), m4.animate.move_to(ORIGIN))
            xms(m8,0,m4,2)
            xms(m9,1,m4,2)
            xs(m10,0,m4,3)
            m10.shift(2*RIGHT)
            sp(xt(m4,m8,[1,1,2,0,3,15,4,17,5,8,6,9,7,10]),xgf(m8,[2,16,18,'4.8','11.15']),xt(m5,m8,[0,3]),agf(m5[1], reverse_rate_function = True),xrgf(m4,[0]))
            refresh(m0,m1,m8,t2)
            sp(xt(m8,m9,[3,0,'4.8',5,0,1,1,4,15,2,17,3]), xt(m8,m10,[9,0,10,1,8,2]),xrgf(m8,[2,16,18,'4.8','11.15']))
            refresh(m9,m10,m0,m1,t2)
View Code

 剩余部分

#         xxp
        if type('xxp') == str:
    #         xxp transform
            def xt(names, *args):
                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'Transform({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
    #         xxp transform 2
            def xt2(a, b, c):
                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'Transform({u}, {v}),'
                        ag += item
                ag += ')'
                agg = eval(ag)
                return agg
    #         xxp color to hex
            def xc2h(c):
                return rgb_to_hex(color_to_rgb(c))
    #         xxp opacity scale
            def xos(inter, *args):
#             最好让透明度也一样
                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)
                if inter == 1:
                    for n in range(len(args)):
                        if n == 0:
                            premovescale(args[n], Text('H', font='Times New Roman', fill_opacity=0.5).scale(1.4))
                        else:
                            premovescale(args[n], args[n-1])
                if inter == 2:
                    for n in range(len(args) - 1):
                        premovescale(args[n+1], args[n])
#             xxp color and opacity init
            def xcoi(*args):
                for a in args:
#                     先缩放再设置透明度(否则会消失不见)
                    a.set_opacity(1)
                    for i in a:
                        if xc2h(i.color) == '#ff0000':
                            i.set_color(RED).set_sheen(0.3)
                        elif xc2h(i.color) == '#ffff00':
                            i.set_color(GOLD).set_sheen(0.3)
                        elif xc2h(i.color) == '#00ff00':
                            i.set_color(GREEN).set_sheen(0.3)
                        elif xc2h(i.color) == '#00ffff':
                            i.set_color(TEAL).set_sheen(0.3)
                        elif xc2h(i.color) == '#0000ff':
                            i.set_color(BLUE).set_sheen(0.3)
                        elif xc2h(i.color) == '#ff00ff':
                            i.set_color(PINK).set_sheen(0.3)
    #         xxp check
            def xc(*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()
    #         xxp align
            def xa(b, a):
                l = len(a)
                for i in range(0, l):
                    b[i].set_x(a[i].get_x())
                    if i > 0:
                        b[i].set_y(b[0].get_y())
    #         xxp find
            def xf(a, b):
                n1 = str.find(a.text, b)
                n2 = n1 + len(b)
                return a[n1:n2]
    #         xxp narrator
            def xn(a):
                text = Text(a, font='STZhongsong').to_edge(DOWN).scale(0.6)
                return text
    #         xxp upnarrator
            def xun(a):
                text = Text(a, font='STZhongsong').to_edge(UP).scale(0.8)
                return text
    #         xxp para
            def xp(x, y):
                a = Text(y, font="STZhongsong").to_edge(DOWN).scale(0.6)
                b = Text(x, font="STZhongsong").to_edge(1.8*DOWN).scale(0.6)
                return VGroup(a, b)
    #         xxp scale
            def xs(a, n1, b, n2):
                scale = b[n2].width/a[n1].width
                a.scale(scale)
    #         xxp move and scale
            def xms(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)
    #         xxp choose color
            def xcc(a, b):
                for i in a:
                    if rgb_to_hex(color_to_rgb(i.color)) == b:
                        return i
    #         xxp narrator wait
            def xnw(a):
                self.wait(0.1*len(a))
    #         xxp text flower
            def xtf(a):
                at = Text(a, font = 'STZhongsong',stroke_width=2).set_color(color = ['#f3e9e0', '#fea8a9'])
    #             at[0].set_color(color = ['#f3e9e0', '#fea8a9'])
    #             at[1].set_color(color = ['#f3e9e0', '#fea8a9'])
                fl = msm('icon')[8].rotate(PI/2).set_color(color = ['#fea8a9', '#f3e9e0']).scale(1.5).set(width = at.width)
                at.next_to(fl, RIGHT)
                vg = VGroup(fl, at)
                vg.set(width = 1.8).to_corner(UL)
                return vg
    #         xxp text flower2
            def xtf2(judge, a):
                if judge == 1:
                    at = Text(a, font = 'STZhongsong',stroke_width=2).set_color(color = ['#f3e9e0', '#b1d85c'])
                elif judge == 2:
#                 一般不是中文
                    at = MarkupText(a, stroke_width=2).set_color(color = ['#f3e9e0', '#b1d85c'])
    #             at[0].set_color(color = ['#f3e9e0', '#fea8a9'])
    #             at[1].set_color(color = ['#f3e9e0', '#fea8a9'])
                fl = msm('icon')[8].rotate(PI/2).set_color(color = ['#b1d85c', '#f3e9e0']).scale(1.5).set(width = at.width)
                at.next_to(fl, RIGHT)
                vg = VGroup(fl, at)
                vg.set(width = 1.8).to_corner(UL).shift(2*RIGHT)
                return vg
    #         xxp color move and scale
            def xcms(a, b):
                x = VGroup()
                y = VGroup()
                for i in a:
                    if rgb_to_hex(color_to_rgb(i.color)) == '#000000':
                        x.add(i)
                for j in b:
                    if rgb_to_hex(color_to_rgb(j.color)) == '#000000':
                        y.add(j)
                scale = y.width/x.width
                vect = y.get_center() - x.get_center()
                a.shift(vect)
                a.scale(scale)
    #         xxp single scale
            def xss(a, n):
                x = Text('C', font="Times New Roman")
                y = a[n]
                scale = x.width/y.width
                a.scale(scale)
    #         xxp pre postion
            def xpp(a, pos):
                d1 = Dot().to_corner(UL)
                d2 = Dot().to_edge(UP)
                d3 = Dot().to_corner(UR)
                d4 = Dot().to_edge(LEFT)
                d5 = Dot()
                d6 = Dot().to_edge(RIGHT)
                d7 = Dot().to_corner(DL)
                d8 = Dot().to_edge(DOWN)
                d9 = Dot().to_corner(DR)
                if pos == 'ul':
                    a.move_to((d1.get_center() + d5.get_center())/2)
                elif pos == 'u':
                    a.move_to((d2.get_center() + d5.get_center())/2)
                elif pos == 'ur':
                    a.move_to((d3.get_center() + d5.get_center())/2)
                elif pos == 'l':
                    a.move_to((d4.get_center() + d5.get_center())/2)
                elif pos == 'o':
                    a.move_to(d5.get_center())
                elif pos == 'r':
                    a.move_to((d6.get_center() + d5.get_center())/2)
                elif pos == 'dl':
                    a.move_to((d7.get_center() + d5.get_center())/2)
                elif pos == 'd':
                    a.move_to((d8.get_center() + d5.get_center())/2)
                elif pos == 'dr':
                    a.move_to((d9.get_center() + d5.get_center())/2)
#             xxp arrange and align
            def xaa(mobs, b, d):
                vg = VGroup()
                for m in mobs:
                    vg.add(m)
                vg.arrange(buff=b)
                if d == 'u':
                    dire = UP
                elif d == 'd':
                    dire = DOWN
                for i in mobs:
                    if i != mobs[0]:
                        i.align_to(mobs[0], dire)
#             xxp add other
            def xao(*args):
                if len(args) == 2:
                    sa(args[0].to_corner(UR), args[1].to_corner(DL))
                if len(args) == 3:
                    sa(args[0].to_corner(UR), args[1].to_corner(DL), args[2].to_corner(DR))
#             xxp grow from center
            def xgf(a, li):
                avg = 'AnimationGroup('
                def pregrow(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
                for j in li:
                    partani = pregrow('a', j)
                    avg += f'GrowFromCenter({partani}), '
                avg += ')'
                return eval(avg)
#             xxp reverse grow from center
            def xrgf(a, li):
                avg = 'AnimationGroup('
                def pregrow(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
                for j in li:
                    partani = pregrow('a', j)
                    avg += f'GrowFromCenter({partani}, reverse_rate_function = True), '
                avg += ')'
                return eval(avg)
#             xxp color and sheen static
            def xcss(a, b):
                a.set_sheen(0.3).set_color(b)
#             xxp place in line
            def xpl(*args):
                vg = VGroup()
                frame = FullScreenRectangle()
                wid = frame.width
                for i in args:
                    vg.add(i.copy())
                    wid -= i.width
                mybuff = wid/(len(args)+1)
                vg.arrange(buff=mybuff)
                for j in range(len(args)):
                    args[j].match_x(vg[j])
#             xxp place in grid
            def xpg(*args):
                n = 0
                full = FullScreenRectangle()
                li = ['ul','ur','dl','dr']
                for a in args:
                    if a.width > a.height:
                        a.set(width = full.width/3)
                        xpp(a,li[n])
                    else:
                        a.set(height = full.height/3)
                        xpp(a,li[n])
                    n += 1             
#             xxp color 1
            def xc1(*args):
                for a in args:
                    a.save_state()
                    a.set_color(WHITE).set_sheen(0)
#             xxp color 2
            def xc2(*args):
                li = []
                for a in args:
                    li.append(Restore(a))
                return self.play(*li)
#             xxp color 3
            def xc3(*args):
                li = []
                for a in args:
                    li.append(a.animate.set_color(WHITE))
                return self.play(*li)
#             xxp animations list
            def xal(t,*argss):
                args = []
                for i in argss:
                    args.append(i)
#                 不是args = atgs.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         
#         manim CE
        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 Transform(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 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 Restore()
            def ar(a, *args, **kwargs):
                return Restore(a, *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 agf(a, *args, **kwargs):
                return GrowFromCenter(a, *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 ast(a, *args, **kwargs):
                return ShrinkToCenter(a, *args, **kwargs)
#             Animation Circumscribe
            def ac(a, *args, **kwargs):
                return Circumscribe(a, *args, **kwargs)
        
#             Group sheen
            def gs(*args):
                li = []
                for i in args:
                    li.append(i.animate.set_sheen(0.3))
                return self.play(*li, run_time=0.5)
#             Group color
            def gc(*args):
                li = []
                for i in range(len(args)):
                    if i % 2 == 0:
                        li.append(args[i].animate.set_color(args[i+1]))
                return self.play(*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 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(), *args, **kwargs)
#         other function
        if type('other function') == str:
    #         refresh
            def refresh(*args, **kwargs):
                sc()
                sa(*args, **kwargs)
    #         color refresh
            def crefresh(*args, **kwargs):
                sc()
                for i in args:
                    xcoi(i)
                sa(*args, **kwargs)
#         playscene
View Code
        def playscene1():
#             self.next_section(skip_animations=True)
            t1 = xn("氢卤酸可以和醇反应生成卤代烷")
            t2 = MarkupText(r'<span font="STZhongsong">氢卤酸与大多数一级醇按</span>S<sub>N</sub>2<span font="STZhongsong">机理进行反应</span>').to_edge(DOWN).scale(0.6);t2[0:3].set_sheen(0.3).set_color(RED);t2[7:10].set_sheen(0.3).set_color(BLUE)
            t3 = xn('醇羟基不是一个好的离去基团,首先进行质子化')
            t4 = MarkupText(r'<span font="STZhongsong">离去基团由</span>OH-<span font="STZhongsong">变为</span>H<sub>2</sub>O').to_edge(DOWN).scale(0.6);t4[7].shift(0.15*UP);xcss(t4[-3:], BLUE)
            t5 = MarkupText(r'H<sub>2</sub>O<span font="STZhongsong">为弱碱,是一个好的离去基团</span>').to_edge(DOWN).scale(0.6);xcss(t5[0:3], BLUE)
            tf1 = xtf('取代');tf2 = xtf2('HX')
            k1 = msm('k1');k2 = msm('k2');k3 = msm('k3');k4 = msm('k4');k5 = msm('k5');k6 = msm('k6');k7 = msm('k7');k8 = msm('k8')
            si = [tf1,tf2];
            xos(1,k1,k2);xpl(k2,k1);xos(2,k1,k3,k5,k6,k7);xos(2,k2,k4);xms(k8,0,k2,0);k8.shift(2*DR + 2*RIGHT)
            xcoi(k1,k2,k3,k4,k5,k6,k7,k8)
                
            sa(tf1);sw(0.5);sp(adb(t1),adb(tf2));sp(adb(k1),adb(k2));sp(at(t1,t2));gc(k1,BLUE,k2,RED);gs(k1,k2);sw()
            sp(xt([k1,k2,k4,k5],[1,3,[0,7]],[1,2,[1,0]],[0,3,['0.6','0.6']]),at(t1,t3));sw(0.5);refresh(si,k5,k4,t1)
            sp(xt([k5,k3],[0,1,['0.6','1.7',10,0,7,7]]));refresh(si,t1,k3,k4);sp(at(t1,t4));sw(2)
            sp(xt([k3,k4,k6],[0,2,[1,1,2,0,3,9,4,11,'5.8','5.8']],[1,2,[0,3,1,4]]));sp(at(t1,t5));sw();refresh(si,k6,t1)
            sp(xt([k6,k7,k8],[0,1,[3,0,4,5,0,1,9,2,11,3,1,4]],[0,2,[6,0,7,1,5,2]]));sw();refresh(si,t1,k7,k8)
            sp(ast(k7),ast(k8),afo(t1))
            sw(0.5)
        def playscene2():
            tf1 = xtf('取代');tf2 = xtf2('HX')
            b1 = msm('b1');b2 = msm('b2');b3 = msm('b3');b4 = msm('b4');b5 = msm('b5');b6 = msm('b6');b7 = msm('b7');b8 = msm('b8');
            xos(1,b1,b2);xpl(b1,b2);xos(2,b1,b3);xos(2,b2,b4,b5,b6,b8);xms(b7,0,b1,0);b7.shift(2*DR + 3*RIGHT)
            xcoi(b1,b2,b3,b4,b5,b6,b7,b8)
            t1 = MarkupText(r'<span font="STZhongsong">氢卤酸与大多数二级、三级醇按</span>S<sub>N</sub>1<span font="STZhongsong">机理进行反应</span>').to_edge(DOWN).scale(0.6);xcss(t1[0:3], RED);xcss(t1[7:13], GREEN)
            t2 = xn('同样地,质子化的羟基以水的形式离去');xcss(t2[11], BLUE)
            
            
            sa(tf1,tf2);sw(0.5);sp(adb(t1));sp(adb(b1),adb(b2));gc(b1,RED,b2,GREEN);gs(b1,b2);sw()
            sp(xt([b1,b2,b3,b4],[0,2,[1,0]],[0,3,[0,4]],[1,3,['0.3','0.3']]), at(t1,t2));refresh(tf1,tf2,t1,b3,b4);sw()
            sp(xt([b4,b5],[0,1,['0.3','0.3',4,3,7,4]]));refresh(tf1,tf2,t1,b3,b5);sw()
            sp(xt([b5,b6,b7],[0,1,[0,0]],[0,2,[2,0,3,1,1,2]]));refresh(tf1,tf2,t1,b3,b6,b7);sw()
            sp(xt([b6,b3,b8],[0,2,[0,0]],[1,2,[0,1]]));refresh(tf1,tf2,t1,b8,b7);sw()
            sp(ast(b7),ast(b8),afo(t1))
            sp(adbr(tf2));sw(0.5)
        def playscene3():
            tf1 = xtf('取代');tf2 = xtf2(2,'PX<sub>3</sub>')
            t1 = xn("醇和卤化磷反应也能生成卤代烷")
            t2 = MarkupText(r'<span font="STZhongsong">大多数一级醇按</span>S<sub>N</sub>2<span font="STZhongsong">机理进行反应</span>').to_edge(DOWN).scale(0.6)
            t3 = xn('类似地,先将羟基转变为一个好的离去基团')
            t4 = MarkupText(r'<span font="STZhongsong">二级、三级醇主要按</span>S<sub>N</sub>1<span font="STZhongsong">机理进行反应</span>').to_edge(DOWN).scale(0.6)
            t5 = MarkupText(r'PX<sub>5</sub><span font="STZhongsong">与醇也会发生类似的反应</span>').to_edge(DOWN).scale(0.6).move_to(t4)

            c1=msm("c1");c2=msm("c2");c3=msm("c3");c4=msm("c4");c5=msm("c5");c6=msm("c6");c7=msm("c7");c8=msm("c8");c9=msm("c9")
            xos(1,c1,c2);xpl(c1,c2);c1.shift(LEFT);xos(2,c1,c3,c5,c7,c8);xos(2,c2,c9);xms(c6,0,c2,1);c6.shift(0.5*RIGHT);xms(c4,0,c2,0);c4[10:13].set_sheen(0.3).set_color(BLUE).set_opacity(0.8)
            xcoi(c1,c2,c3,c4,c5,c6,c7,c8,c9)
            
            
            sa(tf1);sw(0.5);sp(adb(t1),adb(tf2));sp(adb(c1),adb(c2));sp(at(t1,t2))
            sp(xt([c1,c2,c3,c4],[0,2,['0.8','0.8']],[1,3,['0.3','0.3',3,['4.6','7.9']]]));sw();refresh(tf1,tf2,t1,c3,c4);sp(at(t1,t3));sw()
            sp(xt([c3,c4,c5,c6],[0,2,[0,13,1,11,2,12,3,0,4,15,5,17,8,2,6,1,7,8,'9.11',7]],[1,2,[0,3,'7.9','4.6','4.6',6]],[1,3,['1.3','0.2',3,2]]), run_time=2);sw();refresh(tf1,tf2,t1,c5,c6)
            sp(xt([c5,c6,c7],[1,2,['0.2','9.11',2,11]],[0,2,[0,0,15,7,16,8,17,5,18,6,14,4,13,1,11,2,12,3,2,13,1,12,'3.11','14.22']]));sw();refresh(tf1,tf2,t1,c7);sp(afo(t1))
            sp(xt([c7,c8,c9],[0,1,['9.11','0.2',0,2,5,3,7,4,'1.4','5.8']],[0,2,['14.18','2.6',19,0,12,1]]), run_time=2);sw();refresh(tf1,tf2,c8,c9)
            sp(adb(t4));sw();sp(at(t4,t5));sw()
            sp(ast(c8),ast(c9),afo(t4))
            sp(adbr(tf2))
            sw(0.5)
        def playscene4():
            tf1 = xtf('取代');tf2 = xtf2(2,'SOCl<sub>2</sub>')
            t1 = xn('氯化亚砜常用来制备氯代烃')
            t2 = xn('反应机理如下:')
            t3 = xn('最后得到构型保持的产物')
            t4 = MarkupText('<span font="STZhongsong">这种取代犹如在分子内进行,所以叫做分子内亲核取代(用</span>S<sub>Ni</sub><span font="STZhongsong">表示)</span>').to_edge(DOWN).scale(0.6)
            u1 = xun('氯代亚硫酸酯')
            u2 = xun('紧密离子对')
            v1=msm("v1");v2=msm("v2");v3=msm("v3");v4=msm("v4");v5=msm("v5");v6=msm("v6");v7=msm("v7");v8=msm("v8");v80=msm("v80");v9=msm("v9");v10=msm("v10");v11=msm("v11");v12=msm("v12");v13=msm('v13')
            xos(1,v1,v2);xpl(v1,v2);v2.shift(RIGHT);xos(2,v1,v3,v9,v11);xos(2,v2,v4,v5,v7,v8,v10,v12,v13);xs(v6,0,v5,13);v6.to_edge(UP);xcss(v12[5],RED);xcss(v11[10],BLUE);xcss(v10[9],BLUE);xcss(v8[14],BLUE);xcss(v80[2],RED);xcss(v5[4],BLUE);xcss(v5[23],RED);xs(v80,0,v7,14);v80.to_edge(UP);v9.shift(RIGHT);v11.shift(RIGHT)
            xcoi(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13)

            sa(tf1)
            sw(0.5)
            sp(adb(t1),adb(tf2));sp(adb(v1),adb(v2));sw()
            sp(xt([v1,v2,v3,v4],[0,2,[0,[0,5,7,10],1,1,2,3]],[1,3,[0,0,1,1,'2.4','4.6',4,'7.9']]),at(t1,t2));refresh(tf1,tf2,t1,v3,v4);gc(v3[12:14],BLUE,v4[3],RED)
            sp(xt([v3,v4,v5],[0,2,['0.3','0.3','5.12','5.12','12.14',4,4,14,3,13]],[1,2,[0,3,2,16,1,15,3,23,'4.6','17.19',6,19,9,22,'7.9','20.22']]));refresh(tf1,tf2,t1,v5);gc(v5[4],WHITE,v5[23],WHITE)
            sp(at(v5[13],v6[0]),agf(v6[1]),ast(v5[12]),ast(v5[14]));refresh(tf1,tf2,t1,v6,v7);sp(afo(v6));gc(v7[19],RED,v7[20],BLUE)
            sp(at(v7[16],v8[17]),at(v7[14:16],v8[15:17]),at(v7[13],v8[13]),at(v7[20],v8[14]),at(v7[19],v80[2]),at(v7[17:19],v80[0:2]));refresh(tf1,tf2,t1,v8,v80);gc(v8[14],WHITE,v80[2],WHITE);sp(afo(v80));sp(adb(u1));gc(v8[2],BLUE)
            sp(xt([v8,v9,v10],[0,1,[0,0,5,1,6,2,10,6,11,7,7,3,8,4,9,5]],[0,2,[2,9,1,7,4,8,3,0,13,2,14,3,12,1,17,6,'15.17','4.6']]),at(v8[4],v8[4]));sp(at(u1,u2));refresh(tf1,tf2,t1,v9,v10,u1);gc(v10[9],WHITE);gc(v10[6],BLUE,v10[9],RED);sp(afo(u1))
            sp(xt([v9,v10,v11,v12],[0,2,['0.8','0.8']],[1,2,[6,10,'4.6','8.10']],[1,3,['0.4','0.4',7,4,8,6,9,5]]));refresh(tf1,tf2,t1,v11,v12);gc(v11[10],WHITE,v12[5],WHITE)
            sp(xt([v12,v13],[0,1,[0,0,4,1,1,2]]));refresh(tf1,tf2,t1,v11,v13)
            sp(at(t1,t3));sw(1.5);sp(at(t1,t4));sw(2.5);sp(ast(v11),ast(v13),afo(t1));sp(adbr(tf2))
            sw(0.5)
        def playscene5():
            t1 = xn('由于羟基具有吸电子诱导效应,醇的β-H会增加一些活性');xcss(t1[16:19],RED)
            t2 = xn('同时碳氧键是极性共价键,断裂后可以发生消除反应');xcss(t2[2:5],GREEN)
            tf1 = xtf('酸性').move_to([-5.4,2,0]).scale(1.3);tf2 = xtf('碱性').move_to([-5.4,0,0]).scale(1.3);tf3 = xtf('亲核性').move_to([-5.4,-2,0]).scale(1.3);tf4 = xtf('取代');tf5 = xtf('消除')
            al1 = msm('general');al20 = msm('general2').scale(2);xms(al1,0,al20,0)
            o0=msm('o0');o01=msm('o01');o02=msm('o02');
            xcoi(o0,o01,o02);o0.match_width(al1);xms(o01,0,o0,1);xs(o02,0,o0,12);o02.to_edge(UP);xc1(o0)
            
            
            sa(tf4);sw(0.5);
            sp(afi(tf1),afi(tf2),afi(tf3),afi(al1));sp(tf4.animate.move_to([5.4,2,0]).scale(1.3))
            sp(xt([al1,o0],[0,1,[0,'0.2',2,4,1,3,7,10,8,11,4,9,3,8,'9.13','14.18',6,13,5,12]]));refresh(o0,tf1,tf2,tf3,tf4);sp(adb(t1));gc(o0[6],RED);gs(o0[6]);
            sp(Rotate(o0[6],about_point=o0[5].get_center(),angle=-20*DEGREES));sp(Rotate(o0[6],about_point=o0[5].get_center(),angle=20*DEGREES))
            sp(at(t1,t2));gc(o0[9],GREEN);gs(o0[9]);sw(2);sp(afo(t1));xc2(o0);sw()
            sp(xt([o0,o01,o02],[0,1,[0,4,2,5,5,6,1,0,7,2,4,3,3,1,10,8,11,7]],[0,2,[6,0,12,1,8,2]]));sw()
            sp(adb(tf5));sp(afo(o0,tf1,tf2,tf3,tf4))
            sw(0.5)
        def playscene6():
            tf1 = xtf('消除')
            t1 = xn('醇的消除反应均按E1机理进行,且需要在酸的催化下进行')
            t2 = MarkupText('<span font="STZhongsong">酸可以将醇羟基质子化,将其转化成较好的离去基团</span>H<sub>2</sub>O').to_edge(DOWN).scale(0.6)
            x1=msm("x1");x2=msm("x2");x3=msm("x3");x4=msm("x4");x5=msm("x5");x6=msm("x6")
            xos(1,x1,x2);x1.move_to(ORIGIN);x2.shift(3*UP);xos(2,x1,x3,x4,x6);xs(x5,0,x2,0);x5.shift(3*UP)
            xcoi(x1,x2,x3,x4,x5,x6);xc1(x4);x2.save_state()
            
            sa(tf1);sw(0.5);sp(adb(t1));sp(adb(x1),adb(x2));sw();
            sp(at(x2[0],x3[11]),at(x2[1],x3[13]));refresh(tf1,t1,x3);sp(at(t1,t2));sw()
            sp(xt2(x3,x5,[10,0,11,1,9,2]),agf(x4[9]),ast(x3[12]),ast(x3[13]));refresh(tf1,t1,x5,x4);sw();sp(afo(x5),afo(t1));xc2(x4);x2.restore()
            sp(xt([x4,x6,x2],[0,1,[5,5,1,6,0,0,7,3,3,2,2,1,8,4,4,7]],[0,2,[6,0]]));sw();sp(afo(x4,x2[1]))
            sw(0.5)
        def playscene7():
            t1 = xn('为什么醇脱水不按照E2机理进行呢?')
            t2 = xn('在E2消除中,反应的动力为碱主动进攻β-H');xcss(t2[13],RED);xcss(t2[18:],BLUE)
            t3 = xn('进攻试剂的碱性越强,越利于E2反应')
            t4 = xn('但是醇的脱水是在酸催化下进行的,强酸溶液中不可能存在强碱')
            t5 = xn('所以不具备进行E2反应的条件')
            u1 = xun('反式共平面')
            l1=msm("l1");l2=msm("l2");l3=msm("l3");l4=msm("l4");tf1=xtf('消除');cross=msm('cross2')
            xos(1,l1,l3);l3.shift(3*UP);l1.move_to(ORIGIN);xos(2,l1,l2,l4);xms(cross,2,l4,13);cross.scale(1.7);xcss(cross,GOLD);l2.save_state()
            xcoi(l1,l2,l3,l4);xc1(l2)
            
            sa(tf1);sw(0.5);sp(adb(t1));sp(adb(l1))
            sp(xt([l1,l2],[0,1,[4,6,5,7,0,0,1,10,6,9,3,2,2,1,11,11,7,8,10,5,'8.10','3.5']]));refresh(tf1,t1,l2);sp(afi(u1));sw();sp(afo(u1),at(t1,t2));xc2(l2);sp(agf(l3))
            sp(xt2(l3,l4,[0,13,1,14]),xt2(l2,l4,[7,8,5,6]),agf(l4[3]));refresh(tf1,t1,l4);sw();sp(at(t1,t3));sw(1.5);sp(at(t1,t4));sw();sp(aw(cross));sw();sp(afo(l4[13:15]),auw(cross));l2.restore()
            sp(at(t1,t5),xt2(l4,l2,[8,7,6,5]),ast(l4[3]));refresh(tf1,t1,l2);sw(1.5);sp(afo(t1,l2));sw(0.5)
        def playscene8():
            tf1 = xtf('酸性').move_to([-5.4,2,0]).scale(1.3);tf2 = xtf('碱性').move_to([-5.4,0,0]).scale(1.3);tf3 = xtf('亲核性').move_to([-5.4,-2,0]).scale(1.3);tf4 = xtf('取代').move_to([5.4,2,0]).scale(1.3);tf5 = xtf('消除');tf6 = xtf('氧化')
            al1 = msm('general');al20 = msm('general2').scale(2);xms(al1,0,al20,0)
            t1 = xn('由于醇羟基的影响,α-H比较活泼,可以被氧化');xcss(t1[9:12],RED)
            y0=msm('y0');xms(y0,0,al1,1)
            xcoi(y0)
            sa(tf5);sw(0.5)
            sp(afi(tf1,tf2,tf3,tf4,al1));sp(tf5.animate.move_to([5.4,0,0]).scale(1.3));sw()
            sp(xt2(al1,y0,[7,2,8,4]),agf(y0[1]),agf(y0[3]),adb(t1));sw();y0[1].save_state();y0[3].save_state()
            sp(Rotate(y0[1],about_point=y0[3].get_center(),angle=-20*DEGREES),Rotate(y0[3],about_point=y0[1].get_center(),angle=20*DEGREES))
            sp(ar(y0[1]),ar(y0[3]))
            sp(adb(tf6));sp(afo(al1,y0[1],y0[3],tf1,tf2,tf3,tf4,tf5,t1));sw(0.5)
        def playscene9():
            t1 = xn('一级醇被氧化,先生成醛,后者继续被氧化,最后生成羧酸');xcss(t1[0:3],BLUE);xcss(t1[10],GREEN);xcss(t1[24:],GOLD)
            t2 = xn('例如,下列氧化剂可以将一级醇氧化成羧酸');xcss(t2[11:14],BLUE);xcss(t2[17:],GOLD)
            t3 = xn('如果想把一级醇氧化控制在醛的阶段');xcss(t3[4:7],BLUE);xcss(t3[12],GREEN)
            t4 = xn('可以使用沙瑞特试剂和氯铬酸吡啶');xcss(t4[4:9],RED);xcss(t4[10:],BLUE)
            t5 = xn('并且这两种氧化剂不会氧化分子中的碳碳双键')
            tf1 = xtf('氧化');tf2 = xtf2(1,'伯醇')
            z1=msm('z1').scale(0.5);z2=msm('z2');z3=msm('z3');y1=msm('y1');y2=msm('y2');xcoi(z1,z2,z3,y2);xs(z2,6,z1,1);xs(z3,0,z1,1);y1.scale(0.6);y1.shift(1.5*DOWN);y2.scale(0.8);y2.shift(1.2*DOWN)
            c1=z1[0:6].copy();c2=z1[9:13].copy();c3=z1[25].copy()
            
            sa(tf1);sw(0.5);sp(adb(t1));sp(adb(tf2))
            sp(agf(z1[0:6]));sp(agf(z1[6:9]),agf(z1[21:24]));sp(xt2(c1,z1[9:13],[0,0,1,1,2,2,4,3]));sp(agf(z1[13:16]),agf(z1[24:27]));sp(xt2(c2,z1[16:21],[0,0,1,1,2,4,3,2]),at(c3,z1[19]));refresh(z1,t1,tf1,tf2);sw();sp(at(t1,t2),z1[9:16].animate.set_opacity(0.3),z1[24:].animate.set_opacity(0.3))
            sp(z1.animate.shift(1.5*UP),afi(y1,shift=UP));sw(2);sp(at(t1,t3));sw();sp(z1[9:13].animate.set_opacity(1),z1[13:21].animate.set_opacity(0.3));sp(at(t1,t4));sp(afo(y1),afi(y2));sw();sp(at(t1,t5));sw(2)
            sp(afo(t1,z1,y2));sp(adbr(tf2));sw(0.5)
        def playscene10():
            tf1 = xtf('氧化');tf2 = xtf2(1,'仲醇');tf3 = xtf2(1,'叔醇')
            t1 = xn('二级醇在前述氧化剂作用下,生成酮');xcss(t1[0:3],BLUE);xcss(t1[-1],RED)
            t2 = xn('若分子中含有不饱和键,使用下述氧化剂不会氧化分子中的不饱和键')
            t3 = xn('三级醇没有α-H,很难被氧化')
            t4 = xn('但在剧烈酸性氧化条件下,三级醇先脱水生成烯烃');xcss(t4[20:],BLUE);xcss(t4[17],GREEN)
            t5 = xn('然后烯烃氧化断裂');xcss(t5[2:4],BLUE)
            t6 = xn('生成小分子的羧酸及酮的混合物');xcss(t6[9],BLUE);xcss(t6[6:8],GREEN)
            z1=msm('z1').scale(0.5);z2=msm('z2');xcoi(z1,z2);xs(z2,6,z1,1);y3=msm('y3');y3.scale(0.6).shift(1.5*DOWN)
            z3=msm('z3');z4=msm('z4');z5=msm('z5');z6=msm('z6');z7=msm('z7');
            xos(1,z3);xos(2,z3,z4,z6);xcoi(z3,z4,z5,z6,z7);xs(z7,0,z6,0);xs(z5,0,z7,3);z5.shift(3*UP);z7.shift(3*UP)
            
            sa(tf1);sw(0.5);sp(adb(t1));sp(adb(tf2))
            sp(agf(z2[6:14]));sp(agf(z2[0:3]),agf(z2[3:6]));sp(at(z2[10:14].copy(),z2[15:19]),at(z2[6].copy(),z2[14]),at(z2[8].copy(),z2[19]),agf(z2[20:22]));refresh(z2,tf1,tf2,t1);sw();sp(at(t1,t2))
            sp(z2.animate.shift(1.5*UP),afi(y3,shift=UP));sw(3);sp(afo(y3,z2,t1));sp(adbr(tf2));sw()
            
            sp(adb(t3));sp(adb(tf3));sp(agf(z3));sw();sp(at(t3,t4));sw()
            sp(xt([z3,z4,z5],[0,1,[3,0,4,2,1,3,2,4,0,1,9,7,8,5]],[0,2,[5,2,6,0]]));refresh(z4,z5,t3,tf1,tf3);sw();sp(afo(z5));sp(at(t3,t5));sw();sp(at(t3,t6))
            sp(xt2(z4,z7,[5,0]),agf(z7[1:]),agf(z6[5]));sw(2);sp(afo(z4,z6[5],z7[1:],t3));sp(adbr(tf3));sw(0.5)
        def playscene11():
            tf1 = xtf('酸性').move_to([-5.4,2,0]).scale(1.3);tf2 = xtf('碱性').move_to([-5.4,0,0]).scale(1.3);tf3 = xtf('亲核性').move_to([-5.4,-2,0]).scale(1.3);tf4 = xtf('取代').move_to([5.4,2,0]).scale(1.3);tf5 = xtf('消除').move_to([5.4,0,0]).scale(1.3);tf6 = xtf('氧化')
            al1 = msm('general');al20 = msm('general2').scale(2);xms(al1,0,al20,0)
            vg=VGroup(tf1[0],tf2[0],tf3[0],tf4[0],tf5[0],tf6[0])
            t1 = xn('此外,醇还能发生脱氢、分子间的脱水、取代和消去中的重排等反应')
            t2 = xn('这里不再详细介绍')
            
            sa(tf6);sw(0.5);sp(afi(tf1,tf2,tf3,tf4,tf5,al1));sp(tf6.animate.move_to([5.4,-2,0]).scale(1.3))
            sp(adb(t1));sw(2);sp(at(t1,t2));sw();sp(afo(al1,t1,tf1[1],tf2[1],tf3[1],tf4[1],tf5[1],tf6[1]))
            vec = [0,0.75,0]
            tf1[0].generate_target();tf2[0].generate_target();tf3[0].generate_target();tf4[0].generate_target();tf5[0].generate_target();tf6[0].generate_target()
            tf1[0].target.move_to(vec).rotate(-90*DEGREES);tf2[0].target.move_to(vec).rotate(-90*DEGREES).rotate(60*DEGREES,about_point=ORIGIN);tf3[0].target.move_to(vec).rotate(-90*DEGREES).rotate(120*DEGREES,about_point=ORIGIN);tf4[0].target.move_to(vec).rotate(-90*DEGREES).rotate(180*DEGREES,about_point=ORIGIN);tf5[0].target.move_to(vec).rotate(-90*DEGREES).rotate(240*DEGREES,about_point=ORIGIN);tf6[0].target.move_to(vec).rotate(-90*DEGREES).rotate(300*DEGREES,about_point=ORIGIN)
            sp(xal(0.3,MoveToTarget(tf1[0]),MoveToTarget(tf2[0]),MoveToTarget(tf3[0]),MoveToTarget(tf4[0]),MoveToTarget(tf5[0]),MoveToTarget(tf6[0])));sw()
            sp(adbr(vg));sw()
        def playscene12():
            title = mt('本期视频BGM及推荐者',font='YouYuan').scale(0.8).to_edge(UP)
            m1 = ImageMobject(r'C:\Users\86158\Music\m1.png').scale(0.6);n1=xn('东斓').set_color(color=[GRAY,WHITE]).scale(1.1).next_to(m1);v1=Group(m1,n1);xpp(v1,'ur')
            m2 = ImageMobject(r'C:\Users\86158\Music\m2.png').scale(0.6);n2=xn('Franceglary').set_color(color=['#bb2223',WHITE]).scale(1.1).next_to(m2);v2=Group(m2,n2);xpp(v2,'r')
            m3 = ImageMobject(r'C:\Users\86158\Music\m3.png').scale(0.6);n3=xn('黎梧程').set_color(color=['#D5B3A5','#a09890']).scale(1.1).next_to(m3);v3=Group(m3,n3);xpp(v3,'dr')
            t1 = mt('Ascended Vibrations',font='STFangsong').scale(0.6).scale(1.3);xpp(t1,'ul')
            t2 = mt('卡农',font='STFangsong').scale(0.6).scale(1.3);xpp(t2,'l')
            t3 = mt('绿袖子',font='STFangsong').scale(0.6).scale(1.3);xpp(t3,'dl')
            
            sw(0.5);sp(adb(title));sp(xal(0.3,agf(m1),agf(m2),agf(m3)));sp(xal(0.3,agf(n1),agf(n2),agf(n3)));sp(afi(t1,t2,t3));sw(2);sp(afo(title,v1,v2,v3,t1,t2,t3));sw(0.5)
        def icon():
            icon = msm('icon').set_color_by_gradient("#FF66FF","#FFBBFF").scale(0.45)
            base = msm('tu').set_color(color = ['#FF66FF', '#FFBBFF']).scale(2.5);base[3:8].set_opacity(0)
#             base = msm('tu').set_color_by_gradient("#FF66FF","#FFBBFF").scale(2.5);base[3:8].set_opacity(0)
            i1=icon.copy().move_to(base[3]);i2=i1.copy().shift(0.7*LEFT);i3=i1.copy().shift(1.4*LEFT);i4=i1.copy().shift(0.7*RIGHT);i5=i1.copy().shift(1.4*RIGHT)
            i6=icon.copy().scale(1.5).move_to(base[0].get_corner(UL) + 0.2*RIGHT);i7=i1.copy().shift(2.1*LEFT);i8=icon.copy().scale(1.5).move_to((base[2].get_center()+base[1].get_center())/2);i8.scale(3)
            for i in i8:
                i.scale(0.5)
            i88 = i8[4:6].scale(1.01).set_color('#FFBBFF').shift(0.11*LEFT + 0.05*UP)
            i1.rotate(2*PI/7*1)
            i2.rotate(2*PI/7*2)
            i3.rotate(2*PI/7*3)
            i4.rotate(2*PI/7*4)
            i5.rotate(2*PI/7*5)
            i6.rotate(2*PI/7*6)
            i7.rotate(2*PI/7*7)
            vgi=VGroup(i1,i2,i3,i4,i5,i6,i7)
            sa(i88);sa(base,vgi)
View Code

 

posted @ 2022-07-31 23:46  树叶本子  阅读(303)  评论(0)    收藏  举报