uv-ui
Version:
基于vue3的移动端组件库
147 lines (146 loc) • 4.29 kB
JavaScript
import { computed as l, watch as P, openBlock as i, createElementBlock as u, normalizeStyle as d, unref as s, createElementVNode as p, Fragment as N, renderList as T, createCommentVNode as B, renderSlot as L, toDisplayString as O } from "vue";
import { isObject as g } from "../../utils/type.js";
import { useRequestAnimationFrame as W } from "../../hooks/useRequestAnimationFrame.js";
import "../../hooks/useCountDown.js";
import "./circle-progress.vue_vue_type_style_index_0_lang.js";
const j = ["viewBox"], z = { key: 0 }, C = ["offset", "stop-color"], D = ["d"], I = ["d"], G = { class: "uv-circle-progress-text" }, V = {
name: "UvCircleProgress"
}, X = /* @__PURE__ */ Object.assign(V, {
props: {
size: {
type: [String, Boolean]
},
text: {
type: String,
default: ""
},
strokeWidth: {
type: [String, Number],
default: 40
},
startPosition: {
type: String,
default: "top"
},
color: {
type: [String, Object],
default: "#1989fa"
},
layerColor: {
type: String
},
fill: {
type: String,
default: "none"
},
clockwise: {
type: Boolean,
default: !0
},
strokeLinecap: {
type: String,
default: "round"
},
currentRate: {
type: Number
},
rate: {
type: [Number, String],
default: 100
},
speed: {
type: [Number, String],
default: 0
}
},
emits: ["update:currentRate"],
setup(c, { emit: y }) {
const t = c, { requestAnimationFrame: h, cancelAnimationFrame: E } = W();
let _ = 0;
const k = `uv-circle-${_++}`;
function $(r, e) {
const o = r ? 1 : 0;
return `M ${e / 2} ${e / 2} m 0, -500 a 500, 500 0 1, ${o} 0, 1000 a 500, 500 0 1, ${o} 0, -1000`;
}
const f = l(() => +t.strokeWidth + 1e3), v = l(() => $(t.clockwise, f.value)), b = l(() => {
const e = {
top: 0,
right: 90,
bottom: 180,
left: 270
}[t.startPosition];
return e ? {
transform: `rotate(${e}deg)`
} : {
transform: "rotate(0deg)"
};
}), w = l(() => g(t.color) ? Object.keys(t.color).sort((r, e) => parseFloat(r) - parseFloat(e)) : []), M = l(() => ({
fill: t.fill,
stroke: t.layerColor,
strokeWidth: t.strokeWidth + "px"
})), A = l(() => {
const { strokeWidth: e, currentRate: o, strokeLinecap: n } = t, a = 3140 * o / 100;
return {
stroke: g(t.color) ? `url(#${k})` : t.color,
strokeLinecap: n,
strokeWidth: `${+e + 1}px`,
strokeDasharray: `${a}px ${3140}px`
};
}), R = (r) => Math.min(Math.max(+r, 0), 100);
return P(
() => t.rate,
(r) => {
let e;
const o = Date.now(), n = t.currentRate, a = R(r), x = Math.abs(
(n - a) * 1e3 / +t.speed
), S = () => {
const F = Date.now(), m = Math.min((F - o) / x, 1) * (a - n) + n;
y("update:currentRate", R(parseFloat(m.toFixed(1)))), (a > n ? m < a : m > a) && (e = h(S));
};
t.speed ? (e && E(e), e = h(S)) : y("update:currentRate", a);
},
{ immediate: !0 }
), (r, e) => (i(), u("div", {
class: "uv-circle-progress",
style: d({ width: c.size + "px", height: c.size + "px" })
}, [
(i(), u("svg", {
class: "uv-circle-progress-svg",
viewBox: `0 0 ${s(f)} ${s(f)}`,
style: d(s(b))
}, [
s(g)(c.color) ? (i(), u("defs", z, [
p("linearGradient", {
id: k,
x1: "100%",
y1: "0%",
x2: "0%",
y2: "0%"
}, [
(i(!0), u(N, null, T(s(w), (o, n) => (i(), u("stop", {
key: n,
offset: o,
"stop-color": c.color[o]
}, null, 8, C))), 128))
])
])) : B("", !0),
p("path", {
class: "uv-circle-progress-layer",
style: d(s(M)),
d: s(v)
}, null, 12, D),
p("path", {
class: "uv-circle-progress-hover",
style: d(s(A)),
d: s(v)
}, null, 12, I)
], 12, j)),
L(r.$slots, "default", {}, () => [
p("div", G, O(c.text), 1)
])
], 4));
}
});
export {
X as default
};