• 技术文章 >Python技术 >Python基础教程

    Python的文字特效,炫酷了!

     Ly Ly2020-06-23 17:02:28转载4797

    先上两张效果图

    20200605060828872.gif

    20200605060911444.gif

    基本结构

    总结文字特效的特点是,每个文字独立运动,都符合同一个运动规律,但每个文字之间保持一个固定的时间差。

    每个字的运动可以分成三个部分,字体大小的变化、文字位置的变化、文字颜色(透明度)的变化。

    1

    2

    3

    4

    5

    6

    7

    8

    # 把每个文字与它的三个运动结合为一个基本单位

    def newTextMotion(char, posFunc, sizeFunc, colorFunc):

        tm={}

        tm['char']=char

        tm['posFunc']= posFunc

        tm['sizeFunc']= sizeFunc

        tm['colorFunc']= colorFunc

        return tm

    文字动效的展示

    在任意一个时间点上,获得文字的显示效果。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    # 在指定的时间,计算文字的位置、大小、颜色等

    def showText(img, textMotion, time):

        char= textMotion['char']

        pos= textMotion['posFunc'](time)

        size= textMotion['sizeFunc'](time)

        color= textMotion['colorFunc'](time)

        font= ImageFont.truetype(fontName, size)

        draw = ImageDraw.Draw(im=img)

        textSize= draw.textsize(text=char, font=font)

        tx= pos[0]- textSize[0]// 2

        ty= pos[1]- textSize[1]// 2

        draw.text(xy=(tx, ty), text=char, fill=color, font=font)

    针对一组文字,形成一个列表,获取起每个时间点的显示图,作为一帧

    1

    2

    3

    4

    5

    def getTextFrame(tmList, time):

        textImg= Image.new('RGBA', (1280, 720))

        for tm in tmList:

            showText(textImg, tm, time)

        return textImg

    具体文字运动规律

    下面看看这两种特效的具体运动规律。乍一看比较复杂,但拆分为三个运动后,其实每种都比较简单。以此为模块,读者可以自行制作更多的文字特效。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    # 文字缩小

    def makeTextShrink(char, toSize, toPos, toColor, offset, dur):

        def colorFunc(time):

            if time< offset:

                return (0,0,0,0)

            if time> offset+ dur:

                return toColor

            return toColor[:-1] + (50+ round((time-offset)/dur*200),)

        def sizeFunc(time):

            if time< offset:

                return toSize* 8

            if time> offset+ dur:

                return toSize

            return toSize*8 - round((time-offset)/dur* toSize*7.5)

        def posFunc(time):

            if time< offset:

                return (0,0)

            if time> offset+ dur:

                return toPos

            # return (toPos[0], round((time-offset)/dur*toPos[1]))

            return toPos

        return newTextMotion(char, posFunc, sizeFunc, colorFunc)

    # 抛物线降落(有一个回弹效果)

    def makeTextParaDrop(char, toSize, toPos, toColor, offset, dur):

        def colorFunc(time):

            if time< offset:

                return (0,0,0,0)

            if time> offset+ dur:

                return toColor

            return toColor[:-1] + (50+ round((time-offset)/dur*200),)

        def sizeFunc(time):

            if time< offset:

                return toSize

            if time> offset+ dur:

                return toSize

            return toSize

        def posFunc(time):

            if time< offset:

                return (toPos[0], 0)

            if time> offset+ dur:

                return toPos

            r= 0.75

            dur2= dur

            a= toPos[1]/(dur2* dur2* (1- 2* r))

            b= -2* a* dur2* r

            x= (time-offset)

            return (toPos[0], round(a* x* x+ b*x))

        # print(toPos)

        return newTextMotion(char, posFunc, sizeFunc, colorFunc)

    整体设置与运行

    对于一行文字,每个增加特效,并依次给予一个延时。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    # 一行文字,给定所有参数,配置运动函数与延时

    def getMotionList(text, fontSize, fontColor, startPos, fromTime, dur, func):

        tmList=[]

        inter= round(dur/ len(text))

        for i in range(len(text)):

            char= text[i]

            pos= (startPos[0]+ i* fontSize+ 10, startPos[1])

            color= fontColor

            # tm= makeTextDropMotion(char, fontSize, pos, color, 150*i)

            tm= func(char, fontSize, pos, color, fromTime+inter*i, dur)

            tmList.append(tm)

        return tmList

    这里,将不同的文字特效函数作为参数传入即可,有比较好的扩展性。

    最后是一个展示函数,用了imageio来制作gif图。这里注意两个地方,第一是展示时间应当是单文字运动时间的两倍。为了确保动感,当第一个文字到位时,最后一个文字恰好启动,所以时间是两倍的关系。

    第二是制作GIF的延时应当与计算用的延时一致,这里都是50毫秒(20fps)。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    def showTextDrop(text, startPos, func):

        fontSize= 50

        color=(255, 255,  0, 255)

        tmList= getMotionList(text, fontSize, color, startPos, 0, 1000, func)

        frames=[]

        outfilename='temp.gif'

        for i in range(0, 2000, 50):

            print(i)

            img= Image.new('RGB', (640, 360))

            # img= Image.open('back.png').resize((640, 360), Image.ANTIALIAS)

            # img = img.convert("RGB")  

            textImg= getTextFrame(tmList, i)

            r, g, b, a= textImg.split()

            img.paste(textImg, (0,0), mask= a)

            str1= 'tempAA.png'

            img.save(str1)

            im = imageio.imread(str1)

            frames.append(im)

        imageio.mimsave(outfilename, frames, 'GIF', duration=0.05)

         

    if __name__=='__main__':

        # showTextDrop('淡妆浓抹总相宜', (150,200), makeTextParaDrop)

        showTextDrop('淡妆浓抹总相宜', (150,200), makeTextDropMotion)

    更多Python知识,请关注Python视频教程!!

    专题推荐:python
    上一篇:Python之漂亮的太阳系——闪瞎你的双眼! 下一篇:Python中的唯美星空代码详解!

    相关文章推荐

    • python如何建立venv虚拟环境• Python之漂亮的太阳系——闪瞎你的双眼!

    全部评论我要评论

    © 2021 Python学习网 苏ICP备2021003149号-1

  • 取消发布评论
  • 

    Python学习网