搜尋
首頁web前端js教程純js實作3d相簿(附源碼)

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

Nov 30, 2019 pm 02:18 PM
3d相簿js

純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="/static/imghwm/default1.png"  data-src="img3/preview1.jpg"  class="lazy"    alt="純js實作3d相簿(附源碼)" >
<img  src="/static/imghwm/default1.png"  data-src="img3/preview2.jpg"  class="lazy"    alt="純js實作3d相簿(附源碼)" >
<img  src="/static/imghwm/default1.png"  data-src="img3/preview3.jpg"  class="lazy"    alt="純js實作3d相簿(附源碼)" >
<img  src="/static/imghwm/default1.png"  data-src="img3/preview4.jpg"  class="lazy"    alt="純js實作3d相簿(附源碼)" >
<img  src="/static/imghwm/default1.png"  data-src="img3/preview5.jpg"  class="lazy"    alt="純js實作3d相簿(附源碼)" >
<img  src="/static/imghwm/default1.png"  data-src="img3/preview6.jpg"  class="lazy"    alt="純js實作3d相簿(附源碼)" >
<img  src="/static/imghwm/default1.png"  data-src="img3/preview7.jpg"  class="lazy"    alt="純js實作3d相簿(附源碼)" >
<img  src="/static/imghwm/default1.png"  data-src="img3/preview8.jpg"  class="lazy"    alt="純js實作3d相簿(附源碼)" >
<img  src="/static/imghwm/default1.png"  data-src="img3/preview9.jpg"  class="lazy"    alt="純js實作3d相簿(附源碼)" >
<img  src="/static/imghwm/default1.png"  data-src="img3/preview10.jpg"  class="lazy"    alt="純js實作3d相簿(附源碼)" >
<img  src="/static/imghwm/default1.png"  data-src="img3/preview11.jpg"  class="lazy"    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。如有侵權,請聯絡admin@php.cn刪除
JavaScript數據類型:瀏覽器和nodejs之間是否有區別?JavaScript數據類型:瀏覽器和nodejs之間是否有區別?May 14, 2025 am 12:15 AM

JavaScript核心數據類型在瀏覽器和Node.js中一致,但處理方式和額外類型有所不同。 1)全局對像在瀏覽器中為window,在Node.js中為global。 2)Node.js獨有Buffer對象,用於處理二進制數據。 3)性能和時間處理在兩者間也有差異,需根據環境調整代碼。

JavaScript評論:使用//和 / * * / * / * /JavaScript評論:使用//和 / * * / * / * /May 13, 2025 pm 03:49 PM

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)