記錄--一個炫酷的css動畫

来源:https://www.cnblogs.com/smileZAZ/archive/2023/08/25/17657687.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 最近有一個需求,要我實現一個動畫效果,效果如下 簡單分析了一下效果,是一個3d的效果,首先是一個圓,接著是兩段圓環,第三層是一堆小圓環,最裡面是一些線上運動,有著漸變色的矩形。 第一層的圓環很簡單。 第二層的圓環其實也挺簡單的,只要在設置 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

最近有一個需求,要我實現一個動畫效果,效果如下

簡單分析了一下效果,是一個3d的效果,首先是一個圓,接著是兩段圓環,第三層是一堆小圓環,最裡面是一些線上運動,有著漸變色的矩形。

第一層的圓環很簡單。

第二層的圓環其實也挺簡單的,只要在設置了border-radius為50%之後,把左右或者上下邊的顏色設置為transparent就可以了

第三層的一對小圓環其實是最複雜的

我們可以先實現一個小圓環

.annulus {
        width: 200px;
        height: 200px;
        background: conic-gradient(
          rgb(25, 234, 253) 0,
          rgb(25, 234, 253) 4%,
          transparent 4%
        );
        border-radius: 50%;
        -webkit-mask: radial-gradient(
          transparent,
          transparent 50%,
          #000 50%,
          #000 100%
        );
      }

這裡主要用到了兩個屬性,conic-gradient mask

conic-gradient

conic-gradient 是一種 CSS 漸變方式,它用於創建一個錐形漸變,從圓心向外輻射。與線性漸變和徑向漸變不同,錐形漸變是以中心點為起點,按照一定的角度進行漸變。它的語法如下:

conic-gradient([starting position], color-stop1, color-stop2, ...)
  • starting position:錐形漸變的起始位置,預設值是 0deg,表示從頂部開始。你可以使用角度值或關鍵詞 from 來指定起始位置,例如 45degfrom left.
  • color-stop:顏色停止點,定義漸變的顏色和位置。

這裡我們把其他地方都設置為透明,只在4%的範圍內設置顏色,這樣會得到一個扇形。

mask

mask 是一個 CSS 屬性,用於創建遮罩效果,即在元素上應用一個遮罩圖像或圖像源,以控制元素的可見性。它可以讓你根據遮罩圖像的不透明度來決定元素的哪些部分是可見的,哪些部分是隱藏的。

mask 屬性有兩種主要用法:

  1. 使用圖像作為遮罩:
.masked-element { mask: url("mask-image.png"); } 

這將使 .masked-element 元素的內容受到 mask-image.png 圖像的遮罩影響。圖像的不透明部分將允許元素內容顯示,而圖像的透明部分將隱藏元素內容。

  1. 使用線性漸變或徑向漸變作為遮罩:
.masked-element { mask: linear-gradient(to right, transparent 0%, black 100%); }

這裡我們只需要把前面部分設置為透明,後一部分設置為不透明,加上這樣的遮罩效果,就能得到我們需要的一個扇形了。

我們用radial-gradient和mask的結合就可以實現這樣的效果

radial-gradient

radial-gradient 是 CSS 中的一個漸變函數,用於創建徑向漸變效果。它允許你在一個元素的背景中創建從一個顏色到另一個顏色的漸變,呈現出一種從中心向外的徑向效果。

語法如下:

background: radial-gradient([shape] [size] at [position], color-stop1, color-stop2, ...);

radial-gradient 是 CSS 中的一個漸變函數,用於創建徑向漸變效果。它允許你在一個元素的背景中創建從一個顏色到另一個顏色的漸變,呈現出一種從中心向外的徑向效果。

語法如下:

background: radial-gradient([shape] [size] at [position], color-stop1, color-stop2, ...);
  • [shape] 定義漸變的形狀,可以是 circle(圓形)或 ellipse(橢圓形)。
  • [size] 定義漸變的大小,可以是 closest-sidefarthest-sideclosest-cornerfarthest-corner 或一個長度值。
  • [position] 定義漸變的中心位置,可以使用關鍵字(如 centertop left)或百分比/長度值組合。
  • color-stop 是顏色和位置的組合,用於定義漸變的顏色變化。

到了這裡,我們實現了一個小圓環,那麼怎麼實現一堆按照圓環排列的小圓環呢,那其實就是在生成一堆這樣的元素,然後給每次元素不同的rotate角度,就能實現了。

接著是最內層的向上運動的流星動畫 這裡其實也比較簡單,只要畫一個小矩形,然後背景加上漸變色,然後加上自下而上的動畫就可以實現一個矩形,然後複製多個出來,在動畫上要設置不同的持續時間和延時,就能達到隨機的效果。

全部代碼如下,沒有用sass和js去動態生成樣式和元素 下麵的js是滑鼠上下拖動時候會翻轉。

<!DOCTYPE html>
<html>
  <head>
    <style>
      html {
        background: black;
      }
      .container {
        width: 300px;
        height: 300px;
      }
      .main1 {
        width: 500px;
        height: 500px;
        transform: translateZ(-150px);
        transform-style: preserve-3d;
      }
      .main2 {
        width: 300px;
        height: 300px;
        transform-style: preserve-3d;
        transform: rotateX(60deg);
        position: relative;
      }
      .flex {
        display: flex;
        align-items: center;
        justify-content: center;
      }
      .positon {
        position: absolute;
      }
      .center {
        top: 50%;
        left: 50%;
        transform: translateX(-50%) translateY(-50%);
      }
      .firstCircle {
        width: 400px;
        height: 400px;
        border-radius: 50%;
        border: 3px solid rgb(42, 153, 255);
      }
      .secondCircle {
        width: 350px;
        height: 350px;
        border-radius: 50%;
        border: 10px solid rgb(42, 153, 255);
        border-color: rgb(42, 153, 255) transparent;

        animation: rotate1 3s linear infinite;
      }
      .thirdCircle {
      }
      .fourthCircle {
        width: 300px;
        height: 300px;
        transform: translateX(-50%) translateY(-50%) translateZ(30px);
        animation: rotate2 3s linear infinite;
      }
      .annulusContent {
        width: 100%;
        height: 100%;
        position: relative;
        transform-style: preserve-3d;
      }
      .bar {
        width: 280px;
        height: 300px;
        background: transparent;
        top: 50%;
        left: 50%;
        transform: translateZ(150px) translateX(-50%) translateY(-50%)
          rotateX(90deg);
        display: flex;
        gap: 20px;
        overflow: hidden;
      }
      .line {
        width: 3px;
        height: 100px;
        background: linear-gradient(
          to top,
          rgb(69, 164, 254),
          rgba(42, 153, 255, 0.1)
        );
      }
      .line1 {
        animation: line1 1s linear infinite;
      }
      .line2 {
        animation: line1 0.5s 0.2s linear infinite;
      }
      .line3 {
        animation: line1 1.5s 0.5s linear infinite;
      }
      .line4 {
        animation: line1 1.3s 1s linear infinite;
      }
      .line5 {
        animation: line1 1.6s 0.3s linear infinite;
      }
      .line6 {
        animation: line1 2s 0.4s linear infinite;
      }
      .line7 {
        animation: line1 1.2s 0.6s linear infinite;
      }
      .line8 {
        animation: line1 1.1s 1.1s linear infinite;
      }
      .line9 {
        animation: line1 1.9s 0.9s linear infinite;
      }
      .line10 {
        animation: line1 1.7s 1.3s linear infinite;
      }
      .line11 {
        animation: line1 1.3s 1.1s linear infinite;
      }
      .line12 {
        animation: line1 1.4s 0.4s linear infinite;
      }
      .annulus {
        width: 300px;
        height: 300px;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translateX(-50%) translateY(-50%);
        background: conic-gradient(
          rgb(69, 164, 254) 0,
          rgb(69, 164, 254) 2%,
          transparent 2%
        );
        border-radius: 50%;
        -webkit-mask: radial-gradient(
          transparent,
          transparent 57%,
          #000 57%,
          #000 100%
        );
      }
      .annulus1 {
        transform: translateX(-50%) translateY(-50%) rotateZ(10deg);
      }
      .annulus2 {
        transform: translateX(-50%) translateY(-50%) rotateZ(20deg);
      }
      .annulus3 {
        transform: translateX(-50%) translateY(-50%) rotateZ(30deg);
      }
      .annulus4 {
        transform: translateX(-50%) translateY(-50%) rotateZ(40deg);
      }
      .annulus5 {
        transform: translateX(-50%) translateY(-50%) rotateZ(50deg);
      }
      .annulus6 {
        transform: translateX(-50%) translateY(-50%) rotateZ(60deg);
      }
      .annulus7 {
        transform: translateX(-50%) translateY(-50%) rotateZ(70deg);
      }
      .annulus8 {
        transform: translateX(-50%) translateY(-50%) rotateZ(80deg);
      }
      .annulus9 {
        transform: translateX(-50%) translateY(-50%) rotateZ(90deg);
      }
      .annulus10 {
        transform: translateX(-50%) translateY(-50%) rotateZ(100deg);
      }
      .annulus11 {
        transform: translateX(-50%) translateY(-50%) rotateZ(110deg);
      }
      .annulus12 {
        transform: translateX(-50%) translateY(-50%) rotateZ(120deg);
      }
      .annulus13 {
        transform: translateX(-50%) translateY(-50%) rotateZ(130deg);
      }
      .annulus14 {
        transform: translateX(-50%) translateY(-50%) rotateZ(140deg);
      }
      .annulus15 {
        transform: translateX(-50%) translateY(-50%) rotateZ(150deg);
      }
      .annulus16 {
        transform: translateX(-50%) translateY(-50%) rotateZ(160deg);
      }
      .annulus17 {
        transform: translateX(-50%) translateY(-50%) rotateZ(170deg);
      }
      .annulus18 {
        transform: translateX(-50%) translateY(-50%) rotateZ(180deg);
      }
      .annulus19 {
        transform: translateX(-50%) translateY(-50%) rotateZ(190deg);
      }
      .annulus20 {
        transform: translateX(-50%) translateY(-50%) rotateZ(200deg);
      }
      .annulus21 {
        transform: translateX(-50%) translateY(-50%) rotateZ(210deg);
      }
      .annulus22 {
        transform: translateX(-50%) translateY(-50%) rotateZ(220deg);
      }
      .annulus23 {
        transform: translateX(-50%) translateY(-50%) rotateZ(230deg);
      }
      .annulus24 {
        transform: translateX(-50%) translateY(-50%) rotateZ(240deg);
      }
      .annulus25 {
        transform: translateX(-50%) translateY(-50%) rotateZ(250deg);
      }
      .annulus26 {
        transform: translateX(-50%) translateY(-50%) rotateZ(260deg);
      }
      .annulus27 {
        transform: translateX(-50%) translateY(-50%) rotateZ(270deg);
      }
      .annulus28 {
        transform: translateX(-50%) translateY(-50%) rotateZ(280deg);
      }
      .annulus29 {
        transform: translateX(-50%) translateY(-50%) rotateZ(290deg);
      }
      .annulus30 {
        transform: translateX(-50%) translateY(-50%) rotateZ(300deg);
      }
      .annulus31 {
        transform: translateX(-50%) translateY(-50%) rotateZ(310deg);
      }
      .annulus32 {
        transform: translateX(-50%) translateY(-50%) rotateZ(320deg);
      }
      .annulus33 {
        transform: translateX(-50%) translateY(-50%) rotateZ(330deg);
      }
      .annulus34 {
        transform: translateX(-50%) translateY(-50%) rotateZ(340deg);
      }
      .annulus35 {
        transform: translateX(-50%) translateY(-50%) rotateZ(350deg);
      }
      .annulus36 {
        transform: translateX(-50%) translateY(-50%) rotateZ(360deg);
      }
      @keyframes rotate1 {
        0% {
          transform: translateZ(20px) translateX(-50%) translateY(-50%)
            rotateZ(0deg);
        }
        100% {
          transform: translateZ(20px) translateX(-50%) translateY(-50%)
            rotateZ(-360deg);
        }
      }
      @keyframes rotate2 {
        0% {
          transform: translateX(-50%) translateY(-50%) translateZ(30px)
            rotateZ(0deg);
        }
        100% {
          transform: translateX(-50%) translateY(-50%) translateZ(30px)
            rotateZ(360deg);
        }
      }

      @keyframes line1 {
        0% {
          transform: translateY(-220px);
        }
        100% {
          transform: translateY(220px);
        }
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="main1 flex">
        <div class="main2">
          <div class="firstCircle positon center"></div>
          <div class="secondCircle positon center"></div>
          <div class="thirdCircle positon center"></div>
          <div class="fourthCircle flex positon center">
            <div class="annulusContent">
              <div class="annulus annulus1"></div>
              <div class="annulus annulus2"></div>
              <div class="annulus annulus3"></div>
              <div class="annulus annulus4"></div>
              <div class="annulus annulus5"></div>
              <div class="annulus annulus6"></div>
              <div class="annulus annulus7"></div>
              <div class="annulus annulus8"></div>
              <div class="annulus annulus9"></div>
              <div class="annulus annulus10"></div>
              <div class="annulus annulus11"></div>
              <div class="annulus annulus12"></div>
              <div class="annulus annulus13"></div>
              <div class="annulus annulus14"></div>
              <div class="annulus annulus15"></div>
              <div class="annulus annulus16"></div>
              <div class="annulus annulus17"></div>
              <div class="annulus annulus18"></div>
              <div class="annulus annulus19"></div>
              <div class="annulus annulus20"></div>
              <div class="annulus annulus21"></div>
              <div class="annulus annulus22"></div>
              <div class="annulus annulus23"></div>
              <div class="annulus annulus24"></div>
              <div class="annulus annulus25"></div>
              <div class="annulus annulus26"></div>
              <div class="annulus annulus27"></div>
              <div class="annulus annulus28"></div>
              <div class="annulus annulus29"></div>
              <div class="annulus annulus30"></div>
              <div class="annulus annulus31"></div>
              <div class="annulus annulus32"></div>
              <div class="annulus annulus33"></div>
              <div class="annulus annulus34"></div>
              <div class="annulus annulus35"></div>
              <div class="annulus annulus36"></div>
            </div>
          </div>
          <div class="bar positon flex">
            <div class="line line1"></div>
            <div class="line line2"></div>
            <div class="line line3"></div>
            <div class="line line4"></div>
            <div class="line line5"></div>
            <div class="line line6"></div>
            <div class="line line7"></div>
            <div class="line line8"></div>
            <div class="line line9"></div>
            <div class="line line10"></div>
            <div class="line line11"></div>
          </div>
        </div>
      </div>
    </div>

    <script>
      var elem = document.querySelector('.main1')
      var isDragging = false // 用於判斷是否正在拖動
      var initialX = 0 // 初始滑鼠X坐標
      var initialY = 0 // 初始滑鼠Y坐標
      var currentX = 0 // 當前滑鼠X坐標
      var currentY = 0 // 當前滑鼠Y坐標
      var initialRotationY = 0 // 初始旋轉角度(Y軸)
      var initialRotationX = 0 // 初始旋轉角度(X軸)

      elem.addEventListener('mousedown', function (e) {
        // 當滑鼠按下時
        initialY = e.clientY // 獲取初始滑鼠Y坐標
        initialRotationY = parseInt(
          getComputedStyle(elem)
            .getPropertyValue('transform')
            .replace(/[^0-9-.,]/g, '')
            .split(',')[4]
        ) // 獲取初始旋轉角度(Y軸)
        initialRotationX = parseInt(
          getComputedStyle(elem)
            .getPropertyValue('transform')
            .replace(/[^0-9-.,]/g, '')
            .split(',')[5]
        ) // 獲取初始旋轉角度(X軸)
        isDragging = true // 設置isDragging為true,表示正在拖動
      })

      document.addEventListener('mousemove', function (e) {
        // 當滑鼠移動時
        if (isDragging) {
          // 如果正在拖動
          currentY = e.clientY // 獲取當前滑鼠Y坐標
          var dy = currentY - initialY // Y軸方向移動的距離
          var newRotationY = initialRotationY + dy * -1 // 根據移動方向計算新的旋轉角度(Y軸)
          console.log(111, dy)

          elem.style.transform = 'rotateX(' + newRotationY + 'deg)' // 設置元素的旋轉角度
        }
      })

      document.addEventListener('mouseup', function () {
        // 當滑鼠鬆開時
        isDragging = false // 設置isDragging為false,表示已經停止拖動
      })
    </script>
  </body>
</html>

本文轉載於:

https://juejin.cn/post/7271070291689750582

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • linux內核為用戶態進程提供了一組IO相關的系統調用: select/poll/epoll, 這三個系統調用功能類似, 在使用方法和性能等方面存在一些差異. 使用它們, 用戶態的進程可以"監控"自己感興趣的文件描述符, 當這些文件描述符的狀態發生改變時, 比如可讀或者可寫了, 內核會通知進程去處理... ...
  • [toc] # Linux運維工程師面試題(1) > 祝各位小伙伴們早日找到自己心儀的工作。 > 持續學習才不會被淘汰。 > 地球不爆炸,我們不放假。 > 機會總是留給有有準備的人的。 > 加油,打工人! ## 1 別名、內部命令、外部命令的執行順序 命令執行尋找順序:別名 > 內部命令 > 外部命 ...
  • IN 和 EXISTS 是 SQL 中的兩種子查詢操作符,它們都可以用來測試一個值或一組值是否在子查詢的結果集中。然而,它們在某些情況下的性能和語義上有所不同,因此在不同的使用場景中可能會選擇不同的操作符。 IN:IN 操作符用於測試一個值是否在一組值中。它通常用於處理靜態的值列表或返回列的子查詢。 ...
  • 本文分享自華為雲社區《【如何保證你的DWS數據更安全】使用DWS集群,用戶被鎖定如何解鎖?》,作者:Shirley_Dou 。 一、管理員用戶被鎖定,怎麼破?gsql: FATAL: The account has been locked. 1、重置集群密碼可自動解鎖,在集群管理頁面,找到對應集群重 ...
  • 當時買了一臺Windows Server伺服器,然後安裝上SQL Server後,想通過外網訪問到資料庫,遇到了一些問題,查了很多資料也踩了很多坑。本文主要介紹如何配置SQL Server遠程連接?如何新增管理員用戶等。 ...
  • ## 簡介 [CloudCanal](https://www.clougence.com?kw=cnblogs_20230825) 近期發佈了 [GaussDB for MySQL](https://www.huaweicloud.com/product/gaussdbformysql.html)和 ...
  • 本文分享自華為雲社區《華為雲GES:十年磨一劍,打造業界一流的雲原生分散式圖資料庫》,作者:GES圖引擎服務小圖 。 1、淺談雲原生圖資料庫 圖資料庫(graph database)是一個使用圖結構進行語義查詢的資料庫,它使用節點、邊和屬性來表示和存儲數據。該系統的關鍵概念是圖,它直接將存儲中的數據 ...
  • **塑造軟體新生態,賦能發展新變革。** **8月31日-9月2日**,第二十五屆**中國國際軟體博覽會**將於天津梅江會展中心召開。本屆軟博會由中國電子信息行業聯合會主辦,聚焦全球軟體前沿技術與產業發展方向,充分展示軟體賦能數字經濟、信息技術應用創新、工業互聯網平臺、智能製造及元宇宙等多領域發展成 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...