当`text_size=self.size`时如何在不重新排序文本的情况下设置字体大小动画

How to animate font size without text reordering, when `text_size=self.size`

我需要显示一些文本,然后再设置其字体大小的动画。文本不得超过其小部件的大小,因此我使用 text_size: self.size(不过我不介意在动画期间文本超过其小部件大小)

问题是字体大小的动画会强制文本重新排序,这很难看(动画期间图像中的红色圆圈出现)

我宁愿 确实 暂时超过了那个尺寸。

如何实现文本不超过其小部件的大小,以及在字体大小动画期间超过该大小(如下图所示)?


使用的代码:

from kivy.app import App
from kivy.uix.button import Button
from kivy.animation import Animation
from kivy.lang import Builder


kv = """
<MyWidget>:
    text: 'long text...' * 5
    text_size: self.size
    halign: 'center'
    valign: 'middle'
    on_release: self.animate_function()
"""


Builder.load_string(kv)


class MyWidget(Button):

    def animate_function(self):
        initial_font_size = self.font_size
        anim = Animation(font_size=initial_font_size * 1.5, duration=2)
        anim += Animation(font_size=initial_font_size, duration=2)
        anim.start(self)


class MyButtonsApp(App):
    def build(self):
        return MyWidget()


if __name__ == '__main__':
    MyButtonsApp().run()

您可以为文本的拉伸而不是字体大小设置动画。这在图形上会稍微不那么精确(比如放大小图像看起来很模糊),但根据您的参数可能已经足够好了。它的性能也会 ;动画字体大小需要每次重新渲染纹理。

我有一个使用 Scale 指令的非常简单的例子,你可以找到 here

使用 inclement I end up with the following code which behaves as described in 建议的代码:

from kivy.app import App
from kivy.uix.button import Button
from kivy.animation import Animation
from kivy.lang import Builder
from kivy.properties import NumericProperty


kv = """
<MyWidget>:
    text: 'long text...' * 5
    text_size: self.size
    halign: 'center'
    valign: 'middle'
    on_release: self.animate_function()

    canvas.before:
        PushMatrix:
        Scale:
            origin: self.x + 0.5*self.width, self.y + 0.5*self.height
            x: self.scale
            y: self.scale

    canvas.after:
        PopMatrix:
"""


Builder.load_string(kv)


class MyWidget(Button):
    scale = NumericProperty(1)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.initial_scale = self.scale

    def animate_function(self):

        anim = Animation(scale=self.initial_scale * 1.2, duration=.1)
        anim += Animation(scale=self.initial_scale, duration=.1)
        anim.start(self)


class MyButtonsApp(App):
    def build(self):
        return MyWidget()


if __name__ == '__main__':
    MyButtonsApp().run()