three.js 制作魔方

定义的变量
复制代码
posArr = [
[100,100,100],[100,100,0],[100,100,-100],[100,0,100],[100,0,0],[100,0,-100],[100,-100,100],[100,-100,0],[100,-100,-100],
[0,100,100],[0,100,0],[0,100,-100],[0,0,100],[0,0,0],[0,0,-100],[0,-100,100],[0,-100,0],[0,-100,-100],
[-100,100,100],[-100,100,0],[-100,100,-100],[-100,0,100],[-100,0,0],[-100,0,-100],[-100,-100,100],[-100,-100,0],[-100,-100,-100]
],//方块位置坐标
materials,//材质数组
mouse = new THREE.Vector2(),//通过鼠标点击的位置计算出raycaster所需要的点的位置,以屏幕中心为原点,值的范围为-1到1.
raycaster,//射线对象
group,//存放魔方方块的数组
groupTemp,//魔方转动时临时数组
object3d,//魔方被选择面的标志物对象
currentPos,//魔方被点击小块的位置
currentNor,//魔方被点击小块面的法向量
currentUp,//魔方被点击时,相机up的向量
复制代码
2. 定义材质数组
复制代码
initMaterial() {
var map_red = new THREE.TextureLoader().load(’/static/images/color/m_red.jpg’, () => this.loadover --);
var map_orange = new THREE.TextureLoader().load(’/static/images/color/m_orange.jpg’, () => this.loadover --);
var map_yellow = new THREE.TextureLoader().load(’/static/images/color/m_yellow.jpg’, () => this.loadover --);
var map_blue = new THREE.TextureLoader().load(’/static/images/color/m_blue.jpg’, () => this.loadover --);
var map_green = new THREE.TextureLoader().load(’/static/images/color/m_green.jpg’, () => this.loadover --);
var map_white = new THREE.TextureLoader().load(’/static/images/color/m_white.jpg’, () => this.loadover --);
var map_sprite = new THREE.TextureLoader().load(’/static/images/base/direction.png’, () => this.loadover --);

let mater_red = new THREE.MeshBasicMaterial({map: map_red, side: THREE.DoubleSide});
let mater_orange = new THREE.MeshBasicMaterial({map: map_orange, side: THREE.DoubleSide});
let mater_yellow = new THREE.MeshBasicMaterial({map: map_yellow, side: THREE.DoubleSide});
let mater_white = new THREE.MeshBasicMaterial({map: map_white, side: THREE.DoubleSide});
let mater_blue = new THREE.MeshBasicMaterial({map: map_blue, side: THREE.DoubleSide});
let mater_green = new THREE.MeshBasicMaterial({map: map_green, side: THREE.DoubleSide});

materials = [mater_red, mater_orange, mater_yellow,mater_white, mater_blue, mater_green];

}
复制代码
3. 绘制小方块并绘制标志物(先隐藏)
复制代码
initsquare() {
var sphereGeom = new THREE.SphereGeometry(10, 30, 20);
var sphereMate = new THREE.MeshPhongMaterial({color: 0x333333});
object3d = new THREE.Mesh(sphereGeom, sphereMate);
object3d.name = ‘object3d’;
object3d.visible = false;
scene.add(object3d);

group = new THREE.Group();
group.name = 'group';

var geometry = new THREE.BoxGeometry(100, 100, 100);
var mesh = new THREE.Mesh(geometry, materials);
posArr.forEach((d,i) => {
    let meshCopy = mesh.clone();
    meshCopy.position.set(d[0], d[1], d[2])
    meshCopy.name = 'box-' + i;
    group.add(meshCopy);
})

scene.add(group);

this.render();
document.getElementById("loading").style.display = "none";

}
复制代码
4. 监听模型的点击事件
复制代码
initEventListener() {
raycaster = new THREE.Raycaster();
document.addEventListener(‘mousemove’, function (event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
}, false)
document.addEventListener(‘mousedown’, () => {
if (scene.children && scene.getObjectByName(‘group’)) {
raycaster.setFromCamera(mouse, camera);
let intersects = raycaster.intersectObjects(scene.getObjectByName(‘group’).children);
if (intersects[0] && intersects[0].object.name != ‘object3d’) {
let index = intersects[0].faceIndex;
let point = intersects[0].point;
currentUp = this.computedUp(camera);
currentNor = this.computedNor(point)
currentPos = intersects[0].object.position;
let pos = this.computedPos(point);
object3d.position.copy(pos);
object3d.visible = true;
}
}
})
}
复制代码
5. 监听方向软键盘的点击,根据点击键的不同,生成旋转轴
复制代码
handleRotate(num) {
if(!rotateFlag || !currentPos) return ;
rotateFlag = false;
groupTemp = new THREE.Group();
groupTemp.name = ‘group-temp’;
let axis;
let tempMeshArr = [];
switch (num) {
case 1:
axis = currentNor.clone().cross(currentUp);
break;
case 2:
axis = currentNor.clone().cross(currentUp).negate();
break;
case 3:
axis = currentUp.clone().negate();
break;
case 4:
axis = currentUp;
break;
}
let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(axis, currentPos);
scene.getObjectByName(‘group’).children.forEach(d => Math.abs(plane.distanceToPoint(d.position)) < 1 && tempMeshArr.push(d))
tempMeshArr.forEach(d => {
group.remove(d);
groupTemp.add(d);
})
// object3d.visible = false;
scene.remove(scene.getObjectByName(‘group-temp’));
scene.add(groupTemp);
this.handleTween(axis);
}
复制代码
6. 加一点tween的补间动画,效果更好哦
复制代码
handleTween(axis) {
let start = {angle: 0, axis};
let end = {angle: Math.PI/2, axis};
tween = new TWEEN.Tween(start).to(end, 500);
tween.easing(TWEEN.Easing.Linear.None);
tween.onUpdate(function () {
let quaternion = new THREE.Quaternion().setFromAxisAngle(axis, this._object.angle);
groupTemp.rotation.setFromQuaternion(quaternion);
});
tween.onComplete(() => {
let matrix = this.standerMatrix(groupTemp.matrix);
groupTemp.children.forEach(d => {
let mesh = d.clone();
mesh.applyMatrix4(matrix)
mesh.position.copy(this.standarPos(mesh.position))
group.add(mesh);
})
scene.remove(groupTemp)
rotateFlag = true;
})
tween.start();
}
深圳网站建设www.sz886.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值