import flet as ft
import random
import asyncio
def get_random_pos() -> int:
return random.randint(1, 1280)
def get_random_color() -> str:
colors = ['blue', 'white']
return random.choice(colors)
def get_random_offset() -> int:
return random.randint(1, 5)
def get_random_wait() -> int:
return random.randrange(500, 700, 100)
class Thing(ft.Container):
def __init__(self):
color = get_random_color()
super().__init__(
left=get_random_pos(),
top=get_random_pos(),
width=2.5,
height=2.5,
shape=ft.BoxShape(ft.BoxShape.CIRCLE),
bgcolor=color,
opacity=0,
offset=ft.transform.Offset(0, 0),
shadow=ft.BoxShadow(spread_radius=20, blur_radius=100, color=color)
)
self.wait = get_random_wait()
self.animate_opacity = ft.Animation(self.wait, ft.AnimationCurve.EASE)
self.animate_offset = ft.Animation(self.wait, ft.AnimationCurve.EASE)
async def animate_thing(self, event=None):
self.opacity = 1
self.offset = ft.transform.Offset(get_random_offset() ** 2, get_random_offset() ** 2)
self.update()
await asyncio.sleep(self.wait / 1000)
self.opacity = 0
self.offset = ft.transform.Offset(get_random_offset() ** 2, get_random_offset() ** 2)
self.update()
await asyncio.sleep(self.wait / 1000)
await self.animate_thing()
class Input(ft.TextField):
def __init__(self, password: bool) -> None:
super().__init__(
height=38,
focused_border_color=ft.colors.BLUE,
border_radius=5,
cursor_height=16,
cursor_color=ft.colors.WHITE,
content_padding=10,
border_width=1.5,
text_size=12,
password=password
)
class LoginButton(ft.ElevatedButton):
def __init__(self, text: str):
super().__init__(
expand=True,
bgcolor=ft.colors.BLUE,
style=ft.ButtonStyle(shape={'': ft.RoundedRectangleBorder(radius=5)}),
color=ft.colors.WHITE,
text=text
)
class Body(ft.Container):
def __init__(self):
super().__init__(
width=400,
padding=15,
bgcolor=ft.colors.with_opacity(0.045, ft.colors.WHITE),
border_radius=10,
shadow=ft.BoxShadow(spread_radius=20, blur_radius=45, color=ft.colors.with_opacity(0.45, ft.colors.BLACK))
)
self.username = Input(password=False)
self.password = Input(password=True)
self.content = ft.Column(
controls=[
ft.Divider(height=10, color=ft.colors.TRANSPARENT),
ft.Text('用户名', size=10),
self.username,
ft.Divider(height=10, color=ft.colors.TRANSPARENT),
ft.Text('密 码', size=10),
self.password,
ft.Divider(height=15, color=ft.colors.TRANSPARENT),
ft.Row(controls=[LoginButton('登录')])
]
)
def main(page: ft.Page):
page.horizontal_alignment = ft.MainAxisAlignment.CENTER
page.vertical_alignment = ft.alignment.center
page.theme_mode = ft.ThemeMode.DARK
page.padding = 0
page.window_center()
print(page.window_width)
background = ft.Stack(
expand=True,
controls=[Thing() for _ in range(100)]
)
stack = ft.Stack(
expand=True,
controls=[background, ft.Column(
alignment=ft.MainAxisAlignment.CENTER,
controls=[
ft.Row(
alignment=ft.MainAxisAlignment.CENTER,
controls=[Body()]
)
]
)]
)
page.add(stack)
page.update()
async def run():
await asyncio.gather(
*(item.animate_thing() for item in background.controls)
)
asyncio.run(run())
if __name__ == '__main__':
ft.app(main)
