waveform AI changes

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-06-04 20:50:39 +02:00
padre 34233bdab0
commit 339649fe2a
Se han modificado 4 ficheros con 269 adiciones y 47 borrados

Ver fichero

@@ -1,6 +1,7 @@
import "./App.css";
import { useEffect, useRef } from "react";
import WaveForm from "./WaveForm";
import SimpleWaveForm from "./SimpleWaveForm";
import M from "materialize-css";
import text from "./list.txt";
@@ -79,7 +80,7 @@ const App = () => {
<>
<Header />
{analyzerData && <WaveForm analyzerData={analyzerData} />}
<SimpleWaveForm />
<TrackInfo
title={title}

93
src/CanvasTest.jsx Archivo normal
Ver fichero

@@ -0,0 +1,93 @@
import { useRef, useEffect } from "react";
const CanvasTest = () => {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) {
console.log('No canvas ref');
return;
}
const ctx = canvas.getContext("2d");
if (!ctx) {
console.log('No canvas context');
return;
}
console.log('=== CANVAS TEST ===');
console.log('Canvas dimensions:', canvas.width, 'x', canvas.height);
console.log('Canvas style:', canvas.style.width, 'x', canvas.style.height);
// Set canvas size
canvas.width = 800;
canvas.height = 600;
// Clear and draw test pattern
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Background
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Test rectangles
ctx.fillStyle = "red";
ctx.fillRect(50, 50, 100, 100);
ctx.fillStyle = "green";
ctx.fillRect(200, 50, 100, 100);
ctx.fillStyle = "blue";
ctx.fillRect(350, 50, 100, 100);
// Test bars
for (let i = 0; i < 20; i++) {
const x = i * 40;
const height = 100 + Math.sin(i * 0.5) * 50;
ctx.fillStyle = `hsl(${i * 18}, 70%, 50%)`;
ctx.fillRect(x, 300, 35, height);
}
console.log('Canvas test pattern drawn');
}, []);
return (
<div style={{
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
zIndex: 1000,
backgroundColor: 'rgba(255,255,255,0.1)'
}}>
<div style={{
position: 'absolute',
top: '10px',
left: '10px',
color: 'white',
background: 'black',
padding: '10px',
zIndex: 1001
}}>
CANVAS TEST - You should see colored rectangles and bars
</div>
<canvas
ref={canvasRef}
style={{
position: 'absolute',
top: '50px',
left: '50px',
border: '2px solid white',
backgroundColor: 'gray'
}}
width={800}
height={600}
/>
</div>
);
};
export default CanvasTest;

92
src/SimpleWaveForm.jsx Archivo normal
Ver fichero

@@ -0,0 +1,92 @@
import { useRef, useEffect } from "react";
const SimpleWaveForm = () => {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
console.log('=== SIMPLE WAVEFORM STARTED ===');
const animate = () => {
const time = Date.now();
// Set canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw background
ctx.fillStyle = "rgba(0, 0, 100, 0.1)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw bars
const barCount = 32;
const barWidth = canvas.width / barCount;
const centerY = canvas.height / 2;
for (let i = 0; i < barCount; i++) {
const wave = Math.sin(time * 0.003 + i * 0.3) * 0.5;
const barHeight = 100 + wave * 100;
ctx.fillStyle = `hsl(${(i * 11 + time * 0.1) % 360}, 70%, 50%)`;
ctx.fillRect(
i * barWidth + 5,
centerY - barHeight / 2,
barWidth - 10,
barHeight
);
}
console.log('Frame rendered at', time % 1000);
requestAnimationFrame(animate);
};
animate();
}, []);
return (
<div style={{
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
zIndex: 1000,
pointerEvents: 'none'
}}>
<canvas
ref={canvasRef}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
border: '3px solid lime',
backgroundColor: 'rgba(0,0,0,0.2)'
}}
/>
<div style={{
position: 'absolute',
top: '10px',
left: '10px',
color: 'white',
background: 'black',
padding: '10px',
zIndex: 1001,
fontSize: '16px'
}}>
SIMPLE WAVEFORM - You should see animated colorful bars
</div>
</div>
);
};
export default SimpleWaveForm;

Ver fichero

@@ -12,47 +12,51 @@ const BLUE_SHADES = [
const animateFallbackBars = (canvas, ctx, time) => {
const HEIGHT = canvas.height;
const WIDTH = canvas.width;
const barCount = 64;
const barWidth = Math.max(10, Math.floor(WIDTH / barCount));
const barCount = 32; // Reduced for easier debugging
const barWidth = Math.max(20, Math.floor(WIDTH / barCount));
const centerY = HEIGHT / 2;
let x = 0;
console.log('Drawing fallback bars:', { WIDTH, HEIGHT, barCount, barWidth, time: time % 1000 });
// Set rendering properties for better Tizen compatibility
ctx.imageSmoothingEnabled = false;
ctx.globalCompositeOperation = 'source-over';
for (let i = 0; i < barCount; i++) {
// Create animated wave pattern using time directly with slower, more visible movement
const slowTime = time * 0.001; // Very slow animation for TV viewing
const wave1 = Math.sin(slowTime + (i * 0.2)) * 0.4;
const wave2 = Math.sin(slowTime * 0.7 + (i * 0.15)) * 0.3;
const wave3 = Math.sin(slowTime * 1.3 + (i * 0.1)) * 0.2; // Third wave for complexity
const normalizedHeight = Math.max(0.3, Math.min(1, 0.5 + wave1 + wave2 + wave3));
const barHeight = Math.max(40, normalizedHeight * HEIGHT * 0.7);
// Create simple animated wave pattern
const slowTime = time * 0.002; // Slow animation
const wave = Math.sin(slowTime + (i * 0.3)) * 0.5;
const normalizedHeight = Math.max(0.4, Math.min(1, 0.6 + wave));
const barHeight = Math.max(60, normalizedHeight * HEIGHT * 0.5);
// Use dynamic colors based on height for more visual interest
const intensity = Math.floor(normalizedHeight * 200) + 55; // Keep it bright
const blue = Math.floor(255 * normalizedHeight);
ctx.fillStyle = `rgb(${intensity}, ${intensity}, ${blue})`;
// Use bright, solid colors for maximum visibility
ctx.fillStyle = `rgb(0, 150, 255)`; // Bright blue
// Draw main bar
const barY = centerY - barHeight/2;
const barX = x + 3;
const barW = barWidth - 6;
const barX = i * barWidth + 5;
const barW = barWidth - 10;
// Log first bar for debugging
if (i === 0) {
console.log(`First bar:`, { barX, barY, barW, barHeight, normalizedHeight, time: time % 1000 });
}
ctx.fillRect(barX, barY, barW, barHeight);
// Add high contrast outline
// Add white outline for visibility
ctx.strokeStyle = "white";
ctx.lineWidth = 2;
ctx.strokeRect(barX, barY, barW, barHeight);
// Add inner highlight for extra visibility
ctx.fillStyle = `rgba(255,255,255,${0.3 + normalizedHeight * 0.5})`;
ctx.fillRect(barX + 2, barY + 2, Math.max(2, barW - 4), Math.max(2, barHeight - 4));
x += barWidth;
}
// Draw test elements to verify canvas is working
ctx.fillStyle = "lime";
ctx.fillRect(10, 10, 100, 50);
ctx.fillStyle = "yellow";
ctx.fillRect(10, 70, 100, 50);
console.log('Fallback animation completed - test rectangles drawn');
};
// Real Web Audio API animation
@@ -103,16 +107,30 @@ const WaveForm = ({ analyzerData }) => {
const [useFallback, setUseFallback] = useState(true); // Start with fallback immediately
const animationRef = useRef(null);
// Remove fallbackData state and interval - we'll calculate animation in real-time
// Ensure we have minimum dimensions
const canvasWidth = Math.max(width || window.innerWidth || 1920, 800);
const canvasHeight = Math.max(height || window.innerHeight || 1080, 600);
console.log('WaveForm render - dimensions:', { width, height, canvasWidth, canvasHeight });
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
if (!canvas) {
console.log('Canvas ref not available yet');
return;
}
const ctx = canvas.getContext("2d");
if (!ctx) return;
if (!ctx) {
console.log('Canvas context not available');
return;
}
console.log('Canvas initialized:', canvas.width, 'x', canvas.height);
console.log('=== CANVAS INITIALIZED ===');
console.log('Canvas element:', canvas);
console.log('Canvas dimensions:', canvas.width, 'x', canvas.height);
console.log('Window dimensions:', window.innerWidth, 'x', window.innerHeight);
console.log('useSize dimensions:', width, 'x', height);
let webAudioWorking = true;
@@ -129,14 +147,22 @@ const WaveForm = ({ analyzerData }) => {
const currentTime = Date.now();
// Force canvas dimensions update for Tizen
if (canvas.width !== (width || window.innerWidth) ||
canvas.height !== (height || window.innerHeight)) {
canvas.width = width || window.innerWidth;
canvas.height = height || window.innerHeight;
const targetWidth = canvasWidth;
const targetHeight = canvasHeight;
console.log('Render called - Target dimensions:', targetWidth, 'x', targetHeight);
if (canvas.width !== targetWidth || canvas.height !== targetHeight) {
canvas.width = targetWidth;
canvas.height = targetHeight;
console.log('Canvas resized to:', canvas.width, 'x', canvas.height);
}
// Clear canvas with a semi-transparent fill instead of clearRect for Tizen
ctx.fillStyle = "rgba(0,0,0,0.01)"; // Very subtle background to force redraw
// Clear canvas completely first
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Add temporary debug background to see if canvas is working
ctx.fillStyle = "rgba(255, 0, 0, 0.1)"; // Very subtle red background for debugging
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.save();
@@ -186,7 +212,15 @@ const WaveForm = ({ analyzerData }) => {
}, [analyzerData, width, height, useFallback]); // Added useFallback dependency
return (
<div style={{ position: 'relative' }}>
<div style={{
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
zIndex: 1000, // Temporarily put it on top for debugging
pointerEvents: 'none'
}}>
<canvas
style={{
position: "absolute",
@@ -194,21 +228,19 @@ const WaveForm = ({ analyzerData }) => {
left: 0,
width: "100%",
height: "100%",
zIndex: -1,
// Tizen-specific optimizations
willChange: "contents", // Changed to contents for canvas updates
imageRendering: "pixelated", // Sharp rendering for TV
backgroundColor: "transparent",
zIndex: 0,
willChange: "contents",
imageRendering: "pixelated",
backgroundColor: "rgba(0,0,0,0.1)", // Slight background for visibility
pointerEvents: "none",
display: "block",
// Force hardware acceleration
transform: "translateZ(0)",
// Ensure crisp rendering
msInterpolationMode: "nearest-neighbor"
msInterpolationMode: "nearest-neighbor",
border: "2px solid red" // Debug border
}}
ref={canvasRef}
width={width || window.innerWidth}
height={height || window.innerHeight}
width={canvasWidth}
height={canvasHeight}
role="img"
aria-label={useFallback ? "Audio visualization (compatibility mode)" : "Real-time audio visualization"}
/>
@@ -218,18 +250,22 @@ const WaveForm = ({ analyzerData }) => {
position: 'fixed',
top: '10px',
right: '10px',
background: 'rgba(0,0,0,0.7)',
background: 'rgba(0,0,0,0.9)',
color: 'white',
padding: '10px',
borderRadius: '5px',
fontSize: '12px',
zIndex: 1000,
fontFamily: 'monospace'
fontFamily: 'monospace',
border: '1px solid white'
}}>
<div>Canvas: {width}x{height}</div>
<div>Actual: {canvasRef.current?.width}x{canvasRef.current?.height}</div>
<div>Fallback: {useFallback ? 'YES' : 'NO'}</div>
<div>HasAnalyzer: {analyzerData ? 'YES' : 'NO'}</div>
<div>Bars: 64</div>
<div>Time: {Date.now() % 10000}</div>
<div>Visible: {canvasRef.current?.style.display || 'unknown'}</div>
</div>
</div>
);