Skip to content

Commit 2499bda

Browse files
committed
progress
1 parent fc49b0e commit 2499bda

File tree

6 files changed

+115
-30
lines changed

6 files changed

+115
-30
lines changed

Diff for: examples/material_motion.py

Whitespace-only changes.

Diff for: examples/md_axis_transition.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@
4141
text:root.subtext
4242
font_style:"Label"
4343
role:"large"
44-
theme_text_color:"Custom"
45-
text_color:app.theme_cls.surfaceContainerLowestColor[:-1] + [0.5]
44+
text_color:app.theme_cls.onSurfaceVariantColor
4645
4746
<SettingsScreen@MDScreen>:
4847
name:"main"
@@ -96,7 +95,7 @@
9695
font_style:"Body"
9796
role:"large"
9897
theme_text_color:"Custom"
99-
text_color:app.theme_cls.surfaceContainerLowestColor[:-1] + [0.5]
98+
text_color:app.theme_cls.onSurfaceVariantColor
10099
Image:
101100
size_hint_y:1
102101
source:app.image_path

Diff for: kivymd/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,5 @@
6060

6161
import kivymd.factory_registers # NOQA
6262
import kivymd.font_definitions # NOQA
63+
import kivymd.motion # NOQA
6364
from kivymd.tools.packaging.pyinstaller import hooks_path # NOQA

Diff for: kivymd/motion.py

+33-23
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@
33
"""
44

55
import math
6+
import kivy.animation
67

78
float_epsilon = 8.3446500e-7
89

10+
911
class CubicBezier:
12+
"""Ported from Android source code"""
13+
1014
p0 = 0
1115
p1 = 0
1216
p2 = 0
1317
p3 = 0
14-
18+
1519
def __init__(self, *args):
1620
self.p0, self.p1, self.p2, self.p3 = args
17-
21+
1822
def evaluate_cubic(self, p1, p2, t):
1923
a = 1.0 / 3.0 + (p1 - p2)
2024
b = p2 - 2.0 * p1
@@ -37,13 +41,12 @@ def clamp_range(self, r):
3741

3842
def close_to(self, x, y):
3943
return abs(x - y) < float_epsilon
40-
44+
4145
def find_first_cubic_root(self, p0, p1, p2, p3):
4246
a = 3.0 * (p0 - 2.0 * p1 + p2)
4347
b = 3.0 * (p1 - p0)
4448
c = p0
4549
d = -p0 + 3.0 * (p1 - p2) + p3
46-
4750
if self.close_to(d, 0.0):
4851
if self.close_to(a, 0.0):
4952
if self.close_to(b, 0.0):
@@ -52,21 +55,18 @@ def find_first_cubic_root(self, p0, p1, p2, p3):
5255
else:
5356
q = math.sqrt(b * b - 4.0 * a * c)
5457
a2 = 2.0 * a
55-
5658
root = self.clamp_range((q - b) / a2)
5759
if not math.isnan(root):
5860
return root
59-
6061
return self.clamp_range((-b - q) / a2)
61-
6262
a /= d
6363
b /= d
6464
c /= d
6565
o3 = (3.0 * b - a * a) / 9.0
6666
q2 = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0
6767
discriminant = q2 * q2 + o3 * o3 * o3
6868
a3 = a / 3.0
69-
69+
7070
if discriminant < 0.0:
7171
mp33 = -(o3 * o3 * o3)
7272
r = math.sqrt(mp33)
@@ -77,12 +77,16 @@ def find_first_cubic_root(self, p0, p1, p2, p3):
7777
root = self.clamp_range(t1 * math.cos(phi / 3.0) - a3)
7878
if not math.isnan(root):
7979
return root
80-
root = self.clamp_range(t1 * math.cos((phi + 2.0 * math.pi) / 3.0) - a3)
80+
root = self.clamp_range(
81+
t1 * math.cos((phi + 2.0 * math.pi) / 3.0) - a3
82+
)
8183
if not math.isnan(root):
8284
return root
83-
return self.clamp_range(t1 * math.cos((phi + 4.0 * math.pi) / 3.0) - a3)
85+
return self.clamp_range(
86+
t1 * math.cos((phi + 4.0 * math.pi) / 3.0) - a3
87+
)
8488

85-
elif self.close_to(discriminant, 0.0):
89+
elif self.close_to(discriminant, 0.0):
8690
u1 = -math.cbrt(q2)
8791
root = self.clamp_range(2.0 * u1 - a3)
8892
if not math.isnan(root):
@@ -94,24 +98,30 @@ def find_first_cubic_root(self, p0, p1, p2, p3):
9498
v1 = math.cbrt(q2 + sd)
9599
return self.clamp_range(u1 - v1 - a3)
96100

97-
def transform(self, value: float):
101+
def t(self, value: float):
98102
return self.evaluate_cubic(
99-
self.p1, self.p3, self.find_first_cubic_root(
103+
self.p1,
104+
self.p3,
105+
self.find_first_cubic_root(
100106
-value,
101107
self.p0 - value,
102108
self.p2 - value,
103109
1.0 - value,
104-
)
110+
),
105111
)
106112

107113

108-
class MaterialMotion:
114+
class MaterialMotion(kivy.animation.AnimationTransition):
115+
"""KivyMD's equivalent of kivy's `AnimationTransition`"""
109116

110-
easing_standard = CubicBezier(0.4, 0.0, 0.2, 1.0)
111-
easing_decelerated = CubicBezier(0.0, 0.0, 0.2, 1.0)
112-
easing_accelerated = CubicBezier(0.4, 0.0, 1.0, 1.0)
113-
easing_linear = CubicBezier(0.0, 0.0, 1.0, 1.0)
114-
115-
# TODO: add `easing_emphasized` here
116-
# it's defination is
117-
# path(M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1)
117+
easing_standard = CubicBezier(0.4, 0.0, 0.2, 1.0).t
118+
easing_decelerated = CubicBezier(0.0, 0.0, 0.2, 1.0).t
119+
easing_accelerated = CubicBezier(0.4, 0.0, 1.0, 1.0).t
120+
easing_linear = CubicBezier(0.0, 0.0, 1.0, 1.0).t
121+
122+
# TODO: add `easing_emphasized` here
123+
# it's defination is
124+
# path(M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1)
125+
126+
# Monkey patch kivy's animation module
127+
kivy.animation.AnimationTransition = MaterialMotion

Diff for: kivymd/uix/transition/transition.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ def start(self, manager):
402402
# Save hash of the objects
403403
self.ih = hash(self.screen_in)
404404
self.oh = hash(self.screen_out)
405-
405+
406406
# Init pos
407407
self.screen_in.pos = manager.pos
408408
self.screen_out.pos = manager.pos
@@ -439,9 +439,7 @@ def start(self, manager):
439439

440440
def on_progress(self, progress):
441441
# This code could be simplyfied with setattr, but it's slow
442-
progress = getattr(MaterialMotion, self.switch_animation).transform(
443-
progress
444-
)
442+
progress = getattr(MaterialMotion, self.switch_animation)(progress)
445443
progress_i = progress - 1
446444
progress_d = progress * 2
447445
# first half

Diff for: main.py

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from kivy.lang import Builder
2+
from kivy.animation import Animation
3+
from kivy.uix.boxlayout import BoxLayout
4+
from kivy.clock import Clock
5+
from kivy.metrics import dp
6+
from kivy.properties import ListProperty
7+
8+
from kivymd.app import MDApp
9+
10+
11+
class AnimBox(BoxLayout):
12+
obj_pos = ListProperty([0, 0])
13+
14+
15+
UI = """
16+
<AnimBox>:
17+
transition:"in_out_bounce"
18+
size_hint_y:None
19+
height:dp(100)
20+
obj_pos:[dp(40), self.pos[-1] + dp(40)]
21+
canvas:
22+
Color:
23+
rgba:app.theme_cls.primaryContainerColor
24+
Rectangle:
25+
size:[self.size[0], dp(5)]
26+
pos:self.pos[0], self.pos[-1] + dp(50)
27+
Color:
28+
rgba:app.theme_cls.primaryColor
29+
Rectangle:
30+
size:[dp(30)] * 2
31+
pos:root.obj_pos
32+
MDLabel:
33+
adaptive_height:True
34+
text:root.transition
35+
padding:[dp(10), 0]
36+
halign:"center"
37+
38+
MDGridLayout:
39+
orientation:"lr-tb"
40+
cols:1
41+
md_bg_color:app.theme_cls.backgroundColor
42+
spacing:dp(10)
43+
"""
44+
45+
46+
class MotionApp(MDApp):
47+
48+
def build(self):
49+
return Builder.load_string(UI)
50+
51+
def on_start(self):
52+
for transition in [
53+
"easing_linear",
54+
"easing_accelerated",
55+
"easing_decelerated",
56+
"easing_standard",
57+
"in_out_cubic"
58+
]: # Add more here for comparison
59+
print(transition)
60+
widget = AnimBox()
61+
widget.transition = transition
62+
self.root.add_widget(widget)
63+
Clock.schedule_once(self.run_animation, 1)
64+
65+
_inverse = True
66+
67+
def run_animation(self, dt):
68+
x = (self.root.children[0].width - dp(30)) if self._inverse else 0
69+
for widget in self.root.children:
70+
Animation(
71+
obj_pos=[x, widget.obj_pos[-1]], t=widget.transition, d=3
72+
).start(widget)
73+
self._inverse = not self._inverse
74+
Clock.schedule_once(self.run_animation, 3.1)
75+
76+
77+
MotionApp().run()

0 commit comments

Comments
 (0)