前言
开发过程中,我们可能会有碰到变换、动画等特殊效果,这边文章将带大家进入 css 动画 和一些特殊效果的世界,小小游遨游一下,主要介绍 css 的 变换、过渡、常用函数、keyframes关键帧动画
变换 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为转数
。 rotate3d
3d函数,也是三个轴的方向,这个和前面不太一样了,需要我们有立体的思维才能作出我们想要的效果,因为无论是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-gradient
、radial-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)
效果
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
就这样了(不设置百分比,也是如此,平均过渡罢了)
实际上上面的效果就相当于是
//第一个参数不填写,可以理解为就是默认的 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);
百分比就不演示了,跟 conic-gradient
类似,只不过这个是从中心径变到边缘(角落)
突变百分比、固定过渡色百分比(linear、conic、radial都有)
conic-gradient
仅仅看前面的,不多测试肯定做不到,实际上其这个百分比颜色点设置很关键,可以通过特殊百分比设置突然渐变实现截断效果,而不是颜色过渡,如下所示
conic-gradient(red 0%, red 30%, yellow 30%, yellow 60%, blue 60%, blue 100%)
效果如下所示,这种同一百分比突然变色、固定百分比渐变色
效果,是不是意想不到,这样是不是很像饼图了呢,如果中间盖住,是不是就像圆形进度条、饼图
,再加上白色、透明色效果,是不是更像了呢,实际上前面或者后续文章
肯定会有介绍的哈,可以查看或者期待,了解了总会有应用上的一天😂
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%);
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);
常见的形状函数
常见的二维图形,如:多边形、圆形、椭圆、扇形等,了解他们之前我们简单了解使用他们的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();
//随便用一下
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();
//随便用一下,根据情况填充,一般使用默认的比较多
clip-path: ellipse(100px 50px at 50% 50%);
polygon
polygon
典型的多边形,参数是由无数组点坐标组成的,两点一线,以你最少三组坐标,才能形成最小的多边形-三角形
下面我们就创建一个矩形吧
//多边形,不多说了,无数个用逗号隔开的x、y坐标,这就是一个标准的就行了
//只不过和默认框一样大小罢了,像是没剪裁是的
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%)
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 常见属性很多,但是很多属性我们用不到,即使是我们经常用到的属性,很多也可能没我们想象的用的那么灵活,更好的理解这些属性,打好基础,也许某一天碰到某一个场景,就是我们思维发光的时刻 🤔