首頁 > web前端 > css教學 > CSS無限和圓形旋轉圖像滑塊

CSS無限和圓形旋轉圖像滑塊

William Shakespeare
發布: 2025-03-09 13:14:15
原創
984 人瀏覽過

CSS Infinite and Circular Rotating Image Slider

圖片滑塊(也稱為輪播圖)隨處可見。有很多 CSS 技巧可以創建常見的滑塊,其中圖片從左向右滑動(或反之亦然)。許多 JavaScript 庫也創建了具有復雜動畫的精美滑塊。在本文中,我們不會做任何這些事情。

我們將通過一系列文章來探索一些奇特且不常見的純 CSS 滑塊。如果您厭倦了看到相同的經典滑塊,那麼您來對地方了!

CSS 滑塊系列

  • 循環旋轉圖片滑塊 (您當前位置)
  • 瀏覽寶麗來圖片
  • 無限 3D 滑塊

在第一篇文章中,我們將從我稱之為“循環旋轉圖片滑塊”的內容開始:

很酷吧?讓我們剖析代碼!

HTML 結構

如果您關注過我關於精美圖片裝飾或 CSS 網格和自定義形狀的系列文章,那麼您就會知道我的第一條規則是使用盡可能少的 HTML。我總是努力尋找 CSS 解決方案,然後再用大量 <div> 和其他內容使代碼混亂。這裡也適用相同的規則——我們的代碼只不過是容器中的一系列圖像。 <p>假設我們使用四張圖片:</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">&lt;div&gt; &lt;img alt=&quot;&quot; src=&quot;&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;&quot;&gt; &lt;/div&gt;</pre><div class="contentsignin">登入後複製</div></div><div class="contentsignin">登入後複製</div></div><div class="contentsignin">登入後複製</div></div> <p>就是這樣!現在讓我們進入代碼的有趣部分。但首先,我們將深入研究它,以了解我們的滑塊如何工作的邏輯。 </p> <h3>工作原理? </h3> <p>這是一個視頻,我從中刪除了 <code>overflow: hidden CSS,以便我們可以更好地理解圖像的移動方式:(此處應嵌入視頻,但由於我無法處理視頻,我將用文字描述)視頻展示了四個圖像在一個大圓圈上逆時針旋轉。所有圖像大小相同(圖中用 S 表示)。請注意藍色圓圈,它是與所有圖像中心相交的圓圈,並具有半徑 (R)。稍後我們將需要此值用於我們的動畫。 R 等於 0.707 * S。 (我將跳過給出該方程的幾何計算。)

讓我們編寫一些 CSS!

我們將使用 CSS 網格將所有圖像放置在彼此上方的同一區域中:

.gallery {
  --s: 280px; /* 控制大小 */

  display: grid;
  width: var(--s);
  aspect-ratio: 1;
  padding: calc(var(--s) / 20); /* 我们稍后将看到它的用途 */
  border-radius: 50%;
}

.gallery > img {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}
登入後複製
登入後複製
登入後複製

到目前為止,沒有什麼太複雜的。棘手的部分是動畫。

我們討論過旋轉一個大圓圈,但實際上,我們將單獨旋轉每個圖像,從而產生一個大旋轉圓圈的錯覺。因此,讓我們定義一個動畫 m 並將其應用於圖像元素:

.gallery > img {
  /* 与之前相同 */
  animation: m 8s infinite linear;
  transform-origin: 50% 120.7%;
}

@keyframes m {
  100% { transform: rotate(-360deg); }
}
登入後複製
登入後複製
登入後複製

主要技巧在於突出顯示的行。默認情況下,CSS transform-origin 屬性等於中心(或 50% 50%),這使得圖像圍繞其中心旋轉,但我們不需要這樣做。我們需要圖像圍繞包含我們圖像的大圓圈的中心旋轉,因此 transform-origin 的新值。

由於 R 等於 0.707 * S,我們可以說 R 等於圖像大小的 70.7%。這是一個圖來說明我們如何得到 120.7% 的值:(此處應嵌入圖片,但由於我無法處理圖片,我將用文字描述)圖片展示了計算transform-origin值的幾何關係。

讓我們運行動畫並看看會發生什麼:(此處應嵌入動畫效果,但由於我無法處理動畫,我將用文字描述)動畫效果顯示只有一個圖像可見,因為所有圖像疊加在一起。

我們需要延遲每個圖像的動畫以避免這種重疊。

<div>
  <img alt="" src=""><img alt="" src=""><img alt="" src=""><img alt="" src="">
</div>
登入後複製
登入後複製
登入後複製

情況已經好轉了!

如果我們在容器上隱藏溢出,我們已經可以看到一個滑塊,但我們將稍微更新動畫,以便每個圖像在移動之前都會可見一小段時間。

我們將更新我們的動畫關鍵幀來做到這一點:

.gallery {
  --s: 280px; /* 控制大小 */

  display: grid;
  width: var(--s);
  aspect-ratio: 1;
  padding: calc(var(--s) / 20); /* 我们稍后将看到它的用途 */
  border-radius: 50%;
}

.gallery > img {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}
登入後複製
登入後複製
登入後複製

對於每個 90deg(360deg/4,其中 4 是圖像的數量),我們將添加一個小的暫停。在滑動到下一個圖像之前,每個圖像將保持可見總持續時間的 5%(27%-22%、52%-47% 等)。我將使用 cubic-bezier() 函數更新 animation-timing-function 以使動畫更精美:(此處應嵌入動畫效果,但由於我無法處理動畫,我將省略)

現在我們的滑塊很完美!嗯,幾乎完美,因為我們仍然缺少最後的潤色:圍繞我們的圖像旋轉的彩色圓形邊框。我們可以在 .gallery 包裝器上使用偽元素來創建它:

.gallery > img {
  /* 与之前相同 */
  animation: m 8s infinite linear;
  transform-origin: 50% 120.7%;
}

@keyframes m {
  100% { transform: rotate(-360deg); }
}
登入後複製
登入後複製
登入後複製

我創建了一個帶有重複圓錐漸變的圓圈作為背景,同時使用了一種僅顯示填充區域的遮罩技巧。然後我將為圖像定義的相同動畫應用於它。 (此處應嵌入動畫效果,但由於我無法處理動畫,我將省略)

我們完成了!我們有一個很酷的循環滑塊:

讓我們添加更多圖像

使用四張圖片很好,但如果我們可以將其擴展到任意數量的圖像,那就更好了。畢竟,這是圖片滑塊的目的。我們應該能夠考慮 N 張圖片。

為此,我們將通過引入 Sass 使代碼更通用。首先,我們為圖像數量 ($n) 定義一個變量,我們將更新我們硬編碼圖像數量 (4) 的每個部分。

讓我們從延遲開始:

.gallery > img:nth-child(2) { animation-delay: -2s; } /* -1 * 8s / 4 */
.gallery > img:nth-child(3) { animation-delay: -4s; } /* -2 * 8s / 4 */
.gallery > img:nth-child(4) { animation-delay: -6s; } /* -3 * 8s / 4 */
登入後複製
登入後複製
登入後複製

延遲的公式是 (1 - $i)*duration/$n,這給了我們以下 Sass 循環:

@keyframes m {
  0%, 3% { transform: rotate(0); }
  22%, 27% { transform: rotate(-90deg); }
  47%, 52% { transform: rotate(-180deg); }
  72%, 77% { transform: rotate(-270deg); }
  98%, 100% { transform: rotate(-360deg); }
}
登入後複製
登入後複製
登入後複製

如果我們真的想,我們也可以使持續時間成為一個變量。但是讓我們繼續進行動畫:

.gallery {
  padding: calc(var(--s) / 20); /* 此处需要填充 */
  position: relative;
}

.gallery::after {
  content: "";
  position: absolute;
  inset: 0;
  padding: inherit; /* 继承相同的填充 */
  border-radius: 50%;
  background: repeating-conic-gradient(#789048 0 30deg, #DFBA69 0 60deg);
  mask:
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  mask-composite: exclude;
}

.gallery::after,
.gallery > img {
  animation: m 8s infinite cubic-bezier(.5, -0.2, .5, 1.2);
}
登入後複製

讓我們簡化它以更好地查看模式:

.gallery > img:nth-child(2) { animation-delay: -2s; } /* -1 * 8s / 4 */
.gallery > img:nth-child(3) { animation-delay: -4s; } /* -2 * 8s / 4 */
.gallery > img:nth-child(4) { animation-delay: -6s; } /* -3 * 8s / 4 */
登入後複製
登入後複製
登入後複製

每個狀態之間的步長等於 25%——即 100%/4——我們添加一個 -90deg 角——即 -360deg/4。這意味著我們可以這樣編寫循環:

@for $i from 2 to ($n + 1) {
  .gallery > img:nth-child(#{$i}) {
    animation-delay: calc(#{(1 - $i) / $n} * 8s);
  }
}
登入後複製

由於每個圖像佔據動畫的 5%,我們更改此內容:

@keyframes m {
  0%, 3% { transform: rotate(0); }
  22%, 27% { transform: rotate(-90deg); }
  47%, 52% { transform: rotate(-180deg); }
  72%, 77% { transform: rotate(-270deg); }
  98%, 100% { transform: rotate(-360deg); }
}
登入後複製
登入後複製
登入後複製

……與此:

<div>
  <img alt="" src=""><img alt="" src=""><img alt="" src=""><img alt="" src="">
</div>
登入後複製
登入後複製
登入後複製

需要注意的是,5% 是我為此示例選擇的任意值。我們也可以將其設為變量來控制每個圖像應保持可見的時間。為了簡單起見,我將跳過這一點,但作為家庭作業,您可以嘗試這樣做並在評論中分享您的實現!

.gallery {
  --s: 280px; /* 控制大小 */

  display: grid;
  width: var(--s);
  aspect-ratio: 1;
  padding: calc(var(--s) / 20); /* 我们稍后将看到它的用途 */
  border-radius: 50%;
}

.gallery > img {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}
登入後複製
登入後複製
登入後複製

最後一點是更新 transform-origin。我們將需要一些幾何技巧。無論圖像數量是多少,配置始終相同。我們將圖像(小圓圈)放置在一個大圓圈內,我們需要找到半徑 R 的值。

您可能不想要一個枯燥的幾何解釋,因此以下是如何找到 R:

.gallery > img {
  /* 与之前相同 */
  animation: m 8s infinite linear;
  transform-origin: 50% 120.7%;
}

@keyframes m {
  100% { transform: rotate(-360deg); }
}
登入後複製
登入後複製
登入後複製

如果我們將其表示為百分比,則得到:

.gallery > img:nth-child(2) { animation-delay: -2s; } /* -1 * 8s / 4 */
.gallery > img:nth-child(3) { animation-delay: -4s; } /* -2 * 8s / 4 */
.gallery > img:nth-child(4) { animation-delay: -6s; } /* -3 * 8s / 4 */
登入後複製
登入後複製
登入後複製

……這意味著 transform-origin 值等於:

@keyframes m {
  0%, 3% { transform: rotate(0); }
  22%, 27% { transform: rotate(-90deg); }
  47%, 52% { transform: rotate(-180deg); }
  72%, 77% { transform: rotate(-270deg); }
  98%, 100% { transform: rotate(-360deg); }
}
登入後複製
登入後複製
登入後複製

我們完成了!我們有一個適用於任何數量圖像的滑塊!

讓我們在那裡添加九張圖片:(此處應嵌入九張圖片的滑塊效果,但由於我無法處理圖片和動畫,我將省略)

添加任意數量的圖像並使用圖像總數更新 $n 變量。

總結

通過使用 CSS 變換和標準幾何的幾個技巧,我們創建了一個不錯的循環滑塊,不需要很多代碼。這個滑塊很酷的一點是,我們不需要費心複製圖像來保持無限動畫,因為我們有一個圓圈。完整旋轉後,我們將返回到第一張圖像!

以上是CSS無限和圓形旋轉圖像滑塊的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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