Skip to content

Instantly share code, notes, and snippets.

@jaredliw
Created July 18, 2021 05:55
Show Gist options
  • Save jaredliw/424924b4a4470a71c7e5f05baee90495 to your computer and use it in GitHub Desktop.
Save jaredliw/424924b4a4470a71c7e5f05baee90495 to your computer and use it in GitHub Desktop.
Kivy skewed box layout w/ animation
#: import ScrollEffect kivy.effects.scroll.ScrollEffect
<MainScreen>:
anchor_x: "center"
anchor_y: "center"
canvas.before:
Color:
rgba: root.config["background_color_dark"]
Rectangle:
size: self.size
pos: self.pos
HoverBoxLayout:
id: card
size_hint: (0.3, 0.6)
shear: root.config["border_width"]
canvas.before:
Color:
rgba: root.config["border_color"][0]
Quad:
points: (self.pos[0], self.pos[1]+self.size[1], self.pos[0], self.pos[1]+self.size[1]*0.5, self.pos[0]-root.config["border_width"], self.pos[1]+self.size[1]+root.config["border_width"], self.pos[0]+self.size[0]*0.5, self.pos[1]+self.size[1])
Color:
rgba: root.config["border_color"][1]
Quad:
points: (self.pos[0]+self.size[0], self.pos[1]+self.size[1], self.pos[0]+self.size[0], self.pos[1]+self.size[1]*0.5, self.pos[0]+self.size[0]+root.config["border_width"], self.pos[1]+self.size[1]+root.config["border_width"], self.pos[0]+self.size[0]*0.5, self.pos[1]+self.size[1])
Color:
rgba: root.config["border_color"][2]
Quad:
points: (self.pos[0]+self.size[0], self.pos[1], self.pos[0]+self.size[0]*0.5, self.pos[1], self.pos[0]+self.size[0]+root.config["border_width"], self.pos[1]-root.config["border_width"], self.pos[0]+self.size[0], self.pos[1]+self.size[1]*0.5)
Color:
rgba: root.config["border_color"][3]
Quad:
points: (self.pos[0], self.pos[1], self.pos[0]+self.size[0]*0.5, self.pos[1], self.pos[0]-root.config["border_width"], self.pos[1]-root.config["border_width"], self.pos[0], self.pos[1]+self.size[1]*0.5)
Color:
rgba: root.config["background_color_light"]
Rectangle:
size: (self.size[0]*0.5, self.size[1])
pos: self.pos
AnchorLayout:
anchor_x: "center"
anchor_y: "center"
AnchorLayout:
anchor_x: "center"
anchor_y: "center"
padding: (self.size[1]*0.1, self.size[0]*0.1)
BoxLayout:
orientation: "vertical"
size_hint: (0.25, 0.6)
Label:
text: "01"
bold: True
font_size: 230
color: root.config["background_text_color"]
Widget:
id: bg_text_padding
size_hint_y: None
height: root.config["background_animation_initial_position"]
BoxLayout:
orientation: "vertical"
padding: (0, 0, 0, 30)
Widget:
size_hint_y: 0.1
MDLabel:
font_style: "H4"
text: "Lorem Ipsum"
theme_text_color: "Custom"
text_color: (1, 1, 1, 1)
ScrollView:
effect_cls: ScrollEffect
MDLabel:
font_style: "Body1"
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
theme_text_color: "Custom"
text_color: (1, 1, 1, 1)
bg_color: (1, 0, 1, 1)
size_hint_y: None
height: self.texture_size[1]
HoverMDRectangleFlatButton:
id: btn
text: "Learn more"
text_color: (1, 1, 1, 1)
opacity: 0
from typing import Any
from kivy import Config
from kivy.animation import Animation
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivymd.app import MDApp
from kivymd.uix.behaviors import HoverBehavior
from kivymd.uix.button import MDRectangleFlatButton
CONFIGURATION = {
"background_color_dark": (7 / 255, 11 / 255, 34 / 255, 1),
"background_color_light": (18 / 255, 22 / 255, 43 / 255, 0.5),
"background_text_color": (20 / 255, 24 / 255, 47 / 255, 1),
"border_width": 10,
"border_color": [(230 / 255, 72 / 255, 28 / 255, 1),
(0, 0, 0, 0),
(213 / 255, 2 / 255, 70 / 255, 1),
(0, 0, 0, 0)], # (upper_left, upper_right, lower_right, lower_left)
"animation_duration": 0.1,
"background_animation_initial_position": 30,
"background_animation_distance": 170
}
Window.fullscreen = True
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
Builder.load_file("skewedboxlayout.kv")
class HoverBoxLayout(BoxLayout, HoverBehavior):
config = CONFIGURATION
def __init__(self, **kwargs):
super(HoverBoxLayout, self).__init__(**kwargs)
Window.maximize()
self._const_pos = None
self.init_trigger = False
self.init_clock = Clock.schedule_interval(self.set_const_pos, 0.1)
def on_enter(self, *args: Any) -> None:
if self._const_pos is None:
self.init_trigger = True
return
anim = Animation(
height=self.config["background_animation_initial_position"] + self.config["background_animation_distance"],
duration=self.config["animation_duration"])
anim.bind(on_start=self.enter_parallel_anim)
anim.start(MDApp.get_running_app().root.ids.bg_text_padding)
def on_leave(self, *args: Any) -> None:
anim = Animation(height=self.config["background_animation_initial_position"],
duration=self.config["animation_duration"])
anim.bind(on_start=self.leave_parallel_anim)
anim.start(MDApp.get_running_app().root.ids.bg_text_padding)
def enter_parallel_anim(self, *_: Any) -> None:
MDApp.get_running_app().root.ids.btn.pos[1] = self._const_pos
p_anim = Animation(opacity=1, duration=self.config["animation_duration"])
p_anim &= Animation(y=MDApp.get_running_app().root.ids.btn.pos[1] - MDApp.get_running_app().root.ids.btn.height,
duration=self.config["animation_duration"])
p_anim.start(MDApp.get_running_app().root.ids.btn)
def leave_parallel_anim(self, *_: Any) -> None:
p_anim = Animation(opacity=0, duration=self.config["animation_duration"])
p_anim &= Animation(y=MDApp.get_running_app().root.ids.btn.pos[1] + MDApp.get_running_app().root.ids.btn.height,
duration=self.config["animation_duration"])
p_anim.start(MDApp.get_running_app().root.ids.btn)
def set_const_pos(self, *_: Any) -> None:
if MDApp.get_running_app().root.ids.btn.pos[1] != 0:
self._const_pos = MDApp.get_running_app().root.ids.btn.pos[1]
Clock.unschedule(self.set_const_pos)
if self.init_trigger:
self.on_enter()
class HoverMDRectangleFlatButton(MDRectangleFlatButton, HoverBehavior):
def on_enter(self, *args: Any) -> None:
self.md_bg_color = (1, 1, 1, 1)
self.text_color = (20 / 255, 24 / 255, 47 / 255, 1)
def on_leave(self, *args: Any) -> None:
self.text_color = (1, 1, 1, 1)
self.md_bg_color = (0, 0, 0, 0)
class MainScreen(AnchorLayout):
config = CONFIGURATION
class Application(MDApp):
title = "SkewedBoxLayout Showcase"
def __init__(self, **kwargs: Any) -> None:
super(Application, self).__init__(**kwargs)
def build(self) -> MainScreen:
return MainScreen()
if __name__ == "__main__":
Application().run()
@jaredliw
Copy link
Author

showcase

@jaredliw
Copy link
Author

Inspired by this Youtube video from Online Tutorials.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment