css动画、过渡、变换、常用函数等介绍

301 阅读20分钟

前言

开发过程中,我们可能会有碰到变换、动画等特殊效果,这边文章将带大家进入 css 动画 和一些特殊效果的世界,小小游遨游一下,主要介绍 css 的 变换、过渡、常用函数、keyframes关键帧动画

参考地址:mdn菜鸟

变换 transform

transfrom 表示图形的变换,常见的 平移、缩放、旋转(2d中还有一个倾斜),有2d和3d,毋庸置疑3d多了一个z轴概念,垂直屏幕向外,可以根据实际情况变换

translate、translate3d:平移变换,参数分别是朝着某个轴方向x、y、z平移的值(3d的才有z), translate(30px, 0) 指的是x方向平移30px,此外还有单个方向的 translateX、translateY、translateZ

scale、scale3d:这个是缩放变换,分别朝着某个轴方向进行缩放 x、y、z分别对应我们的长、宽、高,一般我们就长宽 x、y 就够了,scale(2, 0),表示x方向变为原来两倍,也就是我们视图的长宽会发生对应比例的变化,1为一倍、其也有 scaleX、scaleY、scaleZ

rotate、rotate3d:旋转变换,自然离不开角度,单位deg,由于rotate函数为2d,其偏向于平面,因此只能按照中心点z轴方向旋转,例如:rotate(30deg),rotate(666turn), deg为度数,turn为转数rotate3d3d函数,也是三个轴的方向,这个和前面不太一样了,需要我们有立体的思维才能作出我们想要的效果,因为无论是x、y、z轴旋转都是会让我们看到饶中心轴线变换的效果,可以同时设置多个参数,rotateX、rotateY、rotateZ

skew:这个是2d的倾斜效果,平时也许用得到,默认可以形成平行四边形,可以通过我们的逻辑将其转化成更加复杂的图形,可以变成梯形哈

matrix、perspective:分别是变换矩阵和投影透视视图(3d),平时用的少,可以自己研究哈,这个需要对图像再多一些了解,投影透视可以让我们的视图更有3d效果

//举个例子吧,直接同时上两个变换,需要注意的是变换顺序会影响变换效果
transform: rotate(30deg) translate(100px, 0px);
/*IE*/
-ms-transform: rotate(30deg)  translate(100px, 0px);
/*Safari 和 Chrome:*/
-webkit-transform: rotate(30deg  translate(100px, 0px));

实际上有了 autoprefixer 之后,就编写一个标准的就行了,这个会自动兼容,webpack、vite 都可配置

过渡 transition

这个过渡动画可以说是属性过渡动画,当涉及到更改自身元素的属性效果变换时,位置、缩放、旋转、颜色等自身属性变化时都会形成比较常见的基础动画(当然自身变化也是有不支持的,例如我们复杂的背景颜色和奇形怪状,有些它也不知道该怎么过渡,那种需要我们后续的动画来改变了),变换属性也支持动画,也用的挺多

ps:需要注意的是他是过渡动画,不存在初始化动画,除非等他初始化后,单独更改他的后续属性

一共有下面几个参数

transition: width 1s linear 1s; //混合属性,分别是后面四个属性,可以只填写属性名称和时间
transition-property: width;  //过渡属性名称
transition-duration: 1s; //动画过渡时长
transition-timing-function: linear; //动画曲线(涉及匀速和变速规则)
transition-delay: 1s; //延迟时长

动画类型有下面这些,可以自行尝试,一般 linear 线性变换就足够了,ease-in-out 慢入慢出基本能满足条件

/* Keyword values */
transition-timing-function: ease;
transition-timing-function: ease-in;
transition-timing-function: ease-out;
transition-timing-function: ease-in-out;
transition-timing-function: linear;
transition-timing-function: step-start;
transition-timing-function: step-end;

/* Function values */
transition-timing-function: steps(4, jump-end);
transition-timing-function: cubic-bezier(0.1, 0.7, 1, 0.1);

/* Steps Function keywords */
transition-timing-function: steps(4, jump-start);
transition-timing-function: steps(10, jump-end);
transition-timing-function: steps(20, jump-none);
transition-timing-function: steps(5, jump-both);
transition-timing-function: steps(6, start);
transition-timing-function: steps(8, end);

/* Multiple timing functions */
transition-timing-function: ease, step-start, cubic-bezier(0.1, 0.7, 1, 0.1);

/* Global values */
transition-timing-function: inherit;
transition-timing-function: initial;
transition-timing-function: revert;
transition-timing-function: revert-layer;
transition-timing-function: unset;

常用函数

calc、max、min

calc() 函数是我们 css 中计算数值之类的函数,可以更方便我们计算实际数值,例如:height:calc(100vh-24px)

max()、min(),跟 math库的类似,传递参数用一个 , 隔开,分别取最大、最小值

cubic-bezier

贝塞尔曲线,这个在很多开发都能听到,绘制图形中比较常见,在css 中比较常见的就是动画、过渡曲线了

通过贝塞尔曲线能控制动画的快慢

例如: animation-timing-function、transition-timing-function

//分别是两个控制点的坐标,但是 x1、x2最大为1,y没限制,但一般不会太大或太小,他们的位置会影响曲率
cubic-bezier(x1, y1, x2, y2)

//随便举个使用案例
animation-timing-function: cubic-bezier(0.1, 0.7, 1.0, 0.1)
transition-timing-function: cubic-bezier(0.1, 0.7, 1.0, 0.1)

做一个简易抛物线

//css
.paowuxian {
    ...
    //中间两个控制点,由于控制点是负数,因此实际距离变长,时间固定,y方向速度会比默认快,且会有反向效果,类似弹性动画,可以多次尝试调节
    transition: 0.5s cubic-bezier(0.5, -0.5, 1.0, 1.0);
}

//js
//从一个对角到另外一个对角,设置贝塞尔曲线,则可以形成抛物线形状
//如果是liner则是x、y同时进行,就是执行右上角到左下角,明显不对
//使用贝塞尔曲线,从
初始位置
transform: translate(200px, 0)

//结束位置
transform: translate(0, 200px)

linear-gradient、conic-gradient、radial-gradient

这三个分别是图像过渡函数,分别是线性方式过渡、圆锥方式过渡、半径过渡,其中用的最多的就是 linear-gradient 了,其次才是 conic-gradientradial-gradient

linear-gradient

线性方式过渡渐变,这也是最常用的一个函数了,平时开发基本上都会用到(哪些只会在蓝湖上粘的,这里也许能有所帮助,个人现在有时也是粘的,毕竟快😂)

我们经常用它来设置 background-image、background 简洁而又方便(至少比起移动原生开发代码少太多太多了)

第一个参数不填写,默认从上到下, 填写 0deg 则是从下到上(to top),90deg则是顺时针从左到右(to right),还能直接使用 to + 方位 的形式,

第一个参数方向选填,后面则是颜色集合,逗号(,)隔开,可以理解为这是一个归一化函数

//默认是从上到下
background-image: linear-gradient(red, yellow, blue);

//也可以设置过渡位置颜色百分比
background-image: linear-gradient(red 20%, yellow 40%, blue 100%);

//0deg 是从下到上
background-image: linear-gradient(0deg, red, yellow, blue);

//90deg 是顺时针变成从左到右了,180deg也就是从上到下了
background-image: linear-gradient(90deg, red, yellow, blue);

//更多的人是写方向
background-image: linear-gradient(to right, red, yellow, blue);
//也可以额外加上一个方向,由于是线性一端到另外一端,给定一个目标方向,就确定实际轨迹了
background-image: linear-gradient(to right bottom, red, yellow, blue);

下面是一个 linear-gradient(to right, red, yellow, blue) 效果

QQ_1732167191021.png

conic-gradient

圆锥方式过渡渐变,做进度条一类的功能比较常用,其他用的比较少

我们也是用它来设置 background-image、background 简洁而又方便

//这个比上面稍复杂一点,但是也很简单,就是第一个参数除了弧度,就是 position了
// 后面的参数也可以设置过渡百分比、度数
background-image: conic-gradient([from angle] [at position], color degree, color degree, ...);

先看一个默认效果,使用默认的一个圆锥过渡 conic-gradient(red 0%, yellow 50%, blue 100%),再加上一个 border-radius 就这样了(不设置百分比,也是如此,平均过渡罢了)

QQ_1732167802465.png

实际上上面的效果就相当于是

//第一个参数不填写,可以理解为就是默认的 from 0 效果
conic-gradient(from 0%, red 0%, yellow 50%, blue 100%)
//不设置百分比就是平均过渡
conic-gradient(red, yellow, blue)

第一个参数 [from angle] [at position]

  • [from angle] 表示初始旋转角度,默认指向顶部,顺时针旋转(逆时针的话,后面参数倒过来就行了),例如:conic-gradient(from 90deg, red 0%, yellow 50%, blue 100%),表示顺时针旋转 90°
  • [at position] 表示中心店位置,这个就不多说了,可以百分比,也可以数值,一般不在中心可能没那么好看,当一个里面有其他渐变效果也许就不一样了

后面颜色百分比 color degree,表示的是过渡颜色占比,都是渐变的

  • color xx%表示对应百分比位置的颜色,到其他百分比之间都是会逐渐过渡过去 例如:conic-gradient(red 0%, yellow 50%, blue 100%)
  • color deg 表示对应弧度位置的颜色,实际上 360deg 就是 100%,这个对应关系就是这么直接,一般直接百分比就可以了,不想计算就 deg, 例如:conic-gradient(red 0, yellow 180deg, blue 360deg)

radial-gradient

以圆形半径方式过渡渐变

我们也是用它来设置 background-image、background 简洁而又方便

//第一个参数分别是 shape、size、position,下面介绍默认值,后面的是颜色,百分比和conic-gradient一样不多介绍
background-image: radial-gradient(shape size at position, start-color, ..., last-color);
  • shape 确定圆的类型:
    • ellipse (默认): 指定椭圆形的径向渐变。
    • circle :指定圆形的径向渐变
  • size 定义渐变的大小,可能值:(由于默认是到方块最远角落,所以圆形效果过渡百分比不自然,设置到 farthest-side 即可,这才是内切圆的实际过渡半径)
    • farthest-corner (默认) : 指定径向渐变的半径长度为从圆心到离圆心最远的角
    • closest-side :指定径向渐变的半径长度为从圆心到离圆心最近的边
    • closest-corner : 指定径向渐变的半径长度为从圆心到离圆心最近的角
    • farthest-side :指定径向渐变的半径长度为从圆心到离圆心最远的边
  • position 定义渐变的位置,可能值:
    • center(默认):设置中间为径向渐变圆心的纵坐标值。
    • top:设置顶部为径向渐变圆心的纵坐标值。
    • bottom:设置底部为径向渐变圆心的纵坐标值。

我们来一组均分效果

//由于默认是到方块最远角落,所以圆形效果过渡百分比不自然,设置到  farthest-side 即可,这才是内切圆的实际过渡半径
//我们顺道设置一下 shape: circle, position: center
background: radial-gradient(circle farthest-side at center, red, yellow, blue);

QQ_1732254409870.png

百分比就不演示了,跟 conic-gradient 类似,只不过这个是从中心径变到边缘(角落)

突变百分比、固定过渡色百分比(linear、conic、radial都有)

conic-gradient仅仅看前面的,不多测试肯定做不到,实际上其这个百分比颜色点设置很关键,可以通过特殊百分比设置突然渐变实现截断效果,而不是颜色过渡,如下所示

conic-gradient(red 0%, red 30%, yellow 30%, yellow 60%, blue 60%, blue 100%)

效果如下所示,这种同一百分比突然变色、固定百分比渐变色效果,是不是意想不到,这样是不是很像饼图了呢,如果中间盖住,是不是就像圆形进度条、饼图,再加上白色、透明色效果,是不是更像了呢,实际上前面或者后续文章 肯定会有介绍的哈,可以查看或者期待,了解了总会有应用上的一天😂

QQ_1732253204954.png

conic-gradient + radial-gradient 做环形效果

有时我们会使用 conic-gradient(background-image) + radial-gradient(mask) 实现一个环形进度条,如下所示,只需要两行代码(动起来的话,需要更多了)

 //后面百分比如果设置百分比颜色是透明,是不是就是进度条了呢🤣
background: conic-gradient(red, yellow, blue);
//mask也不是所有平台或者版本都支持的哈
mask: radial-gradient(circle farthest-side at center,transparent, transparent 80%, #000 80%, #000 100%);

QQ_1732255488020.png

ps: 需要注意的是不是在所有平台都支持这个 mask,必要的话,中心就别透明了,盖上一个好看效果就完事了,需要加动画的话,就通过变量不停更新进度条百分比就行了

repeating-linear-gradient、repeating-radial-gradient、repeating-conic-gradient

重复渐变效果前面的可重复版本

仅仅是重复排列的 linear-gradient、radial-gradient、conic-gradient 罢了,除了设置百分比,还可以设置实际大小 px,唯一的区别是不设置满,其可以设重复平铺,这对于需要重复平铺的效果,挺重要的

例如:斑马线、光栅格子、彩环、波纹 等等,这些重复函数能解决不少问题(例如:我们前面用的 backgroud-size + backgroundRepeat 编写的 连续格子状背景(光栅格子),实际上也可以用这个合并为一个),代码差不多,多一种手段总是好的

举个简单使用的例子

//这就是一个重复的格子
//设置一个百分比的
background-image: repeating-linear-gradient(to right, blue 0%, blue 5%, transparent 5%,  transparent 10%);
//设置一个固定 px 的
background-image: repeating-linear-gradient(to right, blue 0%, blue 10px, transparent 10px, transparent 20px);

QQ_1732257266133.png

常见的形状函数

常见的二维图形,如:多边形、圆形、椭圆、扇形等,了解他们之前我们简单了解使用他们的css属性

常见的就是 mask、clip-path、shape-outside、overflow了

  • mask 属性使用 SVG 图像或 CSS 渐变作为遮罩来裁剪元素内容
  • clip-path 属性允许你定义更复杂的裁剪形状,包括圆形、椭圆形、多边形等。它用于“修剪”元素,创建一个遮罩在其上方,覆盖不想显示的部分。它不影响周围元素如何浮动(它们仍然有一个边框作为参考)
  • shape-outside 在该元素周围创建一个不可见的图层,不会剪切元素或影响其外观,使其具备影响周围浮动元素的能力(周围浮动元素会以 shape-outside 设置的自定义形状作为参考,典型的富文本环绕效果)
  • overflow 通过设置元素的 overflow 属性为 hidden,可以隐藏超出元素框的内容。虽然这不会创建一个裁剪区域,但可以达到类似的效果、border-radius 也类似

你可能觉得他们平时没啥用,当需要特殊形状,或者作出一些动画的时候,就知道有多棒了,例如:剪裁一张图片,从中间一张点原型方式过渡到全局,能想象到一张什么动画效果么,没错,就是扩散效果,反之就是聚拢效果

ps:之前刷到一个地址,可以自己设置剪裁的效果,避免手写,参考地址

inset(矩形-方块内边距方式)

inset 设置矩形,其根据原本元素内部偏移进行剪裁的,其参数就行 padding 类似,只不过后面多了个 round 圆角罢了

//这就是四条边向内缩小10px 的矩形
clip-path: inset(10px)

//这就是四条边向内缩小10px的圆形
clip-path: inset(10px round 50%)

//这就是四条边向内缩小10%的圆形
clip-path: inset(10% round 50%)

//上下缩小 10% 左右缩小 20%,这个就跟 padding 属性差不多了
clip-path: inset(10% 20%)

circle

circle 设置圆形,其可以通过半径方式中心位置设置圆的信息,还记得 radial-gradient 么,只能说有点类似了

`circle( radius? at position? )`

circle函数最多接受两个参数,且选填,positon 前面需要加上 at

  • radius 定义半径的大小,默认 50%,只有一个参数
    • closest-side :指定径向渐变的半径长度为从圆心到离圆心最近的边
    • farthest-side :指定径向渐变的半径长度为从圆心到离圆心最远的边
    • 指定值: 100px 或 50%
  • position 定义渐变的位置 x,y 可设置 px 或 百分比,例如:100px 100px 或者 50% 50%,少填写就是 50%

什么都不填写默认就是一个圆了,到最短边

//默认填满的内切圆
clip-path: circle();

QQ_1732260698514.png

//随便用一下
clip-path: circle(40% at 50% 50%);

ellipse

ellipse 椭圆函数,其和 circle 原型函数类似,学过数学的都知道,圆实际上是特殊的椭圆,也就是这个可以代替圆形函数(实际怎么使用都行😂)

`ellipse( radius-x? radius-y? at position? )`

ellipse最多接受两个参数,且选填,positon 前面需要加上 at,并且有两个半径,分别是x方向,y放行

  • radius 需要分别设置 x、y方向半径的大小,默认都是 50% 填充两边
    • closest-side :指定径向渐变的半径长度为从圆心到离圆心最近的边
    • farthest-side :指定径向渐变的半径长度为从圆心到离圆心最远的边
    • 指定值: 100px 50px 或 50% 50%
  • position 定义渐变的位置 x,y 可设置 px 或 百分比,例如:100px 100px 或者 50% 50%,少填写就是 50%

什么都不填写默认就是一个椭圆了,分别填充满 x、y 方向,算是一个“内切椭圆”了吧😂

//默认填充满的“内切椭圆”
clip-path: ellipse();

QQ_1732261212753.png

//随便用一下,根据情况填充,一般使用默认的比较多
clip-path: ellipse(100px 50px at 50% 50%);

polygon

polygon 典型的多边形,参数是由无数组点坐标组成的,两点一线,以你最少三组坐标,才能形成最小的多边形-三角形

下面我们就创建一个矩形吧

//多边形,不多说了,无数个用逗号隔开的x、y坐标,这就是一个标准的就行了
//只不过和默认框一样大小罢了,像是没剪裁是的
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%) 

QQ_1732261759300.png

css动画(animation)

css animation 动画需要设置 @keyframes,其又叫关键帧动画,可以通过 keyframes 来让我们创建好的效果动起来,animation 动画也可以理解为初始动画

ps:有人会说 transition 不是也能做动画么,还要 keyframes 干甚,毕竟 transition 为过渡动画,自然是过渡使用的,默认是不会触发的,你想怎么刚创建元素后初始动画呢,自然需要 animation 了

ps2:实际上 animation、和 transition 使用的都是属性动画,都是必须要 css 支持动画的属性设置才有效果

css支持过渡的属性有很多,大多数平常使用的都支持(还有设置函数值的一般不支持哈),参考这里

animation 可以设置比 transition 更细腻的效果,下面使用后,基本就可以自行理解了

keyframes

先看看 keyframes 的 css 效果,其中 from、to 表示属性开始样式、结束样式, 后面的是需要过渡动画的属性(css支持东海的属性才会有动画), 设置后自然会从开始效果过渡到结束效果

@keyframes mymove {
    from {background-color:red;}
    to {background-color:blue;}
}
 
/*Safari 和 Chrome:*/ 用了补全插件就不用了
@-webkit-keyframes mymove {}

除了这种两点一线效果,还有更复杂的过渡效果,那么就可以将 from、to 变成 百分比了,除了百分比也可以同时变换多个属性

@keyframes mymove {
    0% { background-color:red; } //可以变换多个属性,就不多写了
    40% { background-color:blue; }
    65% { background-color:gray; }
    100% { background-color:green; }
}

animation 的 css 属性

keyframes aimation 为初始动画,也属于使用属性动画范畴,因此也要利用 css,才能实现我们的效果,除了设置关键帧的过渡属性,还要设置我们的动画过渡属性,也就是时长、曲线之类的

  • animation-name: 动画名字
    • animation-name: move-keyframes;
  • animation-duration: 动画时间
    • animation-duration: 1s;
  • animation-timing-function: 动画过渡曲线,使用会有提示,也可以使用 cubic-bezier 函数设置曲线
    • 默认使用例子:animation-timing-function: linear;
  • animation-delay: 延迟播放,animation-delay: 1s;
  • iteration-count: 动画播放次数,默认为 1 ,也就是一次,比较常用,infinite 是一直播放,
    • animation-iteration-count: infinite;
  • animation-direction: 动画播放方向,前两个用的多
    • normal:默认值, 动画正常播放
    • reverse:动画反向播放,
    • alternate:动画在奇数次(1、2、5…)正向播放,在偶数次(2、4、6…)反向播放
    • alternate-reverse:动画在奇数次(1、3、5…)反向播放,在偶数次(2、4、6…)正向播放
  • animation-fill-mode:
    • none 默认值。:动画在动画执行之前和之后不会应用任何样式到目标元素;
    • forwards:在动画结束后(由 animation-iteration-count 决定),动画将应用该属性值;
    • backwards:动画将应用在 animation-delay 定义期间启动动画的第一次迭代的关键帧中定义的属性值。这些都是 from 关键帧中的值(当 animation-direction 为 “normal” 或 “alternate” 时)或 to 关键帧中的值(当 animation-direction 为 “reverse” 或 “alternate-reverse” 时);
    • both 动画遵循 forwards 和 backwards 的规则。也就是说,动画会在两个方向上扩展动画属性。
  • animation-play-state: 指定动画是否正在运行或已暂停,paused:指定暂停动画,running:指定正在运行的动画,该属性也可以控制动画运行
    • 有时会使用该属性作出高级动画效果,提前设置好动画,默认 paused,通过 hover 效果设置其为 running, 以此控制动画启动和暂停,例如:轮播图hover的旋转和离开后的暂停

ps:看了上面的属性,只要你有想法,就能作出意想不到的效果,基础就那么点,好的效果全靠人的思维,一个小小的属性,能引发巨大的观感,这也是动画的魅力之处

配合css变量做一个简易的动画

下面做一个简易的初始扩大 width 的动画,配合 css 变量

@keyframes move-keyframes
{
    from {width: 0}
    to {width: var(--ydqdperc);}
}

const getPercStyles = (perc: number) => ({
    "--ydqdperc": `${perc}%`,
});

style={{
    ...getPercStyles(item.perc),
    width: `${item.perc}%`,
    backgroundImage:
        "linear-gradient(90deg, #20A6FF 50%, transparent 0)",
    backgroundSize: "10px 100%",
    backgroundRepeat: "repeat",
    animationName: "move-keyframes",
    animationDuration: "1s",
    animationTimingFunction: "linear",
    transition: "width, 1s", //再加上个过渡动画吧
}}

最后

css 常见属性很多,但是很多属性我们用不到,即使是我们经常用到的属性,很多也可能没我们想象的用的那么灵活,更好的理解这些属性,打好基础,也许某一天碰到某一个场景,就是我们思维发光的时刻 🤔