Three.js 可操控3D魔方(键盘转动+打乱+复原)
直接复制整段HTML打开即可运行,WASD/方向键控层旋转,一键打乱、一键复原
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>Three.js 可玩3D魔方</title><style>*{margin:0;padding:0;box-sizing:border-box;}body{overflow:hidden;background:#121218;font-family:sans-serif;}canvas{display:block;}.btn-box{position:fixed;top:20px;left:20px;z-index:999;}button{padding:8px 16px;margin:0 5px;border:none;border-radius:4px;cursor:pointer;background:#2563eb;color:#fff;}</style></head><body><divclass="btn-box"><buttonid="randomBtn">打乱魔方</button><buttonid="resetBtn">一键复原</button></div><scriptsrc="https://cdn.jsdelivr.net/npm/three@0.158.0/build/three.min.js"></script><scriptsrc="https://cdn.jsdelivr.net/npm/three@0.158.0/examples/js/controls/OrbitControls.js"></script><script>// 场景初始化constscene=newTHREE.Scene();scene.background=newTHREE.Color(0x121218);constcamera=newTHREE.PerspectiveCamera(60,innerWidth/innerHeight,0.1,200);camera.position.set(9,9,15);constrenderer=newTHREE.WebGLRenderer({antialias:true});renderer.setSize(innerWidth,innerHeight);document.body.appendChild(renderer.domElement);// 视角控制器constcontrols=newTHREE.OrbitControls(camera,renderer.domElement);controls.enableDamping=true;// 灯光scene.add(newTHREE.AmbientLight(0xffffff,0.5));constdirLight=newTHREE.DirectionalLight(0xffffff,0.7);dirLight.position.set(15,20,10);scene.add(dirLight);// 魔方六色:前、后、左、右、上、下constCOLORS=[0xffffff,// 前白0xffff00,// 后黄0x0000ff,// 左蓝0xff0000,// 右红0x00ff00,// 上绿0xffa500// 下橙];constOFFSET=1.06;letcubies=[];letrubikRoot=newTHREE.Group();// 创建单个魔方小块functioncreateCubie(x,y,z){constgeo=newTHREE.BoxGeometry(1,1,1);constmats=COLORS.map(c=>newTHREE.MeshLambertMaterial({color:c}));constcube=newTHREE.Mesh(geo,mats);cube.userData={ox:x,oy:y,oz:z};cube.position.set(x*OFFSET,y*OFFSET,z*OFFSET);returncube;}// 生成完整3阶魔方functioninitRubik(){cubies=[];rubikRoot.clear();for(letx=-1;x<=1;x++){for(lety=-1;y<=1;y++){for(letz=-1;z<=1;z++){letc=createCubie(x,y,z);cubies.push(c);rubikRoot.add(c);}}}scene.add(rubikRoot);}initRubik();// 旋转指定层functionrotateLayer(axis,idx,dir=1){lettargetGroup=newTHREE.Group();lettargetList=[];cubies.forEach(c=>{letpos=c.position;letval;if(axis==='x')val=Math.round(pos.x/OFFSET);if(axis==='y')val=Math.round(pos.y/OFFSET);if(axis==='z')val=Math.round(pos.z/OFFSET);if(val===idx){targetList.push(c);rubikRoot.remove(c);targetGroup.add(c);}});scene.add(targetGroup);letangle=Math.PI/2*dir;letrotObj={v:0};functionrotateAnimate(){if(rotObj.v>=angle){targetGroup.rotation[axis]=angle;targetList.forEach(item=>{letwp=newTHREE.Vector3();item.getWorldPosition(wp);letq=newTHREE.Quaternion();item.getWorldQuaternion(q);rubikRoot.attach(item);item.position.copy(wp);item.quaternion.copy(q);});scene.remove(targetGroup);return;}rotObj.v+=0.15;targetGroup.rotation[axis]=rotObj.v;requestAnimationFrame(rotateAnimate);}rotateAnimate();}// 键盘控制window.addEventListener('keydown',e=>{switch(e.key.toLowerCase()){case'w':rotateLayer('y',1,1);break;// 上层右转case's':rotateLayer('y',-1,-1);break;// 下层左转case'a':rotateLayer('x',-1,1);break;// 左层顺转case'd':rotateLayer('x',1,-1);break;// 右层逆转case'q':rotateLayer('z',1,1);break;// 前层顺转case'e':rotateLayer('z',-1,-1);break;// 后层逆转}});// 打乱魔方document.getElementById('randomBtn').onclick=()=>{letops=[()=>rotateLayer('y',1,1),()=>rotateLayer('y',-1,-1),()=>rotateLayer('x',1,-1),()=>rotateLayer('x',-1,1),()=>rotateLayer('z',1,1),()=>rotateLayer('z',-1,-1)];lettimes=20;leti=0;functionrandRun(){if(i>=times)return;letfn=ops[Math.floor(Math.random()*ops.length)];fn();i++;setTimeout(randRun,220);}randRun();};// 一键复原document.getElementById('resetBtn').onclick=()=>{initRubik();};// 窗口适配window.onresize=()=>{camera.aspect=innerWidth/innerHeight;camera.updateProjectionMatrix();renderer.setSize(innerWidth,innerHeight);};// 渲染循环functionanimate(){requestAnimationFrame(animate);controls.update();renderer.render(scene,camera);}animate();</script></body></html>操作说明
- 鼠标操作
- 左键拖拽:旋转视角
- 滚轮:缩放远近
- 右键拖拽:平移画面
- 键盘按键控魔方转动
- W:顶层向右旋转
- S:底层向左旋转
- A:左侧面顺时针转
- D:右侧面逆时针转
- Q:前面顺时针转
- E:后面逆时针转
- 按钮功能
- 打乱魔方:自动随机转动20步打乱
- 一键复原:瞬间重置回初始完整状态
后续可加功能
- 加入魔方还原算法自动求解
- 加数字贴纸、边框黑线更逼真
- 手机触屏滑动转层
- 记录转动步数、计时闯关