README / rosetta_animation.py
skenoo's picture
Upload 4 files
9feb1f1 verified
Raw History Blame Contribute Delete
6.99 kB
"""
Rosetta Animation for Hugging Face Spaces Demo
----------------------------------------------
This file contains a Gradio component that adapts the Rosetta animation
from your Next.js project for use in Hugging Face Spaces.
"""
import gradio as gr
import base64
import os
from pathlib import Path
def create_rosetta_animation():
"""Create HTML/CSS/JS for the Rosetta animation"""
# SVG content for light and dark mode
# These are embedded directly rather than loaded from files
light_svg_base64 = "PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyLjAwMDQgMjRDMTguNjI3OSAyNCAyNCAxOC42Mjc5IDI0IDEyLjAwMDRDMjQgNS4zNzI5MSAxOC42Mjc5IDAgMTIuMDAwNCAwQzUuMzcyOTEgMCAwIDUuMzcyOTEgMCAxMi4wMDA0QzAgMTguNjI3OSA1LjM3MjkxIDI0IDEyLjAwMDQgMjRaIiBmaWxsPSIjRkY2MTJDIi8+CjxwYXRoIGQ9Ik0xMi4wMDA0IDIxLjAzQzE3LjAwMDYgMjEuMDMgMjEuMDMgMTcuMDAwNiAyMS4wMyAxMi4wMDA0QzIxLjAzIDcuMDAwMjMgMTcuMDAwNiAyLjk3MSAxMi4wMDA0IDIuOTcxQzcuMDAwMjMgMi45NzEgMi45NzEgNy4wMDAyMyAyLjk3MSAxMi4wMDA0QzIuOTcxIDE3LjAwMDYgNy4wMDAyMyAyMS4wMyAxMi4wMDA0IDIxLjAzWiIgZmlsbD0iYmxhY2siLz4KPC9zdmc+"
dark_svg_base64 = "PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyLjAwMDQgMjRDMTguNjI3OSAyNCAyNCAxOC42Mjc5IDI0IDEyLjAwMDRDMjQgNS4zNzI5MSAxOC42Mjc5IDAgMTIuMDAwNCAwQzUuMzcyOTEgMCAwIDUuMzcyOTEgMCAxMi4wMDA0QzAgMTguNjI3OSA1LjM3MjkxIDI0IDEyLjAwMDQgMjRaIiBmaWxsPSIjRkY2MTJDIi8+CjxwYXRoIGQ9Ik0xMi4wMDA0IDIxLjAzQzE3LjAwMDYgMjEuMDMgMjEuMDMgMTcuMDAwNiAyMS4wMyAxMi4wMDA0QzIxLjAzIDcuMDAwMjMgMTcuMDAwNiAyLjk3MSAxMi4wMDA0IDIuOTcxQzcuMDAwMjMgMi45NzEgMi45NzEgNy4wMDAyMyAyLjk3MSAxMi4wMDA0QzIuOTcxIDE3LjAwMDYgNy4wMDAyMyAyMS4wMyAxMi4wMDA0IDIxLjAzWiIgZmlsbD0iYmxhY2siLz4KPC9zdmc+"
# HTML for the animation
html = f"""
<div class="rosetta-container">
<div class="rosetta-animation" id="rosetta">
<!-- Petals will be added via JavaScript -->
</div>
</div>
<style>
.rosetta-container {{
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}}
.rosetta-animation {{
position: relative;
width: 144px;
height: 144px;
transition: transform 0.3s;
}}
.rosetta-animation:hover {{
transform: scale(1.05);
}}
.petal-container {{
position: absolute;
top: 0;
left: 0;
width: 144px;
height: 144px;
}}
.petal {{
position: absolute;
left: 50%;
top: 50%;
width: 24px;
height: 24px;
}}
@keyframes selfAnimationRosetta {{
/* Cycle 1: Both Pauses Move Elements IN (0% -> 50% of 9s duration) */
0% {{ transform: translate(-50%, -50%) translateY(-30px) rotate(90deg); opacity: 0.9; }}
10% {{ transform: translate(-50%, -50%) translateY(-30px) rotate(90deg); opacity: 0.9; }}
20% {{ transform: translate(-50%, -50%) translateY(-23px) rotate(180deg); opacity: 0.95;}}
25% {{ transform: translate(-50%, -50%) translateY(-23px) rotate(180deg); opacity: 0.95;}}
30% {{ transform: translate(-50%, -50%) translateY(-23px) rotate(270deg); opacity: 1.0; }}
35% {{ transform: translate(-50%, -50%) translateY(-23px) rotate(270deg); opacity: 1.0; }}
50% {{ transform: translate(-50%, -50%) translateY(-30px) rotate(450deg); opacity: 0.9; }}
/* Cycle 2: Skips Midpoint Pause (50% -> 100% of 9s duration) */
50% {{ transform: translate(-50%, -50%) translateY(-30px) rotate(450deg); opacity: 0.9; }}
60% {{ transform: translate(-50%, -50%) translateY(-30px) rotate(450deg); opacity: 0.9; }}
80% {{ transform: translate(-50%, -50%) translateY(-23px) rotate(630deg); opacity: 1.0; }}
85% {{ transform: translate(-50%, -50%) translateY(-23px) rotate(630deg); opacity: 1.0; }}
100% {{ transform: translate(-50%, -50%) translateY(-30px) rotate(810deg); opacity: 0.9; }}
}}
@keyframes groupPulse {{
0% {{ transform: scale(1) rotate(0deg); }}
50% {{ transform: scale(0.98) rotate(180deg); }}
100% {{ transform: scale(1) rotate(360deg); }}
}}
</style>
<script>
(function() {{
// Get container element
const container = document.getElementById('rosetta');
// Set animation for container
container.style.animation = 'groupPulse 8s ease-in-out infinite';
// SVG data as base64
const svgData = '{light_svg_base64}';
const svgDataDark = '{dark_svg_base64}';
// Determine which SVG to use based on color scheme preference
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
const currentSvg = prefersDarkScheme ? svgDataDark : svgData;
// Create petals
const petals = 5;
for (let i = 0; i < petals; i++) {{
// Create petal container
const petalContainer = document.createElement('div');
petalContainer.className = 'petal-container';
petalContainer.style.transform = `rotate(${{(360 / petals) * i}}deg)`;
// Create petal
const petal = document.createElement('div');
petal.className = 'petal';
petal.style.animation = 'selfAnimationRosetta 9s ease-in-out infinite';
petal.style.animationDelay = `${{i * 0.05}}s`;
// Create SVG image
const img = document.createElement('img');
img.src = `data:image/svg+xml;base64,${{currentSvg}}`;
img.alt = `Petal ${{i + 1}}`;
img.style.width = '100%';
img.style.height = '100%';
// Assemble components
petal.appendChild(img);
petalContainer.appendChild(petal);
container.appendChild(petalContainer);
}}
}})();
</script>
"""
return html
def rosetta_logo():
"""Create a Gradio HTML component with the Rosetta animation"""
html_content = create_rosetta_animation()
return gr.HTML(html_content)
# Example usage in a Gradio app:
if __name__ == "__main__":
with gr.Blocks() as demo:
gr.Markdown("# SKENAI-NET Rosetta Animation Demo")
rosetta_logo()
gr.Markdown("This animation demonstrates the Rosetta component adapted for Hugging Face Spaces.")
demo.launch()