Meta Description" name="description" />

Share this result

Previews are deleted daily. Get a permanent share link sent to your inbox:
Script
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Brazo Robotico v5.2 - Simulación</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background: #1a1a2e; color: #eee; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; justify-content: center; padding: 20px; } .main-container { max-width: 650px; width: 100%; background: #16213e; border-radius: 20px; padding: 25px; box-shadow: 0 20px 40px rgba(0,0,0,0.6); } h1 { text-align: center; margin-bottom: 20px; font-size: 1.8em; color: #e94560; } .seccion { background: #0f3460; border-radius: 15px; padding: 20px; margin-bottom: 20px; box-shadow: 0 10px 20px rgba(0,0,0,0.3); } .seccion h2 { font-size: 1.3em; margin-bottom: 15px; color: #f5f5f5; border-bottom: 2px solid #e94560; padding-bottom: 5px; } canvas { display: block; margin: 0 auto; border: 3px solid #e94560; border-radius: 12px; box-shadow: 0 0 20px rgba(233, 69, 96, 0.5); max-width: 100%; height: auto; } .info { display: flex; justify-content: space-between; margin: 10px 0; background: #1a1a2e; padding: 8px 12px; border-radius: 8px; flex-wrap: wrap; } .info span { font-weight: bold; color: #e94560; } button { background: #e94560; border: none; color: white; padding: 12px 15px; margin: 5px; border-radius: 25px; font-size: 0.9em; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 5px 10px rgba(0,0,0,0.2); font-weight: bold; } button:disabled { background: #555; color: #aaa; cursor: not-allowed; box-shadow: none; } button:not(:disabled):hover { background: #c23152; transform: translateY(-2px); box-shadow: 0 8px 15px rgba(0,0,0,0.3); } select { width: 100%; padding: 12px; border-radius: 25px; background: #1a1a2e; color: white; border: 2px solid #e94560; font-size: 1em; margin: 5px 0; } .slider-container { margin: 15px 0; } .slider-container label { display: flex; justify-content: space-between; margin-bottom: 5px; font-weight: bold; } input[type=range] { width: 100%; height: 20px; -webkit-appearance: none; background: #0f3460; border-radius: 10px; outline: none; } input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 30px; height: 30px; background: #e94560; border-radius: 50%; cursor: pointer; box-shadow: 0 0 10px #e94560; } .botones-accion { display: flex; flex-wrap: wrap; justify-content: center; } #mensaje { color: #ff6b6b; font-weight: bold; text-align: center; margin-top: 10px; } .btn-ajuste { width: 30px; height: 30px; padding: 0; font-size: 1.2em; background: #0f3460; } .velocidad-selector { display: flex; justify-content: center; gap: 10px; margin-bottom: 15px; flex-wrap: wrap; } .velocidad-selector label { display: flex; align-items: center; gap: 5px; cursor: pointer; } .velocidad-selector input[type=radio] { display: none; } .velocidad-selector .radio-btn { padding: 8px 15px; border-radius: 20px; background: #555; color: #ccc; cursor: pointer; transition: all 0.3s ease; font-size: 0.9em; } .velocidad-selector input[type=radio]:checked + .radio-btn { background: #e94560; color: white; box-shadow: 0 0 15px rgba(233,69,96,0.5); } .desplegable-container { background: #0a1a2e; border-radius: 15px; padding: 15px; margin: 10px 0; border: 1px solid #e94560; } .desplegable-container p { margin-bottom: 10px; font-weight: bold; } .desplegable-container select { background: #1a1a2e; } </style> </head> <body> <div class="main-container"> <h1>♟️ Brazo Robotico <small style="color:#aaa;">v5.2 Simulación</small></h1> <div class="seccion"> <h2>🎯 Tablero de Ajedrez</h2> <canvas id="chessboard" width="480" height="480"></canvas> <div class="info"> <span>Turno: <b id="turnoActual">Blanco</b></span> <span>Casilla: <b id="casillaSel">-</b></span> <span>Pieza: <b id="piezaSel">-</b></span> </div> <div id="mensaje"></div> <div class="botones-accion"> <button id="grabarBtn" disabled>💾 Grabar</button> <button id="irBtn" disabled>▶️ Ir</button> <button id="borrarBtn" disabled>🗑️ Borrar</button> <button id="moverPiezaBtn" disabled>♟️ Mover pieza</button> <button id="deshacerBtn">↩️ Deshacer</button> <button id="rehacerBtn">↪️ Rehacer</button> <button id="resetTableroBtn">🔄 Reset</button> </div> <div class="desplegable-container"> <p>📍 Casillas guardadas:</p> <select id="selectPosiciones" onchange="seleccionarDesdeDesplegable()"> <option value="">-- Seleccionar casilla grabada --</option> </select> <div class="botones-accion" style="margin-top:10px;"> <button id="irDesdeDesplegable" disabled onclick="irDesdeDesplegable()">▶️ Ir a seleccionada</button> <button id="borrarDesdeDesplegable" disabled onclick="borrarDesdeDesplegable()">🗑️ Borrar seleccionada</button> </div> </div> </div> <div class="seccion"> <h2>🎮 Control Manual</h2> <div class="velocidad-selector"> <label><input type="radio" name="velocidad" value="suave" onchange="cambiarVelocidad('suave')"><span class="radio-btn">🐢 Suave</span></label> <label><input type="radio" name="velocidad" value="medio" onchange="cambiarVelocidad('medio')" checked><span class="radio-btn">🐇 Medio</span></label> <label><input type="radio" name="velocidad" value="rapido" onchange="cambiarVelocidad('rapido')"><span class="radio-btn">🚀 Rápido</span></label> </div> <div id="sliders"></div> <div class="botones-accion"> <button onclick="alert('Reposo')">🧘 Reposo</button> <button onclick="alert('Recoger')">🤏 Recoger (E2)</button> <button onclick="alert('Soltar')">✋ Soltar (E4)</button> </div> </div> <div class="seccion" id="seccionResolucion"> <h2>⚙️ Ajustes de Resolución (por canal)</h2> <div class="slider-container"> <label>Seleccionar canal:</label> <select id="selectCanal" onchange="cargarValoresCanal()"> <option value="0">Canal 0 - Base</option> <option value="1">Canal 1 - Hombro</option> <option value="2">Canal 2 - Codo</option> <option value="3">Canal 3 - Muñeca Inc</option> <option value="4">Canal 4 - Muñeca Giro</option> <option value="5">Canal 5 - Pinza</option> </select> </div> <div class="slider-container"> <label>Zona Muerta (µs): <span id="deadbandVal">5</span></label> <input type="range" id="deadbandSlider" min="1" max="20" value="5" oninput="guardarDeadband(this.value)"> </div> <div class="slider-container"> <label>Suavizado (delay ms): <span id="smoothVal">2</span></label> <input type="range" id="smoothSlider" min="1" max="10" value="2" oninput="guardarSmooth(this.value)"> </div> </div> </div> <script> // --- LÓGICA DE SIMULACIÓN (v5.2 - Guardado por canal corregido) --- (function() { // Variables globales let velocidadGlobal = 'medio'; let casillaSeleccionada = -1, piezaSeleccionada = -1; let posicionesGrabadas = new Array(64).fill(false); let turno = 'blanco'; let historial = []; let indiceHistorial = -1; let canalSeleccionado = 0; // Arrays para deadband y smooth por canal (valores iniciales) const deadbandPorCanal = [5, 5, 5, 5, 5, 5]; const smoothPorCanal = [2, 2, 2, 2, 2, 2]; const piezasIniciales = [ 'r','n','b','q','k','b','n','r', 'p','p','p','p','p','p','p','p', '','','','','','','','', '','','','','','','','', '','','','','','','','', '','','','','','','','', 'P','P','P','P','P','P','P','P', 'R','N','B','Q','K','B','N','R' ]; let tablero = [...piezasIniciales]; // Funciones auxiliares function esMayuscula(c) { return c >= 'A' && c <= 'Z'; } function colorPieza(p) { return p ? (esMayuscula(p) ? 'blanco' : 'negro') : null; } function esMovimientoValido(origen, destino, tablero, turno) { const pieza = tablero[origen]; const captura = tablero[destino]; if (!pieza) return false; if (colorPieza(pieza) !== turno) return false; if (captura && colorPieza(captura) === turno) return false; const filaO = Math.floor(origen / 8), colO = origen % 8; const filaD = Math.floor(destino / 8), colD = destino % 8; const difFil = filaD - filaO, difCol = colD - colO; const tipo = pieza.toUpperCase(); function hayObstaculos(o, d, t) { const fo = Math.floor(o/8), co = o%8, fd = Math.floor(d/8), cd = d%8; const pf = Math.sign(fd - fo), pc = Math.sign(cd - co); let f = fo + pf, c = co + pc; while (f !== fd || c !== cd) { if (t[f*8+c] !== '') return true; f += pf; c += pc; } return false; } switch (tipo) { case 'P': if (turno === 'blanco') { if (difFil === -1 && difCol === 0 && !captura) return true; if (filaO === 6 && difFil === -2 && difCol === 0 && !captura && !tablero[origen-8]) return true; if (difFil === -1 && Math.abs(difCol) === 1 && captura && colorPieza(captura) === 'negro') return true; } else { if (difFil === 1 && difCol === 0 && !captura) return true; if (filaO === 1 && difFil === 2 && difCol === 0 && !captura && !tablero[origen+8]) return true; if (difFil === 1 && Math.abs(difCol) === 1 && captura && colorPieza(captura) === 'blanco') return true; } return false; case 'R': return (difFil===0 || difCol===0) && !hayObstaculos(origen, destino, tablero); case 'N': return (Math.abs(difFil)===2 && Math.abs(difCol)===1) || (Math.abs(difFil)===1 && Math.abs(difCol)===2); case 'B': return Math.abs(difFil)===Math.abs(difCol) && !hayObstaculos(origen, destino, tablero); case 'Q': return (difFil===0 || difCol===0 || Math.abs(difFil)===Math.abs(difCol)) && !hayObstaculos(origen, destino, tablero); case 'K': return Math.abs(difFil)<=1 && Math.abs(difCol)<=1; default: return false; } } function guardarEstado() { historial = historial.slice(0, indiceHistorial + 1); historial.push({ tablero: [...tablero], turno }); indiceHistorial = historial.length - 1; actualizarBotonesHistorial(); } function deshacer() { if (indiceHistorial > 0) { indiceHistorial--; const est = historial[indiceHistorial]; tablero = [...est.tablero]; turno = est.turno; piezaSeleccionada = casillaSeleccionada = -1; actualizarTodo(); dibujarTablero(); } } function rehacer() { if (indiceHistorial < historial.length - 1) { indiceHistorial++; const est = historial[indiceHistorial]; tablero = [...est.tablero]; turno = est.turno; piezaSeleccionada = casillaSeleccionada = -1; actualizarTodo(); dibujarTablero(); } } function actualizarBotonesHistorial() { document.getElementById('deshacerBtn').disabled = (indiceHistorial <= 0); document.getElementById('rehacerBtn').disabled = (indiceHistorial >= historial.length - 1); } // Dibujo del tablero const canvas = document.getElementById('chessboard'); const ctx = canvas.getContext('2d'); const size = 60; function dibujarTablero() { if (!ctx) return; for (let row = 0; row < 8; row++) { for (let col = 0; col < 8; col++) { const idx = row * 8 + col; ctx.fillStyle = (row + col) % 2 === 0 ? '#deb887' : '#8b5a2b'; ctx.fillRect(col * size, row * size, size, size); if (posicionesGrabadas[idx]) { ctx.fillStyle = 'rgba(0, 255, 0, 0.3)'; ctx.fillRect(col * size, row * size, size, size); } if (idx === casillaSeleccionada) { ctx.strokeStyle = '#ff0'; ctx.lineWidth = 4; ctx.strokeRect(col * size + 2, row * size + 2, size - 4, size - 4); } if (idx === piezaSeleccionada) { ctx.strokeStyle = '#0ff'; ctx.lineWidth = 4; ctx.strokeRect(col * size + 2, row * size + 2, size - 4, size - 4); } const pieza = tablero[idx]; if (pieza) { ctx.fillStyle = pieza === pieza.toUpperCase() ? '#fff' : '#000'; ctx.font = 'bold 36px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; const sim = { K:'\u2654',Q:'\u2655',R:'\u2656',B:'\u2657',N:'\u2658',P:'\u2659', k:'\u265A',q:'\u265B',r:'\u265C',b:'\u265D',n:'\u265E',p:'\u265F' }; ctx.fillText(sim[pieza], col * size + size/2, row * size + size/2); } ctx.fillStyle = (row + col) % 2 === 0 ? '#8b5a2b' : '#deb887'; ctx.font = 'bold 12px Arial'; ctx.textAlign = 'left'; if (col === 0) ctx.fillText(8 - row, 5, row * size + 18); if (row === 7) ctx.fillText('abcdefgh'[col], col * size + 48, 476); } } } function actualizarTodo() { document.getElementById('turnoActual').textContent = turno === 'blanco' ? 'Blanco' : 'Negro'; document.getElementById('casillaSel').textContent = casillaSeleccionada >= 0 ? 'abcdefgh'[casillaSeleccionada%8] + (8 - Math.floor(casillaSeleccionada/8)) : '-'; document.getElementById('piezaSel').textContent = piezaSeleccionada >= 0 ? 'abcdefgh'[piezaSeleccionada%8] + (8 - Math.floor(piezaSeleccionada/8)) : '-'; actualizarBotones(); actualizarBotonesHistorial(); } function actualizarBotones() { document.getElementById('grabarBtn').disabled = (casillaSeleccionada < 0); document.getElementById('irBtn').disabled = (casillaSeleccionada < 0 || !posicionesGrabadas[casillaSeleccionada]); document.getElementById('borrarBtn').disabled = (casillaSeleccionada < 0 || !posicionesGrabadas[casillaSeleccionada]); document.getElementById('moverPiezaBtn').disabled = (piezaSeleccionada < 0 || casillaSeleccionada < 0 || piezaSeleccionada === casillaSeleccionada); actualizarBotonesDesplegable(); } function actualizarDesplegable() { const select = document.getElementById('selectPosiciones'); select.innerHTML = '<option value="">-- Seleccionar casilla grabada --</option>'; for (let i = 0; i < 64; i++) { if (posicionesGrabadas[i]) { const casilla = 'abcdefgh'[i%8] + (8 - Math.floor(i/8)); select.innerHTML += '<option value="' + i + '">' + casilla + '</option>'; } } } function actualizarBotonesDesplegable() { document.getElementById('irDesdeDesplegable').disabled = (casillaSeleccionada < 0 || !posicionesGrabadas[casillaSeleccionada]); document.getElementById('borrarDesdeDesplegable').disabled = (casillaSeleccionada < 0 || !posicionesGrabadas[casillaSeleccionada]); } // NUEVO: Cargar valores del canal seleccionado en los sliders window.cargarValoresCanal = function() { const select = document.getElementById('selectCanal'); canalSeleccionado = parseInt(select.value); // Actualizar sliders con los valores guardados para este canal document.getElementById('deadbandSlider').value = deadbandPorCanal[canalSeleccionado]; document.getElementById('smoothSlider').value = smoothPorCanal[canalSeleccionado]; document.getElementById('deadbandVal').textContent = deadbandPorCanal[canalSeleccionado]; document.getElementById('smoothVal').textContent = smoothPorCanal[canalSeleccionado]; }; // NUEVO: Guardar deadband en el array del canal actual window.guardarDeadband = function(val) { const valor = parseInt(val); deadbandPorCanal[canalSeleccionado] = valor; document.getElementById('deadbandVal').textContent = valor; }; // NUEVO: Guardar smooth en el array del canal actual window.guardarSmooth = function(val) { const valor = parseInt(val); smoothPorCanal[canalSeleccionado] = valor; document.getElementById('smoothVal').textContent = valor; }; // Eventos de la interfaz window.seleccionarDesdeDesplegable = function() { const select = document.getElementById('selectPosiciones'); const val = select.value; if (val !== '') { casillaSeleccionada = parseInt(val); document.getElementById('casillaSel').textContent = 'abcdefgh'[casillaSeleccionada%8] + (8 - Math.floor(casillaSeleccionada/8)); actualizarBotones(); dibujarTablero(); } else { casillaSeleccionada = -1; document.getElementById('casillaSel').textContent = '-'; actualizarBotones(); dibujarTablero(); } }; window.irDesdeDesplegable = function() { if (casillaSeleccionada >= 0 && posicionesGrabadas[casillaSeleccionada]) { alert('Moviendo a ' + 'abcdefgh'[casillaSeleccionada%8] + (8 - Math.floor(casillaSeleccionada/8))); } }; window.borrarDesdeDesplegable = function() { if (casillaSeleccionada >= 0 && posicionesGrabadas[casillaSeleccionada]) { posicionesGrabadas[casillaSeleccionada] = false; actualizarBotones(); actualizarDesplegable(); dibujarTablero(); } }; window.cambiarVelocidad = function(nueva) { velocidadGlobal = nueva; console.log('Velocidad simulada: ' + nueva); }; // Crear sliders const nombresServos = ['Base', 'Hombro', 'Codo', 'Muñeca Inc', 'Muñeca Giro', 'Pinza']; function crearSliders() { const container = document.getElementById('sliders'); nombresServos.forEach(function(nombre, i) { const div = document.createElement('div'); div.className = 'slider-container'; div.innerHTML = '<label>' + nombre + ': <span id="valor' + i + '">90</span>°</label><br>' + '<div style="display:flex; align-items:center; gap:5px;">' + '<button class="btn-ajuste" onclick="window.ajustarPaso(' + i + ', -1)">−</button>' + '<input type="range" min="0" max="180" value="90" style="flex:1;" id="slider' + i + '" ' + 'oninput="window.moverSlider(' + i + ', this.value)">' + '<button class="btn-ajuste" onclick="window.ajustarPaso(' + i + ', 1)">+</button>' + '</div>'; container.appendChild(div); }); } window.ajustarPaso = function(canal, delta) { const slider = document.getElementById('slider' + canal); let nuevoAngulo = parseInt(slider.value) + delta; nuevoAngulo = Math.max(0, Math.min(180, nuevoAngulo)); slider.value = nuevoAngulo; document.getElementById('valor' + canal).textContent = nuevoAngulo; }; window.moverSlider = function(canal, valor) { document.getElementById('valor' + canal).textContent = valor; }; // Eventos de botones document.getElementById('grabarBtn').addEventListener('click', function() { if (casillaSeleccionada >= 0) { posicionesGrabadas[casillaSeleccionada] = true; actualizarBotones(); actualizarDesplegable(); dibujarTablero(); } }); document.getElementById('irBtn').addEventListener('click', function() { if (casillaSeleccionada >= 0 && posicionesGrabadas[casillaSeleccionada]) { alert('Moviendo a ' + 'abcdefgh'[casillaSeleccionada%8] + (8 - Math.floor(casillaSeleccionada/8))); } }); document.getElementById('borrarBtn').addEventListener('click', function() { if (casillaSeleccionada >= 0 && posicionesGrabadas[casillaSeleccionada]) { posicionesGrabadas[casillaSeleccionada] = false; actualizarBotones(); actualizarDesplegable(); dibujarTablero(); } }); document.getElementById('moverPiezaBtn').addEventListener('click', function() { if (piezaSeleccionada >= 0 && casillaSeleccionada >= 0 && casillaSeleccionada !== piezaSeleccionada) { if (esMovimientoValido(piezaSeleccionada, casillaSeleccionada, tablero, turno)) { guardarEstado(); tablero[casillaSeleccionada] = tablero[piezaSeleccionada]; tablero[piezaSeleccionada] = ''; turno = turno === 'blanco' ? 'negro' : 'blanco'; piezaSeleccionada = casillaSeleccionada = -1; actualizarTodo(); dibujarTablero(); } else { document.getElementById('mensaje').textContent = '⛔ Movimiento no válido o no es tu turno.'; } } }); document.getElementById('resetTableroBtn').addEventListener('click', function() { tablero = [...piezasIniciales]; turno = 'blanco'; piezaSeleccionada = casillaSeleccionada = -1; historial = []; indiceHistorial = -1; guardarEstado(); actualizarTodo(); dibujarTablero(); }); document.getElementById('deshacerBtn').addEventListener('click', deshacer); document.getElementById('rehacerBtn').addEventListener('click', rehacer); canvas.addEventListener('click', function(e) { const rect = canvas.getBoundingClientRect(); const col = Math.floor((e.clientX - rect.left) / size); const row = Math.floor((e.clientY - rect.top) / size); if (col < 0 || col > 7 || row < 0 || row > 7) return; const idx = row * 8 + col; const pieza = tablero[idx]; document.getElementById('mensaje').textContent = ''; if (piezaSeleccionada >= 0) { if (idx === piezaSeleccionada) { piezaSeleccionada = -1; casillaSeleccionada = idx; } else if (pieza && colorPieza(pieza) === colorPieza(tablero[piezaSeleccionada])) { piezaSeleccionada = idx; casillaSeleccionada = -1; } else { casillaSeleccionada = idx; } } else { casillaSeleccionada = idx; if (pieza && colorPieza(pieza) === turno) piezaSeleccionada = idx; } if (posicionesGrabadas[idx]) { document.getElementById('selectPosiciones').value = idx; actualizarBotonesDesplegable(); } else { document.getElementById('selectPosiciones').value = ''; actualizarBotonesDesplegable(); } actualizarTodo(); dibujarTablero(); }); // Inicialización final crearSliders(); dibujarTablero(); guardarEstado(); actualizarTodo(); })(); </script> </body> </html>
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

1

Requests

1

Domains

23KB

Transfer Size

23KB

Content Size

193.0ms

Dom Content Loaded

216.0ms

First Paint

194.0ms

Load Time
Domain Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...
Timings (ms)
Loading...
Total Time
Loading...
Content Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...