用CSS画一些特殊图案

本篇博文主要是介绍用css画一些特殊的图案,以及一些特殊的效果。
在以下的内容中,可能会用到以下知识点: transform、transition、animation、景深等。首先简单介绍一下这些知识点。

知识点

transform

transform可以对元素进行移动、旋转、缩放、拉伸等转换。具体的用法可以参照2D转换3D转换

transition

transition用来给元素的变换添加一些效果。具体的用法可以参照过渡

animation

animation用来给元素添加动画。使用 @keyframes 规则。具体的用法可以参照动画

景深

景深就是肉眼距离屏幕的距离,将当前容器变成3D的,让本来的皮影戏变成舞台剧。景深设置的越大,元素离我们越远。用法如下。

<div class="box">
<div></div>
</div>
<style>
.box {
perspective: 500px;
}
</style>

浏览器坐标轴

这里以一个正方形的div为例。当一个元素进行一些2D或者3D变换时,作用的坐标轴的中心点就是这个元素的中心。需要注意的是,当元素进行变换时,其坐标轴会跟随移动,始终保持在元素中心。

浏览器坐标轴

正方体

正方体是一个3D的图案,需要借助景深将屏幕变成一个具有z轴的3D空间。首先我们先写出正方体的六个面。

<div class="container">
<div class="cube-box">
<div class="item front">front</div>
<div class="item behind">behind</div>
<div class="item left">left</div>
<div class="item right">right</div>
<div class="item top">top</div>
<div class="item down">down</div>
</div>
</div>

然后我们将正方体的舞台搭建起来。核心是设置景深,以及让子元素在3D空间内变换。添加如下css代码。

.container {
position: relative;
margin: 20px auto;
width: 500px;
height: 500px;
background: radial-gradient(rgba(0, 0, 0, 0) 10%, rgba(0, 0, 0, .5) 100%);
background: -webkit-radial-gradient(rgba(0, 0, 0, 0) 10%, rgba(0, 0, 0, .5) 100%);
background: -o-radial-gradient(rgba(0, 0, 0, 0) 10%, rgba(0, 0, 0, .5) 100%);
background: -moz-radial-gradient(rgba(0, 0, 0, 0) 10%, rgba(0, 0, 0, .5) 100%);
/* 设置景深 */
perspective: 500px;
}

.cube-box {
position: absolute;
top: 200px;
left: 200px;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
/* 让所有的元素在3D空间中呈现 */
transform-style: preserve-3d;
}

然后我们将正方体的6个面画出来。添加如下CSS代码。

.item {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #fff;
opacity: 0.6;
}

这个时候正方体的6个面都已经堆叠在一起了,是时候让他们各自归位了,首先先看正面和背面。

正面是不需要动的,只需要安静的呆在你的面前就可以了。而背面需要向z轴负半轴方向移动正方体的边长的长度。为了方便四个侧面的处理,这里将正面向z轴正半轴的方法移动半个边长的长度,背面向z轴负半轴方向移动半个边长的长度。元素的移动就需要用到 transform 的 translate 方法。

{
transform: translate(50px, -50px); /* 在x轴上移动50px的距离,在y轴上移动-50px的距离。当只写一个值时,默认在y轴上不移动 */
transform: translate3d(50px, 50px, 50px); /* 3D转换。3个值分别为x轴、y轴、z轴 */
transform: translateX(50px); /* 3D转换。在x轴方向上移动 */
transform: translateY(50px); /* 3D转换。在y轴方向上移动 */
transform: translateZ(50px); /* 3D转换。在z轴方向上移动 */
}

添加如下CSS代码。

.front {
transform: translateZ(50px);
}
.behind {
transform: translateZ(-50px);
}

因为他们的中心坐标始终都在同一个XY坐标点上。所以这时候只能透过半透明的 front 看到后面“变小”的其他面。

现在我们来处理左边和右边这两面。发挥你的想象力想象一下,他们两个都是绕Y轴进行旋转,也就是要用到 transform 的 rotate 方法。而为了让其能够正常的旋转到正确的位置上,还需要利用 translate 将其旋转点移动到两边。

{
transform: rotate(45deg); /* 顺时针旋转45度。也就是绕z轴旋转 */
transform: rotate3d(1, 0, 0, 45deg); /* 3D转换。前三个值代表在改方向上是否进行旋转,第四个值代表旋转的角度。 */
transform: rotateX(45deg); /* 3D转换。绕x轴旋转 */
transform: rotateY(45deg); /* 3D转换。绕y轴旋转 */
transform: rotateZ(45deg); /* 3D转换。绕z轴旋转 */
}

添加如下css代码。

.left {
/* 先将 left 在x轴上向左移动半个边长的长度,使 left 的中心点在 front 的左边边线上,然后将其旋转90度,使其与 front 和 behind 垂直,逆时针旋转,使其正面朝外 */
/* 需要注意的是,当使用多个 transform 方法时,需要注意其顺序,不同的顺序会导致不同的结果。 */
transform: translateX(-50px) rotateY(90deg);
}
.right {
transform: translateX(50px) rotateY(-90deg);
}

同样的思想,让我们处理一下 top 和 down 这两个面。这两个面为了出现在上面和下面,需要绕x轴旋转90度。添加如下css代码。

.top {
/* 先将 top 在y轴上向左移动半个边长的长度,使 top 的中心点在 front 的上边边线上,然后将其旋转90度,使其与 front 和 behind 垂直,逆时针旋转,使其正面朝外 */
transform: translateY(-50px) rotateX(90deg);
}
.down {
transform: translateY(50px) rotateX(-90deg);
}

这个时候一个正方体就已经成型了,可是还是只能看到一个面啊,那我们就让其动起来。

正方体旋转动画

这里默认你已经了解了上面我所说的 animation 相关的知识点了。

首先我们定义一个旋转的动画,控制不同阶段的不同旋转角度,命名为 cubeRotating。

@keyframes cubeRotating {
0% {
transform: rotate(0deg);
}
25% {
transform: rotateX(180deg);
}
50% {
transform: rotateX(360deg) rotateY(180deg);
}
75% {
transform: rotateY(360deg) rotateZ(180deg);
}
100% {
transform: rotateZ(360deg);
}
}

这里定义了5个阶段的状态。0% 和 100% 都是初始状态。中间的几个阶段分别进行了不同程度和方向上的旋转。需要注意的是,在每个阶段完成后添加下个阶段的变换时,都需要以变换后的新坐标系为基准添加。

前面我们定义了正方体外壳 div 的位置,其中心点刚好是正方体的正中心。给其添加此动画。

.cube-box {
/*
以数字表示 animation 第几个属性
1: 动画名称
2: 动画持续时长,即完成一个周长所需的时间,默认为0
3: 动画的速度曲线,默认为ease,详细的曲线介绍可以参考[速度曲线](https://www.runoob.com/cssref/css3-pr-animation-timing-function.html)
4: 动画的延迟执行时间,只会在第一次执行时延迟,多次执行间无延迟
5: 动画的执行次数,可以是数字或者 infinite(无限次)
*/
animation: cubeRotating 6s linear 1s infinite;
}

源码&预览

预览:DEMO

源码:GITHUB

未完待续

文章作者: JaCo Wu
文章链接: https://jacokwu.cn/blog/2019/09/15/用CSS画一些特殊图案/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 JaCo Wu的博客