本文正在参加「金石计划」
前言
好久没有分享炫酷的CSS效果了,今天就来给大家带来一个“爱的魔力转圈圈⭕”的CSS
特效。
背景
这次直接把最终的实现效果展示出来,后续再一步步的教你如何实现这样一个特效以及实现下面的特效需要掌握的CSS
知识。那么请看下面的gif
图示→
效果就是这么一个效果,如果让你来实现,你会怎么去实现这么一个效果?话不多说,下面就来看看我是如何实现这么一个CSS特效的。
知识
实现上述这样一个“爱的魔力转圈圈⭕”特效核心的CSS
知识只涉及到了:box-shadow
,transform-style
和transform: rotate()
属性。那下面就用示例讲讲这两种CSS
属性是啥样的效果→
box-shadow
box-shadow
属性用于在元素的框架上添加阴影效果。它有如下属性值:
值 | 说明 |
---|---|
h-shadow | 必需的。水平阴影的位置。允许负值 |
v-shadow | 必需的。垂直阴影的位置。允许负值 |
blur | 可选。模糊距离 |
spread | 可选。阴影的大小 |
color | 可选。阴影的颜色。寻找颜色值的完整列表 |
inset | 可选。从外层的阴影(开始时)改变阴影内侧阴影 |
下面将创建一个文件来演示box-shadow
的实际用法,但是不会去每个属性值都去展开说明,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>box-shadow</title>
<style>
body {
width: 100%;
height: 900px;
display: flex;
justify-content: center;
align-items: center;
}
.box {
width: 15em;
height: 15em;
box-shadow: 10px 0 0 1px #ff4d4d;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
上面代码实现的效果如下:
上图展示的是box-shadow
的外层阴影效果。下面将上述代码改为如下,就能看到另外一个效果:
box-shadow: inset 10px 0 0 1px #ff4d4d;
上图展示的就是box-shadow
的内层阴影效果。
注意:box-shadow
中的inset参数可以写在所有值之后也可写在前面,并且默认的是外层循环。
上述两种效果都会在下面实现“爱的魔力转圈圈⭕”特效中使用到,是不是更期待了呢
transform: rotate()
讲完box-shadow
,那下面接着来讲transform
中的rotate()
属性,这是我们让魔力圈转起来的核心方法。
先来看看rotate()
属性在MDN上如何介绍的→
rotate()
函数定义了一种将元素围绕一个定点(由transform-origin
属性指定)旋转而不变形的转换。指定的角度定义了旋转的量度。若角度为正,则顺时针方向旋转,否则逆时针方向旋转。
下面就用一个示例来演示rotate
沿X轴,Y轴和Z轴来旋转的效果。如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>rotate</title>
<style>
body {
width: 100%;
height: 900px;
display: flex;
justify-content: center;
align-items: center;
}
.box {
width: 100px;
height: 100px;
background-color: brown;
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
打开浏览器控制台,分别修改X轴,Y轴和Z轴的值就可以清楚看到效果:
上述就是transform: rotate()
方法的实现效果,它其实还有3d
效果,但是在这个特效中我们不让元素自身进行3d
旋转,而是交给父元素来进行,交给父元素和交给自身最终的实现效果是一致的。
transform-style
transform-style
设置元素的子元素是位于3D
空间中还是平面中。
这个属性还不好写示例来展示效果,各位看官就将就理解下吧,晓得它是用于控制子元素是处于3D还是平面就行,sry。
实现
下面就要来开始实现在背景介绍中的特效了,我们还是使用的还是React
技术栈,实现逻辑相对简单,但是也认真往下看哦^_^
在背景介绍中的图示可以看到,要想实现这么一个圆盘,那就需要使用box-shadow
属性让一个div
变成只有三面的图形,然后使用border-radius
属性让矩形就能变成圆形,通过代码就能得到如下效果:
这个图示直观的告诉我们要想实现一个圆盘那就需要用一些盒子旋转一定的角度来围成一个圆盘。而这里我们是使用了36
个盒子,让每一个div
旋转10
度,从而形成了一个圆盘。
但是每一个盒子的颜色不能设置成一样,不然最后就是一个纯色圆环了,所以需要我们分别为36
个div
随机设置不同的颜色,这就需要写一个算法来实现了。如下:
// 初始化一个空数组
let colors = [];
// 循环生成36个颜色
while (colors.length < 36) {
// 生成一个随机的 RGB 颜色值
let red = Math.floor(Math.random() * 256);
let green = Math.floor(Math.random() * 256);
let blue = Math.floor(Math.random() * 256);
let color = '#' + red.toString(16).padStart(2, '0') + green.toString(16).padStart(2, '0') + blue.toString(16).padStart(2, '0');
// 如果颜色数组中不存在该颜色,则将其添加到数组中
if (!colors.includes(color)) {
colors.push(color);
}
}
// 打印颜色数组
console.log(colors);
执行代码结果如下:
可以看到算法是成功的,那下面就能来正式创建一个H5Circle.jsx
文件了,如下:
import React, {useEffect, useState} from 'react';
import './index.less';
/**
*
* @constructor
*/
const H5Circle = () => {
const [dataSource, setDataSource] = useState([]);
const [shadow, setShadow] = useState('');
const [rotate, setRotate] = useState('rotate');
useEffect(() => {
// 初始化一个空数组
let colors = [];
// 循环生成36个颜色
while (colors.length < 36) {
// 生成一个随机的 RGB 颜色值
let red = Math.floor(Math.random() * 256);
let green = Math.floor(Math.random() * 256);
let blue = Math.floor(Math.random() * 256);
let color = '#' + red.toString(16).padStart(2, '0') + green.toString(16).padStart(2, '0') + blue.toString(16).padStart(2, '0');
// 如果颜色数组中不存在该颜色,则将其添加到数组中
if (!colors.includes(color)) {
colors.push(color);
}
}
// 打印颜色数组
console.log(colors);
setDataSource(colors)
}, [])
return(
<div className="h5-container">
{
dataSource.map((v, index) =>
<div
key={index}
className="circle"
style={{
boxShadow: `${shadow} 10px 0 0 1px ${v}`,
transform: `${rotate}(${index * 10}deg) translateY(5em)`
}}
></div>
)
}
</div>
);
};
export default H5Circle;
创建index.less
文件:
.h5-container, .h5-container * {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
transform-style: preserve-3d;
}
.circle {
width: 15em;
height: 15em;
border-radius: 50%;
}
根据上面的代码得到如下效果:
下面就是让这个圆盘旋转起来,那就要给它加上动画,如下:
.h5-container {
animation: spin 10s linear infinite;
}
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
再来运行看看效果:
诶,动起来了,nice!到这里,初步的效果就搞定了!
下面就来继续这个动效增加一些操作按钮,如下:
<div className="options">
<div className="item" onClick={() => handleOption(1)}>外阴影</div>
<div className="item" onClick={() => handleOption(2)}>内阴影</div>
<div className="item" onClick={() => handleOption(3)}>X轴旋转</div>
<div className="item" onClick={() => handleOption(4)}>Y轴旋转</div>
<div className="item" onClick={() => handleOption(5)}>Z轴旋转</div>
</div>
为以上操作增加js
和CSS
代码,分别如下:
const handleOption = (option) => {
if (option === 1) {
setShadow('')
} else if (option === 2) {
setShadow('inset')
} else if (option === 3) {
setRotate('rotateX')
} else if (option === 4) {
setRotate('rotateY')
} if (option === 5) {
setRotate('rotateZ')
}
}
.options {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 10;
height: 140px;
display: flex;
justify-content: center;
align-items: center;
.item {
width: 100px;
height: 40px;
margin-right: 10px;
text-align: center;
line-height: 40px;
background-color: #3370EF;
border-radius: 6px;
}
}
最终的实现效果如下:
至此,这样一个“爱的魔力转圈圈⭕”特效就完成了,可以看到只要改变rotate()
的X,Y,Z轴都能得到不同的效果,而改变box-shadow
的inset
值也能得到不同的效果,所以可以看出CSS
还是很强大的。最后,愿看完文章的你也能完美的实现该特效,阿门!
后语
小伙伴们,如果觉得本文对你有些许帮助,点个👍或者➕个关注再走呗^_^ 。另外如果本文章有问题或有不理解的部分,欢迎大家在评论区评论指出,我们一起讨论共勉。
原文链接:https://juejin.cn/post/7215762676654719033 作者:黑土豆