Spaces:
Sleeping
Sleeping
import gradio as gr | |
import random | |
import time | |
def style_special_word(word): | |
"""Apply fancy random style to a special word.""" | |
fonts = [ | |
"'Courier New', monospace", | |
"'Arial', sans-serif", | |
"'Georgia', serif", | |
"'Times New Roman', serif" | |
] | |
colors = ["red", "blue", "green", "black", "orange", "purple", "deeppink", "cyan"] | |
font_weights = ["bold", "normal", "bolder"] | |
decorations = ["underline", "overline", "line-through", "none"] | |
shadows = [ | |
"2px 2px 5px gray", | |
"0px 0px 10px gold", | |
"3px 3px 5px #000000", | |
"1px 1px 5px lime" | |
] | |
transforms = [ | |
"rotate(5deg)", | |
"rotate(-5deg)", | |
"scale(1.2)", | |
"skewX(10deg)", | |
"skewY(-5deg)" | |
] | |
style = ( | |
f"font-family:{random.choice(fonts)};" | |
f"color:{random.choice(colors)};" | |
f"font-weight:{random.choice(font_weights)};" | |
f"text-decoration:{random.choice(decorations)};" | |
f"text-shadow:{random.choice(shadows)};" | |
f"display:inline-block; transform:{random.choice(transforms)};" | |
) | |
return f'<span style="{style}">{word}</span>' | |
def typing_effect(): | |
"""Stream paragraphs word by word with fancy styled words.""" | |
paragraphs = [ | |
"Proctor's voice quavered, “Where are we, Benshiro? This can't be real. We went full speed into that...”", | |
"“Proctor, I hear you! Is that you? I'm so thankful, but where are you? I can't see you.” Benshiro's words echoed in the void." | |
] | |
html_output = "" | |
for paragraph in paragraphs: | |
words = paragraph.split() | |
# Choose a random special word | |
special_word = random.choice(words) | |
styled_words = [ | |
style_special_word(w) if w == special_word else w | |
for w in words | |
] | |
for w in styled_words: | |
html_output += w + " " | |
yield html_output | |
time.sleep(0.05) | |
html_output += "<br><br>" | |
time.sleep(0.5) | |
def animate_letters(current_html): | |
"""Randomly restyle all previously styled words.""" | |
# Just re-run the style_special_word on each styled span text | |
import re | |
def replace_style(match): | |
word = match.group(2) # the inner text | |
return style_special_word(word) | |
return re.sub(r'(<span style="[^"]*">)([^<]+)(</span>)', | |
lambda m: replace_style(m), | |
current_html) | |
with gr.Blocks() as demo: | |
gr.Markdown("## Styled Typing with Clickable Animation") | |
output_html = gr.HTML() | |
with gr.Row(): | |
start_btn = gr.Button("Start Typing") | |
animate_btn = gr.Button("Animate Letters") | |
start_btn.click(typing_effect, outputs=output_html) | |
animate_btn.click(animate_letters, inputs=output_html, outputs=output_html) | |
demo.launch() | |