import { Match, Show, Switch } from "solid-js"; import { Icon } from "../Icon"; import { useClassList } from "../utils/useProps" export interface StrokeProps { percent: number color: string } type ProgressProps = { classList?: any, class?: string, hidePercent?: boolean, status?: 'normal'|'error'|'active'|'success', value?: number, strokeWidth?: number, textInside?: boolean, infoRender?: Function, strokeColor?: string | string[] | StrokeProps[], type?: 'line'|'circle', radius?: number, max?: number, } export function Progress (props: ProgressProps) { const max = () => props.max ?? 100; const value = () => { if(props.value && props.value < 0) { return 0; } if(props.value && props.value >= max()) { return max(); } return props.value ?? 0; }; const strokeWidth = props.strokeWidth ?? 10; const type = props.type ?? 'line'; const radius = () => props.radius ?? 60; let status = () => { if (value() === 100) { return 'finished'; } return props.status ?? 'normal'; } const classList = () => useClassList(props, 'cm-progress', { 'cm-progress-hide-info': props.hidePercent, [`cm-progress-${status()}`]: !!status(), [`cm-progress-${type}`]: !!type, }); const width = () => `${value()}%`; const text = () => { const sta = status(); const size = type === 'line' ? 12 : 24; if (props.infoRender) { return props.infoRender(sta, value()); } if (sta === 'finished') { return ; } if (sta === 'error') { return ; } return `${value()}%`; } const style = () => { const obj: any = { width: width(), height: `${strokeWidth}px` }; if (props.strokeColor) { if (typeof props.strokeColor === 'string') { obj['background-color'] = props.strokeColor; } if (props.strokeColor instanceof Array) { const length = props.strokeColor.length; const arr = (props.strokeColor as string[]).map((color: string, index: number) => { return color + ' ' + (index / length) * 100 + '%'; }); obj['background-image'] = `linear-gradient(to right, ${arr.join(',')})`; } } return obj; } // 计算当前角度对应的弧度值 const rad = 2 * Math.PI; // 极坐标转换成直角坐标 const x = () => (Math.sin(rad) * radius()).toFixed(2); const y = () => -(Math.cos(rad) * radius()).toFixed(2); const tx = () => radius() + strokeWidth / 2; // path 属性 A 61 61 0 1 1 -0 61 A 61 61 0 1 1 -0 -61 const descriptions = () => ['M', 0, -radius(), 'A', radius(), radius(), 0, 1, 1, x(), -y(), 'A', radius(), radius(), 0, 1, 1, x(), y()]; const circleStyle = () => { const percent = () => value() / max(); const dd = () => rad * radius(); const offset = () => dd() * (1 - percent()); const obj: any = { 'stroke-dashoffset': `${offset()}`, 'stroke-dasharray': dd() } if (props.strokeColor) { if (typeof props.strokeColor === 'string') { obj['stroke'] = props.strokeColor; } if (props.strokeColor instanceof Array) { for (let i = 0; i < props.strokeColor.length; i++) { const stroke = props.strokeColor[i] as StrokeProps; if (percent() * 100 >= stroke.percent) { obj['stroke'] = stroke.color; } } } } return obj; } return
{`${value()}%`}
{text()}
}