Discusión

Aplicación de Cubo de Rubik 3D

De Wikiprompt, la enciclopedia libre de prompts

Eyisha Zyer
Contribuido porEyisha ZyerXFuente

11 jul 2026

Aplicación de Cubo de Rubik 3D Un prompt completo para crear un cubo de Rubik 3D interactivo usando Three.js, con controles, interfaz de usuario y animaciones suaves.

Contenido del PromptGuardar

🌐
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>3D Rubik's Cube</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background: #1a1a2e; overflow: hidden; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } #canvas-container { width: 100vw; height: 100vh; } .hud { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 10px; z-index: 100; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); padding: 10px 20px; border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.2); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); } .btn { padding: 10px 24px; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; text-transform: uppercase; letter-spacing: 1px; } .btn-scramble { background: linear-gradient(135deg, #667eea, #764ba2); color: white; } .btn-scramble:hover { transform: translateY(-2px); box-shadow: 0 5px 20px rgba(102, 126, 234, 0.4); } .btn-solve { background: linear-gradient(135deg, #f093fb, #f5576c); color: white; } .btn-solve:hover { transform: translateY(-2px); box-shadow: 0 5px 20px rgba(245, 87, 108, 0.4); } .move-counter { position: fixed; top: 20px; right: 20px; color: white; font-size: 18px; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); padding: 10px 20px; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.2); z-index: 100; } .title { position: fixed; top: 20px; left: 20px; color: white; font-size: 24px; font-weight: 700; text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); z-index: 100; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); padding: 10px 20px; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.2); } .hint { position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%); color: rgba(255, 255, 255, 0.6); font-size: 14px; z-index: 100; text-align: center; background: rgba(0, 0, 0, 0.3); padding: 8px 16px; border-radius: 6px; } @media (max-width: 768px) { .hud { flex-direction: column; bottom: 10px; padding: 8px; } .btn { padding: 8px 16px; font-size: 14px; } .title { font-size: 18px; top: 10px; left: 10px; } .move-counter { font-size: 14px; top: 10px; right: 10px; } } </style> </head> <body> <div id="canvas-container"></div> <div class="title">🧊 Rubik's Cube</div> <div class="move-counter">Moves: <span id="moveCount">0</span></div> <div class="hint">Drag to rotate • Scroll to zoom • R to scramble • S to solve</div> <div class="hud"> <button class="btn btn-scramble" onclick="scrambleCube()">Scramble</button> <button class="btn btn-solve" onclick="solveCube()">Solve</button> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script> <script> // Scene setup const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(5, 5, 5); camera.lookAt(0, 0, 0); const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); renderer.shadowMap.enabled = true; document.getElementById('canvas-container').appendChild(renderer.domElement); // Controls const controls = new THREE.OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.25; controls.rotateSpeed = 0.5; controls.minDistance = 4; controls.maxDistance = 15; // Lighting const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); directionalLight.position.set(5, 10, 7); directionalLight.castShadow = true; scene.add(directionalLight); const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.3); directionalLight2.position.set(-5, -3, -5); scene.add(directionalLight2); // Cube colors const COLORS = { white: 0xffffff, yellow: 0xffff00, red: 0xff0000, orange: 0xff8c00, blue: 0x0000ff, green: 0x00ff00 }; // Create cube const cubeGroup = new THREE.Group(); const cubies = []; const gap = 0.05; const size = 0.9; // Face definitions: [color, axis, position] const faces = [ { color: COLORS.white, axis: 'y', position: 1 }, // Top { color: COLORS.yellow, axis: 'y', position: -1 }, // Bottom { color: COLORS.red, axis: 'x', position: 1 }, // Right { color: COLORS.orange, axis: 'x', position: -1 }, // Left { color: COLORS.blue, axis: 'z', position: 1 }, // Front { color: COLORS.green, axis: 'z', position: -1 } // Back ]; for (let x = -1; x <= 1; x++) { for (let y = -1; y <= 1; y++) { for (let z = -1; z <= 1; z++) { const geometry = new THREE.BoxGeometry(size, size, size); const materials = []; // Create materials for each face for (let i = 0; i < 6; i++) { const face = faces[i]; let shouldColor = false; if (face.axis === 'x' && x === face.position) shouldColor = true; if (face.axis === 'y' && y === face.position) shouldColor = true; if (face.axis === 'z' && z === face.position) shouldColor = true; if (shouldColor) { materials.push(new THREE.MeshStandardMaterial({ color: face.color, roughness: 0.3, metalness: 0.1 })); } else { materials.push(new THREE.MeshStandardMaterial({ color: 0x1a1a2e, roughness: 0.8, metalness: 0.2 })); } } const cubie = new THREE.Mesh(geometry, materials); cubie.position.set(x * (size + gap), y * (size + gap), z * (size + gap)); cubie.castShadow = true; cubie.receiveShadow = true; cubeGroup.add(cubie); cubies.push(cubie); } } } scene.add(cubeGroup); // Add subtle grid floor const gridHelper = new THREE.GridHelper(10, 20, 0x444466, 0x333355); gridHelper.position.y = -2.5; scene.add(gridHelper); // Animation state let isAnimating = false; let moveQueue = []; let moveCount = 0; let scrambleMoves = []; // Move definitions const MOVES = { 'U': { axis: 'y', layer: 1, angle: -Math.PI / 2 }, 'D': { axis: 'y', layer: -1, angle: Math.PI / 2 }, 'R': { axis: 'x', layer: 1, angle: -Math.PI / 2 }, 'L': { axis: 'x', layer: -1, angle: Math.PI / 2 }, 'F': { axis: 'z', layer: 1, angle: -Math.PI / 2 }, 'B': { axis: 'z', layer: -1, angle: Math.PI / 2 }, 'U\'': { axis: 'y', layer: 1, angle: Math.PI / 2 }, 'D\'': { axis: 'y', layer: -1, angle: -Math.PI / 2 }, 'R\'': { axis: 'x', layer: 1, angle: Math.PI / 2 }, 'L\'': { axis: 'x', layer: -1, angle: -Math.PI / 2 }, 'F\'': { axis: 'z', layer: 1, angle: Math.PI / 2 }, 'B\'': { axis: 'z', layer: -1, angle: -Math.PI / 2 } }; function getCubiesInLayer(axis, layer) { const threshold = 0.1; return cubies.filter(cubie => { const pos = cubie.position; if (axis === 'x') return Math.abs(pos.x - layer * (size + gap)) < threshold; if (axis === 'y') return Math.abs(pos.y - layer * (size + gap)) < threshold; if (axis === 'z') return Math.abs(pos.z - layer * (size + gap)) < threshold; return false; }); } function animateMove(move, callback) { if (isAnimating) { moveQueue.push({ move, callback }); return; } isAnimating = true; const moveDef = MOVES[move]; if (!moveDef) { isAnimating = false; if (callback) callback(); return; } const layerCubies = getCubiesInLayer(moveDef.axis, moveDef.layer); const pivot = new THREE.Group(); scene.add(pivot); layerCubies.forEach(cubie => { pivot.attach(cubie); }); const targetRotation = moveDef.angle; const duration = 300; const startTime = Date.now(); function animate() { const elapsed = Date.now() - startTime; const progress = Math.min(elapsed / duration, 1); const easedProgress = 1 - Math.pow(1 - progress, 3); if (moveDef.axis === 'x') pivot.rotation.x = targetRotation * easedProgress; if (moveDef.axis === 'y') pivot.rotation.y = targetRotation * easedProgress; if (moveDef.axis === 'z') pivot.rotation.z = targetRotation * easedProgress; if (progress < 1) { requestAnimationFrame(animate); } else { // Snap to exact rotation if (moveDef.axis === 'x') pivot.rotation.x = targetRotation; if (moveDef.axis === 'y') pivot.rotation.y = targetRotation; if (moveDef.axis === 'z') pivot.rotation.z = targetRotation; // Detach cubies from pivot layerCubies.forEach(cubie => { cubeGroup.attach(cubie); }); scene.remove(pivot); // Round positions to avoid floating point errors layerCubies.forEach(cubie => { cubie.position.x = Math.round(cubie.position.x * 10) / 10; cubie.position.y = Math.round(cubie.position.y * 10) / 10; cubie.position.z = Math.round(cubie.position.z * 10) / 10; }); isAnimating = false; moveCount++; document.getElementById('moveCount').textContent = moveCount; if (callback) callback(); // Process next move in queue if (moveQueue.length > 0) { const next = moveQueue.shift(); animateMove(next.move, next.callback); } } } animate(); } function scrambleCube() { if (isAnimating) return; scrambleMoves = []; const moves = Object.keys(MOVES); const numMoves = Math.floor(Math.random() * 6) + 15; // 15-20 moves for (let i = 0; i < numMoves; i++) { const move = moves[Math.floor(Math.random() * moves.length)]; scrambleMoves.push(move); animateMove(move); } } function solveCube() { if (isAnimating) return; const reverseMoves = scrambleMoves.slice().reverse().map(move => { return move.includes("'") ? move.replace("'", "") : move + "'"; }); reverseMoves.forEach(move => { animateMove(move); }); scrambleMoves = []; } // Keyboard shortcuts document.addEventListener('keydown', (e) => { if (e.key.toLowerCase() === 'r') scrambleCube(); if (e.key.toLowerCase() === 's') solveCube(); }); // Window resize window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); // Animation loop function animate() { requestAnimationFrame(animate); controls.update(); renderer.render(scene, camera); } animate(); // Initial subtle rotation cubeGroup.rotation.x = 0.5; cubeGroup.rotation.y = 0.5; </script> </body> </html>

Iniciá sesión para ver el prompt completo

Continuar con:

Al iniciar sesión, aceptás nuestros Términos de uso y Política de privacidad

Uso

Este prompt está diseñado para usarse con coding. Copiá el contenido de arriba y pegalo en tu herramienta de IA preferida.

Para mejores resultados, personalizá los marcadores (indicados con corchetes o mayúsculas) con tus requisitos específicos.

Referencias

Categorías:coding| twitter| 3d-cube| three-js

Discusión