溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

純js怎樣實(shí)現(xiàn)3d相冊(cè)

發(fā)布時(shí)間:2021-12-14 13:46:40 來(lái)源:億速云 閱讀:153 作者:柒染 欄目:開(kāi)發(fā)技術(shù)

本篇文章給大家分享的是有關(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è)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

js
AI