效果图
<div class="w100 h100 anquanBox">
<div class="demo">
<div class="ul">
<div
class="li"
v-for="(item, index) in transformList"
:key="item"
:style="{ transform: item.value }"
>
<span
:style="{
transform:
'rotate(' +
index * (360 / transformList.length) +
'deg)',
}"
>{{ item.name }}</span
>
</div>
</div>
</div>
<div class="demoBox">
<div class="huanxing">
<img src="@/assets/anquanhuan.png" alt="" />
</div>
<div class="textdec">
{{ state.safetyList.safetyIndex }}
</div>
<div id="anquanchart" class="anquanchart w100 h100"></div>
</div>
</div>
safetyList: {
name: "三恒公司302室测试用1号工作面",
safetyIndex: 74,
data: [{
name: "支架",
safetyIndex: 74
},
{
name: "钻孔",
safetyIndex: 87
},
{
name: "锚杆",
safetyIndex: 62
},
{
name: "离层",
safetyIndex: 77
},
{
name: "顶底板",
safetyIndex: 57
},
{
name: "激光",
safetyIndex: 91
}
]
},
const transformList = computed(() => {
let num = state.safetyList.data.length
let angle = 360 / num
let arr = []
for (let index = 0; index < num; index++) {
arr.push({
val: index * angle,
name: state.safetyList.data[index].name
})
}
arr = arr.map(d => getAxis(d.val, d.name))
return arr
})
首先,它获取 state.safetyList.data 的长度,并将其保存在变量 num 中。
接下来,它计算出每个元素需要旋转的角度,通过将360度除以 num 得到 angle。
然后,它创建一个空数组 arr。
使用 for 循环遍历 num 次,每次迭代时生成一个对象,该对象包含两个属性:
val:表示旋转的角度,通过将当前索引乘以 angle 得到。
name:表示安全列表中对应元素的名称,通过访问 state.safetyList.data[index].name 得到。
将生成的对象推入 arr 数组中。
最后,使用 map 方法对 arr 数组进行遍历,将每个对象作为参数传递给 getAxis 函数进行处理,并将处理结果返回。
最终,计算属性 transformList 返回处理后的数组 arr,其中每个元素都经过了 getAxis 函数的处理。
综上所述,该计算属性用于生成一组旋转和名称数据,供后续使用。
function getAxis(angle, name) {
return {
value: `translate(${70 * Math.sin(angle * Math.PI / 180) + 70}px, ${70 - 70 * Math.cos(angle * Math.PI / 180)}px)`,
name: name
}
}
函数的目的是根据给定的角度 angle 计算平移的坐标,并将结果存储在 value 属性中。具体的计算过程如下:
使用三角函数计算平移的 x 坐标:70 * Math.sin(angle * Math.PI / 180) + 70。
Math.sin(angle * Math.PI / 180) 用于将角度转换为弧度,并计算正弦值。
将计算得到的正弦值乘以 70,然后加上 70,以确保 x 坐标在适当的范围内。
使用三角函数计算平移的 y 坐标:70 - 70 * Math.cos(angle * Math.PI / 180)。
Math.cos(angle * Math.PI / 180) 用于将角度转换为弧度,并计算余弦值。
将 70 减去计算得到的余弦值乘以 70,以确保 y 坐标在适当的范围内。
将计算得到的 x 和 y 坐标组合成一个字符串,并存储在 value 属性中。
将给定的 name 存储在 name 属性中。
返回包含 value 和 name 属性的对象。
@keyframes spin {
from {
transform: translate(-50%, -50%) rotate(0deg);
}
to {
transform: translate(-50%, -50%) rotate(360deg);
}
}
具体来说,transform属性用于对元素进行变换操作。在这行代码中,使用了translate()和rotate()函数来实现平移和旋转效果。
translate(-50%, -50%)表示将元素向左上方平移50%的宽度和高度。这通常用于将元素的中心点定位在父容器的中心位置。
rotate(360deg)表示将元素以中心点为轴心进行360度的旋转。
综合起来,这行代码表示元素在动画的最后一帧时,以自身中心点为轴心,沿顺时针方向旋转360度,并向左上方平移50%的宽度和高度。这样可以实现元素旋转并保持在父容器的中心位置。
@keyframes spin1 {
from {
transform: rotate(0deg);
}
to {
transform: rotate(-360deg);
}
}
@keyframes spin2 {
from {
transform: translate(-50%, -50%) rotate(0deg);
}
to {
transform: translate(-50%, -50%) rotate(0deg);
}
}
.demo {
position: absolute;
left: 49.4%;
top: 54%;
width: 240px;
height: 200px;
color: #fff;
animation: spin 16s linear infinite;
}
.ul {
position: relative;
text-align: center;
width: 100%;
height: 100%;
.li {
position: absolute;
transform-origin: 0px 0px;
span {
white-space: nowrap;
display: inline-block;
position: relative;
padding: 4px 30px;
border-radius: 50% 50% 0 0;
border: 2px solid rgba(0, 255, 247, 1);
border-left: 2px solid transparent;
border-right: 2px solid transparent;
border-bottom: 2px solid transparent;
transform-origin: 50px 30px;
width: 100px;
text-align: center;
&::before {
position: absolute;
content: "";
top: 5px;
left: 7px;
height: 10px;
width: 2px;
background-color: rgba(0, 255, 247, 1);
transform: rotate(-20deg);
}
&::after {
position: absolute;
content: "";
top: 5px;
right: 7px;
height: 10px;
width: 2px;
background-color: rgba(0, 255, 247, 1);
transform: rotate(18deg);
}
}
}
}
// end
.huanxing {
position: absolute;
left: 50%;
top: 54%;
width: 150px;
height: 150px;
animation: spin 16s linear infinite;
img {
width: 100%;
height: 100%;
}
}
.textdec {
position: absolute;
left: 50%;
top: 54%;
font-size: 42px;
font-weight: bold;
color: transparent;
background: linear-gradient(
180deg,
rgba(255, 255, 255, 1) 0%,
rgba(107, 253, 255, 1) 100%
);
-webkit-background-clip: text;
transform: translate(-50%, -50%);
}
.anquanchart {
position: absolute;
left: 50%;
top: 54%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
}