-
Notifications
You must be signed in to change notification settings - Fork 0
/
confettis.py
executable file
·141 lines (118 loc) · 4.06 KB
/
confettis.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python3
"""
Python project of BPI's teacher
The goal of this project is to make an animation (list of .svg files) of
auto-generated confetti falling through the image
Author: Chris Janaqi
Creation Date: 2017-09-06
"""
from random import choice, randint
class Confetti:
"""
Class Confetti :
Attributes:
- x (int): abcissa of the center of the confetti
- y (int): ordinate of the center of the confetti
- color (str): color of the confetti
- radius (int): radius of the confetti
Methods:
- None for now
"""
def __init__(self, x, y, r, color):
"""
Confetti constructor with x, y the position (must be integer)
and the color (must be a string in the svg convention)
"""
assert (isinstance(x, int) and isinstance(y, int)
and isinstance(color, str))
self.x = x
self.y = y
self.radius = r
self.color = color
class Param:
"""
Class Param used to stock the parameters of the animation
Attributes :
- width (int) : width of the animation (in pixels)
- height (int) : height of the animation (in pixels)
- nb_frames (int) : number of frame
- density (float) : density of the rain with
(density == r * nb_confetti / width)
with r the radius of one confetti.
Indicates how much confetti we should generate per
frame
- colors (vector): list of color to use
Methods:
- None for now
"""
def __init__(self, width, height, nb_frames, density,
colors=["red", "green", "blue"]):
self.width = width
self.height = height
self.nb_frames = nb_frames
self.density = density
self.colors = colors
def input_param():
"""
Ask the user for the parameters of the animation to produce :
- width, height of the animation
- number of frames
- density
- color to use
"""
print("/!\\ WARNING /!\\")
print("The previous animation WILL be deleted")
process = input("Continue (y/n)? ") == 'y'
if process:
width = int(input('width ? '))
height = int(input('height ? '))
nb_frames = int(input('number of frames ? '))
density = float(input('density of the generation (float in [0,1]) ? '))
return Param(width, height, nb_frames, density)
else :
return None
def generate_confetti(confettis, param):
"""
Input : confetti vector, parameters of the animation
"""
nb_confetti = int(param.width * param.density / 10)
for _ in range(nb_confetti):
confettis.append(Confetti(randint(0, param.width), 0, 10,
choice(param.colors)))
return confettis
def simulate_fall(confettis, param):
"""
Input : confetti vector
Simulate the fall of confetti, removing those outside of the screen
"""
for confetti in confettis:
confetti.y += 4
confetti.x += randint(-2,2)
if confetti.y >= param.height + confetti.radius:
confettis.pop(confettis.index(confetti))
def draw_image(conffetis, param, index):
"""
Draw into an svg image the confetti vector
"""
with open('frames/frame_{}.svg'.format(index), 'w') as frame:
print('<svg width="{}" height="{}">'.format(param.width, param.height),
file=frame)
for confetti in conffetis:
print('<circle cx="{}" cy="{}" r="{}" fill="{}"/>'
.format(confetti.x, confetti.y, confetti.radius, confetti.color),
file=frame)
print('</svg>', file=frame)
def main():
"""
Main function.
"""
param = input_param()
conffetis = []
if param is not None:
for i in range(param.nb_frames):
conffetis = generate_confetti(conffetis, param)
simulate_fall(conffetis, param)
draw_image(conffetis, param, i)
print("main here")
if __name__ == "__main__":
main()