创建一个动态进度环组件
在现代网页设计中,进度环是一种常见的视觉元素,用于展示任务的完成度或加载状态。本文将介绍如何使用Vue.js和Less创建一个动态进度环组件,该组件不仅具有美观的视觉效果,还能够根据用户输入动态改变颜色。
已经支持动态配置-----
相似&灵感
抖音代码示例–直通车
HTML结构
首先,我们定义了组件的基本HTML结构。在<template>
标签内,我们创建了一个div
元素,它包含了两个子元素:一个用于显示进度环的div
和一个输入框,用户可以通过输入框来改变进度环的颜色。
<template>
<div class="progress-ring">
<div class="progress-ring-circle">
<span
v-for="(item, index) in 25"
:key="index"
:style="{ transform: `rotate(${(index / stripNumber) * 360 + 210}deg)` }"
></span>
</div>
<input type="text" v-model="value" />
<button type="button" @click="chColor()">开始</button>
</div>
</template>
Less样式
接下来,我们使用Less来定义进度环的样式。我们创建了一个.progress-ring-circle
类,它定义了进度环的基本样式,包括尺寸、位置和旋转效果。我们还定义了一个span
伪元素,用于显示进度环的颜色。
<style scoped lang="less">
.progress-ring-circle {
width: 40vw;
height: 40vw;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
transform: rotate3d(1, 0, 0, -66deg);
margin: 120px;
span {
--bg: rgba(0, 0, 0, 0);
--sg: transparent;
position: absolute;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: start;
// transform-origin: 0% 0%; /* 将旋转原点设置在左上角 */
}
span::after {
content: "";
width: 2.5vw; // 可自行改为动态宽度
height: 3vw;
position: absolute;
background-color: var(--bg);
box-shadow: 0 0 0.5vw var(--sg), 0 0 1vw var(--sg), 0 0 2vw var(--sg);
transition: 0.8s linear; /* 指定过渡属性 */
}
}
</style>
Vue.js逻辑
最后,我们使用Vue.js来添加动态功能。在<script>
标签内,我们定义了组件的逻辑。我们创建了一个名为ProgressRing
的Vue组件,并在data
函数中定义了几个数据属性,包括进度环的颜色值和进度值。
<script>
export default {
name: "ProgressRing",
data() {
return {
items: ["item 1", "item 2", "item 3", "item 4", "item 5"], // 你可以根据需要修改这个数组
value: 20,
stripNumber: 25
};
},
mounted() {},
methods: {
chColor() {
const main = document.querySelector(".progress-ring-circle");
console.log(main.children.length);
for (let i = main.children.length - 1; i >= 0; i--) {
var number = this.stripNumber - this.value / (100 / this.stripNumber);
if (i >= number) {
main.children[i].style.setProperty(
"--bg",
`hsl(${(i / this.stripNumber) * 360}, 100%, 50%)`
);
main.children[i].style.setProperty(
"--sg",
`hsl(${(i / this.stripNumber) * 360}, 100%, 50%)`
);
} else {
main.children[i].style.setProperty("--bg", "rgba(0, 0, 0, 0)");
main.children[i].style.setProperty("--sg", "transparent");
}
}
}
}
};
</script>
在chColor
方法中,我们根据用户输入的值动态改变进度环的颜色。我们通过遍历进度环的子元素,并根据当前的进度值来设置每个子元素的颜色。
通过以上步骤,我们成功创建了一个动态进度环组件,它不仅具有美观的视觉效果,还能够根据用户输入动态改变颜色。这种组件在网页设计中非常实用,可以用于展示加载状态或任务完成度。
完整代码:
<style scoped lang="less">
.progress-ring-circle {
width: 40vw;
height: 40vw;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
transform: rotate3d(1, 0, 0, -66deg);
margin: 120px;
span {
--bg: rgba(0, 0, 0, 0);
--sg: transparent;
position: absolute;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: start;
// transform-origin: 0% 0%; /* 将旋转原点设置在左上角 */
}
span::after {
content: "";
width: 2.5vw; // 改变stripNumber时记得改
height: 3vw;
position: absolute;
background-color: var(--bg);
box-shadow: 0 0 0.5vw var(--sg), 0 0 1vw var(--sg), 0 0 2vw var(--sg);
transition: 0.8s linear; /* 指定过渡属性 */
}
}
</style>
<template>
<div class="progress-ring">
<div class="progress-ring-circle">
<span
v-for="(item, index) in stripNumber"
:key="index"
:style="{
transform: `rotate(${(index / stripNumber) * 360 + 210}deg)`
}"
></span>
</div>
<input type="text" v-model="value" />
<button type="button" @click="chColor()">开始</button>
</div>
</template>
<script>
export default {
name: "ProgressRing",
data() {
return {
items: ["item 1", "item 2", "item 3", "item 4", "item 5"], // 你可以根据需要修改这个数组
value: 20,
stripNumber: 25
};
},
mounted() {},
methods: {
chColor() {
const main = document.querySelector(".progress-ring-circle");
console.log(main.children.length);
// for (let i = 0; i < main.children.length; i++) {
for (let i = main.children.length - 1; i >= 0; i--) {
var number = this.stripNumber - this.value / (100 / this.stripNumber);
if (i >= number) {
main.children[i].style.setProperty(
"--bg",
// "red"
`hsl(${(i / this.stripNumber) * 360}, 100%, 50%)`
);
main.children[i].style.setProperty(
"--sg",
`hsl(${(i / this.stripNumber) * 360}, 100%, 50%)`
);
} else {
main.children[i].style.setProperty("--bg", "rgba(0, 0, 0, 0)");
main.children[i].style.setProperty("--sg", "transparent");
}
}
}
}
};
</script>