File size: 6,989 Bytes
9feb1f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
142
143
144
145
146
147
148
149
150
"""
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()