整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Html、Css、JavaScript制作圆形进度条的代码及基础分析

.说明:

推荐指数:★★★★

通俗易懂,小白一看就会,高手请飘过。

学python也是需要懂一点Html、Css、JavaScript的基础知识的。

建议使用vscode编辑器。


2.效果图1


3.代码:保存为html,用浏览器打开即可。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>圆形百分比进度条效果</title>
		<style type="text/css">
		*{
			margin: 0;
			padding: 0;
		}
		.bg{
			width: 200px;
			height: 200px;
			border-radius: 100%;
			background: #ccc;
			position: relative;
			margin: 20px auto;
		}
		.circle-right, .circle-left, .mask-right, .mask-left{
			width: 200px;
			height: 200px;
			border-radius: 100%;
			position: absolute;
			top: 0;
			left: 0;
		}
		.circle-right, .circle-left{
			background: skyblue;
		}
		.mask-right, .mask-left{
			background: #ccc;
		}
		.circle-right, .mask-right{
			clip: rect(0,200px,200px,100px);
		}
		.circle-left, .mask-left{
			clip: rect(0,100px,200px,0);
		}
		.text{
			width: 160px;
			height: 160px;
			line-height: 160px;
			text-align: center;
			font-size: 34px;
			color: deepskyblue;
			border-radius: 100%;
			background: #fff;
			position: absolute;
			top: 20px;
			left: 20px;
		}
		</style>
	</head>
	<body>
		<div class="bg">
			<div class="circle-right"></div>
			<!--100%是显示百分数,动态显示由0~100-->
			<div class="text">100%</div> 

		</div>
		
		<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
		<script type="text/javascript">
			$(function(){				
				//获取百分比值
				var num = parseInt($('.text').html());
				
				//通过计时器来显示过渡的百分比进度
				var temp = 0;
				var timer = setInterval(function(){
					calculate(temp);
					//清除计时器结束该方法调用
					if(temp == num){
						clearInterval(timer);
					}
					temp++;
				},30)

				//改变页面显示百分比
				function calculate(value){
					//改变页面显示的值
					$('.text').html(value + '%');
					
					//清除上次调用该方法残留的效果
					$('.circle-left').remove();
					$('.mask-right').remove();
					
					//当百分比小于等于50
					if(value <= 50){
						var html = '';
						
						html += '<div class="mask-right" style="transform:rotate('+ (value * 3.6) +'deg)"></div>';
						
						//元素里添加子元素
						$('.circle-right').append(html);
					}else{
						value -= 50;
						var html = '';
						
						html += '<div class="circle-left">';
						html += '<div class="mask-left" style="transform:rotate('+ (value * 3.6) +'deg)"></div>';
						html += '</div>';
						
						//元素后添加元素
						$('.circle-right').after(html);
					}
				}
			})
		</script>
		
	</body>
</html>

4.拆分法:把一个含有css和js(JavaScript)的html,拆掉三个文件,一个叫cirbar1.html,另外的叫:cirbar1.css和cirbar1.js文件,放在同一个文件夹内。这是./的意思,也可以指定文件夹。

4.1 cirbar1.html的代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>圆形百分比进度条效果v2</title>
		<!--如果是style type="text/css"这种直接在html中设置css,注意起始是*,不是点-->
		<!--style type="text/css"-->
		<link href="./cirbar1.css" rel="stylesheet" />
	</head>
	<body>
		<div class="bg">
			<div class="circle-right"></div>
			
			<div class="text">100%</div> 
		</div>
		<!--这个外部js文件=jquery.min.js,不能少,否则不能动了-->
		<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"--></script>
        <!--同样的,把写在html的js,新建一个cirbar1.js,复制下去,保存,这样子简洁很多-->
		<!--script type="text/javascript"-->
		<script src="./cirbar1.js"></script>
	</body>
</html>

4.2 cirbar1.css的代码:

		*{
			margin: 0;
			padding: 0;
		}
		.bg{
			width: 200px;
			height: 200px;
			border-radius: 100%;
			background: #ccc;
			position: relative;
			margin: 20px auto;
		}
		.circle-right, .circle-left, .mask-right, .mask-left{
			width: 200px;
			height: 200px;
			border-radius: 100%;
			position: absolute;
			top: 0;
			left: 0;
		}
		.circle-right, .circle-left{
			background: skyblue;
		}
		.mask-right, .mask-left{
			background: #ccc;
		}
		.circle-right, .mask-right{
			clip: rect(0,200px,200px,100px);
		}
		.circle-left, .mask-left{
			clip: rect(0,100px,200px,0);
		}
		.text{
			width: 160px;
			height: 160px;
			line-height: 160px;
			text-align: center;
			font-size: 34px;
			color: deepskyblue;
			border-radius: 100%;
			background: #fff;
			position: absolute;
			top: 20px;
			left: 20px;
		}

4.3 cirbar1.js的代码:

			$(function(){				
				//获取百分比值
				var num = parseInt($('.text').html());
				
				//通过计时器来显示过渡的百分比进度
				var temp = 0;
				var timer = setInterval(function(){
					calculate(temp);
					//清除计时器结束该方法调用
					if(temp == num){
						clearInterval(timer);
					}
					temp++;
				},30)

				//改变页面显示百分比
				function calculate(value){
					//改变页面显示的值
					$('.text').html(value + '%');
					
					//清除上次调用该方法残留的效果
					$('.circle-left').remove();
					$('.mask-right').remove();
					
					//当百分比小于等于50
					if(value <= 50){
						var html = '';
						
						html += '<div class="mask-right" style="transform:rotate('+ (value * 3.6) +'deg)"></div>';
						
						//元素里添加子元素
						$('.circle-right').append(html);
					}else{
						value -= 50;
						var html = '';
						
						html += '<div class="circle-left">';
						html += '<div class="mask-left" style="transform:rotate('+ (value * 3.6) +'deg)"></div>';
						html += '</div>';
						
						//元素后添加元素
						$('.circle-right').after(html);
					}
				}
			})

==============================

再来一个,不用外部js文件的圆形进度条

顺带回顾一下相关知识。

==============================

5.效果图


6.三个文件,放在同一个文件夹中

6.1 cirbar.html代码:

<!--第1步---声明html5-->
<!DOCTYPE html> 

<!--第2步---html大框架-->
<html lang="en">

<!--第2-1步---head部分-->
<head>
    <!--第2-1-1步---meta部分:声明字符编码格式:utf-8-->
    <!--注意与python的第一行声明一样:# -*- coding: utf-8 -*-->
    <meta charset="utf-8" />
    <!--第2-1-2步---标题名称-->
    <title>圆形进度条v1</title>
    <!--注意:./代表同一个文件夹下,也就是css和js文件与本html文件放在同一个文件夹下-->
    <!--第2-1-3步---导入css文件-->
    <link href="./cirbar.css" rel="stylesheet" />
</head>

<!--第2-2步---body部分-->
<body>
    <!--第2-2-1步---定义画布部分,注意没有逗号隔开,大小设置-->
    <canvas class="canvas" id="canvas" width="400" height="400"></canvas>
    <!--第2-2-2步---导入js文件部分-->
    <script src="./cirbar.js"></script>

<!--注意收尾-->
</body>
<!--注意收尾-->
</html>

6.2 cirbar.css代码:

.canvas {
            /*画布的背景颜色设置为:黑色*/
            background:#303030;
            
        }

6.3 cirbar.js代码:

window.onload = function () {
            var canvas = document.getElementById('canvas'),  //获取canvas元素
                context = canvas.getContext('2d'),  //获取画图环境,指明为2d
                centerX = canvas.width / 2,   //Canvas中心点x轴坐标
                centerY = canvas.height / 2,  //Canvas中心点y轴坐标
                rad = Math.PI * 2 / 100, //将360度分成100份,那么每一份就是rad度
                speed = 0.1; //加载的快慢就靠它了
            //绘制红色外圈
            function blueCircle(n) {
                context.save();
                context.strokeStyle = "	#1E90FF"; //随百分数转动的外圈的颜色为蓝色
                context.lineWidth = 3; //设置线宽
                context.beginPath(); //路径开始
                //注意-为顺时针,+为逆时针
                //用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
                //context.arc(centerX, centerY, 50, Math.PI / 2, Math.PI / 2 - n * rad, false); 
                context.arc(centerX, centerY, 50, -Math.PI / 2, -(Math.PI / 2 - n * rad), false); 
                context.stroke(); //绘制
                context.closePath(); //路径结束
                context.restore();
            }
            //绘制白色外圈,初始的白色外圈
            function whiteCircle() {
                context.save();
                context.beginPath();
                // 下面百分数的字体颜色设置后上面的外圈的颜色竟然保持一样
                //context.strokeStyle = "#F8F8FF";
                context.arc(centerX, centerY, 50, 0, Math.PI * 2, false);
                context.stroke();
                context.closePath();
                context.restore();
            }
            //百分比文字绘制
            function text(n) {
                context.save(); //save和restore可以保证样式属性只运用于该段canvas元素
                context.strokeStyle = "#7FFF00";//设置中间动态百分数的颜色
                context.font = "25px Arial"; //设置字体大小和字体
                context.textAlign = 'center';//字体水平居中
                context.textBaseline = 'middle';//字体垂直居中
                //绘制字体,并且指定位置
                context.strokeText(n.toFixed(0) + "%", centerX, centerY);
                context.stroke(); //执行绘制
                context.restore();
            }
            //循环获取
            (function drawFrame() {
                window.requestAnimationFrame(drawFrame, canvas);
                context.clearRect(0, 0, canvas.width, canvas.height);
                whiteCircle();
                text(speed);
                blueCircle(speed);
                if (speed < 100) {
                    //1可从后台获取值,也是从0~100,step为1,代表速度
                    speed += 1;
                }
            }());
        }

注意到6.3js文件与4.3js文件的区别了么?一个有:window.onload =,一个没有,且只有$和小括号,因为外部的就是文件定义了一部分功能。


天我们想向大家展示如何创建一些具有特殊3D外观的纯CSS进度条。不妨将本教程当作是一个高级的CSS练习,以更深入地了解更多有趣的3D属性和着色技术。仅使用CSS创建UI组件将训练你的创造性思维,并且在本教程中,我们将通过制作进度条并动画化来向大家展示一些如何创建更复杂形状的技巧。


注意:某些CSS属性仅在现代浏览器中受支持。IE仍然不支持transform-style:preserve-3d,这是一个用于创建嵌套3D结构的关键属性;所以进度条在IE浏览器中将是扁平/无效的。


浏览器支持:Chrome Firefox Internet Explorer Safari Opera



源码下载(http://www.html5tricks.com/jquery-css3-3d-progress-bar.html)


我们将在本教程中使用Sass(与Compass一起使用),因此请确保设置并了解其基础知识:


  • 安装Sass和Sass Basics
  • 安装Compass Stylesheet Authoring Framework和Compass CSS3


如果你想对动画进度条使用完整的解决方案,那么你应该查看Kimmo Brunfeldt的ProgressBar.js或HubSpot的PACE,以获得出色的页面加载进度条。


为了生成所有必要的前缀,你可以使用像Autoprefixer或用于Sublime Text的插件。


我们将使用许多有趣的CSS属性,如transform,perspective和box-shadow。我们还将大量使用SASS,以节省生成进度条的位置和外观所需的很多时间。通过使用相对大小(em,百分比),我们可以确保进度条的大小易于调整。


构建面


我们先从构建一个包含所有六个面的框开始。这个框将作为我们的主要容器,用来设置进度条的尺寸及其视点。我们还将使用一个包装器用于透视图,并且这个包装器的font-size属性将允许使用某些em单位魔法的帮助来扩展进度条。


为了确保所有的面都是我们3D空间的一部分,我们需要将transform-style: preserve-3d应用于框。


所以让我们从初始化一些颜色变量开始来编写样式吧:


$light-gray: #e0e0e0;

$magenta: #ec0071;

$white: #f5f5f5;


.perspective {

font-size: 5em; // sets the main scale size

perspective: 12em; // sets the perspective

perspective-origin: 50% 50%;

text-align: center;

}


.bar {

display: inline-block;

width: 1em;

height: 1em;

margin-top: 1em;

position: relative;

transform: rotateX(60deg); // sets the view point

transform-style: preserve-3d; // perspective for the children

}


现在,我们来看看这些面。如果我们想要能够毫无困难地重新调整我们的主框,里面包含的面必须得像液体一样具有流动行为以及具备绝对位置。


.bar {

// -> The SCSS written before

.bar-face {

display: inline-block;

width: 100%;

height: 100%;

position: absolute;

bottom: 0;

left: 0;

background-color: rgba($light-gray, .6); // just to see what is happening

}

}


写标记并且确保它是可以访问的:


<div class="perspective">

<div class="bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">

<div class="bar-face"/>

<div class="bar-face"/>

<div class="bar-face"/>

<div class="bar-face"/>

<div class="bar-face"/>

<div class="bar-face"/>

</div>

</div>


如果你有兴趣了解更多有关可访问性的信息,这篇文章(由Gez Lemon撰写)帮助我了很多:‘Introduction to WAI ARIA’


设置面


这是非常重要的一部分。进度条的面必须准确定向,这样当我们开始添加百分比填充时,就不会陷入困境。


.bar {

// -> The SCSS from before

.bar-face {

// -> The SCSS from before

transform-origin: 50% 100%;

&.roof {

transform: translateZ(1em);

}

&.front {

transform: rotateX(-90deg);

}

&.right {

left: auto;

right: -.5em;

width: 1em;

transform: rotateX(-90deg) rotateY(90deg) translateX(.5em);

}

&.back {

transform: rotateX(-90deg) rotateY(0deg) translateZ(-1em);

}

&.left {

width: 1em;

transform: rotateX(-90deg)rotateY(-90deg) translateX(-.5em) translateZ(.5em);

}

}

}


<div class="perspective">

<div class="bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">

<div class="bar-face roof"/>

<div class="bar-face front"/>

<div class="bar-face left"/>

<div class="bar-face right"/>

<div class="bar-face back"/>

<div class="bar-face floor"/>

</div>

</div>



好的,这是一个很棒的立方体,但是我们要为进度条创建一个矩形。如果你还记得的话,我们已经用一种液体化的方法构建了面,所以如果我们只是增加.bar类的width,那么这样就可以。在这个例子中,我们使用了4em的宽度。



构建百分比填充


百分比填充将包含在面内,并且,为了保持HTML代码的最小化,我们将使用伪类:before。这样生成的:before元素将显示相对于面宽度的百分比。


.bar {

// -> The SCSS from before

.bar-face {

// -> The SCSS from before

&.percentage:before {

content: '';

display: block;

position: absolute;

bottom: 0;

width: 0;

height: 100%;

margin: 0;

background-color: rgba($magenta, .8);

transition: width .6s ease-in-out;

}

}

}


<div class="perspective">

<div class="bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">

<div class="bar-face roof percentage"/>

<div class="bar-face front percentage"/>

<div class="bar-face left"/>

<div class="bar-face right"/>

<div class="bar-face back percentage"/>

<div class="bar-face floor percentage"/>

</div>

</div>



现在我们需要编写百分比填充样式。手动编写一百个类将会非常繁琐,所以让我们写一些可靠的循环来从HTML中获取aria-valuenow属性的所有值。


.bar {

// -> The SCSS from before

.bar-face {

// -> The SCSS from before

}


@for $i from 0 to 101 {

&[aria-valuenow='#{$i}'] {

.percentage:before {

width: $i * 1%;

}

}

}

}


如果你想立竿见影地看到成果,那么只需将HTML中的aria-valuenow属性从0更改至100。


构建皮肤


为了构建皮肤,我们将使用Sass mixins。为了得到一个现实化的外观,我们将使用box-shadow属性。这个属性支持一个数组的值,并且这个数组将允许我们模拟照明。我们将在这个属性中包含地面阴影和面的采光。


@mixin build-skin($color, $name) {

&.#{$name} {

.floor {

box-shadow:

0 -0.2em 1em rgba(0,0,0,.15),

0 0.2em 0.1em -5px rgba(0,0,0,.3),

0 -0.75em 1.75em rgba($white,.6);

}

.left {

background-color: rgba($color, .5);

}

.percentage:before {

background-color: rgba($color, .5);

box-shadow: 0 1.6em 3em rgba($color,.25);

}


}

}

.bar {

// -> The SCSS from before

@include build-skin(#57caf4, 'cyan');

}


<div class="perspective">

<div class="bar cyan" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">

<div class="bar-face roof percentage"/>

<div class="bar-face front percentage"/>

<div class="bar-face left"/>

<div class="bar-face right"/>

<div class="bar-face back percentage"/>

<div class="bar-face floor percentage"/>

</div>

</div>



此外,我们需要一个照亮面的技巧。如果我们以正确的顺序输入面的DOM节点,我们将看到奇迹:


<div class="perspective">

<div class="bar cyan" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">

<div class="bar-face roof percentage"/>

<div class="bar-face back percentage"/>

<div class="bar-face floor percentage"/>

<div class="bar-face left"/>

<div class="bar-face right"/>

<div class="bar-face front percentage"/>

</div>

</div>



这里发生了什么?很简单:当浏览器渲染一个绝对元素时,默认情况下它会添加一个自动递增的z-index(如果我们不编辑此属性的话)。所以,如果我们通过先放置底部的面来改变渲染顺序,那么它的阴影就会覆盖在背面的所有面上。这就是我们实现现实化阴影的原理。


关于如何实现进度条就都在这里了!现在,请查看所有DEMO演示和源代码文件,然后开始构建皮肤来训练自己此技能吧。


感谢各位的阅读,希望本教程能对你有所帮助!


源自:www.codeceo.com/article/css3-sass-3d-progress-bar.html

声明:文章著作权归作者所有,如有侵权,请联系小编删除。

多网页为了提升用户体验,都会在页面载入的时候有一个加载进度条的动画效果,以此来提升用户体验。

比较知名的进度条库有 NProgressprogressBarprogressJS 等等。使用方式也差不多,如下所示就是 NProgress 的使用方式:

NProgress.start();
NProgress.done();
NProgress.remove();

可以看到提供 startdoneremove 等方法,分别对应 开始完成删除进度条容器,并且提供 set 方法可以设置进度条的加载速度等。

那么,有没有办法依据页面加载的事件制作一个能较为准确表达加载进度的进度条呢?

其实是可以的。

首先来看网页加载的事件有哪些(不考虑 IEDOMContentLoaded):

document.readystatechange 事件

readystatechange 会在 每次 readyState 发生变化的时候触发

readyState 有以下状态:

uninitialized - 还未开始载入

loading - 载入中

interactive - 互动文档已经完成加载,文档已被解析,但是诸如图像,样式表和框架之类的资源仍在加载,文档与用户可以开始交互

complete - 载入完成

window.onload 事件

load 事件在 window,指的是网页资源已经加载完毕(包括图片、音频、脚本、插件资源以及 CSS)

所有的资源全部加载完成后会触发 windowload 事件。

通俗一点地说 :

  1. document.readystatechange 事件会触发多次。
  2. Dom Tree 生成完毕 那么 document.readyState 状态翻转为 complete
  3. 当 网页所有资源加载完毕 window.onload 触发

但是由于当前页面加载时候,document.readyStateuninitializedloading 这2个状态是无法捕获的。因为 Dom Tree 还未生成,JS 代码尚未能执行,所以能捕获的状态只有interactivecomplete 这2个状态

此时,拥有了3个可用节点,分别是

document.readyStateinteractive

document.readyStatecomplete

window.onload

进度条 DOM 结构

<div class="progress">
  <div></div>
</div>

进度条的 默认 CSS

.abc {
  width: 100%;
  height: 10px;
}

.abc div {
  width: 0;
  height: 100%;
  background: green;
}

记得给进度条加上动画

  transition: width .5s;

js 代码 如下:

document.addEventListener('readystatechange', function () {
  if(document.readyState === 'interactive') {
    document.querySelector('.progress div').style.width = '33%'
  }

  if(document.readyState === 'complete') {
    document.querySelector('.progress div').style.width = '66%'
  }
} )
window.onload = function () {
  document.querySelector('.abc div').style.width = '100%'
}

分别在 3个节点 让 进度条 width 涨 33% 66% 和 100%

此时 就得到了一个 相对准确的 加载进度条

interactive

onload