美文网首页前端开发那些事儿
Step by step!css3、svg 画圆形渐变圆角进度条

Step by step!css3、svg 画圆形渐变圆角进度条

作者: 景阳冈大虫在此 | 来源:发表于2020-05-23 16:03 被阅读0次

css3

首先摆上那个灰色的圈



然后盖上一个蓝色的半圈(由一半的蓝色和一半的透明border组成)



让它转起来
这就像进度为百分之五十的时候的样子

把右边给他遮住,这样他还没到百分之五十的时候,右边不会出现这个半圆的一个部分



动起来是这样的


左边.gif
然后右边我们如法炮制一个,这样整个圆就实现了
完整效果
<template>
    <div class="processCircle">
            <div class="grayCircle center">
                <p>{{ percent }}%</p>
            </div>
            <section class="half left">
                <div class="blueCircle"></div>
            </section>
            <section class="half right">
                <div class="blueCircle"></div>
            </section>
    </div>
</template>
<script>
export default {
    name: 'processCircle',
    data() {
        return {
            percent: 1,
            timeLimit: 5000
        };
    },
    created() {
        let gap = this.timeLimit / 100;
        let clock = setInterval(() => {
            if (this.percent < 99) {
                let res = Math.floor(this.percent + 4);
                this.percent = res >= 99 ? 99 : res;
                if (this.percent > 40) {
                    gap = 0.5;
                }
            } else {
                clearInterval(clock);
            }
        }, 100);
    }
};
</script>
<style lang="scss">
.processCircle {
    $maxl: 110px;
    position: relative;
    width: $maxl;
    height: $maxl;
    display: flex;
    align-items: flex-end;
    .half {
        width: 51%;
        height: 100%;
        overflow: hidden;
        position: absolute;
        top: 0;
    }
    .center {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        display: flex;
        p {
            text-align: center;
            margin: auto;
            color: #384369;
            font-size: 18px;
            font-family: fzlt_bold;
        }
    }
    @mixin circle($w) {
        width: $w;
        height: $w;
        $wh: $w / 2;
        border-radius: $wh;
    }
    .grayCircle {
        @include circle(106px);
        border: 0;
        border: 6px solid #f4f4f4;
    }
    .blueCircle {
        // border-image: linear-gradient(to right, #90b2ff, #6d91ff) 1 10;
        @include circle($maxl);
        border: 10px solid transparent;
    }
    .left {
        left: 0;
        .blueCircle {
            border-top: 10px solid #6d91ff;
            border-left: 10px solid #6d91ff;
            transform: rotate(135deg);
            animation: load_left 2s ease-in;
            animation-fill-mode: forwards;
        }
    }
    .right {
        right: 0;
        .blueCircle {
            transform: rotate(135deg);
            position: relative;
            left: -$maxl / 2;
            animation: load_right 3s ease-in;
            animation-fill-mode: forwards;
        }
    }

    @-webkit-keyframes load_left {
        0% {
            border-top: 10px solid #6d91ff;
            border-left: 10px solid #6d91ff;
            transform: rotate(150deg);
        }
        50% {
            border-top: 10px solid #6d91ff;
            border-left: 10px solid #6d91ff;
            transform: rotate(315deg);
        }
        100% {
            border-top: 10px solid #6d91ff;
            border-left: 10px solid #6d91ff;
            transform: rotate(315deg);
        }
    }
    @-webkit-keyframes load_right {
        0% {
            transform: rotate(135deg);
        }
        50% {
            border-bottom: 10px solid #90b2ff;
            border-right: 10px solid #90b2ff;
            transform: rotate(135deg);
        }
        100% {
            border-bottom: 10px solid #6d91ff;
            border-right: 10px solid #6d91ff;
            transform: rotate(312deg);
        }
    }
    .success {
        width: 90px;
        height: 90px;
        position: relative;
        margin: 0 auto;
        img {
            width: 100%;
            height: auto;
        }
    }
}
</style>

最终

!!
但是这个效果和最终设想的差别有比较大的距离。如果使用这个方案是做不出渐变色和圆角的效果的。

svg


只要去学习一下svg的圆和渐变,就能很容易地做出来这个效果。
所以在这里简单说一下动画的原理。
circle标签上支持两个属性,stroke-dashoffsetstroke-dasharray

stroke-dashoffset 属性指定了dash模式到路径开始的距离
如果使用了一个 <百分比> 值, 那么这个值就代表了当前viewport的一个百分比。
属性stroke-dasharray可控制用来描边的点划线的图案范式。
作为一个外观属性,它也可以直接用作一个CSS样式表内部的属性。

噫,老实说没看懂这两个参数到底是干啥的。动手试一下这两个属性。

控制变量法:
  1. 我的圆周长大约为314。
    此时设置
    stroke-dashoffset: 0;
    stroke-dasharray: 314;

则圆为这样


  1. 设置
    stroke-dashoffset: 0;
    stroke-dasharray: 298;

合理地猜测,stroke-dasharray的改变可以变更轨迹的样子。
其实如果把这个值变小,这个外围就是虚线,所以仅仅靠变更这个值去实现连续的蓝色弧线是行不通的。


  1. 变更stroke-dashoffset
    stroke-dashoffset: 314;
    stroke-dasharray: 314;

如果这两值相等,则蓝色的部分就消失了。

    stroke-dashoffset: 100;
    stroke-dasharray: 314;

终上所述,设置 stroke-dasharray为圆周长,让stroke-dashoffset从大到小变化,则动画就会从缺到完整那么去动。

我这里设置了最终为有缺口的99%状态,效果及源码如下:


最终效果

完整代码如下

// progressBar.vue
<template>
    <div class="loadingContainer">
        <svg
            :width="progressBarParams.boxWidth"
            :height="progressBarParams.boxHeight"
            :VIEWBOX="
                '0 0 ' +
                    progressBarParams.boxWidth +
                    ' ' +
                    progressBarParams.boxHeight
            "
            id="svg"
        >
            <defs>
                <linearGradient id="cirGradient">
                    <stop
                        offset="0%"
                        :stop-color="progressBarParams.frontColor"
                    />
                    <stop
                        offset="100%"
                        :stop-color="progressBarParams.endColor"
                    />
                </linearGradient>
            </defs>
            <circle
                :cx="progressBarParams.boxWidth / 2"
                :cy="progressBarParams.boxHeight / 2"
                :r="progressBarParams.raduis"
                :stroke="progressBarParams.innerClcColor"
                :stroke-width="progressBarParams.innerClcWidth"
                fill="none"
                stroke-linecap="round"
            />
            <circle
                id="clc"
                class="loadingProcess"
                :cx="progressBarParams.boxWidth / 2"
                :cy="progressBarParams.boxHeight / 2"
                :r="progressBarParams.raduis"
                stroke="url(#cirGradient)"
                :stroke-width="progressBarParams.outerClcWidth"
                fill="none"
                stroke-linecap="round"
            />
        </svg>
        <div id="loadingPercent">
            <span>{{ percent }}</span
            ><span style="font-size:14px;">%</span>
        </div>
    </div>
</template>
<script>
export default {
    props: {
        progressBarParams: Object
    },
    data() {
        return {
            offset: 0,
            percent: 0,
            strokeDasharray: 0
        };
    },
    created() {
        let gap = 3;
        let clock = setInterval(() => {
            if (this.percent < 99) {
                let res = Math.floor(this.percent + gap);
                this.percent = res >= 99 ? 99 : res;
                if (this.percent > 50) {
                    gap = 2;
                }
                if (this.percent > 80) {
                    gap = 1.5;
                }
            } else {
                clearInterval(clock);
            }
        }, 100);
    },
    methods: {}
};
</script>

<style lang="scss" scoped>
.loadingContainer {
    position: relative;
    width: 100%;
    height: 110px;
    font-size: 12px;
    display: flex;
}
.loadingContainer span {
    font-size: 18px;
    font-weight: bold;
}
.loadingContainer > svg {
    margin: 0 auto;
}
#loadingPercent {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    font-family: fzlt_bold;
    font-size: 18px;
    color: #384369;
    margin-left: 3px;
    margin-top: 1px;
}
$perimter: 314;
$percent: 1;
.loadingProcess {
    transform-origin: center;
    animation: task 5s ease-in;
    animation-fill-mode: forwards;
    // stroke-dashoffset: ((100 - $percent) / 100) * $perimter;
    // stroke-dasharray: $perimter;
    transform: rotate(95deg);
}
@-webkit-keyframes task {
    0% {
        $percent: 2;
        stroke-dashoffset: ((100 - $percent) / 100) * $perimter;
        stroke-dasharray: $perimter;
    }
    20% {
        $percent: 30;
        stroke-dashoffset: ((100 - $percent) / 100) * $perimter;
        stroke-dasharray: $perimter;
    }
    50% {
        $percent: 60;
        stroke-dashoffset: ((100 - $percent) / 100) * $perimter;
        stroke-dasharray: $perimter;
    }
    90% {
        $percent: 80;
        stroke-dashoffset: ((100 - $percent) / 100) * $perimter;
        stroke-dasharray: $perimter;
    }
    100% {
        // $percent: 93;
        stroke-dashoffset: 32;
        stroke-dasharray: 329;
    }
}
</style>

// 使用
<progress-bar
            v-if="status === 'loading'"
            v-bind:progressBarParams="progressBarParams"
        ></progress-bar>
<script>
import progressBar from './progressBar';

export default {
    name: 'processCircle',
    components: {
        progressBar
    },
    props: {
        status: {
            type: String,
            default: 'loading'
        }
    },
    data() {
        return {
            percent: 1,
            timeLimit: 5000,
            progressBarParams: {
                boxWidth: '110',
                boxHeight: '110',
                raduis: '50',
                innerClcWidth: '6',
                outerClcWidth: '10',
                frontColor: '#90B2FF',
                endColor: '#6D91FF',
                innerClcColor: '#F4F4F4',
                fastDurTime: 100,
                slowDurTime: 1000
            }
        };
    },
}
</script>

相关文章

  • Step by step!css3、svg 画圆形渐变圆角进度条

    css3 首先摆上那个灰色的圈 然后盖上一个蓝色的半圈(由一半的蓝色和一半的透明border组成) 让它转起来 把...

  • 《画画很难吗---手绘树》

    字不重要,看图,今天画的比较粗糙。 step 1: step 2: step 3: step 4:

  • [PS学习]MBE_雷电图标制作

    MEB主页发布 step 1: 云朵的制作 观察云朵图形,可以看出云朵是有圆形和圆角矩形构成。 上方可以随意调整圆...

  • step by step

    忙毕业的事,一直没有时间和心情去研究彩铅画,难的这几天有空闲时间,就找了画纸,买了彩铅(超市里买的儿童24色彩铅笔...

  • Step by step

    我相信,每一个光鲜亮丽的外表下,都有一段执拗而又孤独的坚持。 如果人生只有一次翻身的机会,那么你一定要拼尽全力。 ...

  • Step by step

    今天是第一天来到简书,关于写作这件事情,始终是蛰伏在心底的。 这个星期四,我在数学课上,忽然想换个微博,想在微博上...

  • step by step

    今天开始,慢慢来。 一切,也都会慢慢的到来❤️

  • Step by step

    ----针对多多少少已经有点工作经验的盆友 补充那些被遗忘、忽略的知识 (重点是面试中曾出现过的问题 ajax、...

  • step by step

    或许有时候你会灵感突袭,猛地想写点东西但是又不知从何下笔。每每写文章时你想好了结构却思考不出该写一个怎样的故事。这...

  • Step by Step

    周末整理了一下,发现还有十多本书未学习。其中很大一部分曾经看过,但是并未整理笔记,因此感觉有些焦躁。加之一天五小时...

网友评论

    本文标题:Step by step!css3、svg 画圆形渐变圆角进度条

    本文链接:https://www.haomeiwen.com/subject/mkjkahtx.html