threejs路径
路徑
引用百度百科的解釋:
路徑通常指存在于多種計(jì)算機(jī)圖形設(shè)計(jì)軟件中的以貝塞爾曲線為理論基礎(chǔ)的區(qū)域繪制方式。路徑在Canvas、SVG上都有相關(guān)定義,一般用來(lái)創(chuàng)建形狀。在threejs中,也可以用來(lái)創(chuàng)建形狀,除此之外,還可以用作物體運(yùn)動(dòng)的軌跡。下面就說(shuō)說(shuō)這兩種用法。
在threejs中,Path類代表路徑,Path繼承自CurvePath(曲線路徑),CurvePath繼承自Curve(曲線)。CurvePath和Curve都是抽象類,在threejs文檔中指出,CurvePath用來(lái)連接多條曲線(也就是Curve),其實(shí)質(zhì)上就是一個(gè)Curve數(shù)組。其實(shí),直接用Path類就可以了,對(duì)于CurvePath和Curve,無(wú)需關(guān)心。
另外還有一個(gè)ShapePath類,這個(gè)類可以將形狀轉(zhuǎn)成一系列路徑來(lái)表示,比如將svg繪制的圖形轉(zhuǎn)成threejs的路徑。
使用路徑創(chuàng)建形狀
關(guān)于使用路徑創(chuàng)建形狀,可以參考【創(chuàng)建平面幾何形狀一文】,其中的Shape類,就是Path類的子類,這里不多說(shuō)。
使用路徑作為物體運(yùn)動(dòng)軌跡
如果我們想要物體沿著某一條曲線運(yùn)動(dòng),有兩種辦法:
1、算出曲線的公式,動(dòng)態(tài)的計(jì)算出物體當(dāng)前時(shí)刻的位置
2、創(chuàng)建一條代表該曲線的路徑,然后動(dòng)態(tài)的在該曲線上取點(diǎn),將其位置賦給物體
一般,路徑類會(huì)提供多種創(chuàng)建路徑的方法,所以,第2種方式通常比較好用。
下面就使用threejs提供的Path類創(chuàng)建一條移動(dòng)軌跡,然后把相機(jī)在這條軌跡上移動(dòng)。開始的開始,先創(chuàng)建一條路徑,如下:
path = new THREE.Path();path.bezierCurveTo(10,100,20,-30,30,19);path.bezierCurveTo(40,-5,50,150,60,-39);path.closePath();接著在render循環(huán)中動(dòng)態(tài)的從路徑中取點(diǎn),設(shè)置成相機(jī)的位置:
var progress = 0; function render(){requestAnimationFrame(render);progress += 0.003;let point = path.getPointAt(progress);if(point){camera.position.set(point.x,point.y,300);}else{progress = 0;}renderer.render(scene,camera); }上面的progress是比例,范圍從0~1.完整示例請(qǐng)看【完整示例】
將svg形狀轉(zhuǎn)成路徑
svg是一種矢量圖形格式,同時(shí),javascript也有創(chuàng)建和修改這種圖形格式的接口。各種表示矢量圖形的技術(shù),如Canvas、SVG,本質(zhì)上是相同或相通的,只不過(guò)是實(shí)現(xiàn)和接口不一樣,所以,是有轉(zhuǎn)化的可能的。
在svg中,下面的代碼創(chuàng)建了一條從(0,0)到(100,100)的直線路徑:
<path d="M0 0 L 100 100"/>而在threejs中,使用ShapePath創(chuàng)建一條直線路徑使用:
let path = new ShapePath(); path.moveTo(0,0); path.lineTo(100,100);可見(jiàn),兩者的形式是相近的,從形式上來(lái)看,簡(jiǎn)單的轉(zhuǎn)換難度也不會(huì)很大。下面是一個(gè)轉(zhuǎn)換的例子:
function createShapes(){let dataString = getSvgData(); //獲取svg數(shù)據(jù)let shape = transformToShapePath(dataString); //轉(zhuǎn)換成ShapePath表示let geometry = new THREE.ShapeGeometry(shape);let material = new THREE.LineBasicMaterial({color:0xff0000});let mesh = new THREE.Line(geometry,material);scene.add(mesh);camera.lookAt(mesh.position); }//獲取svg數(shù)據(jù),數(shù)據(jù)來(lái)自w3cschool function getSvgData(){let svgData = "M153 334 C153 334 151 334 151 334 C151 339 153 344 156 344 C164 344 171 339 171 334 C171 322 164 314 156 314 C142 314 131 322 131 334 C131 350 142 364 156 364 C175 364 191 350 191 334 C191 311 175 294 156 294 C131 294 111 311 111 334 C111 361 131 384 156 384 C186 384 211 361 211 334 C211 300 186 274 156 274";return svgData; }//轉(zhuǎn)換成ShapePath表示 function transformToShapePath(dataString){let path = new THREE.ShapePath();let dataArr = dataString.split(" ");var currIndex = 0;while(currIndex<dataArr.length){let command = dataArr[currIndex][0];switch(command){case 'M' : {let inc = moveParse(currIndex,dataArr,path);currIndex += inc;break;}case 'C' : {let inc = curveParse(currIndex,dataArr,path);currIndex += inc;break;}default:{//出錯(cuò)處理currIndex++;}}}return path.toShapes()[0]; }/**************下面是各種命令的轉(zhuǎn)換器****************///moveTo命令轉(zhuǎn)換器function moveParse(currIndex,dataArr,path){let paramsLength = 2; //需要的參數(shù)個(gè)數(shù)let data = [dataArr[currIndex].substring(1),dataArr[currIndex+1]];toThreejsCoor(data);path.moveTo(data[0],data[1]);return paramsLength;}//Curve命令轉(zhuǎn)換器function curveParse(currIndex,dataArr,path){let paramsLength = 6; //需要的參數(shù)個(gè)數(shù)let data = [ dataArr[currIndex].substring(1),dataArr[currIndex+1],dataArr[currIndex+2],dataArr[currIndex+3],dataArr[currIndex+4],dataArr[currIndex+5]];toThreejsCoor(data);path.bezierCurveTo(data[0],data[1],data[2],data[3],data[4],data[5]);return paramsLength;}//屏幕坐標(biāo)轉(zhuǎn)threejs坐標(biāo)function toThreejsCoor(data){for(let i = 0 ; i < data.length; i += 2){data[i] = data[i] - window.innerWidth/2;data[i+1] = window.innerHeight/2 - data[i+1];}}上面的代碼做了下面這幾件事:
- 從svg中提取圖形的定義數(shù)據(jù),比如<path>標(biāo)簽的d屬性
- 將所提取數(shù)據(jù)中的坐標(biāo)轉(zhuǎn)換成threejs坐標(biāo)
- 分析所提取的數(shù)據(jù)里的操作,用ShapePath執(zhí)行這些操作
- 調(diào)用ShapePath類的toShapes()方法,獲得一個(gè)Path對(duì)象數(shù)組
- 用這個(gè)Path數(shù)組中的對(duì)象,創(chuàng)建threejs圖形。
這也是將svg轉(zhuǎn)成Path的幾個(gè)基本步奏。經(jīng)過(guò)轉(zhuǎn)換之后,屏幕上會(huì)顯示出如下圖形:
完整效果,請(qǐng)戳【完整示例】
總結(jié)
- 上一篇: 微信小程序获取tabbar的高度_微信小
- 下一篇: 计算机管理员无法创建密码,找到电脑管理员