摘要:注意第二個參數代表關閉透視投影,因為投影下面會自己去實現。透視投影是視錐體上圖沒有把視錐體畫出來,正交投影是立方體。所以可以設置來使用瀏覽器自身的透視投影,省去過程。
如你所見。這篇就是要講下使用transformjs制作星球的過程。你也可以無視文章,直接去看源碼和在線演示:
源碼 | 在線演示
代碼100行多一點,直接看也沒有什么壓力。下面分幾步講解下。
生成球上點坐標設球心為 (a,b,c),半徑為r,
則球的標準方程為 (x-a)2+(y-b)2+(z-c)2=r2
這里假設球心的(0,0,0),則:
標準方程為 x2+y2+z2=r2
因為可以渲染的時候再把球的本地坐標轉為世界坐標進行位移,所以球心(0,0,0)便可以。
function randomPoints() { var x, y, z, j = -1, i = 0; for (; i < size; i++) { x = getRandomNumber(-250, 250); y = getRandomNumber(-250, 250); j *= -1; if (x * x + y * y <= r * r) { z = j * Math.sqrt(Math.abs(r * r - x * x - y * y)); positions.push({x: x, y: y, z: z}); rd_positions.push({x: x, y: y, z: z}); } } }
上面的生成過程很取巧:
1.隨機生成2D內的圓內的坐標x和y。(x x + y y <= r * r就是表示圓內)
2.根據2D維度的坐標推算其屬于球面上的z
其中positions用來存放所有點的local坐標,rd_positions用來以后存放投影后的坐標。
坐標轉Domfunction createImgs() { var i = 0, len = positions.length; for (; i < len; i++) { var img = document.createElement("img"); img.style.position = "absolute"; img.style.left = "0px"; img.style.top = "0px"; img.src = "../asset/star.png"; document.body.appendChild(img); Transform(img,true); transformImg(img,i); img_list.push(img); } }
所有的點都對應創建一個絕對定位的圖片,并且通過Transform(img,true)給img注入transformation能力。注意第二個參數true代表關閉透視投影,因為投影下面會自己去實現。
投影變換function positionsProjection() { var index = 0, len=positions.length; for (; index < len; index++) { var p = positions[index]; var rp = rd_positions[index]; //perspective projection //rp.x = p.x * distance / Math.abs(camera_position.z - p.z); //rp.y = p.y * distance / Math.abs(camera_position.z - p.z); //orthogonal projection rp.x = p.x ; rp.y = p.y ; } }
為了簡單起見,把球心和攝像機(也可以叫眼睛、亦或是視點)的坐標分別設置為:
center = {x: 300, y: 300, z: 0}, camera_position = {x: 300, y: 300, z: 500}, distance = 600,
distance代表攝像機到投影平面的距離,攝像機就固定在球心的正前方不動,這樣進行透視投影或正交投影計算起來無比方便,免去用齊次坐標、4*4矩陣的過程。如下簡單推導便可:
這里需要注意的是,上面是透視投影的圖解,會產生近大遠小的感覺。透視投影是視錐體(上圖沒有把視錐體畫出來),正交投影是立方體。
正交投影如下圖解,x和y坐標投影后不變就可以了:
可以這么理解:
透視投影從一個點看無數個點
正交投影從無數個點看無數個點
旋轉function rotate() { var cx, z, i = 0, len=positions.length; for (; i < len; i++) { cx = positions[i].x; z = positions[i].z; positions[i].x = positions[i].x * Math.cos(step_angle) - positions[i].z * Math.sin(step_angle); positions[i].z = positions[i].z * Math.cos(step_angle) + cx * Math.sin(step_angle); } }
可以看到,上面是繞y軸旋轉,所以y的坐標不變,x和z需要經過下面的matrix變換:
function transformImg(img, i) { var z = positions[i].z; img.translateX = center.x + rd_positions[i].x; img.translateY = center.x + rd_positions[i].y; //projection img.scaleX = img.scaleY = 0.5 * distance / Math.abs(camera_position.z - z); img.style.opacity =0.1+ 1 - (r - z) / (2 * r); } function render(){ var i = 0, len=positions.length; for (; i < len; i++) { transformImg(img_list[i],i); } }初始化和循環
function tick() { rotate(); positionsProjection(); render(); requestAnimationFrame(tick); } (function () { randomPoints(); createImgs(); positionsProjection(); tick(); })();
通過通過上面幾行代碼串整個流程。通過requestAnimationFrame循環執行tick。
最后為了加深理解,你可以把源碼 clone下來,然后改代碼實現:
試試繞著z軸旋轉
試試繞著x軸旋轉
試試切換下透視投影和正交投影
透視投影的時候試著修改攝像機的z坐標
正交投影的時候試著修改攝像機的z坐標
透視投影的時候試著修改到投影面的距離
正交投影的時候試著修改到投影面的距離
不使用星星素材換過其他素材會達到意想不到的酷炫效果
第二種實現方式:試試Transform(img,false)因為Transform第二個參數不傳,或者設置為false的時候是打開透視投影的。
所以可以設置img.translateZ來使用瀏覽器自身的透視投影,省去positionsProjection過程。
創建圖片的時候,使用下面的方式注入Transformation能力,
Transform(img, false);
即打開透視投影,
即近大遠小,
即不用自己去positionsProjection
即不用自己去設置圖片的scaleX和scaleY
渲染的時候直接使用原始坐標便可:
function transformImg(img, i) { var p = positions[i]; img.translateX = p.x; img.translateY = p.y; img.translateZ = p.z; img.style.opacity =0.1+ 1 - (r - p.z) / (2 * r); } function render(){ var i = 0, len=positions.length; for (; i < len; i++) { transformImg(img_list[i],i); } }
循環和初始化,不再需要投影過程:
function tick() { rotate(); render(); requestAnimationFrame(tick); } (function () { randomPoints(); createImgs(); tick(); })();transformjs
transformjs提供了基礎的transformation能力,不與任何時間和運動庫綁定。雖然官網demo簡單,但是稍微費點腦細胞就可以做出很酷炫的效果。所以酷炫靠大家,用transformjs就對了。
傳送門:transformjs 主頁 | transformjs Github
所有例子可以在上面找到。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91236.html
摘要:寫在前面記得以前做過一款游戲。開場動畫是一塊軟體類似豆腐的東西一起搖擺。基本的原理主要是循環運動抽象的的和來實現軟體搖擺。目前來看也能做到,因為也能運動和??梢院腿我鈺r間運動庫配合使用。 寫在前面 記得以前facebook做過一款HTML5游戲。開場動畫是一塊軟體類似豆腐的東西一起搖擺。類似的效果如下面的gif所示:showImg(https://segmentfault.com/im...
摘要:更別提配合一些運動或者時間的庫來編程了。姿勢封裝了一大堆關鍵幀動畫,開發者只需要關心添加或者移除相關的動畫的便可以。 簡介 在過去的兩年,越來越多的同事、朋友和其他不認識的童鞋進行移動web開發的時候,都使用了transformjs,所有必要介紹一下,讓更多的人受益,提高編程效率,并享受編程樂趣。(當然transformjs不僅僅支持移動設備,支持CSS3 3D Transforms的...
閱讀 1015·2021-10-19 11:42
閱讀 2973·2021-09-10 10:51
閱讀 677·2021-09-09 09:33
閱讀 1760·2021-09-01 10:43
閱讀 2768·2019-08-30 12:43
閱讀 3516·2019-08-30 11:24
閱讀 2114·2019-08-30 10:56
閱讀 2777·2019-08-29 11:00