亲核取代反应

%%manim -v WARNING -qh s1
class s1(Scene):
    def construct(self):
        
        def getall():
            alls = self.mobjects
            vg = VGroup()
            for i in alls:
                vg.add(i)
            return vg
        
        class narrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(DOWN)
                self.scale(0.6)
                
        class upnarrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(UP)
                self.scale(0.8)
        
        def check(svg):
            n = 0
            for i in svg:
                num = Integer(number=n).scale(0.6).set_color(RED).move_to(i)
                n += 1
                self.add(num)
                self.add(svg.set_opacity(0.5))
        
        frame = FullScreenRectangle()
        title = Text('饱和碳原子上的亲核取代反应', font="STZhongsong")
        self.play(DrawBorderThenFill(title))
        self.play(FadeOut(title))
        s0eq = SVGMobject(r'D:\manimSVG\s0eq.svg').set(width=frame.width * 3 / 4)
        s0eq[1].set_color(RED).set_sheen(0.3)
        s0eq[15:17].set_color(GREEN).set_sheen(0.3)
        s0eq[37:39].set_color(GREEN).set_sheen(0.3)
        s0eq[21:23].set_color(GREEN).set_sheen(0.3)
        s0eq[35].set_color(RED).set_sheen(0.3)
        s0eq[39:41].set_color(RED).set_sheen(0.3)

        n1 = narrator('饱和碳原子上的亲核取代反应一般表达式如下:')
        c1 = s0eq[0:14].copy()
        c2 = VGroup(s0eq[15:17].copy(), s0eq[37:39].copy())
        c3 = s0eq[20:35].copy()
        c4 = VGroup(s0eq[35].copy(), s0eq[39:41].copy())
        cc1 = s0eq[0:14].copy().scale(1.5).move_to(ORIGIN).move_to([-2, 0, 0])
        cc2 = VGroup(s0eq[15:17].copy(), s0eq[37:39].copy()).scale(1.5).move_to([2, 0, 0])
        cc3 = s0eq[20:35].copy().scale(1.5).move_to(ORIGIN).move_to([-2, 0, 0])
        cc4 = VGroup(s0eq[35].copy(), s0eq[39:41].copy()).scale(1.5).move_to([2, 0, 0])
        vc1 = VGroup(cc1, cc2)

        # 介绍饱和碳原子上的亲核取代反应
        self.play(DrawBorderThenFill(vc1), DrawBorderThenFill(n1))
        self.play(Transform(cc1[0], cc3[0]), Transform(cc1[13], cc3[14]), Transform(cc1[4:13], cc3[5:14]),
                  Transform(cc1[3], cc3[4]),
                  Transform(cc1[2], cc4[1]), Transform(cc1[1], cc4[0]), Transform(cc2[0], cc3[1:3]),
                  Transform(cc2[1], cc3[3]))
        self.wait()
        self.play(Transform(vc1, s0eq))
        note1 = Text('底物', font="STZhongsong").scale(0.7).next_to(c1, DOWN)
        note2 = Text('亲核试剂', font="STZhongsong").scale(0.7).next_to(c2, DOWN).set_y(note1.get_y())
        note3 = Text('产物', font="STZhongsong").scale(0.7).next_to(c3, DOWN).set_y(note1.get_y())
        note4 = Text('离去基团', font="STZhongsong").scale(0.7).next_to(c4, DOWN).set_y(note1.get_y())
        vgnote = VGroup(note1, note2, note3, note4).set_sheen(0.3).set_color_by_gradient(RED, GREEN)
        self.play(
            AnimationGroup(FadeIn(note1), AnimationGroup(FadeIn(note2),
                                                         AnimationGroup(FadeIn(note3), AnimationGroup(FadeIn(note4)),
                                                                        lag_ratio=0.5), lag_ratio=0.5), lag_ratio=0.5)
        )
        self.wait()
        self.play(FadeOut(vgnote, vc1, n1))
        li1 = MathTex('S_N2').scale(2)
        li2 = MathTex('S_N1')
        li3 = Text('影响卤代烃亲核取代反应的因素', font="STZhongsong")
        # SN2
        n = narrator('有两种分子参与了决速步的亲核取代反应称为双分子亲核取代反应')
        n1 = MarkupText(r'S<sub>N</sub>2<span font="STZhongsong">是一步完成的协同反应</span>').to_edge(DOWN).scale(0.6)
        self.play(DrawBorderThenFill(li1), DrawBorderThenFill(n))
        self.play(Transform(n, n1))
        self.wait()
        self.play(Unwrite(li1), FadeOut(n))
        nu = SVGMobject(r'D:\manimSVG\nu.svg').scale(0.25).set_color(RED).set_sheen(0.3).shift(3 * LEFT)
        x = SVGMobject(r'D:\manimSVG\x.svg').scale(0.25).set_color(GREEN).set_sheen(0.3).shift(3 * RIGHT)
        cx = SVGMobject(r'D:\manimSVG\cx.svg').scale(1.5)
        cnu = SVGMobject(r'D:\manimSVG\cnu.svg').scale(1.5)
        cnu[5:7].set_color(RED).set_sheen(0.3)
        intermediate = SVGMobject(r'D:\manimSVG\intermediate.svg').scale(1.7)
        intermediate[18:20].set_color(RED).set_sheen(0.3)
        intermediate[13].set_color(GREEN).set_sheen(0.3)
        cx[1].set_color(GREEN).set_sheen(0.3)
        vg1 = VGroup(nu, cx)
        self.play(GrowFromCenter(vg1))
        # Nu和底物反应
        self.wait()
        self.play(Transform(nu[0:2], intermediate[18:20]), Transform(nu[2:5], intermediate[20:24]),
                  Transform(cx[0], intermediate[0]),
                  Transform(cx[10], intermediate[3]), Transform(cx[11], intermediate[4]),
                  Transform(cx[3], intermediate[5]),
                  Transform(cx[4:10], intermediate[6:13]), Transform(cx[2], intermediate[14:18]),
                  Transform(cx[1], intermediate[13]),
                  Transform(cx[13], intermediate[2]), Transform(cx[12], intermediate[1]))
        self.clear()
        self.add(intermediate)

        lnote = MathTex(r'\delta - ').next_to(intermediate[18:20], UP)
        rnote = MathTex(r'\delta - ').next_to(intermediate[13], UP)
        dnote = narrator('过渡态').next_to(intermediate[1], DOWN)
        vn = VGroup(lnote, rnote, dnote)
        self.play(Write(vn))
        self.wait(0.5)
        self.play(Unwrite(vn))
        n1 = narrator('此时中心碳原子由原来sp³的四面体结构转为sp²的三角形平面结构')
        self.play(DrawBorderThenFill(n1))
        intermediate.save_state()
        self.play(intermediate[1].animate.set_opacity(0), intermediate[3].animate.set_opacity(0), intermediate[5].animate.set_opacity(0))
        self.play(intermediate.animate.scale(2))
        orbit = SVGMobject(r'D:\manimSVG\orbit.svg', fill_color=BLUE).set_opacity(0.5).scale(0.35)
        o1 = orbit.copy().move_to(intermediate[18:20]).shift(1.5 * RIGHT)
        o2 = orbit.copy().rotate(PI).move_to(intermediate[0]).shift(1.1 * LEFT)
        o3 = orbit.copy().move_to(intermediate[0]).shift(1.1 * RIGHT)
        o4 = orbit.copy().rotate(PI).move_to(intermediate[13]).shift(LEFT)
        vo1 = VGroup(o1, o2)
        vo2 = VGroup(o3, o4)
        # p轨道
        self.play(Transform(intermediate[20:24], vo1), Transform(intermediate[14:18], vo2))
        note1 = narrator('p轨道').move_to((o1.get_center() + o2.get_center()) / 2).shift(DOWN).set_color(BLUE)
        note2 = narrator('p轨道').move_to((o3.get_center() + o4.get_center()) / 2).shift(DOWN).set_color(BLUE)
        self.play(GrowFromCenter(note1), GrowFromCenter(note2))
        self.wait(0.5)
        self.play(FadeOut(note1, note2))
        self.play(Restore(intermediate))
        rect = Polygram(
            [[0, 0, 0], [1, 0.5, 0], [1, -1.5, 0], [0, -2, 0]], color=BLUE
        ).set_opacity(0.5).scale(2.4).move_to(intermediate[0]).shift(0.2 * UP)
        intermediate.save_state()
        self.play(intermediate[1].animate.set_sheen(0.3), intermediate[3].animate.set_sheen(0.3),
                  intermediate[5].animate.set_sheen(0.3), intermediate[0].animate.set_sheen(0.3), run_time=0.5)
        self.play(intermediate[1].animate.set_color(BLUE), intermediate[3].animate.set_color(BLUE),
                  intermediate[5].animate.set_color(BLUE), intermediate[0].animate.set_color(BLUE))
        self.play(Write(rect))
        self.wait()
        self.play(FadeOut(rect), FadeOut(n1))
        self.play(Restore(intermediate))
        self.play(Transform(intermediate[0], cnu[7]), Transform(intermediate[18:20], cnu[5:7]), Transform(intermediate[20:24], cnu[4]),
                 Transform(intermediate[2], cnu[0]), Transform(intermediate[1], cnu[1]), Transform(intermediate[4], cnu[8]),
                 Transform(intermediate[3], cnu[2]), Transform(intermediate[6:13], cnu[9:14]), Transform(intermediate[5], cnu[3]),
                 Transform(intermediate[13], x[0]), Transform(intermediate[14:18], x[1:4]))
        
        self.wait()
        self.play(GrowFromCenter(intermediate, reverse_rate_function = True))
        

 

%%manim -v WARNING -qh s2
class s2(Scene):
    def construct(self):
        
        def getall():
            alls = self.mobjects
            vg = VGroup()
            for i in alls:
                vg.add(i)
            return vg
        
        class narrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(DOWN)
                self.scale(0.6)
                
        class upnarrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(UP)
                self.scale(0.8)
        
        def check(svg):
            n = 0
            for i in svg:
                num = Integer(number=n).scale(0.6).set_color(RED).move_to(i)
                n += 1
                self.add(num)
                self.add(svg.set_opacity(0.5))
        
        def getcos(p1, p2):
            x1 = p1[0]
            y1 = p1[1]
            x2 = p2[0]
            y2 = p2[1]
            return lambda x : (y1-y2)/2*(np.cos(PI/(x2-x1)*(x-x1)))+(y1+y2)/2
                
        def graph(xrange, yrange, xlabel, ylabel, points):
#             按照顺序输入
            frame = FullScreenRectangle()
            ax = Axes(
            x_range=xrange,
            y_range=yrange,
            x_length=11,
            y_length=5,
            axis_config = {"include_tip": False, "include_ticks": False}
        )
            labels = ax.get_axis_labels(
            x_label=Text(xlabel, font="STZhongsong").scale(0.6), y_label=Text(ylabel, font="STZhongsong").scale(0.6)
        )
            vgax = VGroup(ax, labels)
            for i in range(0, len(points)-1):
                p = ax.plot(getcos(points[i], points[i+1]), x_range = [points[i][0],points[i+1][0]], color = BLUE)
                vgax.add(p)
            
            return vgax
        
        frame = FullScreenRectangle()
        n1 = MarkupText(r'<span font="STZhongsong">在</span>S<sub>N</sub>2<span font="STZhongsong">反应中,由于亲核试剂从离去基团的背侧进攻中心碳原子</span>').to_edge(DOWN).scale(0.6)
        n2 = narrator('若中心碳原子为手性碳,在生成产物时,中心碳原子的构型会完全翻转')
        r = SVGMobject(r'D:\manimSVG\r.svg').scale(1.7)
        r[0].set_color(BLUE).set_sheen(0.3)
        r[9].set_color(BLUE).set_sheen(0.3)
        r[6].set_color(BLUE).set_sheen(0.3)
        r[24].set_color(BLUE).set_sheen(0.3)
        r[11:21].set_color(BLUE).set_sheen(0.3)
        s = SVGMobject(r'D:\manimSVG\s.svg').scale(1.7)
        s[13].set_color(RED).set_sheen(0.3)
        s[4].set_color(RED).set_sheen(0.3)
        s[7].set_color(RED).set_sheen(0.3)
        s[14].set_color(RED).set_sheen(0.3)
        s[15:24].set_color(RED).set_sheen(0.3)
        note1 = narrator('(R)-2-溴辛烷').scale(1.5).next_to(r, 3*UP)
        note1[1].set_color(BLUE).set_sheen(0.3)
        note2 = narrator('(S)-2-辛醇').scale(1.5).next_to(s, 3*UP)
        note2[1].set_color(RED).set_sheen(0.3)
        oh = SVGMobject(r'D:\manimSVG\oh.svg').scale(0.25).shift(3 * LEFT)
        br = SVGMobject(r'D:\manimSVG\br.svg').scale(0.25).shift(3 * RIGHT)
        self.play(DrawBorderThenFill(n1), GrowFromCenter(r), GrowFromCenter(oh))
        self.play(Write(note1))
        self.play(Transform(n1, n2))
        self.wait()
        self.play(Transform(r[0], s[13]), Transform(r[24], s[14]), Transform(r[21:24], s[0:3]), Transform(r[11:21], s[15:24]),
                 Transform(r[10], s[3]), Transform(r[6], s[7]), Transform(r[1:6], s[8:13]), Transform(oh[0:2], s[5:7]),
                 Transform(oh[2], s[4]), Transform(r[9], br[2]), Transform(r[7:9], br[0:2]), Transform(note1, note2), run_time=2)
        self.wait()
        self.play(FadeOut(oh, r, note1, n1))


        g = graph([0,10], [0,6], '势能', '反应进程', [[1,2.5], [4,5.5], [9,1.5]])
        point1 = g[0].c2p(1, 2.5)
        dot1 = Dot(point1)
        dot1c = dot1.copy()
        point2 = g[0].c2p(4, 5.5)
        dot2 = Dot(point2)
        point3 = g[0].c2p(9, 1.5)
        dot3 = Dot(point3)
        n0 = MarkupText('S<sub>N</sub>2<span font="STZhongsong">反应中势能变化如图所示</span>').to_edge(DOWN).scale(0.6)
        m1 = MarkupText('Nu<sup><b>- </b></sup>+ RX').scale(0.6).next_to(dot1, DOWN)
        m2 = MarkupText('Nu---R---X').scale(0.6).next_to(dot2, UP)
        m3 = MarkupText('RNu + X<sup><b>- </b></sup>').scale(0.6).next_to(dot3, DOWN)
        self.play(DrawBorderThenFill(n0), Write(g[0:2]))
        self.play(Write(g[2:]))
        self.play(GrowFromCenter(dot1))
        self.play(GrowFromCenter(m1))
        self.play(MoveAlongPath(dot1c, g[2]))
        self.play(GrowFromCenter(m2))
        self.add(dot2)
        self.play(MoveAlongPath(dot1c, g[3]))
        self.play(GrowFromCenter(m3))
        l1 = DashedLine(start=dot1.get_center(), end=np.array([dot2.get_x() + 0.5,dot1.get_y(),0]))
        l2 = DashedLine(start=dot3.get_center(), end=np.array([dot2.get_x() + 0.5,dot3.get_y(),0]))
        self.play(Write(l1), Write(l2))
        arr1 = DoubleArrow(start=dot2.get_center(), end=np.array([dot2.get_x(),dot1.get_y(),0]), buff=0, tip_length=0.2, color=GREEN)
        arr2 = DoubleArrow(start=np.array([dot2.get_x() + 0.5,dot1.get_y(),0]), end=np.array([dot2.get_x() + 0.5,dot3.get_y(),0]), buff=0, tip_length=0.2, color=GREEN)
        self.play(GrowFromCenter(arr1), GrowFromCenter(arr2))
        ea = MathTex('E_a').scale(0.8).set_color(GREEN).next_to(arr1, 0.2*LEFT)
        h = MathTex(r'\Delta H').scale(0.8).set_color(GREEN).next_to(arr2, 0.2*RIGHT)
        self.play(GrowFromCenter(ea), GrowFromCenter(h))
        self.wait()
        n2 = narrator('决速步是双分子的,需要两种分子的碰撞')
        n3 = narrator('故此为双分子的亲核取代反应')
        self.play(Transform(n0, n2), m2[0:2].animate.set_sheen(0.3), m2[-1].animate.set_sheen(0.3))
        self.play(m2.animate.scale(1.7))
        self.play(m2[0:2].animate.set_color(RED), m2[-1].animate.set_color(GREEN))
        self.play(Transform(n0, n3))
        self.wait()
        self.play(FadeOut(g, dot1, dot1c, dot2, m1, m2, m3, l1, l2, arr1, arr2, ea, h, n0))
        

 

%%manim -v WARNING -qh s3
# , disable_ligatures=True, alignment="center"
class s3(Scene):
    def construct(self):
        
        def getall():
            alls = self.mobjects
            vg = VGroup()
            for i in alls:
                vg.add(i)
            return vg
        
        class narrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(DOWN)
                self.scale(0.6)
                
        class upnarrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(UP)
                self.scale(0.8)
        
        def check(svg):
            n = 0
            for i in svg:
                num = Integer(number=n).scale(0.6).set_color(RED).move_to(i)
                n += 1
                self.add(num)
                self.add(svg.set_opacity(0.5))
        
        def getcos(p1, p2):
            x1 = p1[0]
            y1 = p1[1]
            x2 = p2[0]
            y2 = p2[1]
            return lambda x : (y1-y2)/2*(np.cos(PI/(x2-x1)*(x-x1)))+(y1+y2)/2
                
        def graph(xrange, yrange, xlabel, ylabel, points):
#             按照顺序输入
            frame = FullScreenRectangle()
            ax = Axes(
            x_range=xrange,
            y_range=yrange,
            x_length=11,
            y_length=5,
            axis_config = {"include_tip": False, "include_ticks": False}
        )
            labels = ax.get_axis_labels(
            x_label=Text(xlabel, font="STZhongsong").scale(0.6), y_label=Text(ylabel, font="STZhongsong").scale(0.6)
        )
            vgax = VGroup(ax, labels)
            for i in range(0, len(points)-1):
                p = ax.plot(getcos(points[i], points[i+1]), x_range = [points[i][0],points[i+1][0]], color = BLUE)
                vgax.add(p)
            
            return vgax
        
        def mytrans(a, b, c):
            n = int(len(c)/2)
            ag = 'AnimationGroup('
#             range(0, n-1)是错的
            for i in range(0, n):
                s = str(i)
                if len(c[2*i]) == 2:
                    u = f'[c[2*{s}][0]:c[2*{s}][1]]'
                else:
                    u = f'[c[2*{s}][0]]'
                if len(c[2*i+1]) == 2:
                    v = f'[c[2*{s}+1][0]:c[2*{s}+1][1]]'
                else:
                    v = f'[c[2*{s}+1][0]]'
                ag += f'Transform(a{u}, b{v}),'
            ag += ')'
            agg = eval(ag)
            return agg
        
        frame = FullScreenRectangle()
        li2 = MathTex('S_N1').scale(2)
        n = narrator('只有一种分子参与了决速步的亲核取代反应称为单分子亲核取代反应')
        n1 = MarkupText(r'S<sub>N</sub>1<span font="STZhongsong">反应是分步完成的</span>').to_edge(DOWN).scale(0.6)
        self.play(DrawBorderThenFill(li2), DrawBorderThenFill(n))
        self.wait()
        self.play(Transform(n, n1))
        self.wait()
        self.play(Unwrite(li2), FadeOut(n))


        mo1 = MarkupText('R<sub>3</sub>CX', font='Times New Roman').scale(1.5)
        mo1[-1].set_color(GREEN).set_sheen(0.3)
        mo2 = MarkupText('R<sub>3</sub>C- - -X', font='Times New Roman').scale(1.5)
        mo2[-1].set_color(GREEN).set_sheen(0.3)
        mo2[3:6].set_y(mo2[-1].get_y())
        mo3 = MarkupText('R<sub>3</sub>C- - -Nu', font='Times New Roman').scale(1.5)
        mo3[3:6].set_y(mo2[-1].get_y())
        mo3[-1].set_color(RED).set_sheen(0.3)
        mo3[-2].set_color(RED).set_sheen(0.3)
        mo4 = MarkupText('R<sub>3</sub>CNu', font='Times New Roman').scale(1.5)
        mo4[3:5].set_color(RED).set_sheen(0.3)
        rc = MarkupText('R<sub>3</sub>C<sup><b>+</b></sup>', font='Times New Roman').scale(1.5)
        x = MarkupText('X<sup><b>-</b></sup>', font='Times New Roman').scale(1.5).shift(3*RIGHT)
        x[0].set_color(GREEN).set_sheen(0.3)
        nu = MarkupText('Nu<sup><b>-</b></sup>', font='Times New Roman').scale(1.5).shift(3*RIGHT)
        nu[0:2].set_color(RED).set_sheen(0.3)
        self.play(GrowFromCenter(mo1))
        self.play(Transform(mo1[0], mo2[0]), Transform(mo1[1], mo2[1]), Transform(mo1[2], mo2[2:6]), Transform(mo1[-1], mo2[-1]))
        note1 = narrator('第一过渡态').next_to(mo2, 3*DOWN)
        d1 = MathTex(r'\delta + ').next_to(mo2[2], UP)
        d2 = MathTex(r'\delta - ').next_to(mo2[-1], UP).set_y(d1.get_y())
        vd = VGroup(d1, d2)
        self.play(GrowFromCenter(note1), Write(vd))
        self.wait()
        self.play(FadeOut(note1), Unwrite(vd))
        self.clear()
        
        
        self.add(mo2)
        vgnotation = VGroup(x[1], rc[-1])
        self.play(Transform(mo2[0:3], rc[0:3]), Transform(mo2[-1], x[0]), Transform(mo2[3:6], vgnotation))
        self.clear()
        self.add(rc, x)
        self.play(FadeOut(x))
        plane = SVGMobject(r'D:\manimSVG\plane.svg').scale(2.5).shift(0.5*UP)
        vgbond = VGroup(plane[4], plane[7], plane[10])
        co1 = rc[0].copy()
        co2 = rc[0].copy()
        self.play(Transform(rc[0], plane[5:7]), Transform(co1, plane[2:4]), Transform(co2, plane[8:10]), Transform(rc[1], vgbond),
                 Transform(rc[2:4], plane[0:2]))
        self.clear()
        self.add(plane)
        
        
        n1 = narrator('此时,碳原子由sp³四面体结构转变为sp²三角形平面结构')
        n2 = narrator('若碳原子上连接三个不同的基团,产物往往是外消旋体')
        n3 = narrator('这是因为亲核试剂进入平面两侧的机会相等')
        self.play(DrawBorderThenFill(n1))
        self.wait()
        self.play(Transform(n1, n2))
        self.play(plane[5:7].animate.set_sheen(0.3), plane[2:4].animate.set_sheen(0.3), plane[8:10].animate.set_sheen(0.3), run_time=0.5)
        self.play(plane[5:7].animate.set_color(GOLD), plane[2:4].animate.set_color(GREEN), plane[8:10].animate.set_color(BLUE))
        self.wait()
        self.play(Transform(n1, n3))
        self.wait()
        self.play(FadeOut(n1))
        
        
        self.play(plane.animate.rotate(axis=[1,0,0], angle=45*DEGREES))
        dotline = DashedLine().set_length(5).rotate(PI/2).set_color(BLUE).set_opacity(0.8).shift(0.1*LEFT)
        self.play(Write(dotline), plane[5:8].animate.set_opacity(0.3))
        nu1 = nu.copy().scale(0.8).set_color(RED).set_sheen(0.3)
        nu2 = nu.copy().scale(0.8).set_color(RED).set_sheen(0.3)
        nu1.next_to(dotline, UP)
        nu2.next_to(dotline, DOWN)
        self.play(Write(nu1))
        nu1.save_state()
        arr1 = Arrow(color=BLUE, tip_length=0.4).rotate(-PI/2).next_to(nu1, RIGHT).set_length(1.5).shift(0.5*DOWN).set_opacity(0.8)
        self.play(GrowFromCenter(arr1))
        self.play(nu1.animate.shift(2*DOWN), rate_func=rate_functions.rush_into)
        plane.save_state()
        shitl = SVGMobject(r'D:\manimSVG\shitl.svg').scale(2.5)
        shitl[0:2].set_color(RED).set_sheen(0.3)
        shitl[9:11].set_color(GOLD).set_sheen(0.3)
        shitl[6:8].set_color(BLUE).set_sheen(0.3)
        shitl[3:5].set_color(GREEN).set_sheen(0.3)
        self.play(FadeOut(arr1), FadeOut(dotline), Transform(nu1, shitl[0:2]), mytrans(plane, shitl, [[0,2],[2],[5,7],[9,11],[7],[11,20],[2,4],[3,5],[4],[5],[8,10],[6,8],[10],[8]]), rate_func=rate_functions.rush_from)
        self.wait(1.5)
        self.play(Restore(plane), Write(dotline), Restore(nu1))
        self.wait()
        self.play(CounterclockwiseTransform(nu1, nu2), run_time=2)
        arr2 = Arrow(color=BLUE, tip_length=0.4).rotate(PI/2).next_to(nu1, RIGHT).set_length(1.5).shift(0.5*UP).set_opacity(0.8)
        self.play(GrowFromCenter(arr2))
        self.play(nu1.animate.shift(2*UP), rate_func=rate_functions.rush_into)
        shitr = SVGMobject(r'D:\manimSVG\shitr.svg').scale(2.5)
        shitr[8:10].set_color(RED).set_sheen(0.3)
        shitr[0:2].set_color(GOLD).set_sheen(0.3)
        shitr[2:4].set_color(BLUE).set_sheen(0.3)
        shitr[5:7].set_color(GREEN).set_sheen(0.3)
        self.play(FadeOut(arr2), FadeOut(dotline), Transform(nu1, shitr[8:10]), mytrans(plane, shitr, [[0,2],[7],[5,7],[0,2],[7],[11,20],[2,4],[5,7],[4],[4],[8,10],[2,4],[10],[10]]), rate_func=rate_functions.rush_from)
        self.clear()
        self.add(shitr)
        shitl.scale(0.7).shift(3*LEFT)
        na = narrator('最终得到外消旋的混合物')
        self.play(shitr.animate.scale(0.7))
        le = shitr.copy()
        self.play(shitr.animate.shift(3*RIGHT), Transform(le, shitl))
        self.play(DrawBorderThenFill(na))
        self.play(Write(dotline))
        self.wait()
        self.play(FadeOut(dotline, na, le, shitr))
        

 

%%manim -v WARNING -qh s4
# , disable_ligatures=True, alignment="center"
def getall():
            alls = self.mobjects
            vg = VGroup()
            for i in alls:
                vg.add(i)
            return vg
        
class narrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(DOWN)
                self.scale(0.6)
                
def para(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)
                
class upnarrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(UP)
                self.scale(0.8)
        
def check(svg):
            n = 0
            for i in svg:
                num = Integer(number=n).scale(0.6).set_color(RED).move_to(i)
                n += 1
                self.add(num)
                self.add(svg.set_opacity(0.5))
        
def getcos(p1, p2):
            x1 = p1[0]
            y1 = p1[1]
            x2 = p2[0]
            y2 = p2[1]
            return lambda x : (y1-y2)/2*(np.cos(PI/(x2-x1)*(x-x1)))+(y1+y2)/2
                
def graph(xrange, yrange, xlabel, ylabel, points):
#             按照顺序输入
            frame = FullScreenRectangle()
            ax = Axes(
            x_range=xrange,
            y_range=yrange,
            x_length=11,
            y_length=5,
            axis_config = {"include_tip": False, "include_ticks": False}
)
            labels = ax.get_axis_labels(
            x_label=Text(xlabel, font="STZhongsong").scale(0.6), y_label=Text(ylabel, font="STZhongsong").scale(0.6)
)
            vgax = VGroup(ax, labels)
            for i in range(0, len(points)-1):
                p = ax.plot(getcos(points[i], points[i+1]), x_range = [points[i][0],points[i+1][0]], color = BLUE)
                vgax.add(p)
            
            return vgax
        
def mytrans(a, b, c):
            n = int(len(c)/2)
            ag = 'AnimationGroup('
#             range(0, n-1)是错的
            for i in range(0, n):
                s = str(i)
                if len(c[2*i]) == 2:
                    u = f'[c[2*{s}][0]:c[2*{s}][1]]'
                else:
                    u = f'[c[2*{s}][0]]'
                if len(c[2*i+1]) == 2:
                    v = f'[c[2*{s}+1][0]:c[2*{s}+1][1]]'
                else:
                    v = f'[c[2*{s}+1][0]]'
                ag += f'Transform(a{u}, b{v}),'
            ag += ')'
            agg = eval(ag)
            return agg

frame = FullScreenRectangle()
graph = graph([0,10], [0,8], '反应进程', '势能', [[1,3],[4,8],[5,6], [6,7],[9,1]]).shift(0.5*LEFT)
point1 = graph[0].c2p(1,3)
dot1 = Dot(point1)
dot1c = dot1.copy()
point2 = graph[0].c2p(4,8)
dot2 = Dot(point2)
point3 = graph[0].c2p(5,6)
dot3 = Dot(point3)
point4 = graph[0].c2p(6,7)
dot4 = Dot(point4)
point5 = graph[0].c2p(9,1)
dot5 = Dot(point5)
m1 = MarkupText('R<sub>3</sub>CX').scale(0.6).next_to(dot1, DOWN)
m2 = MarkupText('R<sub>3</sub>C---X').scale(0.6).next_to(dot2, UP)
m3 = MarkupText('R<sub>3</sub>C<sup><b>+ </b></sup>+ X<sup><b>- </b></sup>+ Nu<sup><b>- </b></sup>').scale(0.6).next_to(dot3, DOWN)
m4 = MarkupText('R<sub>3</sub>C---Nu').scale(0.6).next_to(dot4, UP)
m5 = MarkupText('R<sub>3</sub>CNu+ X<sup><b>- </b></sup>').scale(0.6).next_to(dot5, UP).shift(0.5*RIGHT)
n1 = MarkupText(r'S<sub>N</sub>1<span font="STZhongsong">反应中势能变化如图所示</span>').to_edge(DOWN).scale(0.6)
vg1 = VGroup(m1,m2,m3,m4,m5,dot1,dot2,dot3,dot4,dot1c,graph,n1)

class s4(Scene):
    def construct(self):
        self.play(DrawBorderThenFill(n1), Write(graph[0:2]))
        self.play(Write(graph[2:]))
        self.play(GrowFromCenter(dot1))
        self.play(GrowFromCenter(m1))
        self.play(MoveAlongPath(dot1c, graph[2]))
        self.add(dot2)
        self.play(GrowFromCenter(m2))
        self.play(MoveAlongPath(dot1c, graph[3]))
        self.add(dot3)
        self.play(GrowFromCenter(m3))
        self.play(MoveAlongPath(dot1c, graph[4]))
        self.add(dot4)
        self.play(GrowFromCenter(m4))
        self.play(MoveAlongPath(dot1c, graph[5]))
        self.play(GrowFromCenter(m5))
        self.wait()
        self.play(DrawBorderThenFill(vg1), reverse_rate_function = True)
        

 

%%manim -v WARNING -qh s5
# , disable_ligatures=True, alignment="center"
def getall():
            alls = self.mobjects
            vg = VGroup()
            for i in alls:
                vg.add(i)
            return vg
        
class narrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(DOWN)
                self.scale(0.6)
                
def para(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)
                
class upnarrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(UP)
                self.scale(0.8)
        
def check(me, svg):
            n = 0
            for i in svg:
                num = Integer(number=n).scale(0.6).set_color(RED).move_to(i)
                n += 1
                me.add(num)
                me.add(svg.set_opacity(0.5))
        
def getcos(p1, p2):
            x1 = p1[0]
            y1 = p1[1]
            x2 = p2[0]
            y2 = p2[1]
            return lambda x : (y1-y2)/2*(np.cos(PI/(x2-x1)*(x-x1)))+(y1+y2)/2
                
def graph(xrange, yrange, xlabel, ylabel, points):
#             按照顺序输入
            frame = FullScreenRectangle()
            ax = Axes(
            x_range=xrange,
            y_range=yrange,
            x_length=11,
            y_length=5,
            axis_config = {"include_tip": False, "include_ticks": False}
)
            labels = ax.get_axis_labels(
            x_label=Text(xlabel, font="STZhongsong").scale(0.6), y_label=Text(ylabel, font="STZhongsong").scale(0.6)
)
            vgax = VGroup(ax, labels)
            for i in range(0, len(points)-1):
                p = ax.plot(getcos(points[i], points[i+1]), x_range = [points[i][0],points[i+1][0]], color = BLUE)
                vgax.add(p)
            
            return vgax
        
def mytrans(a, b, c):
            n = int(len(c)/2)
            ag = 'AnimationGroup('
#             range(0, n-1)是错的
            for i in range(0, n):
                s = str(i)
                if len(c[2*i]) == 2:
                    u = f'[c[2*{s}][0]:c[2*{s}][1]]'
                else:
                    u = f'[c[2*{s}][0]]'
                if len(c[2*i+1]) == 2:
                    v = f'[c[2*{s}+1][0]:c[2*{s}+1][1]]'
                else:
                    v = f'[c[2*{s}+1][0]]'
                ag += f'Transform(a{u}, b{v}),'
            ag += ')'
            agg = eval(ag)
            return agg
        
def myreverse(a, b, c):
            n = int(len(c)/2)
            ag = 'AnimationGroup('
#             range(0, n-1)是错的
            for i in range(0, n):
                s = str(i)
                if len(c[2*i]) == 2:
                    v = f'[c[2*{s}][0]:c[2*{s}][1]]'
                else:
                    v = f'[c[2*{s}][0]]'
                if len(c[2*i+1]) == 2:
                    u = f'[c[2*{s}+1][0]:c[2*{s}+1][1]]'
                else:
                    u = f'[c[2*{s}+1][0]]'
                ag += f'Transform(b{u}, a{v}),'
            ag += ')'
            agg = eval(ag)
            return agg

frame = FullScreenRectangle()
li = Text('影响卤代烃亲核取代反应的因素', font="STZhongsong")
ef1 = SVGMobject(r'D:\manimSVG\ef1.svg').scale(2)
ef1[0].set_color(BLUE).set_opacity(0.8).set_sheen(0.5)
ef1[5:8].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef1.save_state()
ef2 = SVGMobject(r'D:\manimSVG\ef2.svg').scale(2)
ef2[0:2].set_color(BLUE).set_opacity(0.8).set_sheen(0.5)
ef2[10:13].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef2[6:9].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef2.save_state()
ef3 = SVGMobject(r'D:\manimSVG\ef3.svg').scale(2)
ef3[0:3].set_color(BLUE).set_opacity(0.8).set_sheen(0.5)
ef3[15:18].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef3[11:14].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef3[7:10].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef1e = SVGMobject(r'D:\manimSVG\ef1e.svg').scale(2)
ef1e[0].set_color(BLUE).set_opacity(0.8).set_sheen(0.5)
ef1e[3:6].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef2e = SVGMobject(r'D:\manimSVG\ef2e.svg').scale(2)
ef2e[0:2].set_color(BLUE).set_opacity(0.8).set_sheen(0.5)
ef2e[2:5].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef2e[6:9].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
oh = SVGMobject(r'D:\manimSVG\oh.svg').scale(0.3).shift(3.6 * LEFT)
oh.save_state()
br = SVGMobject(r'D:\manimSVG\br.svg').scale(0.3).shift(3.6 * RIGHT)
br.save_state()
item1 = Text('①烃基结构的影响', font='STZhongsong')
item2 = Text('②离去基团的影响', font='STZhongsong')
item3 = Text('③试剂亲核性的影响', font='STZhongsong')
n1 = MarkupText(r'<span font="STZhongsong">烃基结构对</span>S<sub>N</sub>2<span font="STZhongsong">反应的影响主要是空间效应</span>').to_edge(DOWN).scale(0.6)
n2 = narrator('若中心碳原子背后的空间位阻越大,那么亲核试剂与它的碰撞接触越少')
n3 = narrator('反应进行得就越慢')
n4 = narrator('此时反应相对速率:100')
n5 = narrator('相对速率:0.22')
n6 = narrator('相对速率≈0')

class s5(Scene):
    def construct(self):
        self.play(DrawBorderThenFill(li))
        self.wait()
        self.play(Unwrite(li))
        
        self.play(GrowFromCenter(item1))
        self.wait()
        self.play(GrowFromCenter(item1, reverse_rate_function = True))
        
        self.play(DrawBorderThenFill(n1), Write(ef1), Write(oh))
        self.wait()
        self.play(Transform(n1, n2))
        self.wait(1.5)
        self.play(Transform(n1, n3))
        self.wait()
        self.play(Transform(n1, n4))
        self.wait()
        self.play(mytrans(ef1, br, [[2,4],[0,2],[4],[2]]), mytrans(oh, ef1e, [[0],[8],[1],[7],[2],[6]]), mytrans(ef1, ef1e, [[0],[0],[9],[1],[1],[9],[10],[10],[11],[11],[12,19],[12,20],[8],[2],[7],[3],[5],[4],[6],[5]]))
        self.wait()
        self.play(FadeOut(n1))
        self.clear()
        self.add(br, ef1e)
        oh.restore()
        ef1.restore()
        self.play(myreverse(ef1, br, [[2,4],[0,2],[4],[2]]), myreverse(oh, ef1e, [[0],[8],[1],[7],[2],[6]]), myreverse(ef1, ef1e, [[0],[0],[9],[1],[1],[9],[10],[10],[11],[11],[12,19],[12,20],[8],[2],[7],[3],[5],[4],[6],[5]]))
        self.wait()
        self.clear()
        self.add(ef1, oh)
        self.play(Transform(ef1[9], VGroup(ef2[0], ef2[10:13])), mytrans(ef1, ef2, [[1],[2],[11],[14],[12,19],[15,22],[10],[13],[0],[1],[5,8],[6,9],[8],[9],[4],[5],[2,4],[3,5]]))
        self.wait()
        self.clear()
        self.add(ef2, oh)
        br.restore()
        self.play(FadeIn(n5))
        self.play(mytrans(ef2, br, [[3,5],[0,2],[5],[2]]), mytrans(oh, ef2e, [[0],[11],[1],[10],[2],[9]]), mytrans(ef2, ef2e, [[0],[0],[1],[1],[2],[12],[14],[14],[15,22],[15,23],[12],[2],[11],[4],[10],[3],[8],[6],[7],[8],[6],[7],[13],[13],[9],[5]]), run_time=5)
        self.clear()
        self.add(br, ef2e)
        oh.restore()
        ef2.restore()
        self.play(FadeOut(n5))
        self.play(myreverse(ef2, br, [[3,5],[0,2],[5],[2]]), myreverse(oh, ef2e, [[0],[11],[1],[10],[2],[9]]), myreverse(ef2, ef2e, [[0],[0],[1],[1],[2],[12],[14],[14],[15,22],[15,23],[12],[2],[11],[4],[10],[3],[8],[6],[7],[8],[6],[7],[13],[13],[9],[5]]))
        self.wait()
        self.clear()
        self.add(ef2, oh)
        self.play(Transform(ef2[14],VGroup(ef3[0],ef3[15:18])), mytrans(ef2,ef3,[[0],[1],[1],[2],[13],[14],[9],[10],[10,13],[11,14],[6,9],[7,10],[2],[3],[5],[6],[3,5],[4,6],[15,22],[18,26]]))
        self.clear()
        self.add(ef3,oh)
        self.play(FadeIn(n6))
        self.play(oh.animate.shift(2*LEFT))
        self.play(oh.animate.shift(2.8*RIGHT), rate_func=rate_functions.rush_into)
        self.play(oh.animate.shift(2.8*LEFT), rate_func=rate_functions.rush_from)
        self.wait()
        self.play(FadeOut(oh, n6, ef3))
        

 

%%manim -v WARNING -qh s6
# , disable_ligatures=True, alignment="center"
def getall():
            alls = self.mobjects
            vg = VGroup()
            for i in alls:
                vg.add(i)
            return vg
        
class narrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(DOWN)
                self.scale(0.6)
                
def para(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)
                
class upnarrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(UP)
                self.scale(0.8)
        
def check(me, svg):
            n = 0
            for i in svg:
                num = Integer(number=n).scale(0.6).set_color(RED).move_to(i)
                n += 1
                me.add(num)
                me.add(svg.set_opacity(0.5))
            me.wait()
            me.clear()
        
def getcos(p1, p2):
            x1 = p1[0]
            y1 = p1[1]
            x2 = p2[0]
            y2 = p2[1]
            return lambda x : (y1-y2)/2*(np.cos(PI/(x2-x1)*(x-x1)))+(y1+y2)/2
                
def graph(xrange, yrange, xlabel, ylabel, points):
#             按照顺序输入
            frame = FullScreenRectangle()
            ax = Axes(
            x_range=xrange,
            y_range=yrange,
            x_length=11,
            y_length=5,
            axis_config = {"include_tip": False, "include_ticks": False}
)
            labels = ax.get_axis_labels(
            x_label=Text(xlabel, font="STZhongsong").scale(0.6), y_label=Text(ylabel, font="STZhongsong").scale(0.6)
)
            vgax = VGroup(ax, labels)
            for i in range(0, len(points)-1):
                p = ax.plot(getcos(points[i], points[i+1]), x_range = [points[i][0],points[i+1][0]], color = BLUE)
                vgax.add(p)
            
            return vgax
        
def pretrans0(name, i):
    if type(i) == int:
        back = name + '[' + str(i) + ']'
    elif type(i) == float:
        n1 = int(i)
        m = i - n1
        length = len(str(m))-2
        n2 = m*10**length
        back = name + '[' + str(n1) + ':' + str(int(n2)) + ']'
    return back
        
def pretrans(name, i):
    if type(i) == int:
        back = name + '[' + str(i) + ']'
    elif type(i) == float:
        n1 = int(i)
        m = i - n1
        length = len(str(m)) - 2
        n2 = m*10**length
#         注意这里n2仍为float,要int!
        back = name + '[' + str(n1) + ':' + str(int(n2)) + ']'
    elif type(i) == list:
        back = 'VGroup('
        for j in i:
            item = pretrans0(name, j) + ','
            back += item
        back += ')'
    return back

def mytrans(a, b, c):
            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
        
def myreverse(a, b, c):
            n = int(len(c)/2)
            ag = 'AnimationGroup('
#             range(0, n-1)是错的
            for i in range(0, n):
                s = str(i)
                if len(c[2*i]) == 2:
                    v = f'[c[2*{s}][0]:c[2*{s}][1]]'
                else:
                    v = f'[c[2*{s}][0]]'
                if len(c[2*i+1]) == 2:
                    u = f'[c[2*{s}+1][0]:c[2*{s}+1][1]]'
                else:
                    u = f'[c[2*{s}+1][0]]'
                ag += f'Transform(b{u}, a{v}),'
            ag += ')'
            agg = eval(ag)
            return agg

def c2s(a, b):
    for i in a:
        if rgb_to_hex(color_to_rgb(i.color)) == b:
            i.set_sheen(0.5)

def c2sa(a, b):
    for i in a:
        if rgb_to_hex(color_to_rgb(i.color)) == b:
            i.set_opacity(0.8)
            i.set_sheen(0.5)
            
frame = FullScreenRectangle()
n1 = MarkupText(r'<span font="STZhongsong">在</span>S<sub>N</sub>1<span font="STZhongsong">反应中,决速步为C-X键断裂生成碳正离子</span>').to_edge(DOWN).scale(0.6)
n2 = narrator('反应活性的高低主要取决于碳正离子生成的难易')
n3 = narrator('三级碳正离子最容易形成')
n4 = narrator('从电子效应看,三级碳正离子超共轭效应最大')
n5 = narrator('从空间效应看,因为三级卤代烃连有三个烷基,比较拥挤')
n6 = narrator('当它解离成碳正离子后,烷基之间距离较远,互相排斥较小')
n7 = narrator('这对碳正离子的形成是一种空助效应(空间帮助)')
n8 = narrator('显然三级卤代烃解离时的空助效应最强')
mo2 = MarkupText('R<sub>3</sub>C- - -X', font='Times New Roman').scale(1.5)
mo2[-1].set_color(GREEN).set_sheen(0.3)
mo2[3:6].set_y(mo2[-1].get_y())
rc = MarkupText('R<sub>3</sub>C<sup><b>+</b></sup>', font='Times New Roman').scale(1.5)
x = MarkupText('X<sup><b>-</b></sup>', font='Times New Roman').scale(1.5).shift(3*RIGHT)
x[0].set_color(GREEN).set_sheen(0.3)
vgnotation = VGroup(x[1], rc[-1])

ef3 = SVGMobject(r'D:\manimSVG\ef3.svg').scale(2)
ef3[0:3].set_color(BLUE).set_opacity(0.8).set_sheen(0.5)
ef3[15:18].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef3[11:14].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef3[7:10].set_color(TEAL).set_opacity(0.8).set_sheen(0.5)
ef3[4:7].set_opacity(0)
ef3plus = Text('+').move_to(ef3[3]).shift(0.45*RIGHT + 0.2*UP)
vgef = VGroup(ef3, ef3plus)
vgef.save_state()
loose = SVGMobject(r'D:\manimSVG\loose.svg').scale(2)
c2sa(loose, "#58c4dd")
c2sa(loose, "#5cd0b3")
pic = ImageMobject(r'D:\manimSVG\pic.png').scale(0.7)
rect = RoundedRectangle(corner_radius=0.5, height=pic.height+2, width=pic.width+1)
vgpic = Group(pic,rect).to_edge(RIGHT, buff=1).shift(0.5*UP)
picnote = narrator('【有机化学可视化】烷烃的卤化').scale(0.9).next_to(rect, DOWN).set_color(GREY)
class s6(Scene):
    def construct(self):
#         self.add(note)
#         self.wait()
#         check(self, ef3)
#         check(self, loose)


        self.play(DrawBorderThenFill(mo2), DrawBorderThenFill(n1))
        self.play(Transform(mo2[0:3], rc[0:3]), Transform(mo2[-1], x[0]), Transform(mo2[3:6], vgnotation))
        self.clear()
        self.add(rc, x, n1)
        self.play(FadeOut(x))
        self.play(Transform(n1,n2))
        self.wait()
        self.play(Transform(n1,n3))
        self.play(mytrans(rc, ef3, [2,3,0.2,15.26]), Transform(rc[3], ef3plus), Transform(rc[0:2].copy(), ef3[11:15]), Transform(rc[0:2].copy(), ef3[7:11]))
        self.play(GrowFromCenter(ef3[0]), GrowFromCenter(ef3[1]), GrowFromCenter(ef3[2]))
        self.clear()
        self.add(vgef, n1)
        self.play(Transform(n1,n4))
        self.play(vgef.animate.scale(0.6))
        self.play(vgef.animate.shift(5*LEFT))
        self.play(Write(rect), FadeIn(pic))
        self.play(GrowFromCenter(picnote))
        self.wait()
        self.play(FadeOut(rect, pic, picnote))
        self.play(Restore(vgef))
        self.play(Transform(n1,n5))
        self.wait()
        self.play(Transform(n1,n6))
        self.play(mytrans(ef3, loose, [3,3,0,0,15,13,16,14,17,12,18.26,15,1,2,11,8,12,9,13,10,2,1,7,5,8,6,9,4,14,11,10,7]), Transform(ef3plus, loose[16]))
        self.clear()
        self.add(n1, loose)
        self.play(Transform(n1,n7))
        self.wait()
        self.play(Transform(n1,n8))
        self.wait()
        self.play(FadeOut(n1, loose))

 

%%manim -v WARNING -qh s7
# , disable_ligatures=True, alignment="center"
class s7(Scene):
    def construct(self):
        def para(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)
        
        def fn(a, b):
            n1 = str.find(a.text ,b)
            n2 = n1 + len(b)
            return a[n1:n2]
        
        def check(svg):
            n = 0
            for i in svg:
                num = Integer(number=n).scale(0.6).set_color(RED).move_to(i)
                n += 1
                self.add(num)
                self.add(svg.set_opacity(0.5))
        
        class narrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(DOWN)
                self.scale(0.6)
        
        def mytrans(a, b, c):
            n = int(len(c)/2)
            ag = 'AnimationGroup('
#             range(0, n-1)是错的
            for i in range(0, n):
                s = str(i)
                if len(c[2*i]) == 2:
                    u = f'[c[2*{s}][0]:c[2*{s}][1]]'
                else:
                    u = f'[c[2*{s}][0]]'
                if len(c[2*i+1]) == 2:
                    v = f'[c[2*{s}+1][0]:c[2*{s}+1][1]]'
                else:
                    v = f'[c[2*{s}+1][0]]'
                ag += f'Transform(a{u}, b{v}),'
            ag += ')'
            agg = eval(ag)
            return agg
        
        note = narrator('p-π共轭').scale(1.5)
        benzyl1 = SVGMobject(r'D:\manimSVG\benzyl1.svg').scale(1.5)
        benzyl2 = SVGMobject(r'D:\manimSVG\benzyl2.svg')
        benzyl3 = SVGMobject(r'D:\manimSVG\benzyl3.svg').scale(2)
        benzyl3[19].set_sheen(0.3)
        benzyl3[20].set_sheen(0.3)
        benzyl3[21].set_sheen(0.3)
        benzyl3[22].set_sheen(0.3)
        benzyl3[23].set_sheen(0.3)
        benzyl3[24].set_sheen(0.3)
        benzyl3[27].set_sheen(0.3)
        name1 = SVGMobject(r'D:\manimSVG\name1.svg').scale(0.4).shift(UP)
        name1.save_state()
        name3 = SVGMobject(r'D:\manimSVG\name3.svg').scale(0.4).shift(DOWN)
        name3.save_state()
        
        name0 = name1.copy()
        name2 = SVGMobject(r'D:\manimSVG\name2.svg').scale(0.6)
        note[2].set_color(GREEN).set_sheen(0.3)
        note[0].set_color('#58c4dd').set_sheen(0.3)
        n1 = narrator('此外,苯甲型卤化物与烯丙型卤化物的π电子可以和')
        fn(n1, "苯甲型卤化物").set_color(RED).set_sheen(0.3)
        fn(n1, "烯丙型卤化物").set_color(BLUE).set_sheen(0.3) 
        n2 = narrator('碳正离子的空轨道发生共轭效应,体系比较稳定')
        n3 = narrator('故这两种化合物表现得特别活泼')
        n4 = MarkupText(r'<span font="STZhongsong">它们既可进行</span>S<sub>N</sub>1<span font="STZhongsong">反应,又可进行</span>S<sub>N</sub>2<span font="STZhongsong">反应</span>').to_edge(DOWN).scale(0.6)

#         self.add(name1,name3)
#         self.wait()
#         check(benzyl3)
#         self.wait()
#         self.clear()
        
        self.play(DrawBorderThenFill(name1), DrawBorderThenFill(name3))
        self.play(name1.animate.set_color(RED), name3.animate.set_color(BLUE))
        self.play(name1.animate.set_sheen(0.3), name3.animate.set_sheen(0.3),run_time=0.5)
        self.play(DrawBorderThenFill(n1))
        self.wait()
        self.play(Transform(n1,n2))
        self.wait()
        self.play(Transform(n1,n3))
        self.wait()
        self.play(Transform(n1,n4))
        self.wait()
        self.play(FadeOut(n1), Restore(name1), Restore(name3))
        self.play(FadeOut(name3))
        self.play(name1.animate.shift(DOWN))
        self.play(mytrans(name1, name2, [[0],[0],[1],[1],[2],[2],[3],[3],[4],[4],[5],[5,7]]))
        self.wait()
        self.clear()
        self.add(name2)
        self.play(Transform(name2[0:2],VGroup(benzyl1[0:7], benzyl1[11])), mytrans(name2,benzyl1,[[2],[7],[3],[8],[4],[9]]), Transform(VGroup(name2[5],name2[6]), benzyl1[10]))
        self.wait()
        self.clear()
        self.add(benzyl1)
        self.play(mytrans(benzyl1,benzyl2,[[0],[0],[1],[1],[2],[2],[3],[3],[4],[4],[5],[5],[6],[6],[7],[7],[8],[8],[9],[9],[10],[10],[11],[11]]))
        self.wait()
        self.clear()
        self.add(benzyl2)
        self.play(benzyl2[10].animate.set_sheen(0.3), run_time=0.5)
        self.play(benzyl2[10].animate.set_color(BLUE), run_time=0.5)
        self.play(benzyl2[10].animate.scale(2.5),FadeOut(benzyl2[6]))
        self.play(mytrans(benzyl2,benzyl3,[[0],[0],[1],[1],[2],[2],[3],[3],[4],[4],[5],[5],[11],[6]]),
                  Transform(VGroup(benzyl2[7],benzyl2[10]), benzyl3[27]), Transform(benzyl2[8:10], VGroup(benzyl3[9:19], benzyl3[25:27])),
                  Transform(benzyl2[8:10].copy(), benzyl3[7:9]))
        self.wait()
        self.play(GrowFromPoint(benzyl3[36:38], benzyl3[20]),GrowFromPoint(benzyl3[32:34], benzyl3[19]),GrowFromPoint(benzyl3[28:30], benzyl3[21]),
                 GrowFromPoint(benzyl3[30:32], benzyl3[22]),GrowFromPoint(benzyl3[38:40], benzyl3[23]))
        self.wait()
        self.play(GrowFromCenter(benzyl3[19]), GrowFromCenter(benzyl3[20]), GrowFromCenter(benzyl3[21]), GrowFromCenter(benzyl3[22]), GrowFromCenter(benzyl3[23]), GrowFromCenter(benzyl3[24]))
        self.play(Write(benzyl3[34]), Write(benzyl3[35]), Write(benzyl3[40]), Write(benzyl3[41]))
        self.clear()
        self.add(benzyl3)
        self.play(DrawBorderThenFill(note))
        self.wait()
        self.play(FadeOut(note), Transform(benzyl3, name0))
        self.play(FadeIn(name3))
        self.wait()

 

%%manim -v WARNING -qh s8
# , disable_ligatures=True, alignment="center"
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

def mytrans(a, b, c):
            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

def check(me, svg):
            n = 0
            for i in svg:
                num = Integer(number=n).scale(0.6).set_color(RED).move_to(i)
                n += 1
                me.add(num)
                me.add(svg.set_opacity(0.5))
            me.wait()
            me.clear()

class s8(Scene):
    def construct(self):
        def para(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)
        
        def fn(a, b):
            n1 = str.find(a.text ,b)
            n2 = n1 + len(b)
            return a[n1:n2]
        
        class narrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(DOWN)
                self.scale(0.6)
        
        
        note = narrator('p-π共轭').scale(1.5)
        note[2].set_color(GREEN).set_sheen(0.3)
        note[0].set_color('#58c4dd').set_sheen(0.3)
        name1 = SVGMobject(r'D:\manimSVG\name1.svg').scale(0.4).shift(UP)
        name3 = SVGMobject(r'D:\manimSVG\name3.svg').scale(0.4).shift(DOWN)
        name0 = name3.copy()
        name4 = SVGMobject(r'D:\manimSVG\name4.svg').scale(0.5)
        guo1 = SVGMobject(r'D:\manimSVG\guo1.svg').scale(1.5)
        guo2 = SVGMobject(r'D:\manimSVG\guo2.svg').scale(2.3)
        allylic = SVGMobject(r'D:\manimSVG\allylic.svg').scale(2.3)
        
#         check(self,guo2)
#         check(self,allylic)
#         check(self,allylic)
#         self.wait()
#         check(name4)
#         self.wait()
#         self.clear()
        
        self.add(name1,name3)
        self.play(FadeOut(name1))
        self.play(name3.animate.shift(UP))
        self.play(mytrans(name3,name4,[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,10,9,8,10,9]))
        self.wait()
        self.clear()
        self.add(name4)
        self.play(mytrans(name4,guo1,[0,5,1,6,2,7,3,[0,4],4,11,5,1,6,2,7,3,10,10,8,8,9,9]))
        self.wait()
        self.clear()
        self.add(guo1)
        self.play(mytrans(guo1,guo2,[7,3,8,4,9,5,0,0,4,2,1,1,10,16,'5.7','8.10',11,'10.12','2.4','14.16']), Transform(guo1[5:7].copy(), guo2[6:8]), Transform(guo1[2:4].copy(), guo2[12:14]))
        self.wait()
        self.clear()
        self.add(guo2)
        self.play(guo2[4].animate.set_color(GREEN), guo2[16].animate.set_color(BLUE))
        self.play(guo2[4].animate.set_sheen(0.5), guo2[16].animate.set_sheen(0.5), run_time=0.5)
        self.play(Flash(guo2[4], color=GREEN, radius=3, line_length=0.5), Flash(guo2[16], color=BLUE, radius=5, line_length=0.5))
        self.wait()
        self.play(mytrans(guo2,allylic,['8.10','12.14','6.8','10.12',3,0,4,[14,17],5,2,0,1,10,15,11,16,2,4,1,3,16,9,'14.16','7.9','12.14','5.7']))
        self.wait()
        self.clear()
        self.add(allylic)
        self.play(Write(allylic[18:20]))
        self.play(DrawBorderThenFill(note))
        self.wait()
        self.play(FadeOut(note), Transform(allylic, name0))
        self.play(FadeIn(name1))
        self.wait()
        self.play(FadeOut(allylic, name1))

 

%%manim -v WARNING -qh s9
# , disable_ligatures=True, alignment="center"
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

def mytrans(a, b, c):
            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

def check(me, svg):
            n = 0
            for i in svg:
                num = Integer(number=n).scale(0.6).set_color(RED).move_to(i)
                n += 1
                me.add(num)
                me.add(svg.set_opacity(0.5))
            me.wait()
            me.clear()

def neg(a):
    b = Text(a)
    neg = Text('-').move_to(b.get_corner(UR)).shift(0.2*RIGHT)
    return VGroup(b, neg)

def align(a,b):
    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())
    return b

def bond(a):
    a[1].set_y(a[0].get_y())
    return a
    
class s9(Scene):
    def construct(self):
        def para(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)
        
        def fn(a, b):
            n1 = str.find(a.text ,b)
            n2 = n1 + len(b)
            return a[n1:n2]
        
        class narrator(Text):
            def __init__(
                self,
                *text_parts,
                font: str = "STZhongsong",
                **kwargs
            ):
                self.font = font
                super().__init__(*text_parts,font=font,**kwargs)
                self.to_edge(DOWN)
                self.scale(0.6)
        
        
        item2 = Text('②离去基团的影响', font='STZhongsong')
        n1 = MarkupText(r'<span font="STZhongsong">离去基团的离去能力强,对</span>S<sub>N</sub>1<span font="STZhongsong">和</span>S<sub>N</sub>2<span font="STZhongsong">反应均有利</span>').to_edge(DOWN).scale(0.6)
        li1 = VGroup(neg('F'), Text('<'), neg('Cl'), Text('<'), neg('Br'), Text('<'), neg('I')).set_color_by_gradient(BLUE_A,BLUE_E).arrange(buff=0.8).shift(0.6*RIGHT)
        li02 = VGroup(MathTex('10^{-2}'), Text('<'), MathTex('1'), Text('<'), MathTex('50'), Text('<'), MathTex('150')).set_color_by_gradient(BLUE_A,BLUE_E).shift(DOWN)
        li2 = align(li1,li02)
        note1 = narrator('相对速率').scale(1.2).set_color(BLUE).set_sheen(0.3).next_to(li2, 3*LEFT)
        vgli = VGroup(li1,li2,note1)
        vgli.save_state()
        n2 = narrator('断裂键的键能越小,键就越容易断裂')
        n3 = narrator('离去基团的碱性越弱,形成的负离子就越稳定,离去的倾向就越大')
        n4 = narrator('这样的基团是好的离去基团')
        q1 = bond(Text('C—F'))
        q2 = bond(Text('C—Cl'))
        q3 = bond(Text('C—Br'))
        q4 = bond(Text('C—I'))
        li30 = VGroup(q1,Text('>'),q2,Text('>'),q3,Text('>'),q4).set_color_by_gradient(GOLD_E,GOLD_A)
        li3 = align(li1,li30).shift(DOWN)
        li40 = VGroup(MathTex('485.3'),Text('>'), MathTex('339.0'),Text('>'), MathTex('284.5'),Text('>'), MathTex('217.6')).set_color_by_gradient(GOLD_E,GOLD_A)
        li4 = align(li1,li40).shift(2*DOWN)
        note2 = narrator('键能/(kJ/mol)').scale(0.8).set_color(GOLD).set_sheen(0.3).next_to(li4, 3*LEFT).set_x(note1.get_x())
        vgli2 = VGroup(li3,li4,note2)
        li50 = VGroup(Text('HF'),Text('<'),Text('HCl'),Text('<'),Text('HBr'),Text('<'),Text('HI')).set_color_by_gradient(RED_A,RED_E)
        li5 = align(li1,li50).shift(DOWN)
        note3 = narrator('酸性').scale(1.2).set_color(RED).set_sheen(0.3).next_to(li5, 3*LEFT).set_x(note1.get_x())
        li60 = VGroup(neg('F'), Text('>'), neg('Cl'), Text('>'), neg('Br'), Text('>'), neg('I')).set_color_by_gradient(GREEN_E,GREEN_A)
        li6 = align(li1,li60).shift(2*DOWN)
        note4 = narrator('碱性').scale(1.2).set_color(GREEN).set_sheen(0.3).next_to(li6, 3*LEFT).set_x(note1.get_x())
        vgli3 = VGroup(li5,note3)
        vgli4 = VGroup(li6,note4)
#         check(self,allylic)
#         self.wait()
#         check(name4)
#         self.wait()
#         self.clear()

#         self.add(li6,note4,li5,note3)
#         self.wait()

        
        self.play(GrowFromCenter(item2))
        self.wait()
        self.play(GrowFromCenter(item2, reverse_rate_function = True))
        self.play(DrawBorderThenFill(n1), DrawBorderThenFill(vgli))
        self.wait()
        self.play(Transform(n1,n2))
        self.wait()
        self.play(vgli.animate.shift(1.5*UP))
        self.play(Write(vgli2))
        self.wait()
        self.play(FadeOut(vgli2), Transform(n1,n3))
        self.play(Write(vgli3))
        self.play(Write(vgli4))
        self.wait(1.5)
        self.play(FadeOut(vgli3), FadeOut(vgli4), Transform(n1, n4))
        self.wait()
        self.play(Restore(vgli))
        self.wait()
        self.play(FadeOut(n1,vgli))

 

posted @ 2022-07-24 14:09  树叶本子  阅读(286)  评论(0)    收藏  举报