您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)純js怎樣實(shí)現(xiàn)3d相冊(cè),小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。
純JavaScript實(shí)現(xiàn) 旋轉(zhuǎn)木馬/3d相冊(cè)特效(鼠標(biāo)拖拽旋轉(zhuǎn))
先來(lái)看看效果圖
說(shuō)一下實(shí)現(xiàn)的思路
旋轉(zhuǎn)木馬是通過(guò)依靠擁有景深(perspective)屬性的盒子(此處盒子id起為:perspective)產(chǎn)生向網(wǎng)頁(yè)內(nèi)部的延伸感,并讓裝有圖片沿z軸平移后(translateZ(Xpx))的盒子(此處起名為wrap)在擁有景深屬性的盒子(perspective)內(nèi)憑借transform屬性產(chǎn)生的3d效果沿盒子(wrap)y軸旋轉(zhuǎn)轉(zhuǎn)動(dòng)來(lái)實(shí)現(xiàn)的。
3d實(shí)現(xiàn)過(guò)程
首先要知道在js中transform中的xyz軸的含義
首先設(shè)置一個(gè)div,為其加上perspective的屬性(撐開(kāi)空間),方便后邊觀察效果
/* 場(chǎng)景景深 */ #perspective{perspective: 700px; /*此屬性是實(shí)現(xiàn)旋轉(zhuǎn)木馬的要點(diǎn),能產(chǎn)生空間上的距離/延伸感。在此盒子中放置圖片的盒子便可以實(shí)現(xiàn)向網(wǎng)頁(yè)內(nèi)部延伸的感覺(jué)*/}
2. 其次,設(shè)置裝有圖片盒子的容器wrap,使其居中顯示,并加上position:relative的屬性,讓其內(nèi)的圖片定位。加上transform屬性,在之后會(huì)用到。
#wrap{position: relative;width: 200px;height: 200px;margin: 150px auto;border: 1px solid black;transform-style: preserve-3d; /*實(shí)現(xiàn)3d效果的關(guān)鍵步驟,與boxshadow配合使用可以忽略層級(jí)問(wèn)題,之后會(huì)說(shuō)到*/transform: rotateX(0deg) rotateY(0deg) ;//為盒子的3d效果和旋轉(zhuǎn)效果做準(zhǔn)備。}
加入圖片,設(shè)置樣式,使用position:absolute;使其重疊。以數(shù)組的形式獲取,并根據(jù)其數(shù)組長(zhǎng)度length來(lái)計(jì)算圖片的旋轉(zhuǎn)角度。
#wrap img{position: absolute;width: 200px;}<script>var oImg = document.getElementsByTagName('img');var Deg = 360/oImg.length; oWrap = document.getElementById('wrap'); /*順便拿一下容器*/</script>
遍歷數(shù)組,使其沿y軸旋轉(zhuǎn)Deg度。此處使用了原型,使用foreach方法遍歷了數(shù)組,讓其內(nèi)每個(gè)圖片都執(zhí)行了function(el,index)。使用index下標(biāo)區(qū)分開(kāi)了數(shù)組內(nèi)每個(gè)圖片需要旋轉(zhuǎn)的不同度數(shù)(第一張0°(Deg * 0) 第二張Deg度 (Deg * 1) 第三張(Deg * 2)度…)
/*oImg表示數(shù)組對(duì)象, function(el,index)表示數(shù)組內(nèi)每個(gè)對(duì)象要執(zhí)行的函數(shù), index為其下標(biāo)。 */Array.prototype.forEach.call(oImg,function(el,index){ el.style.transform = "rotateY("+Deg*index+"deg)"; })
Array.prototype 屬性表示 Array 構(gòu)造函數(shù)的原型,并允許我們向所有Array對(duì)象添加新的屬性和方法。
forEach() 方法對(duì)數(shù)組的每個(gè)元素執(zhí)行一次提供的函數(shù)。
此處值得注意的是,xxx.xx.transform = “rotateY(”+Deg*index+“deg)”;
需要加上deg單位,括號(hào)要被雙引號(hào)包著,也就是說(shuō),出來(lái)后的結(jié)果是transform :rotateY(度數(shù)deg);度數(shù)表示數(shù)字,要避免被轉(zhuǎn)為字符串。
做完上一步操作后,讓盒子其內(nèi)圖片沿Z軸平移translateZ(350px)屬性便能初步看到3d效果,但此時(shí)會(huì)發(fā)現(xiàn)容器內(nèi)圖片數(shù)組出現(xiàn)了層級(jí)問(wèn)題(Zindex)導(dǎo)致了理應(yīng)在后面的圖片能被顯示出來(lái)。
這里有一種方法能忽略掉這個(gè)影響,避開(kāi)層級(jí)問(wèn)題:
/*加上沿z擴(kuò)散*/<script>Array.prototype.forEach.call(oImg,function(el,index){el.style.transform = "rotateY("+Deg*index+"deg)translateZ(350px)"; //沿z軸擴(kuò)散350px})</script>-------執(zhí)行完畢后--------加上屬性觀察效果---------#wrap{width: 200px;height: 200px;position: relative;margin:150px auto;transform-style: preserve-3d; /*實(shí)現(xiàn)3d效果的關(guān)鍵步驟,與boxshadow配合使用可以忽略層級(jí)問(wèn)題*/}#wrap img{position: absolute;width: 200px;box-shadow: 0px 0px 1px #000000; /* 用box-shadow配合transform-style: preserve-3d;可以忽略層級(jí)問(wèn)題 */}
這時(shí)候?yàn)檠b有圖片的盒子加上transform:rotateX(-15deg);便能看到較為完整的3d效果了,此時(shí)實(shí)現(xiàn)盒子繞y軸轉(zhuǎn)動(dòng)便可實(shí)現(xiàn)旋轉(zhuǎn)木馬的效果。
實(shí)現(xiàn)運(yùn)動(dòng)過(guò)程
單純使盒子轉(zhuǎn)動(dòng)就可以實(shí)現(xiàn)旋轉(zhuǎn)木馬,可以使用setinterval來(lái)不斷使其旋轉(zhuǎn)。
如果想使用鼠標(biāo)拖動(dòng)實(shí)現(xiàn)旋轉(zhuǎn)木馬,則需要再加一些代碼,使裝有盒子的容器(wrap)能夠根據(jù)鼠標(biāo)坐標(biāo)變化繞容器(wrap)自身y軸轉(zhuǎn)動(dòng)。
var nowX ,nowY,//當(dāng)前鼠標(biāo)坐標(biāo)lastX ,lastY ,//上一次鼠標(biāo)坐標(biāo)minusX,minusY ,//距離差roX = -10,roY = 0;//總旋轉(zhuǎn)度數(shù)window.onmousedown = function(ev){var ev = ev;//獲得事件源//鼠標(biāo)移動(dòng)后當(dāng)前坐標(biāo)會(huì)變?yōu)榕f坐標(biāo),此處先保存,在算鼠標(biāo)位移距離差的時(shí)候會(huì)用到。lastX = ev.clientX;lastY = ev.clientY;this.onmousemove = function(ev){var ev = ev;//獲得事件源nowX = ev.clientX;nowY = ev.clientY;//獲得移動(dòng)時(shí)的當(dāng)前坐標(biāo)minusX = nowX - lastX;//坐標(biāo)差minusY = nowY - lastY;//坐標(biāo)差//累計(jì)差值,如果不累計(jì)的話轉(zhuǎn)輪在每次點(diǎn)擊-->移動(dòng)后都會(huì)從第一張開(kāi)始。roY += minusX;roX -= minusY;//累計(jì)差值//轉(zhuǎn)動(dòng)容器的x軸和y軸,使其轉(zhuǎn)動(dòng)度數(shù)(數(shù)值,不帶單位)等于鼠標(biāo)坐標(biāo)差。oWrap.style.transform = "rotateX("+roX+"deg)"+"rotateY("+roY+"deg)";lastX = nowX;lastY = nowY;//移動(dòng)末期現(xiàn)坐標(biāo)變?yōu)榕f坐標(biāo)}this.onmouseup = function(){this.onmousemove = null;//取消鼠標(biāo)移動(dòng)的影響// this.onmousedown = null;}}}
完整代碼
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css">*{margin: 0; padding: 0;} body{overflow: hidden;background: #000000;} /* 場(chǎng)景景深 */#perspective{perspective: 700px; }#wrap{position: relative;width: 200px; height: 200px;margin: 150px auto; border: 1px solid black;transform-style: preserve-3d;transform: rotateX(-15deg) rotateY(0deg) ; /*景深可以簡(jiǎn)寫(xiě)在此屬性里*/}#wrap img{position: absolute; width: 200px; transform: rotateX(0deg) rotateY(0deg); box-shadow: 0px 0px 1px #000000; /* 用box-shadow可以忽略層級(jí)問(wèn)題 */} </style> </head> <body> <div id="perspective"> <div id="wrap"> <img src="img3/preview1.jpg" > <img src="img3/preview2.jpg" > <img src="img3/preview3.jpg" > <img src="img3/preview4.jpg" > <img src="img3/preview5.jpg" > <img src="img3/preview6.jpg" > <img src="img3/preview7.jpg" > <img src="img3/preview8.jpg" > <img src="img3/preview9.jpg" > <img src="img3/preview10.jpg" > <img src="img3/preview11.jpg" > </div> </div> <script type="text/javascript"> window.onload=function(){ var oImg = document.getElementsByTagName('img'),oWrap = document.getElementById('wrap'); var Deg = 360/(oImg.length);Array.prototype.forEach.call(oImg,function(el,index){el.style.transform = "rotateY("+Deg*index+"deg)translateZ(350px)"; // el.style.zIndex = -index;el.style.transition = "transform 1s "+ index*0.1 +"s";}); var nowX ,nowY,//當(dāng)前鼠標(biāo)坐標(biāo) lastX ,lastY ,//上一次鼠標(biāo)坐標(biāo) minusX,minusY ,//距離差 roX = -10,roY = 0;//總旋轉(zhuǎn)度數(shù) window.onmousedown = function(ev){var ev = ev;//獲得事件源 lastX = ev.clientX;lastY = ev.clientY;this.onmousemove = function(ev){var ev = ev;//獲得事件源 nowX = ev.clientX;nowY = ev.clientY;//獲得當(dāng)前坐標(biāo) minusX = nowX - lastX;minusY = nowY - lastY;//坐標(biāo)差 roY += minusX;//累計(jì)差值 roX -= minusY;//累計(jì)差值 oWrap.style.transform = "rotateX("+roX+"deg)"+"rotateY("+roY+"deg)";lastX = nowX;lastY = nowY;//移動(dòng)末期現(xiàn)坐標(biāo)變?yōu)榕f坐標(biāo)} this.onmouseup = function(){this.onmousemove = null;//取消鼠標(biāo)移動(dòng)的影響 // this.onmousedown = null; }}}</script> </body> </html>
以上就是純js怎樣實(shí)現(xiàn)3d相冊(cè),小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。