純JavaScript實作旋轉木馬/3d相簿特效(滑鼠拖曳旋轉)
先來看看效果圖
說一下實現的想法
#旋轉木馬是透過依靠擁有景深(perspective)屬性的盒子(此處盒子id起為:perspective)產生向網頁內部的延伸感,並讓裝有圖片沿z軸平移後(translateZ(Xpx))的盒子(此處起名為wrap)在擁有景深屬性的盒子( perspective)內憑藉transform屬性產生的3d效果沿著盒子(wrap)y軸旋轉轉動來實現的。
【相關課程推薦:##JavaScript視訊教學#】
3d實現過程
首先要知道在js中transform中的xyz軸的意義 #先設定一個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('img'); var Deg = 360/oImg.length; oWrap = document.getElementById('wrap'); /*顺便拿一下容器*/ </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('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,//当前鼠标坐标 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中文網其他相關文章!