开发过程中会碰到各种各样的ui样式,除了普通的长条状进度条,还有各种各样的进度条中,比如我就碰到了一个格子状的进度条,下面简单介绍一下(实际还有一个环形渐变进度条,下一篇在介绍😂)
如果让你编写下面连续的格子效果,你会怎么编呢
如下所示,我们通过 backgroundImage + linear-gradient 渐变 + 固定大小背景 + 重复铺满
即可实现该效果(就没必要编写那么多的div了)
//只需要控制其长度就可以控制实际格子长度了,这里使用的是tailwindcss,不多解释了
<div className="w-[458px] h-[23px] bg-[rgba(4,124,255,0.11)] flex items-center rounded-[5px]">
<div
className="h-[14px] w-[80%]"
style={{
//设置背景
backgroundImage:
"linear-gradient(90deg,transparent 50%, #20A6FF 0)",
//设置大小,这样才可以利用其大小填充不满的特性,通过重复填充达成连续格子状视图了
backgroundSize: "10px 14px",
backgroundRepeat: "repeat",
}}
/>
</div>
我们在配合css变量做一个初始动画
@keyframes gezi_perc_keyframes
{
from {width: 0}
to {width: var(--perc);}
}
const getPercStyles = (perc: number) => ({
"--perc": `${perc}%`,
});
style={{
...getPercStyles(item.perc),
width: `${item.perc}%`,
animationName: "gezi_perc_keyframes",
animationDuration: "1s",
animationTimingFunction: "linear",
transition: "width 1s",
}}
为了保证不最大的不占慢整个进度条(显得夸张一般会有一些留白),我们可以自己设置占用百分比不到100%即可,或者右侧设置一个间距,这个最大值还是按照100%,本案例按照右侧留白方式编写
实际实现如下所示
...jsx
const GeziPercView = (props: {
title: string,
info: any[] //实际是name、value也可以自己调整
}) => {
let max = 0;
info.forEach((item) => {
if (item.value > max) {
max = item.value;
}
});
info.forEach((item) => {
item.perc = (item.value / max) * 100;
if (item.perc < 0.1) item.perc = 0.1;
});
const getPercStyles = (perc: number) => ({
"--ydqdperc": `${perc}%`,
});
return (
<div className="h-[430px] w-full">
<CardTitle title={props.title} />
<div className="flex flex-col">
{props.info.map((item, index) => (
<div
key={index}
className={`flex items-center ${
index < 1 ? "mt-[36px]" : "mt-[18px]"
}`}
>
<span className="text-[14px] font-thin w-[108px] text-right mr-[20px]">
{item.name}
</span>
<div className="w-[458px] h-[24px] bg-[rgba(4,124,255,0.11)] flex items-center rounded-[5px]">
<div
className="h-[14px] ml-2 mr-8"
style={{
...getPercStyles(item.perc),
width: `${item.perc}%`,
backgroundImage:
"linear-gradient(90deg, #20A6FF 50%, transparent 0)",
backgroundSize: "10px 100%",
backgroundRepeat: "repeat",
animationName: "gezi_perc_keyframes",
animationDuration: "1s",
animationTimingFunction: "linear",
transition: "width 1s",
}}
/>
</div>
<span className="text-[14px] font-thin ml-[14px] hover:scale-[150%]">
{item.value}
</span>
</div>
))}
</div>
</div>
);
};
...css
@keyframes gezi_perc_keyframes
{
from {width: 0}
to {width: var(--ydqdperc);}
}