首頁 > web前端 > js教程 > 主體

純js實作3d相簿(附源碼)

angryTom
發布: 2019-11-30 14:18:11
轉載
3445 人瀏覽過

純js實作3d相簿(附源碼)

純JavaScript實作旋轉木馬/3d相簿特效(滑鼠拖曳旋轉)

先來看看效果圖

純js實作3d相簿(附源碼)

說一下實現的想法

#旋轉木馬是透過依靠擁有景深(perspective)屬性的盒子(此處盒子id起為:perspective)產生向網頁內部的延伸感,並讓裝有圖片沿z軸平移後(translateZ(Xpx))的盒子(此處起名為wrap)在擁有景深屬性的盒子( perspective)內憑藉transform屬性產生的3d效果沿著盒子(wrap)y軸旋轉轉動來實現的。

【相關課程推薦:##JavaScript視訊教學#】  

3d實現過程

首先要知道在js中transform中的xyz軸的意義

純js實作3d相簿(附源碼)

#先設定一個div,為其加上perspective的屬性(撐開空間),方便後邊觀察效果


/* 场景景深 */
#perspective{
perspective: 700px;/*此属性是实现旋转木马的要点,能产生空间上的距离/延伸感。
在此盒子中放置图片的盒子便可以实现向网页内部延伸的感觉*/
}
登入後複製

2. 其次,設置裝有圖片盒子的容器wrap,使其居中顯示,並加上position:relative的屬性,讓其內的圖片定位。加上transform屬性,之後會用到。

#wrap{
position: relative;
width: 200px;
height: 200px;
margin: 150px  auto;
border:  1px solid black;
transform-style: preserve-3d;  /*实现3d效果的关键步骤,与boxshadow配合使用可以忽略层级问题,之后会说到*/
transform: rotateX(0deg) rotateY(0deg) ;//为盒子的3d效果和旋转效果做准备。
}
登入後複製

加入圖片,設定樣式,使用position:absolute;使其重疊。以數組的形式獲取,並根據其數組長度length來計算圖片的旋轉角度。

#wrap img{
position: absolute;
width: 200px;
}
<script>
var oImg = document.getElementsByTagName(&#39;img&#39;);
var Deg = 360/oImg.length; 
oWrap = document.getElementById(&#39;wrap&#39;);  /*顺便拿一下容器*/
</script>
登入後複製

遍歷數組,使其沿y軸旋轉Deg度。此處使用了原型,使用foreach方法遍歷了數組,讓其內每個圖片都執行了function(el,index)。使用index下標區分開了數組內每個圖片需要旋轉的不同度數(第一張0°(Deg * 0) 第二張Deg度(Deg * 1) 第三張(Deg * 2)度…)

/*oImg表示数组对象,function(el,index)表示数组内每个对象要执行的函数,index为其下标。*/
Array.prototype.forEach.call(oImg,function(el,index){
el.style.transform = "rotateY("+Deg*index+"deg)";
})
登入後複製

Array.prototype 屬性表示Array 建構函數的原型,並允許我們為所有Array物件新增新的屬性和方法。

forEach() 方法對陣列的每個元素執行一次提供的函數。

此處值得注意的是,xxx.xx.transform = “rotateY(” Deg*index “deg)”;

需要加上deg單位,括號要被雙引號包著,也就是說,出來後的結果是transform :rotateY(度數deg);度數表示數字,要避免被轉為字串。

做完上一步操作後,讓盒子其內圖片沿著Z軸平移translateZ(350px)屬性便能初步看到3d效果,但此時會發現容器內圖片數組出現了層級問題(Zindex )導致了理應在後面的圖片能被顯示出來。

這裡有一種方法能忽略掉這個影響,避開層級問題:

/*加上沿z扩散*/
<script>
Array.prototype.forEach.call(oImg,function(el,index){
el.style.transform = "rotateY("+Deg*index+"deg)translateZ(350px)"; //沿z轴扩散350px
})
</script>
-------执行完毕后--------加上属性观察效果---------
#wrap{
width: 200px;
height: 200px;
position: relative;
margin:150px auto;
transform-style: preserve-3d;  /*实现3d效果的关键步骤,与boxshadow配合使用可以忽略层级问题*/
}
#wrap img{
position: absolute;
width: 200px;
box-shadow: 0px 0px 1px #000000;  /* 用box-shadow配合transform-style: preserve-3d;可以忽略层级问题 */
}
登入後複製

這時候為裝有圖片的盒子加上transform:rotateX(-15deg);便能看到較完整的3d效果了,此時實現盒子繞y軸轉動便可實現旋轉木馬的效果。

實現運動過程

單純讓盒子轉動就可以實現旋轉木馬,可以使用setinterval來不斷使其旋轉。

如果想使用滑鼠拖曳實現旋轉木馬,則需要再加一些程式碼,使裝有盒子的容器(wrap)能夠根據滑鼠座標變化繞容器(wrap)自身y軸轉動。

var nowX ,nowY,//当前鼠标坐标
lastX ,lastY ,//上一次鼠标坐标
minusX,minusY ,//距离差
roX = -10,roY = 0;//总旋转度数
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;//获得移动时的当前坐标
minusX = nowX - lastX;//坐标差
minusY = nowY - lastY;//坐标差
//累计差值,如果不累计的话转轮在每次点击-->移动后都会从第一张开始。
roY += minusX;
roX -= minusY;//累计差值
//转动容器的x轴和y轴,使其转动度数(数值,不带单位)等于鼠标坐标差。
oWrap.style.transform = "rotateX("+roX+"deg)"
+"rotateY("+roY+"deg)";
lastX = nowX;lastY = nowY;//移动末期现坐标变为旧坐标
}
this.onmouseup = function(){
this.onmousemove = null;//取消鼠标移动的影响
// 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;
}
/* 场景景深 */
#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) ;/*景深可以简写在此属性里*/
}
#wrap img{
position: absolute;
width: 200px;
transform: rotateX(0deg) rotateY(0deg);
box-shadow: 0px 0px 1px #000000;
/* 用box-shadow可以忽略层级问题 */
}
</style>
</head>
<body>
<div id="perspective">
<div id="wrap">
<img  src="img3/preview1.jpg"  alt="純js實作3d相簿(附源碼)" >
<img  src="img3/preview2.jpg"  alt="純js實作3d相簿(附源碼)" >
<img  src="img3/preview3.jpg"  alt="純js實作3d相簿(附源碼)" >
<img  src="img3/preview4.jpg"  alt="純js實作3d相簿(附源碼)" >
<img  src="img3/preview5.jpg"  alt="純js實作3d相簿(附源碼)" >
<img  src="img3/preview6.jpg"  alt="純js實作3d相簿(附源碼)" >
<img  src="img3/preview7.jpg"  alt="純js實作3d相簿(附源碼)" >
<img  src="img3/preview8.jpg"  alt="純js實作3d相簿(附源碼)" >
<img  src="img3/preview9.jpg"  alt="純js實作3d相簿(附源碼)" >
<img  src="img3/preview10.jpg"  alt="純js實作3d相簿(附源碼)" >
<img  src="img3/preview11.jpg"  alt="純js實作3d相簿(附源碼)" >
</div>
</div>
<script type="text/javascript">
window.onload=function(){
var oImg = document.getElementsByTagName(&#39;img&#39;),
oWrap = document.getElementById(&#39;wrap&#39;);
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,//当前鼠标坐标
lastX ,lastY ,//上一次鼠标坐标
minusX,minusY ,//距离差
roX = -10,roY = 0;//总旋转度数
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;//获得当前坐标
minusX = nowX - lastX;minusY = nowY - lastY;//坐标差
roY += minusX;//累计差值
roX -= minusY;//累计差值
oWrap.style.transform = "rotateX("+roX+"deg)"
+"rotateY("+roY+"deg)";
lastX = nowX;lastY = nowY;//移动末期现坐标变为旧坐标
}
this.onmouseup = function(){
this.onmousemove = null;//取消鼠标移动的影响
// this.onmousedown = null;
}
}
}
</script>
</body>
</html>
登入後複製

本文來自

js教學 欄目,歡迎學習!  

以上是純js實作3d相簿(附源碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:csdn.net
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板