這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 最近有一個需求,要我實現一個動畫效果,效果如下 簡單分析了一下效果,是一個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
來指定起始位置,例如45deg
或from left
.color-stop
:顏色停止點,定義漸變的顏色和位置。
這裡我們把其他地方都設置為透明,只在4%的範圍內設置顏色,這樣會得到一個扇形。
mask
mask
是一個 CSS 屬性,用於創建遮罩效果,即在元素上應用一個遮罩圖像或圖像源,以控制元素的可見性。它可以讓你根據遮罩圖像的不透明度來決定元素的哪些部分是可見的,哪些部分是隱藏的。
mask
屬性有兩種主要用法:
- 使用圖像作為遮罩:
.masked-element { mask: url("mask-image.png"); }
這將使 .masked-element
元素的內容受到 mask-image.png
圖像的遮罩影響。圖像的不透明部分將允許元素內容顯示,而圖像的透明部分將隱藏元素內容。
- 使用線性漸變或徑向漸變作為遮罩:
.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-side
、farthest-side
、closest-corner
、farthest-corner
或一個長度值。[position]
定義漸變的中心位置,可以使用關鍵字(如center
、top 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>