構建一個交互式的3D旋轉輪播圖,使用CSS 3D轉換和JavaScript增強網頁圖像或內容的動態展示效果。本文將逐步指導您如何創建這個組件。
我最初研究這個主題時,並不需要一個3D輪播圖,而更關注其具體的實現細節。核心技術當然是來自CSS Transforms Module Level 1,但在此過程中,將應用許多其他前端開發技術,涉及CSS、Sass和客戶端JavaScript的各個方面。
這個CodePen展示了不同版本的組件,我將向您展示如何構建它們。
為了說明CSS 3D轉換的設置,我將向您展示組件的純CSS版本。然後,我將向您展示如何使用JavaScript增強它,開發一個簡單的組件腳本。
關鍵要點
- 使用CSS 3D轉換和JavaScript創建一個交互式的3D旋轉輪播圖,從而在網頁上更動態地展示圖像或內容。
- 通過將圖像排列在圓形3D空間中來構建輪播圖,使用基於圖像數量的多邊形近似值,並通過JavaScript增強來控制可見性和導航。
- 通過在CSS中使用媒體查詢和基於百分比的大小調整,實現輪播圖的自適應設計,確保它能夠適應不同的屏幕尺寸和設備方向。
- 通過HTML和JavaScript添加導航控件來增強用戶交互,使用戶能夠手動循環瀏覽輪播圖項目。
- 探索高級自定義選項,例如自動播放功能、過渡效果、無限循環以及添加文本或不同形狀,提供靈活的自定義選項以滿足特定設計需求。
輪播圖的標記
對於標記,組件內的圖像被包裝在一個<figure></figure>
元素中,它提供了一個基本的框架:
<div class="carousel"> <figure> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> ... <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> </figure> </div>
這將是我們的起點。
輪播圖的幾何結構
在查看CSS之前,讓我們概述一下將在以下部分開發的計劃。
<img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/173967151412585.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript ">
因此,這種多邊形的邊數與輪播圖中的圖像數量相同:三個圖像的多邊形是等邊三角形;四個圖像是正方形;五個是五邊形;等等:
如果輪播圖中的圖像少於三個怎麼辦?多邊形無法定義,以下過程無法按原樣應用。無論如何,只有一個圖像的情況相當沒用;兩個圖像稍微更可能,它們可以放置在圓圈上兩個直徑相對的點上。為簡單起見,這些特殊情況未處理,並假定至少有三個圖像。但是,相關的代碼修改並不難。
這個虛構的參考多邊形將位於3D空間中,垂直於視口的平面,並且其中心向屏幕後推,距離等於其旁心距(多邊形的一條邊到其中心的距離),如下圖所示:
這樣,當前面向觀看者的邊將位於屏幕平面z = 0處,而前部圖像不受透視縮短的影響,將具有其普通的2D大小。圖片中的d字母代表CSS perspective屬性的值。
構建輪播圖幾何結構
在本節中,我將向您展示關鍵的CSS規則,我將逐步講解。
在以下代碼片段中,使用一些Sass變量來使組件更易於配置。我將使用$n
表示輪播圖中的圖像數量,使用$item-width
指定圖像的寬度。
<figure></figure>
元素是第一個圖像的包含框,也是其他圖像圍繞其定位和轉換的參考元素。假設現在輪播圖只有一個圖像要展示,我可以從大小和對齊開始:
<div class="carousel"> <figure> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> ... <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> </figure> </div>
<figure></figure>
元素具有規定的輪播項目寬度,並且具有與圖像相同的高度(它們可以具有不同的尺寸,但必須具有相同的縱橫比)。這樣,輪播容器高度會根據圖像高度自動調整。此外,<figure></figure>
在輪播容器中水平居中。
第一個圖像不需要額外的轉換,因為它已經在其目標位置,即輪播圖的正面。
可以通過對<figure></figure>
元素應用旋轉變換來在3D空間中旋轉輪播圖。此旋轉必須圍繞多邊形的中心進行,因此我將更改<figure></figure>
的默認transform-origin:
.carousel { display: flex; flex-direction: column; align-items: center; > * { flex: 0 0 auto; } .figure { width: $item-width; transform-style: preserve-3d; img { width: 100%; &:not(:first-of-type) { display: none /* Just for now */ } } } }
此值取反,因為在CSS中,z軸的正方向是離開屏幕,朝向觀看者。需要括號以避免Sass語法錯誤。多邊形旁心距的計算將在後面解釋。
轉換了<figure></figure>
元素的參考系統後,整個輪播圖可以通過其(新的)y軸旋轉來旋轉:
.carousel figure { transform-origin: 50% 50% (-$apothem); }
我稍後將返回此旋轉的詳細信息。
讓我們繼續進行其他圖像的轉換。使用絕對定位,圖像堆疊在<figure></figure>
內部:
.carousel figure { transform: rotateY(/* some amount here */rad); }
z-index值被忽略,因為這只是後續轉換的初步步驟。事實上,現在每個圖像都可以圍繞輪播圖的y軸旋轉一個角度,該角度取決於分配圖像的多邊形邊。首先,與<figure></figure>
元素一樣,修改圖像的默認transform-origin,將其移動到多邊形的中心:
<div class="carousel"> <figure> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> ... <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> </figure> </div>
然後,圖像可以圍繞其新的y軸旋轉一個量,該量由($i - 1) * $theta
弧度給出,其中$i
是圖像的索引(從1開始),$theta = 2 * $PI / $n
,其中$PI
表示數學常數π。因此,第二個圖像將旋轉$theta
,第三個旋轉2 * $theta
,依此類推,直到最後一個圖像旋轉($n - 1) * $theta
。
由於嵌套CSS轉換的層次性質,在輪播圖旋轉(即圍繞<figure></figure>
修改後的y軸旋轉)期間,圖像的這種相對排列將被保留。
可以使用Sass @for
控制指令分配此每個圖像的旋轉量:
.carousel { display: flex; flex-direction: column; align-items: center; > * { flex: 0 0 auto; } .figure { width: $item-width; transform-style: preserve-3d; img { width: 100%; &:not(:first-of-type) { display: none /* Just for now */ } } } }
這是使用for...through
結構而不是for...to
,因為對於for...to
,分配給索引變量$i
的最後一個值將是n-1而不是n。
請注意Sass的#{}
插值語法的兩個實例。在第一個實例中,它用於:nth-child()
選擇器的索引;在第二個實例中,它用於設置旋轉屬性值。
計算旁心距
多邊形旁心距的計算取決於邊數和邊的寬度,即取決於$n
和$item-width
變量。公式是:
.carousel figure { transform-origin: 50% 50% (-$apothem); }
其中tan()
是正切三角函數。
這個公式可以通過一些幾何和三角學推導出來。在筆的源代碼中,此公式未按原樣實現,因為正切函數在Sass中不可用,因此使用了硬編碼值。相反,該公式將在JavaScript演示中完全實現。
間隔輪播項目
此時,輪播圖像並排“縫合”,形成所需的多邊形形狀。但是在這裡,它們緊密地堆積在一起,而在3D輪播圖中,它們之間通常會有空間。這種距離增強了3D空間的感知,因為它允許您看到輪播圖背面朝後的圖像。
可以通過引入另一個配置變量$item-separation
並將其用作每個<img alt="用CSS和JavaScript構建3D旋轉的輪播" >
元素的水平填充來可選地添加圖像之間的此間隙。更準確地說,取此值的一半作為左填充和右填充:
.carousel figure { transform: rotateY(/* some amount here */rad); }
最終結果可以在以下演示中看到:(此處應插入CodePen鏈接,展示間隔輪播項目)
圖像使用opacity
屬性變為半透明以更好地說明輪播結構,並且輪播根元素上的flex佈局用於將其在視口中垂直居中。
旋轉輪播圖
為了方便測試輪播圖旋轉,我將添加一個UI控件來在圖像之間來回導航。 (此處應插入CodePen鏈接,展示旋轉輪播圖)
我們使用一個currImage
整數變量來指示哪個圖像位於輪播圖的前面。當用戶與上一個/下一個按鈕交互時,此變量會增加或減少一個單位。
更新currImage
後,輪播圖旋轉將通過以下方式執行:
<div class="carousel"> <figure> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> ... <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> </figure> </div>
(此處以及以下代碼片段中,使用ES6模板字面量在字符串中插入表達式;如果您願意,可以使用傳統的“ ”連接運算符)
其中theta
與之前相同:
.carousel { display: flex; flex-direction: column; align-items: center; > * { flex: 0 0 auto; } .figure { width: $item-width; transform-style: preserve-3d; img { width: 100%; &:not(:first-of-type) { display: none /* Just for now */ } } } }
旋轉是-theta
,因為要導航到下一個項目,需要逆時針旋轉,並且這種旋轉值在CSS轉換中為負值。
請注意,currImage
值不受限於[0, numImages – 1]
範圍,而是可以無限增長,在正方向和負方向上都可以。事實上,如果前面的圖像是最後一個(所以currImage == n-1
),並且用戶單擊下一個按鈕,如果我們將currImage
重置為0以前進到第一個輪播圖像,則旋轉角度將從(n-1)*theta
轉換為0,這將使輪播圖在所有之前的圖像上向相反方向旋轉。當單擊上一個按鈕時,如果前面的圖像是第一個,則會出現類似的問題。
為了挑剔,我甚至應該檢查currentImage
的潛在溢出,因為Number
數據類型不能取任意大的值。這些檢查未在演示代碼中實現。
使用JavaScript增強
在看到構成輪播圖核心的基本CSS之後,現在可以使用JavaScript以多種方式增強組件,例如:
- 任意數量的圖像
- 百分比寬度的圖像
- 頁面上的多個輪播實例
- 每個實例的配置,例如間隙大小和背面可見性
- 使用HTML5數據-*屬性進行配置
首先,我從樣式表中刪除與轉換原點和旋轉相關的變量和規則,因為這些將使用JavaScript完成:(此處應插入更新後的CSS代碼)
接下來,腳本中的carousel()
函數負責實例的初始化:
.carousel figure { transform-origin: 50% 50% (-$apothem); }
root
參數指的是保存輪播圖的DOM元素。
通常,此函數將是一個構造函數,為頁面上的每個輪播圖生成一個對象,但在這裡我沒有編寫輪播庫,因此簡單的函數就足夠了。
為了在同一頁面上實例化多個組件,代碼等待所有圖像加載,為window
對象註冊load
事件的偵聽器,然後為每個具有carousel
類的元素調用carousel()
:
.carousel figure { transform: rotateY(/* some amount here */rad); }
carousel()
執行三個主要任務:
- 導航設置。這與第二個CodePen演示中介紹的代碼相同。
- 轉換設置
- 註冊窗口大小調整偵聽器以保持輪播圖自適應,使其適應新的視口大小
在檢查轉換設置代碼之前,我將介紹一些關鍵變量以及如何根據實例配置初始化它們:
<div class="carousel"> <figure> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> ... <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Building a 3D Rotating Carousel with CSS and JavaScript " /> </figure> </div>
圖像數量(n)根據<figure></figure>
元素的子元素數量初始化。幻燈片之間的間距(gap)從HTML5 data-gap
屬性(如果設置)初始化。背面可見性標誌(bfc)使用HTML5的dataset
API讀取。這將在稍後用於確定輪播圖背面的圖像是否可見。
設置CSS轉換
設置CSS轉換相關屬性的代碼封裝在setupCarousel()
中。此嵌套函數有兩個參數。第一個是輪播圖中的項目數量,即上面介紹的n變量。第二個參數s是輪播圖多邊形的邊長。正如我前面提到的,這等於圖像的寬度,因此可以使用getComputedStyle()
讀取其中一個的當前寬度:
.carousel { display: flex; flex-direction: column; align-items: center; > * { flex: 0 0 auto; } .figure { width: $item-width; transform-style: preserve-3d; img { width: 100%; &:not(:first-of-type) { display: none /* Just for now */ } } } }
這樣,圖像寬度可以使用百分比值設置。
為了保持輪播圖自適應,我註冊了一個窗口大小調整事件的偵聽器,該偵聽器再次使用(可能已修改的)圖像大小調用setupCarousel()
:
.carousel figure { transform-origin: 50% 50% (-$apothem); }
為簡單起見,我沒有去抖動大小調整偵聽器。
setupCarousel()
做的第一件事是使用傳遞的參數和前面討論的公式計算多邊形的旁心距:
.carousel figure { transform: rotateY(/* some amount here */rad); }
然後,此值用於修改<figure></figure>
元素的transform-origin
,以獲得輪播圖的新旋轉軸:
.carousel figure img:not(:first-of-type) { position: absolute; left: 0; top: 0; }
接下來,應用圖像的樣式:
.img:not(:first-of-type) { transform-origin: 50% 50% (-$apothem); }
第一個循環為輪播項目之間的空間分配填充。第二個循環設置3D轉換。最後一個循環處理背面,如果在輪播圖配置中指定了相關標誌。
最後,調用rotateCarousel()
以將當前圖像移到前面。這是一個小的輔助函數,給定要顯示的圖像的索引,它會圍繞其y軸旋轉<figure></figure>
元素以將目標圖像移動到前面。導航代碼也使用它來回移動:
.carousel figure img { @for $i from 2 through $n { &:nth-child(#{$i}) { transform: rotateY(#{($i - 1) * $theta}rad); } } }
這是最終結果,一個演示,其中實例化了幾個輪播圖,每個輪播圖都有不同的配置:(此處應插入最終CodePen鏈接)
來源和結論
在結束之前,我只是想感謝一些用於研究本教程的來源:(此處應列出參考來源)
如果您對代碼或輪播圖的功能有任何疑問或意見,請隨時在下面留言。
關於使用CSS和JavaScript構建3D旋轉輪播圖的常見問題解答(FAQ)
如何使我的3D旋轉輪播圖自適應?
使您的3D旋轉輪播圖自適應涉及在CSS中使用媒體查詢。媒體查詢允許您根據設備的屏幕尺寸為不同的設備應用不同的樣式。您可以調整輪播圖元素的大小和位置以適應較小的屏幕。此外,還要考慮移動設備的觸摸事件,因為它們不像台式機那樣具有懸停狀態。
我可以向輪播圖添加更多幻燈片嗎?
是的,您可以向輪播圖添加更多幻燈片。在HTML結構中,您可以在無序列表中添加更多列表項。每個列表項代表一個幻燈片。請記住調整CSS中每個幻燈片的旋轉角度以正確地在3D空間中定位它們。
如何向輪播圖添加導航按鈕?
可以使用HTML和JavaScript向輪播圖添加導航按鈕。在您的HTML中,添加兩個用於上一個和下一個導航的按鈕。在您的JavaScript中,向這些按鈕添加事件偵聽器。單擊時,它們應該更新輪播圖的旋轉以顯示上一個或下一個幻燈片。
我可以使用圖像而不是純色作為幻燈片嗎?
當然,您可以使用圖像作為幻燈片。不要在CSS中設置背景顏色,而是可以為每個幻燈片設置背景圖像。確保圖像具有正確的大小和分辨率,以獲得最佳視覺效果。
如何向輪播圖添加自動播放功能?
可以使用JavaScript添加自動播放功能。您可以使用setInterval
函數在一段時間後自動更新輪播圖的旋轉。請記住在用戶與輪播圖交互時清除間隔,以防止出現意外行為。
我可以向輪播圖添加過渡效果嗎?
是的,您可以使用CSS向輪播圖添加過渡效果。 transition
屬性允許您在指定持續時間內動畫化CSS屬性的變化。您可以將其應用於transform
屬性以動畫化輪播圖的旋轉。
如何使輪播圖無限循環?
使輪播圖無限循環涉及一些JavaScript。當輪播圖到達最後一個幻燈片時,您可以將其旋轉重置為第一個幻燈片。這給人一種無限循環的錯覺。
我可以在幻燈片上添加文本嗎?
是的,您可以在幻燈片上添加文本。在您的HTML中,您可以在每個列表項中添加文本元素。在您的CSS中,根據幻燈片的位置定位文本元素並根據需要對其進行樣式設置。
如何向輪播圖添加淡入淡出效果?
可以使用CSS添加淡入淡出效果。您可以將opacity
屬性與transition
屬性結合使用以動畫化淡入淡出效果。根據幻燈片在輪播圖中的位置調整其opacity
以創建所需的效果。
我可以使用不同的形狀作為輪播圖嗎?
是的,您可以使用不同的形狀作為輪播圖。輪播圖的形狀由CSS中的transform
屬性確定。通過調整transform
屬性的值,您可以創建立方體、圓柱體或任何其他3D形狀的輪播圖。
以上是用CSS和JavaScript構建3D旋轉的輪播的詳細內容。更多資訊請關注PHP中文網其他相關文章!

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

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

禪工作室 13.0.1
強大的PHP整合開發環境

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境