chore: sync local DataV boards and assets for standalone repo
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div class="grid-progress-bar" :id="domId">
|
||||
<div
|
||||
v-for="(item, index) in totalItems"
|
||||
:key="index"
|
||||
class="grid-item"
|
||||
:class="{ completed: index < completedItems }"
|
||||
:style="{ backgroundColor: getColor(completedItems, index) }"
|
||||
></div>
|
||||
</div>
|
||||
<div class="tip-text">{{ percent }}%</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watchEffect, onMounted, onUnmounted } from "vue";
|
||||
|
||||
// 示例数据
|
||||
const props = defineProps({
|
||||
domId: {
|
||||
type: String,
|
||||
default: "progressBar",
|
||||
require: true,
|
||||
},
|
||||
percent: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
totalWidth: {
|
||||
type: String,
|
||||
default: "80%",
|
||||
},
|
||||
gapWidth: {
|
||||
type: String,
|
||||
default: "4px",
|
||||
},
|
||||
gridWidth: {
|
||||
type: String,
|
||||
default: "6.68px",
|
||||
},
|
||||
gridHeight: {
|
||||
type: String,
|
||||
default: "21px",
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: "#4caf50",
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: "#ccc",
|
||||
},
|
||||
startColor: {
|
||||
type: String,
|
||||
//default: "#21564F",
|
||||
},
|
||||
endColor: {
|
||||
type: String,
|
||||
//default: "#3BFFBA",
|
||||
},
|
||||
});
|
||||
|
||||
const totalItems = ref(0);
|
||||
const completedItems = ref(0);
|
||||
const cacheContainerWidth = ref(0);
|
||||
|
||||
const getColor = (total, index) => {
|
||||
if (total <= index) {
|
||||
return props.bgColor;
|
||||
}
|
||||
if (!props.startColor || !props.endColor) {
|
||||
return props.color;
|
||||
}
|
||||
const totalSteps = total - 1; // 因为是从0到19,共有20个div
|
||||
const r1 = parseInt(props.startColor.substring(1, 3), 16);
|
||||
const g1 = parseInt(props.startColor.substring(3, 5), 16);
|
||||
const b1 = parseInt(props.startColor.substring(5, 7), 16);
|
||||
const r2 = parseInt(props.endColor.substring(1, 3), 16);
|
||||
const g2 = parseInt(props.endColor.substring(3, 5), 16);
|
||||
const b2 = parseInt(props.endColor.substring(5, 7), 16);
|
||||
|
||||
const r = Math.round(r1 + ((r2 - r1) * index) / totalSteps).toString(16);
|
||||
const g = Math.round(g1 + ((g2 - g1) * index) / totalSteps).toString(16);
|
||||
const b = Math.round(b1 + ((b2 - b1) * index) / totalSteps).toString(16);
|
||||
|
||||
return `#${r.padStart(2, "0")}${g.padStart(2, "0")}${b.padStart(2, "0")}`;
|
||||
};
|
||||
// const gradientColors = computed(() => {
|
||||
// const _completedItems = completedItems.value;
|
||||
// const colors = [];
|
||||
// for (let i = 0; i < _completedItems; i++) {
|
||||
// colors.push(getColor(_completedItems, i));
|
||||
// }
|
||||
// return colors;
|
||||
// });
|
||||
/////
|
||||
const getTransNumFromCss = (v) => {
|
||||
return Number(v.replace("px", ""));
|
||||
};
|
||||
const setTotalItems = () => {
|
||||
const div =
|
||||
(cacheContainerWidth.value - getTransNumFromCss(props.gapWidth)) /
|
||||
(getTransNumFromCss(props.gapWidth) + getTransNumFromCss(props.gridWidth));
|
||||
console.log(cacheContainerWidth.value, totalItems.value, "值==---===");
|
||||
totalItems.value = Math.floor(div);
|
||||
completedItems.value = Math.floor((totalItems.value * props.percent) / 100);
|
||||
};
|
||||
|
||||
const setContainerWidth = () => {
|
||||
const dom = document.getElementById(props.domId);
|
||||
cacheContainerWidth.value = dom.offsetWidth;
|
||||
setTotalItems();
|
||||
};
|
||||
const resizeHandler = () => {
|
||||
setContainerWidth();
|
||||
};
|
||||
const onResize = () => {
|
||||
window.addEventListener("resize", resizeHandler);
|
||||
};
|
||||
const removeResize = () => {
|
||||
window.removeEventListener("resize", resizeHandler);
|
||||
};
|
||||
onMounted(() => {
|
||||
resizeHandler();
|
||||
onResize();
|
||||
});
|
||||
onUnmounted(() => {
|
||||
removeResize();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.grid-progress-bar {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: v-bind(gapWidth);
|
||||
width: v-bind(totalWidth);
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
width: v-bind(gridWidth); /* 固定宽度 */
|
||||
height: v-bind(gridHeight); /* 固定高度 */
|
||||
background-color: v-bind(bgColor);
|
||||
}
|
||||
|
||||
.completed {
|
||||
background-color: v-bind(color);
|
||||
}
|
||||
.tip-text {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
font-size: 20px;
|
||||
height: v-bind(gridHeight);
|
||||
line-height: v-bind(gridHeight);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user