CSS 深入 3D 动画

Web 技术飞速发展,但是绝大数技术人员并没有跟上其脚步,博主就是其中一员。当我们还在琢磨上一代技术时,那些技术前沿的弄潮儿开始打造新一代技术。这里聊一聊非高频却十分炫酷的 3D 技术,使用 CSS3 即可实现。
3d轮播

二维与三维

在说到三维之前,我们先聊一聊二维。

二维很好理解,即平面。我们使用 x 轴和 y 轴就可以轻松表示。

三维是在二维的基础上增加了一个维度。这个稍微有点难理解,可以参考下图:
三维坐标系
我们在网页里面构造一个正方形非常简单,但是如果想构造一个正方体,那就麻烦了。正常情况下,页面是一个二维空间,所以无法构造立体图。如果想构造立方体,我们必须在三维空间里面。

相关属性

先认识下 CSS3 中提供的一些 3d 属性:

  • perspective:规定 3D 元素的透视效果。
  • perspective-origin:规定 3D 元素的底部位置。
  • transform-style:规定被嵌套元素如何在 3D 空间中显示。
  • transform-origin:允许你改变被转换元素的位置。
  • transform:向元素应用 2D 或 3D 转换。
  • backface-visibility:定义元素在不面对屏幕时是否可见。

perspective

这个属性表示眼睛离物体的距离,并且这个值是非负的。在 Web 3d 的世界中,该值表示屏幕离物体的距离。

由此不难理解,该值越大,界面呈现的物体越小。该值越小,界面呈现的物体越大。

perspective-origin

表示视线灭点的位置,默认值是物体的中心。可以简单理解为视线的焦点。

transform-style

表示空间内元素的展示模式,有平面和立体两种,flat 和 preserve-3d。

perspectiveperspective-origintransform-style 这三个属性都作用于父元素,即 3d 物体的元素的上级元素。

backface-visibility

表示当元素不面向屏幕时是否可见。如果我们把一个元素翻转 180 度,并且不想看到这个元素,那么我们将 backface-visibility 设为 false 即可。

transformtransform-origin 不在赘述,在上一篇博文里有讲述。

实战

理论与实践结合,我们才能更好的理解。这里结合两个小例子,进一步巩固前面的理论基础。

正方体

正方体的实现思路就是利用六个面,经过旋转变化组合而成。

前后两个面,通过 z 轴方向的偏移可以得到。

左右两个面,需要先经过一次 y 轴方向的旋转,再经过 z 轴方向的偏移。

上下两个面,需要先经过一次 x 轴方向的旋转,再经过 z 轴方向的偏移。
正方体
关键代码

<div class="cube">
	<div class="c1"><img src="./img/1.jpg" alt=""></div>
	<div class="c2"><img src="./img/2.jpg" alt=""></div>
	<div class="c3"><img src="./img/3.jpg" alt=""></div>
	<div class="c4"><img src="./img/4.jpg" alt=""></div>
	<div class="c5"><img src="./img/5.jpg" alt=""></div>
	<div class="c6"><img src="./img/6.jpg" alt=""></div>
</div>
.cube {
	position: relative;
	transform-style: preserve-3d;
	animation: move 10s linear infinite;
	border: 1px solid #ccc;
	width: 200px;
	height: 200px;
}
@keyframes move {
	from {
		transform: rotateX(0deg) rotateY(0deg);
	}
	to {
		transform: rotateX(-360deg) rotateY(360deg);
	}
}
.cube div {
	position: absolute;
	width: 200px;
	height: 200px;
	border: 1px solid #ccc;
	text-align: center;
	line-height: 100px;
	box-shadow: inset 0 0 20px #3333FF;
	opacity: .8;
}
img {
	width: 100%;
	height: 100%;
}
.c1 {
	transform: translateZ(100px);
}
.c2 {
	transform: rotateY(180deg) translateZ(100px);
}
.c3 {
	transform: rotateY(90deg) translateZ(100px);
}	
.c4 {
	transform: rotateY(270deg) translateZ(100px);
}
.c5 {
	transform: rotateX(-90deg) translateZ(100px);
}
.c6 {
	transform: rotateX(90deg) translateZ(100px);
}

3d轮播图

效果图就是博文开头那张,为了方便阅读,这里也放置一张。
3d轮播
思路和上个正方体一样,细节可以参考代码。

<div class="container">
	<h2>埃菲尔铁塔</h2>

	<ul>
		<li><img src="./img/1.jpg" alt=""></li>
		<li><img src="./img/2.jpg" alt=""></li>
		<li><img src="./img/3.jpg" alt=""></li>
		<li><img src="./img/4.jpg" alt=""></li>
		<li><img src="./img/5.jpg" alt=""></li>
		<li><img src="./img/6.jpg" alt=""></li>
	</ul>

	<div class="btn-wrapper">
		<button class="prev">上一张</button>
		<button class="next">下一张</button>
	</div>
</div>
.container {
	width: 800px;
	height: 400px;
	border: 1px solid #ccc;
	margin: 50px auto 0 auto;
	display: flex;;
	align-items: center;
	justify-content: center;
	perspective: 800px;
	position: relative;
	background-color: #99CCCC;
	border-radius: 10px;
}

ul {
	position: relative;
	width: 200px;
	height: 200px;
	transform-style: preserve-3d;
	transition: transform 1s ease;
}

li {
	position: absolute;
	width: 200px;
	height: 200px;
	opacity: .9;
	box-shadow: 0px 0px 5px #3399FF;
	border-radius: 5%;
}

li:nth-child(1) {
	transform: rotateY(0) translateZ(180px);
}
li:nth-child(2) {
	transform: rotateY(60deg) translateZ(180px);
}
li:nth-child(3) {
	transform: rotateY(120deg) translateZ(180px);
}
li:nth-child(4) {
	transform: rotateY(180deg) translateZ(180px);
}
li:nth-child(5) {
	transform: rotateY(240deg) translateZ(180px);
}
li:nth-child(6) {
	transform: rotateY(300deg) translateZ(180px);
}

img {
	width: 100%;
	height: 100%;
	border-radius: 5%;
}

.btn-wrapper {
	position: absolute;
	left: 50%;
	bottom: 10px;
	transform: translateX(-50%);
}
button {
	padding: 8px 25px;
	font-size: 14px;
	color: #333;
	background-color: #3399FF;
	color: #fff;
	border: none;
	outline: none;
	border-radius: 4px;
}
button:last-child {
	margin-left: 20px;
}

h2 {
	position: absolute;
	top: 10px;
	left: 50%;
	transform: translateX(-50%);
	color: #333;
}
var cities = [
	'埃菲尔铁塔',
	'故宫',
	'凯旋门',
	'长城',
	'黄鹤楼',
	'悉尼歌剧院'
]
var prev = document.querySelector('.prev');
var next = document.querySelector('.next');
var ul = document.querySelector('ul');
var h2 = document.querySelector('h2');
var deg = 0
var i = 0
prev.addEventListener('click', function() {
	deg += 60
	i--
	if (i < 0) {
		i = 5
	}
	h2.innerHTML = cities[i]
	ul.style.transform = `rotateY(${deg}deg)`
})
next.addEventListener('click', function() {
	deg -= 60
	i++
	if (i > 5) {
		i = 0
	}
	h2.innerHTML = cities[i]
	ul.style.transform = `rotateY(${deg}deg)`
})

小结

这里主要是博主自己的学习记录,很多细节如果有不明白的,可以参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值