circulartext commited on
Commit
a14b594
·
verified ·
1 Parent(s): 34d154f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +161 -43
app.py CHANGED
@@ -8,8 +8,9 @@ generator = pipeline('text-generation', model='distilgpt2') # Lightweight model
8
  # Predefined words to check
9
  SPECIAL_WORDS = ['weather', 'sun', 'middle', 'summer', 'heat']
10
 
11
- def generate_circular_text_design(word):
12
- """Generate a styled design for a word by styling each letter individually, including animations."""
 
13
  # Controlled randomization parameters
14
  fonts = [
15
  "'VT323', monospace",
@@ -47,22 +48,74 @@ def generate_circular_text_design(word):
47
  "1px 0px 1px"
48
  ]
49
  skew_angles = ["-25deg", "-20deg", "-15deg", "-10deg", "0deg", "10deg", "15deg", "20deg", "25deg"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  # Generate a unique animation name for CSS
52
  animation_name = f"animate_{random.randint(0, 10000)}"
53
-
54
  # Create CSS keyframes for the animation
55
  keyframes = f"""
56
  @keyframes {animation_name} {{
57
- 0% {{ transform: scale(1) rotate(0deg); }}
58
- 25% {{ transform: scale(1.2) rotate(10deg); }}
59
- 50% {{ transform: scale(1) rotate(0deg); }}
60
- 75% {{ transform: scale(1.2) rotate(-10deg); }}
61
- 100% {{ transform: scale(1) rotate(0deg); }}
62
  }}
63
  """
64
-
65
- # Create HTML for each letter with dynamic styling and animation
 
 
66
  letters = list(word)
67
  styled_letters = []
68
  for i, letter in enumerate(letters):
@@ -73,58 +126,61 @@ def generate_circular_text_design(word):
73
  'letter-spacing': random.choice(letter_spacings),
74
  'text-shadow': random.choice(text_shadows),
75
  'transform': f'skew({random.choice(skew_angles)})',
76
- 'margin-top': f'{random.choice(["-0.06cm", "-0.03cm", "0.00cm", "0.03cm", "0.06cm"])}',
77
  'position': 'relative',
78
  'top': random.choice(font_tops),
79
- 'color': f'#{random.randint(0, 0xFFFFFF):06x}',
80
  'display': 'inline-block',
81
  'margin': '0 1px',
82
- 'animation': f'{animation_name} 2s infinite'
83
  }
84
-
85
  # Convert style to inline CSS
86
  style_str = '; '.join([f'{k}: {v}' for k, v in style.items()])
87
-
88
- # Assign a unique ID for possible future reference
89
- styled_letter = f'<div class="styled-letter" style="{style_str}">{letter}</div>'
90
  styled_letters.append(styled_letter)
91
-
92
- # Combine letters into a container with flex display
93
  return f'''
94
  <style>
95
  {keyframes}
96
  </style>
97
- <div style="display: flex; align-items: baseline;">{" ".join(styled_letters)}</div>
98
  '''
99
 
100
- def process_text(input_text):
101
- """Process text and apply special styling to matching words."""
102
- # Limit input length to prevent long processing times
103
- max_input_length = 20 # Adjust as needed
104
- input_text = ' '.join(input_text.split()[:max_input_length])
105
 
 
 
 
 
106
  # Generate text with limited length
107
  generated = generator(input_text, max_length=50, num_return_sequences=1)
108
  generated_text = generated[0]['generated_text']
109
-
110
  # Limit output length to prevent overflow
111
  generated_text = generated_text[:300] # Limit to first 300 characters
112
-
113
  # Split text into words
114
  words = generated_text.split()
115
-
116
- # Check for special words and apply styling
117
  for i, word in enumerate(words):
118
  # Clean the word for matching
119
  clean_word = ''.join(filter(str.isalnum, word)).lower()
120
  if clean_word in SPECIAL_WORDS:
121
- words[i] = generate_circular_text_design(word)
 
 
122
  else:
123
  words[i] = word
124
-
125
  # Combine words back into HTML-formatted text
126
  output_html = ' '.join(words)
127
-
128
  # Build the complete HTML
129
  final_output = f"""
130
  <html>
@@ -150,23 +206,85 @@ def process_text(input_text):
150
  <link href="https://fonts.googleapis.com/css?family=Teko" rel="stylesheet" type="text/css">
151
  <link href="https://fonts.googleapis.com/css?family=Abril+Fatface|Josefin+Sans|Gloria+Hallelujah|Roboto+Slab|Righteous|Sacramento|Yellowtail" rel="stylesheet">
152
  <link href="https://fonts.googleapis.com/css?family=Annie+Use+Your+Telescope|Just+Me+Again+Down+Here|Nixie+One|Six+Caps|Unkempt" rel="stylesheet">
 
 
 
 
 
 
 
 
 
153
  </head>
154
- <body style='background-color: #000; color: #fff; font-size: 18px; line-height: 1.6; font-family: "Josefin Sans", sans-serif;'>
155
  <div style='max-width: 800px; margin: auto; padding: 20px;'>
156
  {output_html}
157
  </div>
158
  </body>
159
  </html>
160
  """
161
-
162
  return final_output
163
 
164
- # Create Gradio interface
165
- iface = gr.Interface(
166
- fn=process_text,
167
- inputs="text",
168
- outputs=gr.HTML(label="Generated Text"),
169
- title="Circular Text Styler",
170
- description="Enter a prompt to generate text with special word styling."
171
- )
172
- iface.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  # Predefined words to check
9
  SPECIAL_WORDS = ['weather', 'sun', 'middle', 'summer', 'heat']
10
 
11
+ # Function to generate the initial design (black color)
12
+ def generate_initial_design(word):
13
+ """Generate initial design for the special word in black color."""
14
  # Controlled randomization parameters
15
  fonts = [
16
  "'VT323', monospace",
 
48
  "1px 0px 1px"
49
  ]
50
  skew_angles = ["-25deg", "-20deg", "-15deg", "-10deg", "0deg", "10deg", "15deg", "20deg", "25deg"]
51
+
52
+ # Create HTML for each letter with random styling (black color)
53
+ letters = list(word)
54
+ styled_letters = []
55
+ for i, letter in enumerate(letters):
56
+ style = {
57
+ 'font-family': random.choice(fonts),
58
+ 'line-height': '110%',
59
+ 'font-size': random.choice(font_sizes),
60
+ 'letter-spacing': random.choice(letter_spacings),
61
+ 'text-shadow': random.choice(text_shadows),
62
+ 'transform': f'skew({random.choice(skew_angles)})',
63
+ 'margin-top': random.choice(["-0.06cm", "-0.03cm", "0.00cm", "0.03cm", "0.06cm"]),
64
+ 'position': 'relative',
65
+ 'top': random.choice(font_tops),
66
+ 'color': '#000000', # Black color
67
+ 'display': 'inline-block',
68
+ 'margin': '0 1px'
69
+ }
70
+
71
+ # Convert style to inline CSS
72
+ style_str = '; '.join([f'{k}: {v}' for k, v in style.items()])
73
+
74
+ # Wrap the letter in a span
75
+ styled_letter = f'<span class="styled-letter" style="{style_str}">{letter}</span>'
76
+ styled_letters.append(styled_letter)
77
+
78
+ # Combine letters into a container with inline display
79
+ return f'<span>{" ".join(styled_letters)}</span>'
80
 
81
+ # Function to generate the movement design (random color)
82
+ def generate_movement_design(word):
83
+ """Generate movement design for the special word in random color."""
84
+ # Controlled randomization parameters (could be different ranges if desired)
85
+ # Reuse the same parameters or define new ranges for the movement
86
+ fonts = [
87
+ "'VT323', monospace",
88
+ "'Josefin Sans', sans-serif",
89
+ "'Rajdhani', sans-serif",
90
+ "'Anton', sans-serif",
91
+ # You can include different fonts if you want
92
+ ]
93
+ font_sizes = ["20px", "22px", "24px", "26px", "28px", "30px"]
94
+ font_tops = ["10px", "12px", "14px", "16px"]
95
+ letter_spacings = ["-3px", "-2px", "-1px", "0px", "1px", "2px", "3px"]
96
+ text_shadows = [
97
+ "0px 0px 5px #ff0000", # Red glow
98
+ "0px 0px 5px #00ff00", # Green glow
99
+ "0px 0px 5px #0000ff", # Blue glow
100
+ # Add more if desired
101
+ ]
102
+ skew_angles = ["-15deg", "-10deg", "0deg", "10deg", "15deg"]
103
+
104
  # Generate a unique animation name for CSS
105
  animation_name = f"animate_{random.randint(0, 10000)}"
106
+
107
  # Create CSS keyframes for the animation
108
  keyframes = f"""
109
  @keyframes {animation_name} {{
110
+ 0% {{ transform: translateY(0px); }}
111
+ 50% {{ transform: translateY(-10px); }}
112
+ 100% {{ transform: translateY(0px); }}
 
 
113
  }}
114
  """
115
+ # Generate random color
116
+ random_color = f'#{random.randint(0, 0xFFFFFF):06x}'
117
+
118
+ # Create HTML for each letter with random styling and animation (random color)
119
  letters = list(word)
120
  styled_letters = []
121
  for i, letter in enumerate(letters):
 
126
  'letter-spacing': random.choice(letter_spacings),
127
  'text-shadow': random.choice(text_shadows),
128
  'transform': f'skew({random.choice(skew_angles)})',
129
+ 'margin-top': random.choice(["-0.03cm", "0.00cm", "0.03cm"]),
130
  'position': 'relative',
131
  'top': random.choice(font_tops),
132
+ 'color': random_color, # Random color
133
  'display': 'inline-block',
134
  'margin': '0 1px',
135
+ 'animation': f'{animation_name} 1s ease-in-out forwards'
136
  }
137
+
138
  # Convert style to inline CSS
139
  style_str = '; '.join([f'{k}: {v}' for k, v in style.items()])
140
+
141
+ # Wrap the letter in a span
142
+ styled_letter = f'<span class="styled-letter" style="{style_str}">{letter}</span>'
143
  styled_letters.append(styled_letter)
144
+
145
+ # Combine letters into a container with inline display and include keyframes
146
  return f'''
147
  <style>
148
  {keyframes}
149
  </style>
150
+ <span>{" ".join(styled_letters)}</span>
151
  '''
152
 
153
+ # Global variable to store the initial design
154
+ initial_word_design = ""
 
 
 
155
 
156
+ def process_text(input_text):
157
+ """Process text and generate the initial output with special word styled in black."""
158
+ global initial_word_design
159
+
160
  # Generate text with limited length
161
  generated = generator(input_text, max_length=50, num_return_sequences=1)
162
  generated_text = generated[0]['generated_text']
163
+
164
  # Limit output length to prevent overflow
165
  generated_text = generated_text[:300] # Limit to first 300 characters
166
+
167
  # Split text into words
168
  words = generated_text.split()
169
+
170
+ # Check for special words and apply initial styling
171
  for i, word in enumerate(words):
172
  # Clean the word for matching
173
  clean_word = ''.join(filter(str.isalnum, word)).lower()
174
  if clean_word in SPECIAL_WORDS:
175
+ # Store the initial design
176
+ initial_word_design = generate_initial_design(word)
177
+ words[i] = initial_word_design
178
  else:
179
  words[i] = word
180
+
181
  # Combine words back into HTML-formatted text
182
  output_html = ' '.join(words)
183
+
184
  # Build the complete HTML
185
  final_output = f"""
186
  <html>
 
206
  <link href="https://fonts.googleapis.com/css?family=Teko" rel="stylesheet" type="text/css">
207
  <link href="https://fonts.googleapis.com/css?family=Abril+Fatface|Josefin+Sans|Gloria+Hallelujah|Roboto+Slab|Righteous|Sacramento|Yellowtail" rel="stylesheet">
208
  <link href="https://fonts.googleapis.com/css?family=Annie+Use+Your+Telescope|Just+Me+Again+Down+Here|Nixie+One|Six+Caps|Unkempt" rel="stylesheet">
209
+ <style>
210
+ body {{
211
+ background-color: #fff;
212
+ color: #000;
213
+ font-size: 18px;
214
+ line-height: 1.6;
215
+ font-family: "Josefin Sans", sans-serif;
216
+ }}
217
+ </style>
218
  </head>
219
+ <body>
220
  <div style='max-width: 800px; margin: auto; padding: 20px;'>
221
  {output_html}
222
  </div>
223
  </body>
224
  </html>
225
  """
226
+
227
  return final_output
228
 
229
+ def trigger_movement(input_html):
230
+ """Function to trigger the movement animation by updating the special word design."""
231
+ # Since we don't have a way to animate already rendered HTML, we regenerate the movement design.
232
+ # We need to replace the initial design with the movement design in the input_html.
233
+ global initial_word_design
234
+
235
+ # Edge case: if initial_word_design is empty, return the input_html
236
+ if not initial_word_design:
237
+ return input_html # No special word was found previously
238
+
239
+ # Extract the special word from the initial design
240
+ start_marker = '<span class="'
241
+ start_index = initial_word_design.find(start_marker)
242
+ if start_index == -1:
243
+ return input_html # Can't find the initial design
244
+
245
+ # Get the word from the initial_design
246
+ special_word = ''.join([c for c in initial_word_design if c.isalpha()])
247
+
248
+ # Generate the movement design
249
+ movement_design = generate_movement_design(special_word)
250
+
251
+ # Replace the initial design with the movement design in the input_html
252
+ updated_html = input_html.replace(initial_word_design, movement_design, 1)
253
+
254
+ # After the animation ends, we can set the design back to initial
255
+ # Since we can't execute JavaScript, the design will remain as the movement design
256
+ # Alternatively, we can schedule the change back using CSS animations
257
+
258
+ # Append CSS to change back to black after animation (using animation-fill-mode)
259
+ updated_html = updated_html.replace('</head>', '''
260
+ <style>
261
+ .styled-letter {
262
+ animation-fill-mode: forwards;
263
+ }
264
+ </style>
265
+ </head>''')
266
+
267
+ return updated_html
268
+
269
+ # Create Gradio interface using Blocks
270
+ with gr.Blocks() as demo:
271
+ gr.Markdown("# Circular Text Styler\nEnter a prompt to generate text with special word styling.")
272
+
273
+ with gr.Row():
274
+ input_text = gr.Textbox(label="Input Prompt")
275
+ submit_button = gr.Button("Generate")
276
+
277
+ output_html = gr.HTML()
278
+ animate_button = gr.Button("Trigger Movement")
279
+
280
+ # Connect functions
281
+ submit_button.click(process_text, inputs=input_text, outputs=output_html)
282
+ animate_button.click(trigger_movement, inputs=output_html, outputs=output_html)
283
+
284
+ gr.HTML("""
285
+ <style>
286
+ /* Center the buttons */
287
+ .gradio-container .gr-button {
288
+ margin-top: 10px;
289
+ margin-bottom: 10px;
290
+ <span class="ml-2" /><span class="inline-block w-3 h-3 rounded-full bg-neutral-a12 align-middle mb-[0.1rem]" />