ノート

3Dルービックキューブアプリ

フリーのプロンプト百科事典 Wikiprompt より

Eyisha Zyer

2026年7月11日

3Dルービックキューブアプリ Three.jsを用いてインタラクティブな3Dルービックキューブを作成するための包括的なプロンプト。コントロール、UI、スムーズなアニメーションを備えています。

プロンプト内容保存

🌐
<!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 { display: block; } .hud { position: fixed; bottom: 30px; left: 50%; transform: translateX(-50%); display: flex; gap: 20px; align-items: center; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); padding: 15px 25px; border-radius: 50px; border: 1px solid rgba(255, 255, 255, 0.2); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); z-index: 100; } .btn { padding: 10px 25px; border: none; border-radius: 25px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; color: white; letter-spacing: 0.5px; } .btn-scramble { background: linear-gradient(135deg, #667eea, #764ba2); box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4); } .btn-scramble:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6); } .btn-solve { background: linear-gradient(135deg, #f093fb, #f5576c); box-shadow: 0 4px 15px rgba(245, 87, 108, 0.4); } .btn-solve:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(245, 87, 108, 0.6); } .move-counter { color: white; font-size: 16px; font-weight: 500; padding: 10px 20px; background: rgba(255, 255, 255, 0.1); border-radius: 25px; border: 1px solid rgba(255, 255, 255, 0.2); min-width: 80px; text-align: center; } .title { position: fixed; top: 30px; left: 50%; transform: translateX(-50%); color: white; font-size: 24px; font-weight: 700; text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); z-index: 100; letter-spacing: 1px; } .hint { position: fixed; bottom: 100px; 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: 20px; backdrop-filter: blur(5px); } @media (max-width: 768px) { .hud { bottom: 20px; padding: 10px 15px; gap: 10px; } .btn { padding: 8px 15px; font-size: 14px; } .move-counter { padding: 8px 12px; font-size: 14px; min-width: 60px; } .title { font-size: 18px; top: 20px; } .hint { bottom: 80px; font-size: 12px; } } </style> </head> <body> <div class="title">🎲 Rubik's Cube</div> <div class="hint">Drag to rotate • Scroll to zoom • Press R to scramble, S to solve</div> <div class="hud"> <button class="btn btn-scramble" onclick="scrambleCube()">Scramble</button> <div class="move-counter" id="moveCounter">0 moves</div> <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.body.appendChild(renderer.domElement); // Controls const controls = new THREE.OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.25; controls.rotateSpeed = 0.8; controls.zoomSpeed = 1.2; 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: 0xffd500, 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 colors for each cubie position const faceColors = { right: colors.red, left: colors.orange, up: colors.white, down: colors.yellow, front: colors.green, back: colors.blue }; // Create materials for each face function createCubie(x, y, z) { const materials = []; // Right (+x) - Red materials.push(new THREE.MeshPhongMaterial({ color: x === 1 ? faceColors.right : 0x333333, shininess: 30 })); // Left (-x) - Orange materials.push(new THREE.MeshPhongMaterial({ color: x === -1 ? faceColors.left : 0x333333, shininess: 30 })); // Up (+y) - White materials.push(new THREE.MeshPhongMaterial({ color: y === 1 ? faceColors.up : 0x333333, shininess: 30 })); // Down (-y) - Yellow materials.push(new THREE.MeshPhongMaterial({ color: y === -1 ? faceColors.down : 0x333333, shininess: 30 })); // Front (+z) - Green materials.push(new THREE.MeshPhongMaterial({ color: z === 1 ? faceColors.front : 0x333333, shininess: 30 })); // Back (-z) - Blue materials.push(new THREE.MeshPhongMaterial({ color: z === -1 ? faceColors.back : 0x333333, shininess: 30 })); const geometry = new THREE.BoxGeometry(size, size, size); 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; // Store original position for solving cubie.userData = { x, y, z }; return cubie; } // Create all 27 cubies for (let x = -1; x <= 1; x++) { for (let y = -1; y <= 1; y++) { for (let z = -1; z <= 1; z++) { const cubie = createCubie(x, y, z); cubeGroup.add(cubie); cubies.push(cubie); } } } scene.add(cubeGroup); // Animation state let isAnimating = false; let moveQueue = []; let moveCount = 0; let scrambleMoves = []; // Move definitions const moves = { 'R': { axis: 'x', layer: 1, angle: -Math.PI / 2 }, 'R\'': { axis: 'x', layer: 1, angle: Math.PI / 2 }, 'L': { axis: 'x', layer: -1, angle: Math.PI / 2 }, 'L\'': { axis: 'x', layer: -1, angle: -Math.PI / 2 }, 'U': { axis: 'y', layer: 1, angle: -Math.PI / 2 }, 'U\'': { axis: 'y', layer: 1, angle: Math.PI / 2 }, 'D': { axis: 'y', layer: -1, angle: Math.PI / 2 }, 'D\'': { axis: 'y', layer: -1, angle: -Math.PI / 2 }, 'F': { axis: 'z', layer: 1, angle: -Math.PI / 2 }, 'F\'': { axis: 'z', layer: 1, angle: Math.PI / 2 }, 'B': { axis: 'z', layer: -1, angle: Math.PI / 2 }, 'B\'': { axis: 'z', layer: -1, angle: -Math.PI / 2 } }; // Get cubies in a layer function getCubiesInLayer(axis, layer) { return cubies.filter(cubie => { const pos = cubie.position; return Math.round(pos[axis]) === layer * (size + gap); }); } // Perform a move function performMove(moveName) { const move = moves[moveName]; if (!move) return; const layerCubies = getCubiesInLayer(move.axis, move.layer); const pivot = new THREE.Group(); // Add cubies to pivot layerCubies.forEach(cubie => { cubeGroup.remove(cubie); pivot.add(cubie); }); cubeGroup.add(pivot); // Animate rotation const targetRotation = move.angle; let currentRotation = 0; const duration = 300; // ms const startTime = Date.now(); function animateMove() { const elapsed = Date.now() - startTime; const progress = Math.min(elapsed / duration, 1); const easedProgress = 1 - Math.pow(1 - progress, 3); // easeOutCubic const rotation = targetRotation * easedProgress; const delta = rotation - currentRotation; if (move.axis === 'x') pivot.rotation.x += delta; else if (move.axis === 'y') pivot.rotation.y += delta; else if (move.axis === 'z') pivot.rotation.z += delta; currentRotation = rotation; if (progress < 1) { requestAnimationFrame(animateMove); } else { // Snap to exact rotation if (move.axis === 'x') pivot.rotation.x = targetRotation; else if (move.axis === 'y') pivot.rotation.y = targetRotation; else if (move.axis === 'z') pivot.rotation.z = targetRotation; // Remove pivot and add cubies back pivot.updateMatrixWorld(); layerCubies.forEach(cubie => { const worldPos = new THREE.Vector3(); cubie.getWorldPosition(worldPos); const worldQuat = new THREE.Quaternion(); cubie.getWorldQuaternion(worldQuat); pivot.remove(cubie); cubeGroup.add(cubie); cubie.position.copy(worldPos); cubie.quaternion.copy(worldQuat); // Round positions to avoid floating point errors 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; }); cubeGroup.remove(pivot); // Process next move moveCount++; document.getElementById('moveCounter').textContent = moveCount + ' moves'; if (moveQueue.length > 0) { const nextMove = moveQueue.shift(); setTimeout(() => performMove(nextMove), 50); } else { isAnimating = false; } } } animateMove(); } // Queue a move function queueMove(moveName) { moveQueue.push(moveName); if (!isAnimating) { isAnimating = true; const nextMove = moveQueue.shift(); setTimeout(() => performMove(nextMove), 50); } } // Scramble function function scrambleCube() { if (isAnimating) return; // Clear any pending moves moveQueue = []; scrambleMoves = []; const moveNames = Object.keys(moves); const numMoves = Math.floor(Math.random() * 6) + 15; // 15-20 moves let lastMove = ''; for (let i = 0; i < numMoves; i++) { let move; do { move = moveNames[Math.floor(Math.random() * moveNames.length)]; } while (move.replace("'", "") === lastMove.replace("'", "")); lastMove = move; scrambleMoves.push(move); queueMove(move); } } // Solve function function solveCube() { if (isAnimating) return; // Clear any pending moves moveQueue = []; // Reverse the scramble moves const reverseMoves = scrambleMoves.slice().reverse().map(move => { return move.includes("'") ? move.replace("'", "") : move + "'"; }); scrambleMoves = []; reverseMoves.forEach(move => queueMove(move)); } // Keyboard shortcuts document.addEventListener('keydown', (e) => { if (e.key.toLowerCase() === 'r') { scrambleCube(); } else 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 scramble for visual interest setTimeout(() => { scrambleCube(); }, 500); </script> </body> </html>

ログインして完全なプロンプトを表示

次で続行:

ログインすると、次に同意したことになります: 利用規約 と プライバシーポリシー

使い方

このプロンプトは coding 向けに設計されています。上の内容をコピーして、お好みの AI ツールに貼り付けてください。

最良の結果を得るには、プレースホルダー(角括弧や大文字で示された部分)を具体的な要件に置き換えてください。

参考資料

カテゴリ:coding| twitter| 3d-cube| three-js

ノート