Selaa lähdekoodia

improve preview

Tuan Nguyen 1 vuosi sitten
vanhempi
sitoutus
ce8c966e9e
3 muutettua tiedostoa jossa 109 lisäystä ja 43 poistoa
  1. 35 2
      app.py
  2. 19 0
      static/css/style.css
  3. 55 41
      static/js/main.js

+ 35 - 2
app.py

@@ -1,5 +1,5 @@
 from fastapi import FastAPI, UploadFile, File, HTTPException, BackgroundTasks, WebSocket, WebSocketDisconnect
-from fastapi.responses import JSONResponse, FileResponse
+from fastapi.responses import JSONResponse, FileResponse, Response
 from fastapi.staticfiles import StaticFiles
 from fastapi.templating import Jinja2Templates
 from pydantic import BaseModel
@@ -19,6 +19,8 @@ import sys
 import asyncio
 from contextlib import asynccontextmanager
 from modules.led.led_controller import LEDController, effect_idle
+import math
+
 # Configure logging
 logging.basicConfig(
     level=logging.INFO,
@@ -353,7 +355,38 @@ async def preview_thr(request: DeleteFileRequest):
 
     try:
         coordinates = pattern_manager.parse_theta_rho_file(file_path)
-        return {"success": True, "coordinates": coordinates}
+        
+        # Convert polar coordinates to SVG path
+        svg_path = []
+        for i, (theta, rho) in enumerate(coordinates):
+            # Convert polar to cartesian coordinates
+            # Use a larger viewBox (200x200) for better resolution
+            x = 100 + rho * 90 * math.cos(theta)  # Scale and center
+            y = 100 - rho * 90 * math.sin(theta)  # Scale and center, flip y-axis
+            
+            if i == 0:
+                svg_path.append(f"M {x:.2f} {y:.2f}")
+            else:
+                svg_path.append(f"L {x:.2f} {y:.2f}")
+        
+        # Create SVG with larger viewBox and preserveAspectRatio
+        svg = f'''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="100%" height="100%" viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg">
+    <path d="{' '.join(svg_path)}" 
+          fill="none" 
+          stroke="currentColor" 
+          stroke-width="0.5"/>
+</svg>'''
+        
+        # Get first and last coordinates
+        first_coord = coordinates[0] if coordinates else None
+        last_coord = coordinates[-1] if coordinates else None
+        
+        return {
+            "svg": svg,
+            "first_coordinate": first_coord,
+            "last_coordinate": last_coord
+        }
     except Exception as e:
         logger.error(f"Failed to generate preview for {request.file_name}: {str(e)}")
         raise HTTPException(status_code=500, detail=str(e))

+ 19 - 0
static/css/style.css

@@ -1550,3 +1550,22 @@ input[type="number"]:focus {
         display: flex;
     }
 }
+
+#pattern-preview-container .svg-container {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    min-height: 200px;
+}
+
+#pattern-preview-container .coordinate-display {
+    margin-top: 10px;
+    text-align: center;
+}
+
+#pattern-preview-container.fullscreen .svg-container {
+    width: initial;
+    max-width: calc(100vw - 30px);
+}

+ 55 - 41
static/js/main.js

@@ -145,6 +145,15 @@ async function selectFile(file, listItem) {
     }
 
     logMessage(`Selected file: ${file}`);
+    
+    // Show the preview container
+    const previewContainer = document.getElementById('pattern-preview-container');
+    if (previewContainer) {
+        previewContainer.classList.remove('hidden');
+        previewContainer.classList.add('visible');
+    }
+    
+    // Update the preview
     await previewPattern(file);
 
     // Populate the playlist dropdown after selecting a pattern
@@ -384,51 +393,56 @@ async function previewPattern(fileName, containerId = 'pattern-preview-container
             body: JSON.stringify({ file_name: fileName })
         });
 
-        const result = await response.json();
-        if (result.success) {
-            // Mirror the theta values in the coordinates
-            const coordinates = result.coordinates.map(coord => [
-                (coord[0] < Math.PI) ? 
-                    Math.PI - coord[0] : // For first half
-                    3 * Math.PI - coord[0], // For second half
-                coord[1]
-            ]);
-
-            // Render the pattern in the specified container
-            const canvasId = containerId === 'currently-playing-container'
-                ? 'currentlyPlayingCanvas'
-                : 'patternPreviewCanvas';
-            renderPattern(coordinates, canvasId);
-
-            // Update coordinate display
-            const firstCoordElement = document.getElementById('first_coordinate');
-            const lastCoordElement = document.getElementById('last_coordinate');
-
-            if (firstCoordElement) {
-                const firstCoord = coordinates[0];
-                firstCoordElement.textContent = `First Coordinate: θ=${firstCoord[0].toFixed(2)}, ρ=${firstCoord[1].toFixed(2)}`;
-            } else {
-                logMessage('First coordinate element not found.', LOG_TYPE.WARNING);
-            }
+        if (!response.ok) {
+            throw new Error(`HTTP error! status: ${response.status}`);
+        }
 
-            if (lastCoordElement) {
-                const lastCoord = coordinates[coordinates.length - 1];
-                lastCoordElement.textContent = `Last Coordinate: θ=${lastCoord[0].toFixed(2)}, ρ=${lastCoord[1].toFixed(2)}`;
-            } else {
-                logMessage('Last coordinate element not found.', LOG_TYPE.WARNING);
-            }
+        const data = await response.json();
+        
+        // Get the preview container
+        const previewContainer = document.getElementById(containerId);
+        if (!previewContainer) {
+            logMessage(`Preview container not found: ${containerId}`, LOG_TYPE.ERROR);
+            return;
+        }
 
-            // Show the preview container
-            const previewContainer = document.getElementById(containerId);
-            if (previewContainer) {
-                previewContainer.classList.remove('hidden');
-                previewContainer.classList.add('visible');
-            } else {
-                logMessage(`Preview container not found: ${containerId}`, LOG_TYPE.ERROR);
-            }
+        // Get the pattern preview section
+        const patternPreview = previewContainer.querySelector('#pattern-preview');
+        if (!patternPreview) {
+            logMessage('Pattern preview section not found', LOG_TYPE.ERROR);
+            return;
+        }
+
+        // Clear existing content
+        patternPreview.innerHTML = '';
+
+        // Create SVG container
+        const svgContainer = document.createElement('div');
+        svgContainer.className = 'svg-container';
+        svgContainer.innerHTML = data.svg;
+
+        // Create coordinate display
+        const coordDisplay = document.createElement('div');
+        coordDisplay.className = 'coordinate-display';
+
+        // Update coordinate text
+        if (data.first_coordinate && data.last_coordinate) {
+            coordDisplay.innerHTML = `
+                <div>First Coordinate: θ=${data.first_coordinate[0].toFixed(2)}, ρ=${data.first_coordinate[1].toFixed(2)}</div>
+                <div>Last Coordinate: θ=${data.last_coordinate[0].toFixed(2)}, ρ=${data.last_coordinate[1].toFixed(2)}</div>
+            `;
         } else {
-            logMessage(`Failed to fetch preview for file: ${fileName}`, LOG_TYPE.WARNING);
+            coordDisplay.innerHTML = 'No coordinates available';
         }
+
+        // Add elements to the preview
+        patternPreview.appendChild(svgContainer);
+        patternPreview.appendChild(coordDisplay);
+
+        // Show the preview container
+        previewContainer.classList.remove('hidden');
+        previewContainer.classList.add('visible');
+
     } catch (error) {
         logMessage(`Error previewing pattern: ${error.message}`, LOG_TYPE.ERROR);
     }