变形动画
基础知识
CSS 提供的变形动作。
选项 | 说明 |
---|---|
none | 定义不进行转换。 |
translate(x,y) | 定义 2D 转换。 |
translate3d(x,y,z) | 定义 3D 转换。 |
translateX(x) | 定义转换,只是用 X 轴的值。 |
translateY(y) | 定义转换,只是用 Y 轴的值。 |
translateZ(z) | 定义 3D 转换,只是用 Z 轴的值。 |
scale(x,y) | 定义 2D 缩放转换。 |
scale3d(x,y,z) | 定义 3D 缩放转换。 |
scaleX(x) | 通过设置 X 轴的值来定义缩放转换。 |
scaleY(y) | 通过设置 Y 轴的值来定义缩放转换。 |
scaleZ(z) | 通过设置 Z 轴的值来定义 3D 缩放转换。 |
rotate(angle) | 定义 2D 旋转,在参数中规定角度。 |
rotate3d(x,y,z,angle) | 定义 3D 旋转。 |
rotateX(angle) | 定义沿着 X 轴的 3D 旋转。 |
rotateY(angle) | 定义沿着 Y 轴的 3D 旋转。 |
rotateZ(angle) | 定义沿着 Z 轴的 3D 旋转。 |
skew(x-angle,y-angle) | 定义沿着 X 和 Y 轴的 2D 倾斜转换。 |
skewX(angle) | 定义沿着 X 轴的 2D 倾斜转换。 |
skewY(angle) | 定义沿着 Y 轴的 2D 倾斜转换。 |
perspective(n) | 为 3D 转换元素定义透视视图。 |
perspective-origin | 透视位置 |
行级元素
行级元素不产生变形效果,将其转为 inline-block
或 block
以及弹性元素时都可以产生变化效果。
移动元素
translate
使用 translate
可以控制按 X、Y 同时移动操作,第一个值控制 X 移动,第二个值控制 Y 移动。
元素居中
居中可以使用多种方式,如弹性布局、定位操作,下面来看使用移动操作居中。
div{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
translateZ
控制 Z 轴移动,正数向外、负数向里移动。因为 Z 轴是透视轴没有像 X/Y 一样的固定尺寸,所以不能使用百分数。
缩放元素
scale
使用 scale
可同时设置 X/Y
轴的缩放,如果只设置一个值时表示两轴缩放相同。
使用数值定义缩放,如 .5 表示缩小一半,2 表示放大两倍。
scaleZ
沿 Z 轴缩放元素,需要有 3D 透视才可以查看到效果。
旋转操作
旋转放心遵循左手定则,即大拇指指向坐标轴正向,手握方向为正向,反之为负向。
rotate
在 X 与 Y 轴平面旋转,效果与使用 rotateZ
相同。可以是deg
,也可以是turn
1turn=360。
rotate3d
同时设置 X/Y/Z 轴的旋转向量值来控制元素的旋转。
需要同时设置如下四个参数
rotate3d(tx,ty,tz,angle)
综合案例
<style>
main.love-tranform-clock {
margin: 50px;
position: relative;
width: 400px;
height: 400px;
border-radius: 50%;
background: #34495e;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
background: radial-gradient(at right, #27ae60, #e67e22, #e74c3c, #e67e22, #27ae60);
transform: scale(1.2);
z-index: -1
}
.line {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
transform: translate(-50%, -50%);
display: flex;
justify-content: center;
align-items: center;
&::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
border-radius: 50%;
background: #34495e;
transform: translate(-50%, -50%) scale(0.85);
}
&>div {
width: 2px;
height: 20px;
background-color: #fff;
position: absolute;
top: 50%;
left: 50%;
width: 10px;
height: 95%;
transform: translate(-50%, -50%);
&:nth-child(1) {
transform: translate(-50%, -50%) rotate(30deg);
}
&:nth-child(2) {
transform: translate(-50%, -50%) rotate(60deg);
}
&:nth-child(3) {
transform: translate(-50%, -50%) rotate(90deg);
}
&:nth-child(4) {
transform: translate(-50%, -50%) rotate(120deg);
}
&:nth-child(5) {
transform: translate(-50%, -50%) rotate(150deg);
}
&:nth-child(6) {
transform: translate(-50%, -50%) rotate(180deg);
}
}
}
.hour {
position: absolute;
left: 50%;
bottom: 50%;
width: 15px;
height: 25%;
background-color: #95a5a6;
transform: translate(-50%, 0);
}
.minute {
position: absolute;
left: 50%;
bottom: 50%;
width: 8px;
height: 30%;
background-color: #3498db;
transform: translate(-50%, 0) rotate(30deg);
transform-origin: bottom center;
}
.second {
position: absolute;
left: 50%;
bottom: 50%;
width: 4px;
height: 40%;
background-color: #c5dd13;
transform: translate(-50%, 0) rotate(120deg);
transform-origin: bottom center;
transition: 10s linear;
}
.point {
position: absolute;
top: 50%;
left: 50%;
width: 20px;
height: 20px;
background-color: #f00;
border-radius: 50%;
transform: translate(-50%, -50%);
}
&:hover .second {
transform: translate(-50%, 0) rotate(360deg);
}
}
</style>
<main class="love-tranform-clock">
<section class="line">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
<div class="hour"></div>
<div class="minute"></div>
<div class="second"></div>
<div class="point"></div>
</main>
倾斜操作
默认情况下倾斜变形的参考点为图形正中心位置,即矩形中心。
skew
同时设置 X/Y 轴倾斜操作,不指定第二个参数时 Y 轴倾斜为零。
skew(x) = skewX(x)
变形基点
使用 transform-origin
设置元素的 X/Y/Z 操作的基点,用于控制旋转、倾斜等操作。
- 元素移动不受变形基点所影响
- 基点是元素原始空间位,而不是 translate 移动后的空间位
元素变形或偏移原点关键字所代表的值,默认的转换原点是 center
keyword | value |
---|---|
left | 0% |
center | 50% |
right | 100% |
top | 0% |
bottom | 100% |
新年贺卡
源代码
<style>
.love-transform-card {
margin: 120px;
width: 300px;
height: 200px;
background: #e67e22;
display: flex;
justify-content: center;
align-items: center;
font-size: 3em;
color: whitesmoke;
position: relative;
transform-style: preserve-3d;
transform: perspective(600px) rotateX(35deg) rotateY(15deg);
&::before,
&::after {
transition: 1s;
background: #e74c3c;
line-height: 4em;
backface-visibility: visible;
}
&::before {
content: '新年';
width: 150px;
height: 100%;
left: 0px;
top: 0;
text-align: right;
position: absolute;
transform-origin: left;
}
&::after {
content: '快乐';
width: 150px;
height: 100%;
right: 0px;
top: 0;
position: absolute;
transform-origin: right;
}
&:hover::before {
transform: rotateY(-170deg);
}
&:hover::after {
transform: rotateY(170deg);
}
}
</style>
<div class="love-transform-card">I Love You</div>
变形顺序的影响
先旋转后移动, 旋转就是参考原来位置的
先移动后旋转, 旋转是参考移动后的位置的
圆圈
<style>
ul.love-transform-circle {
width: 200px;
height: 200px;
background: #ffc00d;
opacity: 0.5;
border-radius: 50%;
position: relative;
transition: 1s;
li {
position: absolute;
top: 50px;
left: 50px;
width: 80px;
height: 80px;
background: pink;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
transition: all 0.5s ease-in-out;
transform-origin: 150px 150px;
transition: 0.5s;
opacity: 0;
}
&:hover li {
top: -50px;
left: -50px;
opacity: 1;
}
&:hover li:nth-child(1) {
transform: rotate(40deg);
}
&:hover li:nth-child(1)>span {
transform: rotate(1040deg);
}
&:hover li:nth-child(2) {
transform: rotate(80deg);
}
&:hover li:nth-child(2)>span {
transform: rotate(1000deg);
}
&:hover li:nth-child(3) {
transform: rotate(120deg);
}
&:hover li:nth-child(3)>span {
transform: rotate(960deg);
}
&:hover li:nth-child(4) {
transform: rotate(160deg);
}
&:hover li:nth-child(4)>span {
transform: rotate(720deg);
}
&:hover li:nth-child(5) {
transform: rotate(200deg);
}
&:hover li:nth-child(5)>span {
transform: rotate(880deg);
}
&:hover li:nth-child(6) {
transform: rotate(240deg);
}
&:hover li:nth-child(6)>span {
transform: rotate(1680deg);
}
&:hover li:nth-child(7) {
transform: rotate(280deg);
}
&:hover li:nth-child(7)>span {
transform: rotate(1920deg);
}
&:hover li:nth-child(8) {
transform: rotate(320deg);
}
&:hover li:nth-child(8)>span {
transform: rotate(2200deg);
}
&:hover li:nth-child(9) {
transform: rotate(360deg);
}
&:hover li:nth-child(9)>span {
transform: rotate(2520deg);
}
}
</style>
<ul class="love-transform-circle">
<li><span>1</span></li>
<li><span>2</span></li>
<li><span>3</span></li>
<li><span>4</span></li>
<li><span>5</span></li>
<li><span>6</span></li>
<li><span>7</span></li>
<li><span>8</span></li>
<li><span>9</span></li>
</ul>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
透视景深
perspective
- 使用
perspective
来控制元素的透视景深 perspective
规则为舞台元素控制景深,transform的perspective
函数为控制单个元素
舞台透视
perspective
规则用于将父级整个做为透视元素,会造成里面的每个子元素的透视是不一样的。就像现实中摆一排杯子,是使用统一透视的,每个杯子的透视不一样,造成有大有小。
单独透视
perspective
函数用于为元素设置单独透视,下面是为元素单独设置透视参数,每个元素的透视效果是一样的。
正方体
<style>
main.love-transform-square {
position: relative;
left: 50%;
top: 50%;
width: 200px;
height: 200px;
transform-style: preserve-3d;
transform-origin: 50% 50% 50px;
perspective-origin: -500px -500px;
transform: rotate3d(1, 0.6, 0.7, 50deg);
transition: 2s;
&:hover {
transform: rotate3d(0.4, 0.9, 0.3, 170deg);
}
div {
position: absolute;
width: 200px;
height: 200px;
background: #3498db;
font-size: 30px;
color: #fff;
line-height: 200px;
opacity: 0.5;
text-align: center;
transition: 5s;
}
div:nth-child(1) {
background: peru;
transform: translateZ(-200px);
}
div:nth-child(2) {
background: pink;
transform-origin: right;
transform: rotateY(-90deg);
}
div:nth-child(3) {
background: yellow;
transform-origin: left;
transform: rotateY(90deg);
}
div:nth-child(4) {
background: green;
transform-origin: top;
transform: rotateX(270deg);
}
div:nth-child(5) {
background: red;
transform-origin: bottom;
transform: rotateX(90deg);
}
}
</style>
<main class="love-transform-square">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</main>
隐藏背面
backface-visibility
使用 backface-visibility
用于控制是否可以看到元素的背面。
- 一般设置在元素上而不是舞台元素上
- 需要舞台元素(父级元素)设置
transform-style: preserve-3d
过度延迟
transitionend
用于控制过渡结束后执行的 JS 事件,简写属性会触发多次如 border-radius
会触发四次事件,不难理解因为可以为border-bottom-left-radius
等四个属性独立设置过渡,所以就会有四次事件。
属性 | 说明 |
---|---|
propertyName | 结束过渡样式 |
elapsedTime | 过渡需要的时间 |
pseudoElement | 过渡的伪元素 |
isTrusted | true:用户触发,false:脚本触发 |