本期为您详细讲解如何动态监控 Circle 环形进度条的当前进度点 并添加自定义元素跟随,希望能够帮助到您。
温馨提示:本案例 vue2 + vant2 源码实现,您可借鉴修改为 vue3 or React。
注:作者声明坚决不丢份!!!直接马国成C档起步,我上早八!!!
一:C档起步,先看效果
组件基本效果:👇
修改过后的效果:👇
二:我上早八(源码)!!!
<template>
<div class="loadings">
<!-- van-circle 标签中使用到的参数
v-model 代表 当前进度
rate 代表 目标进度
stroke-width 代表 进度条宽度
color 代表 进度条颜色,传入对象格式可以定义渐变色
layer-color 代表 轨道颜色(后续进度还未加载到的空白轨道颜色)
注:本案例传入的 color 值为渐变色对象 gradientColor,在 data 中定义。
-->
<van-circle
v-model="schedule"
:rate="schedule"
:speed="100"
:stroke-width="30"
:color="gradientColor"
layer-color="#EDF1F4"
class="custom-circle"
>
<!--
van-circle 标签中嵌入 template 模板标签,slot 设置为 default,
此时 template 标签里的内容为自定义内容。
-->
<template slot="default">
<!-- 下方为显示百分比的背景图,动态设置 style 值,添加 boxPosition 计算方法,动态计算距离左侧和距离顶部的距离 -->
<img
class="percentage-box"
:style="{ left: boxPosition.left, top: boxPosition.top }"
:src="require('@/assets/imgs/scan/a.png')"
alt=""
/>
<!-- 下方div显示百分比,动态设置 style 值,添加 boxPositionLabel 计算方法,动态计算距离左侧和距离顶部的距离 -->
<div
class="percentage-box percentage-box-text"
:style="{
left: boxPositionLabel.left,
top: boxPositionLabel.top,
}"
>
{{ schedule }}%
</div>
<!-- 下方为显示dot点的图片位置,动态设置 style 值,添加 boxPositionDot 计算方法,动态计算距离左侧和顶部的距离 -->
<img
class="percentage-box percentage-box-dot"
:style="{
left: boxPositionDot.left,
top: boxPositionDot.top,
}"
:src="require('@/assets/imgs/scan/dot.png')"
alt=""
/>
</template>
</van-circle>
</div>
</template>
<script>
export default {
data() {
return {
schedule: 94, // 当前进度值
gradientColor: { // 给 van-circle 标签设置进度条渐变色
"0%": "#93CFFF",
"100%": "#0D8FFE",
},
};
},
// 这里使用计算属性,根据 schedule 进度值变化而变化。注:计算属性需要有依赖
computed: {
// 下方三个方法的 radius 变量以及 return 出去的 left、right 可根据实际使用微调
// 因为是环形进度条,所以就因该想象到自定义元素是根据一个圆形来做旋转的,跟着进度点走的
boxPositionLabel() {
const radius = 49; // 进度条半径
const angle = (this.schedule / 100) * 360 - 90; // 转换为角度
const radians = (angle * Math.PI) / 180; // 转换为弧度
return {
left: 50 + radius * Math.cos(radians) + "%",
top: 37 + radius * Math.sin(radians) + "%",
};
},
boxPositionDot() {
const radius = 49; // 进度条半径
const angle = (this.schedule / 100) * 360 - 90; // 转换为角度
const radians = (angle * Math.PI) / 180; // 转换为弧度
return {
left: 50.1 + radius * Math.cos(radians) + "%",
top: 47 + radius * Math.sin(radians) + "%",
};
},
boxPosition() {
const radius = 49; // 进度条半径
const angle = (this.schedule / 100) * 360 - 90; // 转换为角度
const radians = (angle * Math.PI) / 180; // 转换为弧度
return {
left: 50 + radius * Math.cos(radians) + "%",
top: 35 + radius * Math.sin(radians) + "%",
};
},
// 方法注释:
// 以 boxPosition 为例,它计算并返回一个对象,该对象包含两个属性:left 和 top。
// const radius = 49 表示进度条的半径。
// const angle = (this.schedule / 100) * 360 - 90;
// 这里,将 this.schedule 转换为 0 到 360 之间的角度(表示一个完整的圆),然后,从这个角度中减去 90 度,为了将进度条的起始点从顶部移动到左侧。
//(因为 Math.cos(0) 是 1,Math.sin(0) 是 0,所以 (50 + radius, 35) 会是圆的顶部中心)。
// 角度到弧度的转换:
// const radians = (angle * Math.PI) / 180; 由于 JavaScript 的 Math 函数(如 Math.cos 和 Math.sin)期望输入是弧度而不是角度,所以这里将角度转换为弧度。
// 计算 left 和 top 的值:
// left: 50 + radius * Math.cos(radians) + "%"; 这里,50 是容器或父元素的中心点的 x 坐标(假设容器是 100% 宽)。然后,根据计算出的弧度,使用 Math.cos 函数来确定在 x 轴上的偏移量。最后,将结果转换为百分比字符串。
// top: 35 + radius * Math.sin(radians) + "%"; 同样,35 是容器或父元素的中心点的 y 坐标(假设容器的高度是 70% 或其他某个值)。然后,使用 Math.sin 函数来确定在 y 轴上的偏移量。最后,将结果转换为百分比字符串。
// 总结: 基于给定的进度 this.schedule 计算一个点在圆形或弧形进度条上的位置,并返回该点的 CSS 定位属性(left 和 top)。计算考虑了进度条的半径和起始角度(从顶部开始,并向左偏移 90 度)。
},
};
</script>
看到这里给你点个赞👍,感觉有用的记得点赞收藏加关注,持续更新中...
<style lang="less" scoped>
.loadings {
width: 100%;
height: 100%;
margin-top: 100px;
.custom-circle {
position: relative;
width: 330px;
height: 330px;
.schedule {
width: 36px;
}
}
.custom-circle .van-circle__layer {
position: absolute;
}
.custom-circle .van-circle__layer::after {
content: "";
position: absolute;
width: 10px;
height: 10px;
background-color: blue;
border-radius: 50%;
transform: translateY(-50%);
}
}
.percentage-box {
background: rgba(0, 0, 0, 0);
width: 60px;
position: absolute;
top: 0; /* 根据需要调整 */
left: 50%; /* 根据需要调整 */
transform: translateX(-50%);
border-radius: 5px;
/* 设置背景图像不重复 */
background-repeat: no-repeat;
/* 设置背景图像的位置,这里设置为居中顶部 */
background-position: center top;
/* 设置背景图像的大小,这里设置为覆盖整个元素 */
// background-size: cover;
/* (可选)设置背景图像固定,不随页面滚动 */
background-attachment: fixed;
}
.percentage-box-text {
position: absolute;
font-size: 20px;
color: white;
}
.percentage-box-dot {
position: absolute;
width: 24px;
}
</style>
注:版权所有,侵权必究。请尊重原创,未经许可禁止用于商业用途。