Sideband/sbapp/kivymd/uix/behaviors/magic_behavior.py

190 lines
4.5 KiB
Python

"""
Behaviors/Magic
===============
.. rubric:: Magical effects for buttons.
.. warning:: Magic effects do not work correctly with `KivyMD` buttons!
To apply magic effects, you must create a new class that is inherited from the
widget to which you apply the effect and from the :attr:`MagicBehavior` class.
In `KV file`:
.. code-block:: kv
<MagicButton@MagicBehavior+MDRectangleFlatButton>
In `python file`:
.. code-block:: python
class MagicButton(MagicBehavior, MDRectangleFlatButton):
pass
.. rubric:: The :attr:`MagicBehavior` class provides five effects:
- :attr:`MagicBehavior.wobble`
- :attr:`MagicBehavior.grow`
- :attr:`MagicBehavior.shake`
- :attr:`MagicBehavior.twist`
- :attr:`MagicBehavior.shrink`
Example:
.. code-block:: python
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
<MagicButton@MagicBehavior+MDRectangleFlatButton>
MDFloatLayout:
MagicButton:
text: "WOBBLE EFFECT"
on_release: self.wobble()
pos_hint: {"center_x": .5, "center_y": .3}
MagicButton:
text: "GROW EFFECT"
on_release: self.grow()
pos_hint: {"center_x": .5, "center_y": .4}
MagicButton:
text: "SHAKE EFFECT"
on_release: self.shake()
pos_hint: {"center_x": .5, "center_y": .5}
MagicButton:
text: "TWIST EFFECT"
on_release: self.twist()
pos_hint: {"center_x": .5, "center_y": .6}
MagicButton:
text: "SHRINK EFFECT"
on_release: self.shrink()
pos_hint: {"center_x": .5, "center_y": .7}
'''
class Example(MDApp):
def build(self):
return Builder.load_string(KV)
Example().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/magic-button.gif
:width: 250 px
:align: center
"""
__all__ = ("MagicBehavior",)
from kivy.animation import Animation
from kivy.lang import Builder
from kivy.properties import NumericProperty
Builder.load_string(
"""
<MagicBehavior>
translate_x: 0
translate_y: 0
scale_x: 1
scale_y: 1
rotate: 0
canvas.before:
PushMatrix
Translate:
x: self.translate_x or 0
y: self.translate_y or 0
Rotate:
origin: self.center
angle: self.rotate or 0
Scale:
origin: self.center
x: self.scale_x or 1
y: self.scale_y or 1
canvas.after:
PopMatrix
"""
)
class MagicBehavior:
magic_speed = NumericProperty(1)
"""
Animation playback speed.
:attr:`magic_speed` is a :class:`~kivy.properties.NumericProperty`
and defaults to `1`.
"""
def grow(self) -> None:
"""Grow effect animation."""
(
Animation(
scale_x=1.2,
scale_y=1.2,
t="out_quad",
d=0.03 / self.magic_speed,
)
+ Animation(
scale_x=1, scale_y=1, t="out_elastic", d=0.4 / self.magic_speed
)
).start(self)
def shake(self) -> None:
"""Shake effect animation."""
(
Animation(translate_x=50, t="out_quad", d=0.02 / self.magic_speed)
+ Animation(
translate_x=0, t="out_elastic", d=0.5 / self.magic_speed
)
).start(self)
def wobble(self) -> None:
"""Wobble effect animation."""
(
(
Animation(scale_y=0.7, t="out_quad", d=0.03 / self.magic_speed)
& Animation(
scale_x=1.4, t="out_quad", d=0.03 / self.magic_speed
)
)
+ (
Animation(scale_y=1, t="out_elastic", d=0.5 / self.magic_speed)
& Animation(
scale_x=1, t="out_elastic", d=0.4 / self.magic_speed
)
)
).start(self)
def twist(self) -> None:
"""Twist effect animation."""
(
Animation(rotate=25, t="out_quad", d=0.05 / self.magic_speed)
+ Animation(rotate=0, t="out_elastic", d=0.5 / self.magic_speed)
).start(self)
def shrink(self) -> None:
"""Shrink effect animation."""
Animation(
scale_x=0.95, scale_y=0.95, t="out_quad", d=0.1 / self.magic_speed
).start(self)
def on_touch_up(self, *args):
Animation.stop_all(self)
return super().on_touch_up(*args)