2D3D转换

1 2D转换

转换是 CSS3 中具有颠覆性的⼀个特征,可以实现元素的位移、旋转、变形、缩放。

通过 transform 转换来实现 2D 转换或者 3D 转换。

2D转换包括:

  • 缩放

  • 移动

  • 旋转

  • 倾斜

1.1 scale

设置元素的缩放效果

语法:

  • transform: scale(x, y);

  • transform: scale(2, 0.5);

参数:

  • x:表示水平方向的缩放倍数

  • y:表示垂直方向的缩放倍数

注意:如果只写⼀个值就是等比例缩放

取值:

  • ⼤于1表示放⼤

  • ⼩于1表示缩⼩

  • 不能为百分⽐

给元素设置 2D 转换,并不会把兄弟元素挤⾛

<style>
    .box {
        float: left;
        width: 200px;
        height: 200px;
    }
​
    .box1 {
        transform: scale(1.2);
        background: #ff0000;
    }
​
    .box2 {
        background: #00ff00;
    }
</style>
<div class="box box1"></div>
<div class="box box2"></div>

1.2 translate

设置元素的移动效果

语法:

  • transform: translate(⽔平位移, 垂直位移);

  • transform: translate(-50%, -50%);

参数:

  • 参数为百分⽐,相对于⾃身移动

  • 正值:向右和向下

  • 负值:向左和向上

  • 如果只写⼀个值,则表示⽔平移动

注意:与相对定位相⽐,效果是⼀样的,但是相对定位会影响⼦元素的定位参考。

使用:让绝对定位中的盒⼦在父元素里居中,我们知道,如果想让⼀个标准流中的盒⼦在⽗盒⼦⾥居中(⽔平⽅向看),可以将其设置margin: 0 auto; 属性。

如果盒⼦是绝对定位的,如果还想让其居中(位于⽗盒⼦的正中间),之前的做法是利用 margin 负值

<style>
    .wrapper {
        float: left;
        width: 600px;
        height: 600px;
        background: #0000ff;
        position: relative;
    }
​
    .box {
        float: left;
        width: 200px;
        height: 200px;
    }
​
    .box1 {
        background: #ff0000;
        margin: -100px 0 0 -100px;
        position: absolute;
        left: 50%;
        top: 50%;
        z-index: 9;
    }
</style>
<div class="wrapper">
    <div class="box box1"></div>
</div>

现在,我们还可以利⽤ translate 偏移来做,这也是⽐较推荐的写法

<style>
    .wrapper {
        float: left;
        width: 600px;
        height: 600px;
        background: #0000ff;
        position: relative;
    }
​
    .box {
        float: left;
        width: 200px;
        height: 200px;
    }
​
    .box1 {
        background: #ff0000;
        transform: translate(-50%, -50%);
        position: absolute;
        left: 50%;
        top: 50%; 
        z-index: 9;
    }
</style>
<div class="wrapper">
    <div class="box box1"></div>
</div>

1.3 rotate

设置元素的旋转

语法:

  • transform: rotate(⻆度);

  • transform: rotate(45deg);

参数:

  • 单位是deg

  • 正值:顺时针旋转

  • 负值:逆时针旋转

<style>
    .rotate {
        width: 100px;
        height: 100px;
        background: #000fff;
    }
​
    .rotate:hover {
        transform: rotate(45deg);
    }
</style>
<div class="rotate"></div>

transform 可以书写多个 2D 转换,中间⽤空格隔开。我们可以将 transform 的两个属性合并起来写

<style>
    .rotate {
        width: 100px;
        height: 100px;
    }
​
    .rotate1 {
        background: #000fff;
    }
​
    .rotate2 {
        background: #00ff00;
    }
​
    .rotate1:hover {
        transform: translate(200px) rotate(45deg);
    }
​
    .rotate2:hover {
        transform: rotate(45deg) translate(200px);
    }
</style>
<div class="rotate rotate1"></div>
<div class="rotate rotate2"></div>

但是这两者效果不同,第⼀种是先平移再旋转,第⼆种是先旋转再平移。

rotate 旋转时,默认是以盒⼦的正中⼼为坐标原点的。如果想改变旋转的坐标原点,可以⽤ transform-origin 属性

取值:

  • px

  • 百分⽐

  • 英⽂单词(left、center等)

语法:

  • transform-origin: ⽔平坐标 垂直坐标;

  • transform-origin: 50px 50px;

  • transform-origin: center bottom;

实现扑克牌效果

<style>
    .box {
        width: 300px;
        height: 440px;
        margin: 100px auto;
        position: relative;
    }
​
    .item {
        width: 100%;
        height: 100%;
        border: 1px solid #fff000;
        position: absolute;
        left: 0;
        top: 0;
        /* 变换中心原点 */
        transform-origin: center bottom;
    }
​
    .box:hover .item:nth-child(6) {
        transform: rotate(-10deg);
    }
​
    .box:hover .item:nth-child(5) {
        transform: rotate(-20deg);
    }
​
    .box:hover .item:nth-child(4) {
        transform: rotate(-30deg);
    }
​
    .box:hover .item:nth-child(3) {
        transform: rotate(-40deg);
    }
​
    .box:hover .item:nth-child(2) {
        transform: rotate(-50deg);
    }
​
    .box:hover .item:nth-child(1) {
        transform: rotate(-60deg);
    }
​
    .box:hover .item:nth-child(8) {
        transform: rotate(10deg);
    }
​
    .box:hover .item:nth-child(9) {
        transform: rotate(20deg);
    }
​
    .box:hover .item:nth-child(10) {
        transform: rotate(30deg);
    }
​
    .box:hover .item:nth-child(11) {
        transform: rotate(40deg);
    }
​
    .box:hover .item:nth-child(12) {
        transform: rotate(50deg);
    }
​
    .box:hover .item:nth-child(13) {
        transform: rotate(60deg);
    }
</style>
​
<div class="box">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

实现红心效果

<style>
    .heart {
        position: relative;
        width: 100px;
        height: 100px;
        margin-top: 80px;
    }
​
    .heart:before,
    .heart:after {
        position: absolute;
        content: "";
        left: 50px;
        top: 0;
        width: 50px;
        height: 80px;
        background: red;
        border-radius: 50px 50px 0 0;
        transform: rotate(-45deg);
        transform-origin: 0 100%;
    }
​
    .heart:after {
        left: 0;
        transform: rotate(45deg);
        transform-origin: 100% 100%;
    }
​
    .heart:hover {
        transform: scale(1.2);
    }
</style>
<div class="heart"></div>

1.4 skew

设置元素的倾斜

语法:

  • transform: skew(⽔平倾斜⻆度,垂直倾斜⻆度);

  • transform: skew(45deg,10deg);

参数:

  • 单位是deg

  • 正值:顺时针倾斜

  • 负值:逆时针倾斜

<style>
    .skew {
        width: 100px;
        height: 100px;
        background: #000fff;
    }
​
    .skew:hover {
        transform: skew(45deg, 10deg);
    }
</style>
<div class="skew"></div>

注意:

  • 转换操作不会影响到其他元素

  • 只能添加给块元素或行内块元素,不能添加给⾏内元素

  • 复合写法:可以同时添加多个变形操作,先执⾏前⾯的,再执⾏后⾯的

2 3D转换

2.1 缩放

2.1.1 scaleX

元素沿着 X 轴缩放

语法:

  • transform: scaleX(x);

  • transform: scaleX(1.2);

参数:

  • x:表示水平方向的缩放倍数

取值:

  • ⼤于1表示放⼤

  • ⼩于1表示缩⼩

  • 不能为百分⽐

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
	}

	.box>.fill {
        height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.scaleX:hover .fill {
		transform: scaleX(2);
	}
</style>
<div class="box scaleX">
	<div class="fill"></div>
</div>

2.1.2 scaleY

元素沿着 Y 轴缩放

语法:

  • transform: scaleY(y);

  • transform: scaleY(1.2);

参数:

  • y:表示垂直方向的缩放倍数

取值:

  • ⼤于1表示放⼤

  • ⼩于1表示缩⼩

  • 不能为百分⽐

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
	}

	.box>.fill {
        height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.scaleY:hover .fill {
		transform: scaleY(2);
	}
</style>
<div class="box scaleY">
	<div class="fill"></div>
</div>

2.1.3 scaleZ

元素沿着 Z 轴缩放

语法:

  • transform: scaleZ(z);

  • transform: scaleZ(1.2);

参数:

  • z:表示面向屏幕方向的缩放倍数

取值:

  • ⼤于1表示放⼤

  • ⼩于1表示缩⼩

  • 不能为百分⽐

2.1.4 scale3d

设置元素的 3D 缩放效果

语法:

  • transform: scale3d(x,y,z);

  • transform: scale3d(2,2,2);

参数:

  • x:表示水平方向的缩放倍数

  • y:表示垂直方向的缩放倍数

  • z:表示面向屏幕方向的缩放倍数

取值:

  • ⼤于1表示放⼤

  • ⼩于1表示缩⼩

  • 不能为百分⽐

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
        perspective: 800px;
	}

	.box>.fill {
		height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.scale3d:hover .fill {
		transform: scale3d(2, 2, 1);
	}
</style>
<div class="box scale3d">
	<div class="fill"></div>
</div>

2.2 移动

2.2.1 translateX

元素沿着 X 轴移动

语法:

  • transform: translateX(x);

  • transform: translateX(100px);

参数:

  • x:表示水平方向的移动

取值:

  • 正值:向右

  • 负值:向左

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
        perspective: 800px;
	}

	.box>.fill {
		height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.translateX:hover .fill {
		transform: translateX(50px);
	}
</style>
<div class="box translateX">
	<div class="fill"></div>
</div>

2.2.2 translateY

元素沿着 Y 轴移动

语法:

  • transform: translateY(y);

  • transform: translateY(100px);

参数:

  • y:表示垂直方向的移动

取值:

  • 正值:向下

  • 负值:向上

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
        perspective: 800px;
	}

	.box>.fill {
		height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.translateY:hover .fill {
		transform: translateY(50px);
	}
</style>
<div class="box translateY">
	<div class="fill"></div>
</div>

2.2.3 translateZ

元素沿着 Z 轴移动

语法:

  • transform: translateZ(z);

  • transform: translateZ(100px);

参数:

  • z:表示面向屏幕方向的移动

取值:

  • 正值:向前

  • 负值:向后

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
        /* ⽗元素加透视效果 */
        perspective: 800px;
	}

	.box>.fill {
		height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.translateZ:hover .fill {
		transform: translateZ(200px);
	}
</style>
<div class="box translateZ">
	<div class="fill"></div>
</div>

如果不加透视属性,是看不到 translateZ 的效果的。

2.2.4 translate3d

元素进行 3D 移动

语法:

  • transform: translate3d(x,y,z);

  • transform: translate3d(100px,100px,100px);

参数:

  • x:表示水平方向的移动

  • y:表示垂直方向的移动

  • z:表示面向屏幕方向的移动

取值:

  • 正值:向右、向下、向前

  • 负值:向左、向上、向后

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
		/* ⽗元素加透视效果 */
		perspective: 800px;
	}

	.box>.fill {
		height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.translate3d:hover .fill {
		transform: translate3d(50px, 50px, 200px);
	}
</style>
<div class="box translate3d">
	<div class="fill"></div>
</div>

2.3 旋转

旋转的方向:(左⼿法则)左⼿握住旋转轴,竖起拇指指向旋转轴的正⽅向,正向就是其余⼿指卷曲的⽅向。

注意:所有的3d旋转,对着正⽅向去看,都是顺时针旋转。

2.3.1 rotateX

元素沿着 X 轴旋转

语法:

  • transform: rotateX(a);

  • transform: rotateX(360deg);

参数:

  • a:角度,单位为deg

取值:

  • 正值:顺时针旋转

  • 负值:逆时针旋转

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
        /* ⽗元素加透视效果 */
		perspective: 200px;
	}

	.box>.fill {
		height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.rotateX:hover .fill {
		transform: rotateX(45deg);
	}
</style>
<div class="box rotateX">
	<div class="fill"></div>
</div>

透视的是要加给图⽚的⽗元素 div,⽅能⽣效。我们在后⾯会讲解透视属性。

2.3.2 rotateY

元素沿着 Y 轴旋转

语法:

  • transform: rotateY(a);

  • transform: rotateY(360deg);

参数:

  • a:角度,单位为deg

取值:

  • 正值:顺时针旋转

  • 负值:逆时针旋转

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
		/* ⽗元素加透视效果 */
		perspective: 200px;
	}

	.box>.fill {
		height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.rotateY:hover .fill {
		transform: rotateY(45deg);
	}
</style>
<div class="box rotateY">
	<div class="fill"></div>
</div>

2.3.3 rotateZ

元素沿着 Z 轴旋转

语法:

  • transform: rotateZ(a);

  • transform: rotateZ(360deg);

参数:

  • a:角度,单位为deg

取值:

  • 正值:顺时针旋转

  • 负值:逆时针旋转

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
        /* ⽗元素加透视效果 */
		perspective: 200px;
	}

	.box>.fill {
		height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.rotateZ:hover .fill {
		transform: rotateZ(45deg);
	}
</style>
<div class="box rotateZ">
	<div class="fill"></div>
</div>

2.3.4 rotate3d

沿着自定义轴,元素 3D 旋转,综合写法

语法:

  • transform: rotate3d(1, 1, 1, 0);

  • transform: rotate3d(x, y, z, a)

取值:

  • x 表示旋转轴X坐标方向的矢量。

  • y 表示旋转轴Y坐标方向的矢量。

  • z 表示旋转轴Z坐标方向的矢量。

  • a 表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转。

<style>
	.box {
		width: 100px;
		height: 100px;
		margin: 100px auto;
		background: #ddd;
		/* ⽗元素加透视效果 */
		perspective: 200px;
	}

	.box>.fill {
		height: 100px;
		background: #03A9F4;
		opacity: .5;
		transition: 0.3s;
	}

	.rotate3d1 .fill {
		transform: rotate3d(1, 1, 0, 45deg);
	}

    .rotate3d2 .fill {
		transform: rotate3d(-1, 1, 0, 45deg);
	}
</style>
<div class="box rotate3d1">
	<div class="fill"></div>
</div>
<div class="box rotate3d2">
	<div class="fill"></div>
</div>

2.3.5 3D旋转

<style>
	.box {
		width: 300px;
		height: 300px;
		margin: 50px auto;
		position: relative;
	}

	.box-item {
		width: 100%;
		height: 100%;
		position: absolute;
		border-radius: 50%;
		transition: all 2s;
        /* 隐藏背面 */
		backface-visibility: hidden;
	}

	.box1 {
		background: #ff0000
	}

	.box2 {
		background: #0000ff;
		transform: rotateY(180deg);
	}

	.box:hover .box1 {
		transform: rotateY(180deg);
	}

	.box:hover .box2 {
		transform: rotateY(0deg);
	}
</style>
<div class="box">
	<div class="box-item box1"></div>
	<div class="box-item box2"></div>
</div>

2.4 透视

显示屏是⼀个 2D 平⾯,图像之所以具有⽴体感(3D效果),其实只是⼀种视觉呈现,通过透视可以 实现此⽬的。

透视可以将⼀个2D平⾯,在转换的过程当中,呈现3D效果。但仅仅只是视觉呈现出3d 效果,并不是正真 的3d。

简单来说,就是设置这个属性后,那么就可以模拟出像我们人看电脑上的显示的元素一样。比如说,perspective:800px; 意思就是,我在离屏幕 800px 的地方观看这个元素。(这个属性,要设置在父元素上面)

加了perspective 和 没有加是什么区别, 第一个小方块,是有加的效果,能明显的看到空间感了有没有, 感觉他是真的像在旋转, 而第二个呢,像是在伸缩。

<style>
	.wrapper1 {
		/* 透视:加给变换的⽗盒⼦ */
		/* 设置的是⽤户的眼睛距离 平⾯的距离 */
		/* 透视效果只是视觉上的呈现,并不是正真的3d */
		perspective: 400px;
	}

	.box {
		width: 300px;
		height: 220px;
		margin: 100px auto 0;
		background: #ff0000;
		transition: all 2s;
	}

	.box:hover {
		transform: rotateY(180deg);
	}
</style>
<div class="wrapper1">
	<div class="box"></div>
</div>
<div class="wrapper2">
	<div class="box"></div>
</div>

比如之前学到的属性值:transform: translateZ(400px); 增加 Z 轴的距离,那么 Z 轴越大,是不是也就代表着,这个元素,离我们的距离越近?

那么,你把一张图片,贴到你脸上,有什么效果? 是不是非常大?这个 perspective 配合 transform:translateZ 就有这种效果。

<style>
	.wrapper {
		/* ⽗元素加透视效果 */
		perspective: 800px;
	}

	.box {
		width: 200px;
		margin: 200px auto;
		background: #ff0000;
		transform: translateZ(400px)
	}

	.box::after {
		content: '';
		display: block;
		clear: both;
	}

	.box>img {
		float: left;
		width: 100%;
	}

	.box:hover {
		/* translateZ 必须配合透视来使⽤ */
		/* transform: translateZ(400px) */
	}
</style>
<div class="wrapper">
	<div class="box"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F0719%2Fa38e408fp00qwhqu10032d000go00b4p.png&thumbnail=650x2147483647&quality=80&type=jpg" alt=""></div>
</div>

这个其实很像我们现实中的例子一样,一张远处的图片,慢慢的移动到你脸上, 你会看见图片越来越大,贴到你脸上的时候,是不是你就看不见了?

到 800px 的时候,你人都和图片融合在一体了, 如果 801px 是不是你都穿过这张图片了?道理是一样的。

那么 transform:translateZ,到负数的时候,是不是值越小,图片离我们越远,同理的图片也就越小呢?

按照我们的思路继续,如果 perspective 值越小,是不是我们就离屏幕越近,那么图片也会越大(translateZ 是移动图片,perspective 是移动人和屏幕的距离,对吧,那么把 translateZ 归零。然后增加 perspective 试试看。)

然后,你会惊奇的发现,好像无论是增加,还是减少,图片都没有任何变化。

把 translateZ 设置成负值(按照我们的想法,Z 的值是正数,说明这个图片,离我们越近,那么反之,负值,离我们越远)移动 perspective 的值,把他的值变小(正常来说,值越小,是不是就代表我们离屏幕越近, 看的东西也就越大)

然后,你又会惊奇的发现,怎么图片不是越来越大呢? 我们离屏幕越近,图片应该越大才对啊,怎么变小了呢?

实际情况是,我们看到的,并不是图片本身,而是图片的投影。是不是有点晕了,投影是什么鬼。

我们下面分析总结一下各种情况:

第一个情况,translateZ 的值越大,图片越大。

第二个情况,translateZ 的值越小,图片越小。

第三个情况,translateZ 为 0 的时候,图片不会移动,也就不会有投影了。

第四个情况,translateZ 为负数之后,人眼离得越近看的倒影越小。

最后补充一点,这个perspective 属性呢,要放在父级身上。

还有一个属性 perspective-origin,这个属性也是设置在父级身上。

这个属性呢,默认值是 center center,也就是 居中。这两个参数呢,是根据自身来定位的, 0px 0px 代表着元素的左上角,center center代表着元素的中间点。可以设置像素 50px 也可设置百分比 50%,还可以设置 top right left bottom center 等。

这个属性有什么用呢? 这个属性是相当于人 的眼睛看哪里。你没有设置,也就是默认看父元素中间的地方。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值