Three.js的入門(mén)案例(下)

關(guān)注初識(shí)Threejs與小編一起學(xué)習(xí)成長(zhǎng)
在上一篇案例中實(shí)現(xiàn)了幾何體-球體旋轉(zhuǎn)效果,今天繼續(xù)豐富這個(gè)案例效果,在球體的周?chē)砑庸馊靶D(zhuǎn)模塊(圖片+文字組成),均勻的分布在球體周?chē)瑖@著球體逆時(shí)針旋轉(zhuǎn),最終效果如圖:
知識(shí)點(diǎn)
1、基礎(chǔ)線條材料、線條模型;
2、矩形平面模型;
3、射線拾取;
繪制光圈
圍繞著球體繪制光圈。定義好參數(shù)(大小、透明度、顏色等),循環(huán)繪制四個(gè)大小不一,不同透明度的橢圓,調(diào)整好位置,效果如圖:
代碼如下:
_this.drawCircle=function(){//光圈參數(shù)(大小、透明度)var param = [{ size: 7, opacity: '.3' },{ size: 8, opacity: '.5' },{ size: 9.5, opacity: '1' },{ size: 11, opacity: '.2' }];var line;for (var j = 0; j < param.length; j++) {//基礎(chǔ)線條材料var lineMaterial = new THREE.LineBasicMaterial({transparent: true, // 開(kāi)啟透明opacity: param[j].opacity,// 透明度color: 'rgb(129,146,255)'//線段顏色});//橢圓曲線var ellipse = new THREE.EllipseCurve(0,0, //橢圓的中心的x、y坐標(biāo)param[j].size,param[j].size, //橢圓在x,y軸的半徑0,//以弧度來(lái)表示,從正X軸算起曲線開(kāi)始的角度2* Math.PI, //以弧度來(lái)表示,從正X軸算起曲線終止的角度false,//橢圓是否按照順時(shí)針?lè)较騺?lái)繪制0//以弧度表示,橢圓從X軸正方向逆時(shí)針的旋轉(zhuǎn)角度(可選));var ellipsePath = new THREE.CurvePath();//曲線路徑ellipsePath.add(ellipse);var ellipseGeometry = ellipsePath.createPointsGeometry(100);//返回幾何體對(duì)象//線條模型對(duì)象line = new THREE.Line(ellipseGeometry, lineMaterial);scene.add(line);//將光圈添加到場(chǎng)景中line.rotation.x = Math.PI / 2;line.position.y = -1;}}
繪制球體周?chē)K
在球體周?chē)L制可點(diǎn)擊模塊,我們這里使用默認(rèn)圖片與業(yè)務(wù)名稱(chēng)合并生成一張新圖片,然后通過(guò)矩形平面模型、基礎(chǔ)網(wǎng)孔材料設(shè)置紋理貼圖的方式。核心代碼:
_this.drawModel=function(){var that=this;//創(chuàng)建一個(gè)月亮模型分組var moons = window.moons = new THREE.Mesh();/*添加xyz坐標(biāo)軸*/// var axesHelper = new THREE.AxesHelper(30);// moons.add(axesHelper);//矩形平面模型(x軸寬度、y軸高度、x方向的分段數(shù)、y方向的分段數(shù))//要與map貼圖比例成正比,否則圖片會(huì)變形var bufferGeometry = new THREE.PlaneBufferGeometry(4, 2, 2, 2);//基礎(chǔ)網(wǎng)孔材料var basicMaterial = new THREE.MeshBasicMaterial({// map: textureLoader.load(modelBg),//設(shè)置紋理貼圖depthWrite: false,transparent: true,alphaTest: 0,side: 2});var planeMesh = new THREE.Mesh(bufferGeometry, basicMaterial);planeMesh.position.z = 9.5;//球體周?chē)矬w的z軸var moonsBox = new THREE.Mesh();moonsBox.add(planeMesh);//循環(huán)球體周?chē)臄?shù)據(jù)for (var i = 0; i < roundData.length; i++) {//解決異步循環(huán)(function (i) {//生成帶文字的圖片that.cenerateImages(i,function (d) {var newMoonBox = moonsBox.clone();//克隆一個(gè)網(wǎng)格模型newMoonBox.children[0].material = newMoonBox.children[0].material.clone();// console.log(JSON.stringify(roundData[i].imgh));//更新帶文字的圖片,保存模塊數(shù)據(jù)(id、索引等)newMoonBox.children[0].material.map = textureLoader.load(roundData[i].img);newMoonBox.children[0].roundData = roundData[i].id;newMoonBox.children[0].roundData_index = i;//旋轉(zhuǎn)位置,均勻分布球體周?chē)?/span>newMoonBox.rotation.y = Math.PI * 2 / roundData.length * i;//渲染之后直接執(zhí)行newMoonBox.onBeforeRender = function (renderer, scene, camera, geometry, material) {this.children[0].lookAt(this.children[0].getWorldPosition(new THREE.Vector3()).add(camera.position));}moons.add(newMoonBox);});})(i)}scene.add(moons);//將周?chē)D(zhuǎn)模塊添加到場(chǎng)景中}
在周期性渲染場(chǎng)景方法中添加:
moons.rotation.y += Math.PI / 180 / delay * intc;//球體周?chē)K旋轉(zhuǎn)
方可圍繞球體旋轉(zhuǎn)。
觸發(fā)點(diǎn)擊事件
通過(guò)使用Raycaster對(duì)象來(lái)實(shí)現(xiàn)(射線拾取)點(diǎn)擊效果:
代碼如下:
_this.onDocumentClick=function(event) {var raycaster = new THREE.Raycaster();var mouseVector = new THREE.Vector3();event.preventDefault();//防止冒泡mouseVector.x = (event.offsetX / canvasWidth) * 2 - 1;mouseVector.y = -(event.offsetY / canvasHeight) * 2 + 1;raycaster.setFromCamera(mouseVector, camera); // 設(shè)置射線拾取的參數(shù)selectObject = raycaster.intersectObjects(moons.children, true)[0];if (selectObject&&selectObject.object) {//初始化選中的樣式var clickThat = selectObject.object.parent.children;if (clickThat.length > 0) {//清空之前選中樣式for (var i = 0; i < moons.children.length; i++) {var tempobj=moons.children[i].children[0];tempobj.material.map = textureLoader.load(roundData[tempobj.roundData_index].img);}var idcont = selectObject.object.roundData;//當(dāng)前選中的值var idcontIndex = idcont - 1 < 0 ? 0 : idcont - 1;selectObject.object.material.map = textureLoader.load(roundData[idcontIndex].imgh);//更新當(dāng)前選中模塊樣式}else {}}else {}}
可以通過(guò)射線拾取達(dá)到與鼠標(biāo)交互的效果,大家就可以根據(jù)自身的業(yè)務(wù)做出處理,比如彈框等。
寫(xiě)在最后
至此這個(gè)案例就結(jié)束了,在繪制周?chē)K的方案上不是很友好,要每個(gè)模塊生成兩種狀態(tài)的圖片,大家也可以想想有沒(méi)有更好的解決方案,期待與您交流學(xué)習(xí),快去動(dòng)手實(shí)踐吧~
你“在看”我嗎?
