记录实现使用svg动态扇形进度条

679 阅读1分钟

原理,参考地址:sparkbox.com/foundry/how…

圆周长计算:

image.png

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Title</title>
        <style>
            /* http://meyerweb.com/eric/tools/css/reset/ 
            v2.0 | 20110126
            License: none (public domain)
            */

            html,
            body,
            div,
            span,
            applet,
            object,
            iframe,
            h1,
            h2,
            h3,
            h4,
            h5,
            h6,
            p,
            blockquote,
            pre,
            a,
            abbr,
            acronym,
            address,
            big,
            cite,
            code,
            del,
            dfn,
            em,
            img,
            ins,
            kbd,
            q,
            s,
            samp,
            small,
            strike,
            strong,
            sub,
            sup,
            tt,
            var,
            b,
            u,
            i,
            center,
            dl,
            dt,
            dd,
            ol,
            ul,
            li,
            fieldset,
            form,
            label,
            legend,
            table,
            caption,
            tbody,
            tfoot,
            thead,
            tr,
            th,
            td,
            article,
            aside,
            canvas,
            details,
            embed,
            figure,
            figcaption,
            footer,
            header,
            hgroup,
            menu,
            nav,
            output,
            ruby,
            section,
            summary,
            time,
            mark,
            audio,
            video {
                margin: 0;
                padding: 0;
                border: 0;
                font-size: 100%;
                font: inherit;
                font-size: 12px;
                vertical-align: baseline;
            }
            /* HTML5 display-role reset for older browsers */
            article,
            aside,
            details,
            figcaption,
            figure,
            footer,
            header,
            hgroup,
            menu,
            nav,
            section {
                display: block;
            }
            body {
                line-height: 1;
            }
            ol,
            ul {
                list-style: none;
            }
            blockquote,
            q {
                quotes: none;
            }
            blockquote:before,
            blockquote:after,
            q:before,
            q:after {
                content: "";
                content: none;
            }
            table {
                border-collapse: collapse;
                border-spacing: 0;
            }

            .svg-progress {
                position: relative;
                width: 12px;
                height: 12px;
            }
            .svg-progress svg {
                position: absolute;
            }
            .svg-progress .svg-circle {
                /* display: inline-flex; */
                width: 12px;
                height: 12px;
                position: relative;
            }
            .svg-progress .svg-inner {
                height: 12px;
                position: absolute;
                top: 50%;
                left: 50%;
                margin-left: -3.75px;
                margin-top: -3.75px;

                /* display: inline-flex; */
            }
            .svg-container {
                height: 12px;
                position: relative;
            }
            .svg-container svg {
                position: absolute;
            }
        </style>
    </head>
    <body>
        <h1>饼图</h1>
        <div>
            <div class="svg-container">
                <span>UI svg</span>
                <svg
                    width="12"
                    height="12"
                    viewBox="0 0 12 12"
                    fill="none"
                    xmlns="http://www.w3.org/2000/svg"
                >
                    <circle
                        cx="6"
                        cy="6"
                        r="5.475"
                        stroke="#275EDB"
                        stroke-width="1.05"
                    />
                    <path
                        d="M9.75 6C9.75 5.50754 9.653 5.01991 9.46455 4.56494C9.27609 4.10997 8.99987 3.69657 8.65165 3.34835C8.30343 3.00013 7.89003 2.72391 7.43506 2.53545C6.98009 2.347 6.49246 2.25 6 2.25L6 6H9.75Z"
                        fill="#275EDB"
                    />
                </svg>
            </div>
            <div>
                <span>all read</span>
                <div class="svg-container">
                    <svg
                        width="12"
                        height="12"
                        viewBox="0 0 12 12"
                        fill="none"
                        xmlns="http://www.w3.org/2000/svg"
                    >
                        <circle
                            cx="6"
                            cy="6"
                            r="5.475"
                            stroke="#275EDB"
                            stroke-width="1.05"
                        />
                        <rect
                            x="2.54999"
                            y="5.85843"
                            width="1.05"
                            height="3.75"
                            rx="0.525"
                            transform="rotate(-45 2.54999 5.85843)"
                            fill="#275EDB"
                        />
                        <rect
                            x="8.70178"
                            y="3.52499"
                            width="1.05"
                            height="6"
                            rx="0.525"
                            transform="rotate(45 8.70178 3.52499)"
                            fill="#275EDB"
                        />
                    </svg>
                </div>
            </div>
            <div>
                <span>all un read</span>
                <div class="svg-container">
                    <svg
                        width="12"
                        height="12"
                        viewBox="0 0 12 12"
                        fill="none"
                        xmlns="http://www.w3.org/2000/svg"
                    >
                        <circle
                            cx="6"
                            cy="6"
                            r="5.475"
                            stroke="#d9d9d9"
                            stroke-width="1.05"
                        />
                        <rect
                            x="2.54999"
                            y="5.85843"
                            width="1.05"
                            height="3.75"
                            rx="0.525"
                            transform="rotate(-45 2.54999 5.85843)"
                            fill="#d9d9d9"
                        />
                        <rect
                            x="8.70178"
                            y="3.52499"
                            width="1.05"
                            height="6"
                            rx="0.525"
                            transform="rotate(45 8.70178 3.52499)"
                            fill="#d9d9d9"
                        />
                    </svg>
                </div>
            </div>

            <div class="svg-progress">
                <div class="svg-circle">
                    <svg
                        height="12"
                        width="12"
                        viewBox="0 0 12 12"
                        fill="none"
                        xmlns="http://www.w3.org/2000/svg"
                    >
                        <circle
                            cx="6"
                            cy="6"
                            r="5.475"
                            stroke="#275EDB"
                            fill="transparent"
                            stroke-width="1.05"
                        />
                    </svg>
                </div>
                <div class="svg-inner">
                    <svg
                        height="7.5"
                        width="7.5"
                        viewBox="0 0 7.5 7.5"
                        fill="none"
                        xmlns="http://www.w3.org/2000/svg"
                    >
                        <circle
                            r="1.875"
                            cx="3.75"
                            cy="3.75"
                            fill="transparent"
                            stroke="#275EDB"
                            stroke-width="3.75"
                            stroke-dasharray="calc(25 * 11.78 / 100) 11.78"
                            transform="rotate(-90) translate(-7.5)"
                        />
                    </svg>
                </div>
            </div>

            <div id="container">
                <div class="svg-container">
                    <svg
                        width="12"
                        height="12"
                        viewBox="0 0 12 12"
                        fill="none"
                        xmlns="http://www.w3.org/2000/svg"
                    >
                        <circle
                            cx="6"
                            cy="6"
                            r="5.475"
                            stroke="#d9d9d9"
                            stroke-width="1.05"
                        />
                        <rect
                            x="2.54999"
                            y="5.85843"
                            width="1.05"
                            height="3.75"
                            rx="0.525"
                            transform="rotate(-45 2.54999 5.85843)"
                            fill="#d9d9d9"
                        />
                        <rect
                            x="8.70178"
                            y="3.52499"
                            width="1.05"
                            height="6"
                            rx="0.525"
                            transform="rotate(45 8.70178 3.52499)"
                            fill="#d9d9d9"
                        />
                    </svg>
                </div>
            </div>
            <hr />
            <h6>圆周长:31.4</h6>
            <div>
                <svg height="20" width="20" viewBox="0 0 20 20">
                    <circle r="10" cx="10" cy="10" fill="#eee" />
                    <circle
                        r="5"
                        cx="10"
                        cy="10"
                        fill="transparent"
                        stroke="#275EDB"
                        stroke-width="10"
                        stroke-dasharray="calc(35 * 31.4 / 100) 31.4"
                        transform="rotate(-90) translate(-20)"
                    />
                </svg>
            </div>
        </div>
        <script>
            // https://sparkbox.com/foundry/how_to_code_an_SVG_pie_chart

            // Google 搜索,
            // circumference of circle
            // 输入圆的半径,算出圆周长

            const container = document.querySelector("#container");
            const Circumference = Math.PI * 2 * 1.875; // 圆周长
            const html = (progress) => {
                if (progress === 100) {
                    return `<div class="svg-progress">
                        <div class="svg-circle">
                            <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <circle cx="6" cy="6" r="5.475" stroke="#275EDB" stroke-width="1.05"/>
                                <rect x="2.54999" y="5.85843" width="1.05" height="3.75" rx="0.525" transform="rotate(-45 2.54999 5.85843)" fill="#275EDB"/>
                                <rect x="8.70178" y="3.52499" width="1.05" height="6" rx="0.525" transform="rotate(45 8.70178 3.52499)" fill="#275EDB"/>
                            </svg>
                        </div>
                    </div>`;
                }

                return `
            <div class="svg-progress">
                <div class="svg-circle">
                    <svg
                        height="12"
                        width="12"
                        viewBox="0 0 12 12"
                        fill="none"
                        xmlns="http://www.w3.org/2000/svg"
                    >
                        <circle
                            cx="6"
                            cy="6"
                            r="5.475"
                            stroke="#275EDB"
                            fill="transparent"
                            stroke-width="1.05"
                        />
                    </svg>
                </div>
                <div class="svg-inner">
                    <svg
                        height="7.5"
                        width="7.5"
                        viewBox="0 0 7.5 7.5"
                        fill="none"
                        xmlns="http://www.w3.org/2000/svg"
                    >
                        <circle
                            r="1.875"
                            cx="3.75"
                            cy="3.75"
                            fill="transparent"
                            stroke="#275EDB"
                            stroke-width="3.75"
                            stroke-dasharray="calc(${progress} * ${Circumference} / 100) ${Circumference}"
                            transform="rotate(-90) translate(-7.5)"
                        />
                    </svg>
                </div>
            </div>
            `;
            };
            let progress = 0;
            let interval = null;
            function trigger(timer = 10) {
                interval = setInterval(() => {
                    if (progress > 30) {
                        clearInterval(interval);
                        trigger(50);
                    }
                    if (progress > 100) {
                        clearInterval(interval);
                        return;
                    }
                    container.innerHTML = html(progress++);
                }, timer);
            }
            setTimeout(() => {
                trigger();
            }, 1 * 1000);
        </script>
    </body>
</html>