circulartext commited on
Commit
34be810
·
verified ·
1 Parent(s): 9e972ca

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +126 -63
app.py CHANGED
@@ -1,15 +1,15 @@
1
  import gradio as gr
2
  import random
3
  import time
4
- import threading
5
 
6
  # Global variables
7
  current_text = ""
8
  special_words = []
9
- is_styling = False
 
10
 
11
- def generate_random_style(word):
12
- """Generate random styling for a word but keep it black."""
13
  fonts = [
14
  "'VT323', monospace",
15
  "'Josefin Sans', sans-serif",
@@ -22,51 +22,125 @@ def generate_random_style(word):
22
  "'Orbitron', sans-serif",
23
  "'Raleway', sans-serif"
24
  ]
25
- font_sizes = ["16px", "17px", "18px" , "19px", "20px"]
26
  font_tops = ["0px", "1px", "-1px"]
27
  letter_spacings = ["-3px", "-2px", "-1px", "1px", "-2px", "-3px"]
28
  text_shadows = [
29
- "0px 0px 1px",
30
- "0px 0px 2px",
31
- "1px 0px 0px",
32
- "0px 0px 0px",
33
- "0px 1px 0px",
34
- "0px 2px 0px",
35
- "0px 1px 1px",
36
- "1px 1px 0px",
37
- "1px 0px 1px"
38
  ]
39
  skew_angles = ["-25deg", "-20deg", "-15deg", "-10deg", "0deg", "10deg", "15deg", "20deg", "25deg"]
40
 
41
  letters = list(word)
42
  styled_letters = []
 
43
 
44
  for i, letter in enumerate(letters):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  style = {
46
- 'font-family': random.choice(fonts),
47
  'line-height': '1.6',
48
- 'font-size': random.choice(font_sizes),
49
- 'letter-spacing': random.choice(letter_spacings),
50
- 'text-shadow': random.choice(text_shadows),
51
- 'transform': f'skew({random.choice(skew_angles)})',
52
- 'margin-top': random.choice(["-0.02cm", "0.00cm", "0.02cm"]),
53
  'position': 'relative',
54
- 'top': random.choice(font_tops),
55
- 'color': '#000000', # Keep black
56
  'display': 'inline-block',
57
  'margin': '0 1px',
58
- 'vertical-align': 'middle'
 
 
59
  }
60
 
61
  style_str = '; '.join([f'{k}: {v}' for k, v in style.items()])
62
  styled_letter = f'<span class="styled-letter" style="{style_str}">{letter}</span>'
63
  styled_letters.append(styled_letter)
64
 
65
- return f'<span class="special-word">{" ".join(styled_letters)}</span>'
 
 
 
66
 
67
  def display_normal_text():
68
  """Display the text normally without any styling."""
69
- global current_text, special_words
70
 
71
  paragraphs = [
72
  'How did we get here December 30th 2124 "Good morning, Benshiro. Wake up! We\'ve got A.I. training ahead," urged Benshiro\'s partner as they prepared for their day in sector A1 - A1000, one of the elite development sectors serving the World One government. It was the year 2124.',
@@ -75,6 +149,9 @@ def display_normal_text():
75
  '2036 By 2036, the government implemented a new policy for One Country accounts. If individuals committed a crime and did not turn themselves in, their accounts would be frozen. This rule was highly controversial, as it curtailed personal freedoms. In a bold initiative, the One Country President announced plans to establish a 99% robotic police force by 2045. The program will begin immediately, aiming to have 30% of the force composed of active robots within the first phase. Human officers would collaborate with these machines in decision-making processes. To support this vision, a vast 10,000-acre automation facility—equivalent to the size of Manhattan—was constructed. This facility aimed to produce advanced robots and flying vehicles, initially reserved for government officials and the wealthy, signaling a significant shift towards automation in society.'
76
  ]
77
 
 
 
 
78
  # Select one random word from each paragraph for future styling
79
  special_words = []
80
  for paragraph in paragraphs:
@@ -91,20 +168,34 @@ def display_normal_text():
91
  </div>
92
  """
93
 
94
- def get_styled_text():
95
- """Get the styled version of the text."""
96
- global current_text, special_words
 
 
 
97
 
98
- if not special_words:
99
- return current_text
100
 
101
- paragraphs = current_text.split('<br><br>')
102
  styled_paragraphs = []
 
103
 
104
- for i, paragraph in enumerate(paragraphs):
105
  if i < len(special_words):
106
  special_word = special_words[i]
107
- styled_word = generate_random_style(special_word)
 
 
 
 
 
 
 
 
 
 
 
108
  # Replace only the first occurrence of the special word in this paragraph
109
  styled_paragraph = paragraph.replace(special_word, styled_word, 1)
110
  styled_paragraphs.append(styled_paragraph)
@@ -114,43 +205,15 @@ def get_styled_text():
114
  styled_text = '<br><br>'.join(styled_paragraphs)
115
 
116
  return f"""
 
117
  <div style="font-family: 'Josefin Sans', sans-serif; font-size: 16px; line-height: 1.6; padding: 20px; max-width: 800px;">
118
  {styled_text}
119
  </div>
120
  """
121
 
122
- def get_normal_text():
123
- """Get the normal version of the text."""
124
- global current_text
125
-
126
- return f"""
127
- <div style="font-family: 'Josefin Sans', sans-serif; font-size: 16px; line-height: 1.6; padding: 20px; max-width: 800px;">
128
- {current_text}
129
- </div>
130
- """
131
-
132
- def trigger_movement():
133
- """Apply styling then revert back to normal - creates sneaking effect."""
134
- global is_styling
135
-
136
- if is_styling:
137
- return get_normal_text()
138
-
139
- # Show styled version first
140
- styled_output = get_styled_text()
141
- is_styling = True
142
-
143
- # Use generator to show styled then normal
144
- yield styled_output
145
-
146
- # Wait a moment then show normal text
147
- time.sleep(1.5) # Show styled text for 1.5 seconds
148
- is_styling = False
149
- yield get_normal_text()
150
-
151
  # Create Gradio interface using Blocks
152
  with gr.Blocks() as demo:
153
- gr.Markdown("# CircularText Styler\nText with sneaking style effect - words style briefly then return to normal.")
154
 
155
  output_html = gr.HTML()
156
  with gr.Row():
 
1
  import gradio as gr
2
  import random
3
  import time
 
4
 
5
  # Global variables
6
  current_text = ""
7
  special_words = []
8
+ original_paragraphs = []
9
+ animation_counter = 0
10
 
11
+ def generate_transition_style(word, animation_id):
12
+ """Generate styling with transition animation from normal to styled and back to normal."""
13
  fonts = [
14
  "'VT323', monospace",
15
  "'Josefin Sans', sans-serif",
 
22
  "'Orbitron', sans-serif",
23
  "'Raleway', sans-serif"
24
  ]
25
+ font_sizes = ["16px", "17px", "18px", "19px", "20px"]
26
  font_tops = ["0px", "1px", "-1px"]
27
  letter_spacings = ["-3px", "-2px", "-1px", "1px", "-2px", "-3px"]
28
  text_shadows = [
29
+ "0px 0px 1px #000",
30
+ "0px 0px 2px #000",
31
+ "1px 0px 0px #000",
32
+ "0px 0px 0px #000",
33
+ "0px 1px 0px #000",
34
+ "0px 2px 0px #000",
35
+ "0px 1px 1px #000",
36
+ "1px 1px 0px #000",
37
+ "1px 0px 1px #000"
38
  ]
39
  skew_angles = ["-25deg", "-20deg", "-15deg", "-10deg", "0deg", "10deg", "15deg", "20deg", "25deg"]
40
 
41
  letters = list(word)
42
  styled_letters = []
43
+ keyframes_css = ""
44
 
45
  for i, letter in enumerate(letters):
46
+ # Generate random styled properties
47
+ styled_font_family = random.choice(fonts)
48
+ styled_font_size = random.choice(font_sizes)
49
+ styled_letter_spacing = random.choice(letter_spacings)
50
+ styled_text_shadow = random.choice(text_shadows)
51
+ styled_skew_angle = random.choice(skew_angles)
52
+ styled_top = random.choice(font_tops)
53
+ styled_margin_top = random.choice(["-0.02cm", "0.00cm", "0.02cm"])
54
+
55
+ # Create unique animation name
56
+ animation_name = f"sneakStyle_{animation_id}_{i}"
57
+
58
+ # Create keyframes that go: normal → styled → normal
59
+ keyframes_css += f"""
60
+ @keyframes {animation_name} {{
61
+ 0% {{
62
+ font-family: 'Josefin Sans', sans-serif;
63
+ font-size: 16px;
64
+ letter-spacing: 0px;
65
+ color: #000000;
66
+ text-shadow: 0px 0px 0px #000;
67
+ transform: skew(0deg) scale(1);
68
+ top: 0px;
69
+ margin-top: 0.00cm;
70
+ }}
71
+ 25% {{
72
+ font-family: {styled_font_family};
73
+ font-size: {styled_font_size};
74
+ letter-spacing: {styled_letter_spacing};
75
+ color: #000000;
76
+ text-shadow: {styled_text_shadow};
77
+ transform: skew({styled_skew_angle}) scale(1.1);
78
+ top: {styled_top};
79
+ margin-top: {styled_margin_top};
80
+ }}
81
+ 50% {{
82
+ font-family: {styled_font_family};
83
+ font-size: {styled_font_size};
84
+ letter-spacing: {styled_letter_spacing};
85
+ color: #000000;
86
+ text-shadow: {styled_text_shadow};
87
+ transform: skew({styled_skew_angle}) scale(0.95);
88
+ top: {styled_top};
89
+ margin-top: {styled_margin_top};
90
+ }}
91
+ 75% {{
92
+ font-family: {styled_font_family};
93
+ font-size: {styled_font_size};
94
+ letter-spacing: {styled_letter_spacing};
95
+ color: #000000;
96
+ text-shadow: {styled_text_shadow};
97
+ transform: skew({styled_skew_angle}) scale(1.05);
98
+ top: {styled_top};
99
+ margin-top: {styled_margin_top};
100
+ }}
101
+ 100% {{
102
+ font-family: 'Josefin Sans', sans-serif;
103
+ font-size: 16px;
104
+ letter-spacing: 0px;
105
+ color: #000000;
106
+ text-shadow: 0px 0px 0px #000;
107
+ transform: skew(0deg) scale(1);
108
+ top: 0px;
109
+ margin-top: 0.00cm;
110
+ }}
111
+ }}
112
+ """
113
+
114
  style = {
115
+ 'font-family': "'Josefin Sans', sans-serif", # Start normal
116
  'line-height': '1.6',
117
+ 'font-size': '16px',
118
+ 'letter-spacing': '0px',
119
+ 'text-shadow': '0px 0px 0px #000',
120
+ 'transform': 'skew(0deg)',
121
+ 'margin-top': '0.00cm',
122
  'position': 'relative',
123
+ 'top': '0px',
124
+ 'color': '#000000',
125
  'display': 'inline-block',
126
  'margin': '0 1px',
127
+ 'vertical-align': 'middle',
128
+ 'animation': f'{animation_name} 3s ease-in-out forwards',
129
+ 'animation-delay': f'{i * 0.1}s'
130
  }
131
 
132
  style_str = '; '.join([f'{k}: {v}' for k, v in style.items()])
133
  styled_letter = f'<span class="styled-letter" style="{style_str}">{letter}</span>'
134
  styled_letters.append(styled_letter)
135
 
136
+ return f"""
137
+ <style>{keyframes_css}</style>
138
+ <span class="special-word">{" ".join(styled_letters)}</span>
139
+ """
140
 
141
  def display_normal_text():
142
  """Display the text normally without any styling."""
143
+ global current_text, special_words, original_paragraphs
144
 
145
  paragraphs = [
146
  'How did we get here December 30th 2124 "Good morning, Benshiro. Wake up! We\'ve got A.I. training ahead," urged Benshiro\'s partner as they prepared for their day in sector A1 - A1000, one of the elite development sectors serving the World One government. It was the year 2124.',
 
149
  '2036 By 2036, the government implemented a new policy for One Country accounts. If individuals committed a crime and did not turn themselves in, their accounts would be frozen. This rule was highly controversial, as it curtailed personal freedoms. In a bold initiative, the One Country President announced plans to establish a 99% robotic police force by 2045. The program will begin immediately, aiming to have 30% of the force composed of active robots within the first phase. Human officers would collaborate with these machines in decision-making processes. To support this vision, a vast 10,000-acre automation facility—equivalent to the size of Manhattan—was constructed. This facility aimed to produce advanced robots and flying vehicles, initially reserved for government officials and the wealthy, signaling a significant shift towards automation in society.'
150
  ]
151
 
152
+ # Store original paragraphs
153
+ original_paragraphs = paragraphs[:]
154
+
155
  # Select one random word from each paragraph for future styling
156
  special_words = []
157
  for paragraph in paragraphs:
 
168
  </div>
169
  """
170
 
171
+ def trigger_movement():
172
+ """Apply transition styling to selected words - they style then return to normal automatically."""
173
+ global current_text, special_words, original_paragraphs, animation_counter
174
+
175
+ if not special_words or not original_paragraphs:
176
+ return display_normal_text()
177
 
178
+ # Increment animation counter for unique animations
179
+ animation_counter += 1
180
 
 
181
  styled_paragraphs = []
182
+ all_styles = ""
183
 
184
+ for i, paragraph in enumerate(original_paragraphs):
185
  if i < len(special_words):
186
  special_word = special_words[i]
187
+ animation_id = f"{animation_counter}_{i}"
188
+ styled_word_html = generate_transition_style(special_word, animation_id)
189
+
190
+ # Extract styles from styled_word_html
191
+ if "<style>" in styled_word_html:
192
+ style_start = styled_word_html.find("<style>") + 7
193
+ style_end = styled_word_html.find("</style>")
194
+ all_styles += styled_word_html[style_start:style_end]
195
+ styled_word = styled_word_html[styled_word_html.find("</style>") + 8:]
196
+ else:
197
+ styled_word = styled_word_html
198
+
199
  # Replace only the first occurrence of the special word in this paragraph
200
  styled_paragraph = paragraph.replace(special_word, styled_word, 1)
201
  styled_paragraphs.append(styled_paragraph)
 
205
  styled_text = '<br><br>'.join(styled_paragraphs)
206
 
207
  return f"""
208
+ <style>{all_styles}</style>
209
  <div style="font-family: 'Josefin Sans', sans-serif; font-size: 16px; line-height: 1.6; padding: 20px; max-width: 800px;">
210
  {styled_text}
211
  </div>
212
  """
213
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  # Create Gradio interface using Blocks
215
  with gr.Blocks() as demo:
216
+ gr.Markdown("# CircularText Styler\nText with smooth sneaking style transitions - words style then smoothly return to normal.")
217
 
218
  output_html = gr.HTML()
219
  with gr.Row():