这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

最近有一个需求,要我实现一个动画效果,效果如下

简单分析了一下效果,是一个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是鼠标上下拖动时候会翻转。

            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);        }      }            
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,表示已经停止拖动 })

本文转载于:https://juejin.cn/post/7271070291689750582如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。