搜尋

CSS 製作圓點載入動畫 ( 陰影動畫 )

這個範例教學會使用 CSS box-shadow 的陰影樣式,讓單一個 div 的多重陰影在畫面中產生十六個圓點,並搭配自訂屬性 @property 和動畫 animation 讓陰影動起來,實作漂亮的圓點載入動畫。

快速導覽:

CSS 教學 - CSS 製作圓點載入動畫 ( 陰影動畫 )

多重陰影產生十六個圓點

box-shadow 陰影樣式屬性撰寫多種陰影樣式,就能做出多重陰影的效果,運用三角函數公式,就能將這些陰影定位在一個圓的圓周上,舉例來說,當一個圓的半徑為 50px,就能產生下方的座標點:

(50px, 0px)         
(46.20px, 19.14px)    // 50px * cos(22.5deg), 50px * sin(22.5deg) 
(35.36px, 35.36px)    // (50px * cos(45deg), 50px * sin(45deg))  
(19.14px, 46.20px)    // (50px * cos(67.5deg), 50px * sin(67.5deg))  
(0px, 50px)
(-19.14px, 46.20px)   // 50px * cos(112.5deg), 50px * sin(112.5deg)
(-35.36px, 35.36px)   // 50px * cos(135deg), 50px * sin(135deg)
(-46.20px, 19.14px)   // 50px * cos(157.5deg), 50px * sin(157.5deg)
(-46.20px, -19.14px)  // 50px * cos(202.5deg), 50px * sin(202.5deg) 
(-35.36px, -35.36px)  // 50px * cos(225deg), 50px * sin(225deg)
(-19.14px, -46.20px)  // 50px * cos(247.5deg), 50px * sin(247.5deg)
(0px, -50px)
(19.14px, -46.20px)   // 50px * cos(292.5deg), 50px * sin(292.5deg)
(35.36px, -35.36px)   // 50px * cos(315deg), 50px * sin(315deg)
(46.20px, -19.14px)   // 50px * cos(337.5deg), 50px * sin(337.5deg)

將這些座標點改成 CSS 的寫法,使用透明色隱藏元素本身,畫面中就會出現十六個透過陰影產生的圓點。

<!-- HTML 程式碼 -->
<div class="c"></div>

<!-- CSS 程式碼 -->
<style>
  .c {
    position: absolute;
    top: 100px;
    left: 100px;
    width: 10px;
    height: 10px;
    background: #0000;    /* 元素本身透明 */
    border-radius: 50%;   /* 圓角產生圓形,影子才會是圓形 */
    /* 多重陰影 */
    box-shadow: 
      #f00 50px 0 0 0,
      #f00 46.19px 19.14px 0 0,
      #f00 35.36px 35.36px 0 0,
      #f00 19.14px 46.19px 0 0,
      #f00 0 50px 0 0,
      #f00 -19.14px 46.19px 0 0,
      #f00 -35.36px 35.36px 0 0,
      #f00 -46.19px 19.14px 0 0,
      #f00 -50px 0 0 0,
      #f00 -46.19px -19.14px 0 0,
      #f00 -35.36px -35.36px 0 0,
      #f00 -19.14px -46.19px 0 0,
      #f00 0 -50px 0 0,
      #f00 19.14px -46.19px 0 0,
      #f00 35.36px -35.36px 0 0,
      #f00 46.19px -19.14px 0 0;
  }
</style>

CSS 教學 - CSS 製作圓點載入動畫 ( 陰影動畫 ) - 多重陰影產生十六個圓點

使用 @property 和 animation 讓陰影動起來

如果要在 CSS 的陰影無法使用基本的方法套用動畫效果 ( 類似漸層色無法直接套用動畫效果 ),必須使用「自訂屬性 @property」,透過改變屬性值的方式產生動畫,下方範例會新增一個 --c 自訂屬性,並將陰影的「尺寸」換成 var(--c),透過改變自訂屬性的方式讓圓點出現和消失。

<!-- HTML 程式碼 -->
<div class="c"></div>

<!-- CSS 程式碼 -->
<style>
  @property --c {
    syntax: "<length>";  /* 自訂屬性類型是長度 */
    inherits: true;
    initial-value: -5px; /* 自訂屬性預設值為 -5px */
  }
  .c {
    position: absolute;
    width: 10px;
    height: 10px;
    background: #0000;
    border-radius: 50%;
    top: 100px;
    left: 100px;
    /* 陰影尺寸都改成 var(--c) 讀取自訂屬性 */
    box-shadow: 
      #f00 50px 0 0 var(--c),
      #f00 46.19px 19.14px 0 var(--c),
      #f00 35.36px 35.36px 0 var(--c),
      #f00 19.14px 46.19px 0 var(--c),
      #f00 0 50px 0 var(--c),
      #f00 -19.14px 46.19px 0 var(--c),
      #f00 -35.36px 35.36px 0 var(--c),
      #f00 -46.19px 19.14px 0 var(--c),
      #f00 -50px 0 0 var(--c),
      #f00 -46.19px -19.14px 0 var(--c),
      #f00 -35.36px -35.36px 0 var(--c),
      #f00 -19.14px -46.19px 0 var(--c),
      #f00 0 -50px 0 var(--c),
      #f00 19.14px -46.19px 0 var(--c),
      #f00 35.36px -35.36px 0 var(--c),
      #f00 46.19px -19.14px 0 var(--c);
    animation: oxxo 1s alternate infinite; /* 重複不斷播放 */
  }
  /* 動畫改變自訂屬性 */
  @keyframes oxxo {
    0% {--c: -5px;}  /* -5px 為圓點大小 10px 的半徑 */
    100% {--c: 0;}
  }
</style>

CSS 教學 - CSS 製作圓點載入動畫 ( 陰影動畫 ) - 使用 @property 和 animation 讓陰影動起來

使用動畫延遲,讓圓點依序出現

為了利用圓點「大小出現的時間差」產生「旋轉」效果,必須透過「動畫延遲」和「多重動畫」方式,讓每個圓點出現的時間有所不同並依序出現,修*改上述的範例程式碼,增加一些自訂屬性 ( 改成 --c1、--c2 等 ) 以及動畫影格名稱 ( oxxo1、oxxo2 等 ),並加入延遲時間,就能產生依序出現的效果,下方範例先修改四個圓點 ( 程式碼會開始大幅增加 )。

<!-- HTML 程式碼 -->
<div class="c"></div>

<!-- CSS 程式碼 -->
<style>
  /* 自訂屬性 */
  @property --c1 {
    syntax: "<length>";
    inherits: true;
    initial-value: -5px;
  }
  @property --c2 {
    syntax: "<length>";
    inherits: true;
    initial-value: -5px;
  }
  @property --c3 {
    syntax: "<length>";
    inherits: true;
    initial-value: -5px;
  }
  @property --c4 {
    syntax: "<length>";
    inherits: true;
    initial-value: -5px;
  }
  .c {
    position: absolute;
    width: 10px;
    height: 10px;
    background: #0000;
    border-radius: 50%;
    top: 100px;
    left: 100px;
    /* 注意自訂屬性名稱不同 */
    box-shadow: 
      #f00 50px 0 0 var(--c1),
      #f00 46.19px 19.14px 0 var(--c2),
      #f00 35.36px 35.36px 0 var(--c3),
      #f00 19.14px 46.19px 0 var(--c4),
      #f00 0 50px 0 var(--c1),
      #f00 -19.14px 46.19px 0 var(--c2),
      #f00 -35.36px 35.36px 0 var(--c3),
      #f00 -46.19px 19.14px 0 var(--c4),
      #f00 -50px 0 0 var(--c1),
      #f00 -46.19px -19.14px 0 var(--c2),
      #f00 -35.36px -35.36px 0 var(--c3),
      #f00 -19.14px -46.19px 0 var(--c4),
      #f00 0 -50px 0 var(--c1),
      #f00 19.14px -46.19px 0 var(--c2),
      #f00 35.36px -35.36px 0 var(--c3),
      #f00 46.19px -19.14px 0 var(--c4);
    /* 多重動畫,每個動畫都增加 0.2s 延遲 */
    animation: oxxo1 1s alternate infinite,
      oxxo2 1s 0.2s alternate infinite,
      oxxo3 1s 0.4s alternate infinite,
      oxxo4 1s 0.6s alternate infinite;
  }
  /* 動畫影格名稱不同 */
  @keyframes oxxo1 {
    0% {--c1: -5px;}
    100% {--c1: 0;}
  }
  @keyframes oxxo2 {
    0% {--c2: -5px;}
    100% {--c2: 0;}
  }
  @keyframes oxxo3 {
    0% {--c3: -5px;}
    100% {--c3: 0;}
  }
  @keyframes oxxo4 {
    0% {--c4: -5px;}
    100% {--c4: 0;}
  } 
</style>

CSS 教學 - CSS 製作圓點載入動畫 ( 陰影動畫 ) - 使用動畫延遲,讓圓點依序出現

圓點載入動畫 ( 使用 JavaScript 簡化程式碼 )

因為透過多重陰影產生的動畫需要撰寫「大量又類似」的 CSS 程式碼,為了縮減程式碼長度,可以透過 JavaScript 將重複的部分獨立出來,並運用迴圈替換變數,後續也比較方便修改調整,如果要做得更有彈性,連同陰影的顏色和陰影位置都能運用 JavaScript 來調整,詳細說明可以參考下方範例:

<!-- HTML 程式碼 -->
<div class="c"></div>

<!-- CSS 程式碼 -->
<style>
  /* 將重複的程式碼全部交由 JS 處裡 */
  .c {
    position: absolute;
    width: 10px;
    height: 10px;
    background: #0000;
    border-radius: 50%;
    top: 100px;
    left: 100px;
  }
</style>

<!-- JavaScript 程式碼 -->
<script>
  const head = document.head;   // 取得頁面的 head 區塊
  const style = document.createElement('style'); // 建立一個新的 style 區塊
  head.appendChild(style);      // head 區塊中加入 style

  let cssProperty = '';         // CSS 自訂屬性和影格內容
  let anime = '';               // CSS 動畫
  let boxShadow = '';           // CSS 陰影
  let color = 'red';            // 圓點顏色
  let radius = 50;              // 繞圓的半徑
  let num = 16;                 // 圓的數量
  let deg = ~~(360/num*10)/10;  // 根據數量計算角度,取值到小數點第二位
  let cr = 10;                  // 小圓點半徑

  // 建立函式,根據角度計算位置
  function pos(angle, r){
    let rad = angle*Math.PI/180; // 換算弧度
    let px = Math.cos(rad)*r;    // x 座標
    let py = Math.sin(rad)*r;    // y 座標
    return [px, py];             // 回傳陣列結果
  }

  // 使用迴圈,產生每個點的自訂屬性和動畫影格名稱
  for(let i=1; i<num+1; i++){
    let c = `
      @property --c${i} {
        syntax: "<length>";
        inherits: true;
        initial-value: -${cr}px;
      }
      @keyframes oxxo${i} {
        0% {--c${i}: -${cr}px;}
        100% {--c${i}: 0;}
      }`;
    let xy = pos((i-1)*deg, radius); // 透過函式取得 xy 座標
    let x = ~~(xy[0]*100)/100;       // x 座標,取值到小數點第二位
    let y = ~~(xy[1]*100)/100;       // y 座標,取值到小數點第二位
    let sec = ~~((i-1)*0.2*10)/10;   // 延遲秒數,取值到小數點第一位,處理 JS 很多的小數點問題
    anime = anime + `oxxo${i} 1s ${sec}s alternate infinite,`;        // 動畫 CSS
    boxShadow = boxShadow + `${color} ${x}px ${y}px 0 var(--c${i}),`; // 陰影 CSS
    cssProperty = cssProperty + c;   // 組合 CSS
  }
  anime = anime.replace(/.$/,';');           // 替換最後的 , 為 ;
  boxShadow = boxShadow.replace(/.$/,';');   // 替換最後的 , 為 ;
  cssProperty = cssProperty + `.c {animation: ${anime} box-shadow: ${boxShadow} }`; // 組合 CSS
  style.appendChild(document.createTextNode(cssProperty)); // 添加 CSS
</script>

CSS 教學 - CSS 製作圓點載入動畫 ( 陰影動畫 ) - 圓點載入動畫 ( 使用 JavaScript 簡化程式碼 )

CSS 教學 - CSS 製作圓點載入動畫 ( 陰影動畫 ) - 圓點載入動畫 ( 使用 JavaScript 簡化程式碼 )

小結

CSS 的圓點載入動畫其實不複雜,只是程式碼多了點 ( 大多都是重複撰寫 ),單純透過 CSS 也可以實現,只是為了減少重複的程式碼,使用 JavaScript 處理會更有效率,不過這篇範例的重點是在於多重陰影、多重動畫、自訂屬性的互相搭配,只要熟練運用,就能做出許多有趣的效果。

意見回饋

如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

CSS 教學

基本介紹

認識 CSS 開始使用 CSS CSS 語法規則 CSS 命名原則 CSS 常用樣式屬性

CSS 選擇器

認識 CSS 選擇器 優先順序 ( 權重 ) 樣式繼承與聯集 使用巢狀結構語法 元素選擇器 ID 和 Class 選擇器 屬性選擇器 文件結構選擇器 虛擬類別選擇器 ( 結構 ) 虛擬類別選擇器 ( 類型 ) 虛擬類別選擇器 ( 輸入 ) 虛擬類別選擇器 ( 行為 ) 虛擬類別選擇器 ( 超連結 ) 虛擬類別選擇器 ( 邏輯 ) 虛擬類別選擇器 ( 其他 ) 虛擬元素選擇器 群組與組合選擇器

數值與單位

全域關鍵字與文字數值 長度與角度單位 位置名稱與時間單位 特殊樣式屬性 ( all、appearance)

規則與定義

變數 ( Variables ) 媒體查詢 ( @media ) 容器查詢 ( @container ) 自訂屬性值 ( @property ) 匯入樣式 ( @import ) 分層優先順序 ( @layer ) 定義字型 ( @font-face ) 計數規則 ( @counter-style ) 列印網頁 ( @page )

函式類型

數學計算 文字與清單計數 形狀與線段 路徑 ( path ) 生成內容與引號

顏色與濾鏡

顏色單位 色彩模型 漸層色 影像濾鏡 ( filter ) 背景濾鏡 ( backdrop-filter ) 混合模式 ( mix-blend-mode )

文字與段落

設定字型 ( font-family ) 使用外部字型 文字尺寸 文字樣式 ( 常用 ) 文字樣式 ( 其他實用 ) 文字樣式 ( 特殊用途 ) 文字換行 文字空白與 Tab 大小 文字行高與縮排 文字水平與垂直對齊 文字書寫方向 文字自動分欄 使用 Icon Font ( 圖示文字 ) 製作自己的 Icon Font

元素容器

容器顯示類型 ( display ) 元素 display 對照表 盒子模型 ( Box Model ) 寬度與高度 內邊距 ( padding ) 外邊界 ( margin ) 邊框 ( border ) 邊框圓角 ( border-radius ) 影像邊框 ( border-image ) 輪廓 ( outline ) 內容溢出與裁切 ( overflow ) 內容範圍 ( contain ) 可見性與透明度

背景與陰影

背景顏色 背景圖 ( 定位、尺寸 ) 背景圖 ( 固定、重複 ) 背景圖 ( 多重背景、混合 ) 背景縮寫 ( background ) 容器陰影 ( box-shadow )

清單與表格

清單樣式 清單計數器 表格基本樣式 表格邊框樣式 表格內容寬度與對齊

基本排版與定位

元素排版方式 浮動 ( float ) 浮動形狀 ( shape-* ) 定位 ( position ) 邏輯屬性 ( logical properties ) 水平置中技巧 垂直置中技巧

Flex 彈性排版

Flexbox 彈性盒子 Flex 對齊方式 Flex 彈性伸縮

Grid 網格排版

Grid 網格容器與格線 Grid 網格空間與命名 Grid 網格流向與間距 Grid 排列網格項目 Grid 項目對齊與順序

轉場與動畫

轉場 ( transition ) 轉場觸發事件 動畫 ( animation ) 自訂動畫路徑 ( offset ) 動畫觸發事件 多重動畫的權重與順序 動畫進度控制 ( timeline )

變形、裁切與遮罩

裁切路徑 ( clip-path ) 影像遮罩 ( mask ) 物件填滿方式與定位 轉換函式 ( transform ) 平移、旋轉與縮放 3D 轉換與透視

視窗與使用者行為

捲軸樣式 ( scrollbar ) 拉霸、滑桿樣式 ( slider ) 滑鼠游標圖示 ( cursor ) 滑鼠事件 ( pointer-events ) 使用者選取 ( user-select ) 捲動行為 ( scroll、overscroll ) 列印換頁 ( break-* )

CSS 預處理器

認識 CSS 預處理器 Less ( 安裝、開始使用 ) Less ( 巢狀結構、選擇器 ) Less ( 變數、import ) Less ( Extend、Mixin ) Less ( 邏輯、迴圈、函式 )

範例效果

CSS 圓餅圖 CSS 跑馬燈 Google 載入動畫 漸層色的轉場與動畫 電子時鐘數字 不規則形狀動畫 彈跳的正方形動畫 3D 正多面體 超連結底線動畫效果 噁心黏黏球效果 漸層色製作星空背景 CSS 視差滾動效果 捲軸控制放射形選單 捲軸改變文字背景色 CSS 頁面捲動進度條 CSS 水波效果 圓點載入動畫 ( 陰影動畫 )