Guest User

Untitled

a guest
Jan 27th, 2024
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.55 KB | None | 0 0
  1. from kivy.app import App
  2. from kivy.app import Widget
  3. from kivy.core.window import Window
  4. from kivy.graphics import *
  5. from kivy.graphics.instructions import *
  6. from kivy.clock import *
  7. from kivy.uix.boxlayout import BoxLayout
  8. from kivy.properties import OptionProperty
  9. from random import uniform as uniform
  10. from random import randint
  11. from kivy.uix.label import Label
  12. from kivy.uix.button import Button
  13. from kivy.uix.pagelayout import PageLayout
  14. from kivy.uix.scrollview import ScrollView
  15. from kivy.animation import *
  16. import math
  17. import sys
  18.  
  19. angles_list = []
  20. small_elipse_list = []
  21. elipse_list = []
  22. ellipses = 0
  23. class SpinningCircles(Widget):
  24. direction = OptionProperty('CW', options=['CW', 'CCW'])
  25.  
  26. def __init__(self, **kwargs):
  27. super().__init__(**kwargs)
  28. self.elipses = []
  29. self.colors = []
  30. self.color = [uniform(0, 1), uniform(0, 1), uniform(0, 1), .4]
  31. self.colors.append(self.color)
  32. self.multi_angle = round(uniform(0.6, 1),2)
  33. self.multi_distance = round(uniform(0.8,1.8),2)
  34. Clock.schedule_interval(self.update, 1 / 60)
  35. # Clock.schedule_interval(self.create_circle, 3)
  36. self.create_circle()
  37. with self.canvas.before:
  38. PushMatrix()
  39. self.rotation = Rotate(angle=randint(0, 360), origin=(Window.size[0] / 2, Window.size[1] / 2))
  40. with self.canvas.after:
  41. PopMatrix()
  42.  
  43. def create_circle(self, *dt):
  44. global ellipses
  45. with self.canvas:
  46. Color(1, 0, 0, 0)
  47. self.rec1 = Rectangle(size=(Window.size[0] / self.multi_distance, Window.size[1] / 6))
  48. self.rec1.pos = (Window.size[0] / 2 - self.rec1.size[0] / 2, Window.size[1] / 2 - self.rec1.size[1] / 2)
  49. Color(*self.color)
  50. self.ellipse = Ellipse(size=(Window.size[0] / 10, Window.size[0] / 10))
  51. self.ellipse.pos = (self.rec1.pos[0], self.rec1.pos[1] + (self.rec1.size[1] - self.ellipse.size[1]) / 2)
  52. small_elipse_list.append(self.ellipse)
  53. ellipses += 1
  54. Color(self.color[0], self.color[1], self.color[2], self.color[3] + 0.4)
  55. self.ellipse3 = Ellipse(size=(Window.size[0] / 8, Window.size[0] / 8))
  56. self.ellipse3.pos = (self.rec1.pos[0], self.rec1.pos[1] + (self.rec1.size[1] - self.ellipse3.size[1]) / 2)
  57. elipse_list.append(self.ellipse3)
  58. self.line = Line(points=(Window.size[0] / 2, Window.size[1] / 2,
  59. self.ellipse3.pos[0] + self.ellipse3.size[0],
  60. self.ellipse3.pos[1] + self.ellipse3.size[1] / 2),
  61. width=1.4)
  62. self.label = Label(text=str(self.multi_angle), font_size = f"{Window.size[0]/40}dp")
  63. self.label.size = (self.ellipse3.size[0],self.ellipse3.size[1])
  64. self.label.pos = (self.ellipse3.pos[0],self.ellipse3.pos[1])
  65.  
  66. def update(self, dt):
  67. self.rotation.angle += {'CW': -1, 'CCW': 1}[self.direction] * self.multi_angle
  68. self.rec1.size = (self.rec1.size[0] / 2, self.rec1.size[1] / 2)
  69. if self.ellipse3 in elipse_list and len(elipse_list) == len(angles_list): angles_list[elipse_list.index(self.ellipse3)] = self.rotation.angle
  70. elif self.ellipse3 in elipse_list: angles_list.append(self.rotation.angle)
  71.  
  72. # print(self.color)
  73.  
  74. def on_size(self, *args):
  75. self.rotation.origin = Window.size[0] / 2, Window.size[1] / 2
  76. self.rec1.size = (Window.size[0] / self.multi_distance, Window.size[0] / 6)
  77. self.rec1.pos = (Window.size[0] / 2 - self.rec1.size[0] / 2, Window.size[1] / 2 - self.rec1.size[1] / 2)
  78. self.ellipse.size = (Window.size[0] / 10, Window.size[0] / 10)
  79. self.ellipse.pos = (self.rec1.pos[0], self.rec1.pos[1] + (self.rec1.size[1] - self.ellipse.size[1]) / 2)
  80. self.ellipse3.size = (Window.size[0] / 8, Window.size[0] / 8)
  81. self.ellipse3.pos = (self.rec1.pos[0], self.rec1.pos[1] + (self.rec1.size[1] - self.ellipse3.size[1]) / 2)
  82. self.label.size = (self.ellipse3.size[0],self.ellipse3.size[1])
  83. self.label.pos = (self.ellipse3.pos[0],self.ellipse3.pos[1])
  84. self.line.points = (Window.size[0] / 2, Window.size[1] / 2,
  85. self.ellipse3.pos[0] + self.ellipse3.size[0],
  86. self.ellipse3.pos[1] + self.ellipse3.size[1] / 2)
  87. self.label.font_size = f"{Window.size[0]/40}dp"
  88.  
  89.  
  90. class MyAnimation(Widget):
  91. def __init__(self, **kwargs):
  92. super().__init__(**kwargs)
  93. self.spinning_widgets = []
  94. self.layout = BoxLayout()
  95. self.add_rect()
  96. Clock.schedule_interval(self.add_rect, randint(1,2))
  97. self.add_widget(self.layout)
  98.  
  99. def add_rect(self, *dt):
  100. if randint(0,1):
  101. self.widget = SpinningCircles(direction='CW')
  102. StartPage.label1_text_update()
  103. self.spinning_widgets.append(self.widget)
  104. self.layout.add_widget(self.widget)
  105. else:
  106. self.widget = SpinningCircles(direction='CCW')
  107. StartPage.label1_text_update()
  108. self.spinning_widgets.append(self.widget)
  109. self.layout.add_widget(self.widget)
  110.  
  111. class StartPage(PageLayout):
  112. label1 = Label(text=f"{ellipses}", font_size='20sp')
  113.  
  114. def __init__(self, **kwargs):
  115. super().__init__(**kwargs)
  116. # First Page: MyAnimation
  117. self.group1 = InstructionGroup()
  118. self.group2 = InstructionGroup()
  119. self.my_animation = MyAnimation()
  120. self.add_widget(self.my_animation)
  121. #Clock.schedule_interval(lambda x: self.clear_checkpos() if [child for child in self.group1.children if isinstance(child, Ellipse)] else None, .5)
  122. #Clock.schedule_interval(self.label1_text_update, .5)
  123.  
  124. self.button1 = Button(text="Option1", size_hint=(1, 1), background_color=(uniform(0, 1), uniform(0, 1), uniform(0, 1), .8),
  125. background_normal='',on_press=self.button1_pressed)
  126. self.button2 = Button(text="Delete Ellipse", size_hint=(1, 1), background_color=(uniform(0, 1), uniform(0, 1), uniform(0, 1), .8),
  127. background_normal='', on_press=self.button2_pressed)
  128. self.button3 = Button(text="Add Ellipse", size_hint=(1, 1), background_color=(uniform(0, 1), uniform(0, 1), uniform(0, 1), .8),
  129. background_normal='', on_press=self.button3_pressed, on_release=self.button3_onrelease)
  130.  
  131. # BOX LAYOUT
  132. self.boxlayout = BoxLayout(orientation="vertical", spacing=70, padding=50)
  133. self.boxlayout.add_widget(self.label1)
  134. self.boxlayout.add_widget(self.button1)
  135. self.boxlayout.add_widget(self.button2)
  136. self.boxlayout.add_widget(self.button3)
  137. self.add_widget(self.boxlayout)
  138.  
  139. def get_ellipse_positions(self, list, *dt):
  140. ellipses_positions = []
  141. if angles_list and list:
  142. for el in range(len(angles_list)):
  143. angle = angles_list[el]
  144. ellipse = list[el]
  145. midpoint = (Window.size[0] / 2-list[el].size[0]/2, Window.size[1] / 2-list[el].size[1]/2)
  146. angle_radians = math.radians(angle)
  147. x = list[el].pos[0]
  148. y = list[el].pos[1]
  149. dx = x - midpoint[0]
  150. dy = y - midpoint[1]
  151. new_x = midpoint[0] + dx * math.cos(angle_radians) - dy * math.sin(angle_radians)
  152. new_y = midpoint[1] + dx * math.sin(angle_radians) + dy * math.cos(angle_radians)
  153. #self.check_pos(new_x,new_y)
  154. ellipses_positions.append((new_x,new_y))
  155. return ellipses_positions
  156.  
  157. def on_touch_down(self, touch):
  158. if elipse_list:
  159. for ellipse_pos, ellipse in zip(self.get_ellipse_positions(elipse_list),elipse_list):
  160. if (touch.pos[0] >= ellipse_pos[0] and touch.pos[0] <= ellipse_pos[0] + ellipse.size[0]
  161. and touch.pos[1] >= ellipse_pos[1] and touch.pos[1] <= ellipse_pos[1] + ellipse.size[1]):
  162. self.check_pos(ellipse_pos[0],ellipse_pos[1],elipse_list.index(ellipse))
  163. self.remove_ellipse(elipse_list.index(ellipse))
  164. return super().on_touch_down(touch)
  165.  
  166. def check_pos(self, x, y, index):
  167. colors = self.my_animation.spinning_widgets[index].colors[0]
  168. self.group1.add(Color(colors[0],colors[1],colors[2],colors[3]+0.4))
  169. small_ellipse = Ellipse(size=(Window.size[0] / 10, Window.size[0] / 10),pos = self.get_ellipse_positions(small_elipse_list)[index])
  170. self.group1.add(small_ellipse)
  171. self.group2.add(small_ellipse)
  172. # + small ellipse #need to get his pos
  173. self.group1.add(Color(*colors))
  174. self.group1.add(Ellipse(size=(Window.size[0] / 8, Window.size[0] / 8),pos = self.get_ellipse_positions(elipse_list)[index]))
  175. self.group1.add(Line(points=self.find_line_points(x, y, index),width=1.4))
  176. self.canvas.after.add(self.group1)
  177. self.clear_checkpos()
  178.  
  179. def find_line_points(self, x, y, index):
  180. return (Window.size[0]/2, Window.size[1]/2,
  181. x + elipse_list[index].size[0]/2, y + elipse_list[index].size[1]/2)
  182.  
  183. def clear_checkpos(self, *dt):
  184. small_ellipses = [child for child in self.group1.children if isinstance(child, Ellipse) and child in self.group2.children]
  185. big_ellipses = [child for child in self.group1.children if isinstance(child, Ellipse) and child not in self.group2.children]
  186. lines = [child for child in self.group1.children if isinstance(child, Line)]
  187. anim = Animation(size = (0,0),pos=(Window.size[0]/2, Window.size[1]/2), duration= 1.1)
  188. anim2 = Animation(points = (Window.size[0]/2, Window.size[1]/2, Window.size[0]/2, Window.size[1]/2), duration = 1.1)
  189. def inner_clear_checkpos(instance, value):
  190. if not len(self.group1.children) % 8:
  191. for _ in range(8):
  192. if self.group1.children: self.group1.children.pop(0)
  193. anim2.bind(on_complete=inner_clear_checkpos)
  194. for small_ellipse, big_ellipse, line in zip(small_ellipses,big_ellipses,lines):
  195. anim.start(small_ellipse)
  196. anim.start(big_ellipse)
  197. anim2.start(line)
  198. #Clock.schedule_once(inner_clear_checkpos, 0.2)
  199.  
  200. def remove_ellipse(self, index):
  201. global ellipses
  202. global angles_list
  203. global elipse_list
  204. objects_list = self.my_animation.spinning_widgets
  205. if objects_list:
  206. objects_list[index].canvas.clear()
  207. objects_list.pop(index)
  208. angles_list.pop(index)
  209. elipse_list.pop(index)
  210. small_elipse_list.pop(index)
  211. ellipses -= 1
  212. self.label1_text_update()
  213.  
  214. @classmethod
  215. def label1_text_update(cls, *dt):
  216. cls.label1.text = f"Elipses in total: {ellipses}"
  217.  
  218. # SecondPage - BUTTONS
  219.  
  220. def button1_pressed(self, instance):
  221. pass
  222.  
  223. def button2_pressed(self, instance):
  224. pass
  225. #self.remove_ellipse()
  226.  
  227. def button3_pressed(self, instance):
  228. self.button3.pos = (self.button3.pos[0], self.button3.pos[1] + 5)
  229. for x in range(10): self.my_animation.add_rect(1)
  230. self.label1_text_update()
  231.  
  232. def button3_onrelease(self, instance):
  233. self.button3.pos = (self.button3.pos[0], self.button3.pos[1] - 5)
  234.  
  235. class ApplicationApp(App):
  236. def build(self):
  237. return StartPage()
  238.  
  239. ApplicationApp().run()
Advertisement
Add Comment
Please, Sign In to add comment