Как да анимирате размера на шрифта без пренареждане на текста, когато `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()

person user    schedule 11.05.2016    source източник


Отговори (2)


Можете да анимирате разтягане на текста вместо неговия размер на шрифта. Това би било малко по-малко графично прецизно (като уголемяването на малко изображение изглежда размазано), но може да е достатъчно добро в зависимост от вашите параметри. Освен това би било много по-ефективно; анимирането на размера на шрифта изисква повторно изобразяване на текстурата всеки път.

Имам много прост пример за използване на инструкция за мащабиране за това, която можете да намерите тук.

person inclement    schedule 11.05.2016
comment
Ако използвам scale в джаджа, която е дете на BoxLayout, няма ли да принуди други деца в това BoxLayout също да променят размера? - person user; 12.05.2016
comment
Можете да използвате PushMatrix и PopMatrix, за да ограничите къде мащабът влиза в сила. - person inclement; 12.05.2016
comment
Тъй като връзките могат да се повредят, включих кода от вашата връзка в отговор по-долу. Може да е полезно за посетителите (т.е. по-бързо за използване), ако включите този код в отговора си (разбира се, не се изисква приписване; все пак това е вашият код). Ако го направите, уведомете ме, за да мога да изтрия отговора си. (Не редактирах кода във вашия отговор, тъй като това би било твърде съществена промяна) - person user; 13.05.2016

Използвайки кода, предложен от inclement, в крайна сметка получавам следния код, който се държи, както е описано в отговорът му:

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()
person user    schedule 13.05.2016