canvas/CSS仪表盘效果

 

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>canvas仪表盘动画效果</title>
		<style type="text/css">
			html,
			body {
				width: 100%;
				height: 100%;
				margin: 0;
			}
			
			canvas {
				display: none;
				border: 1px solid red;
				display: block;
				margin: 0 auto;
				background: -webkit-linear-gradient(top, #0e83f5 0%, #21bdf6 100%);
			}
		</style>
		<script type="text/javascript">
			window.onload = function() {
				window.requestAnimFrame = (function() {
					return window.requestAnimationFrame ||
						window.webkitRequestAnimationFrame ||
						window.mozRequestAnimationFrame ||
						function(callback) {
							window.setTimeout(callback, 1000 / 60);
						};
				})();
				
				var canvas = document.getElementById('canvas'),
					ctx = canvas.getContext('2d'),
					cWidth = canvas.width,
					cHeight = canvas.height,
					score = canvas.attributes['data-score'].value,
					radius = 100, //圆的半径
					deg0 = Math.PI / 9, //每一格20度
					mum = 100, //数字步长
					/*
					 * 要求:圆弧走完,数字得自加完,就得确定圆弧走的次数和数字走的次数相等!
					 数字最大10000,对应的度数是11*PI/9,那每个步长mum对应的度数如下:
					 */
					deg1 = mum * Math.PI * 11 / 9 / 10000; // 每mum对应的度数

				var angle = 0, //初始角度
					credit = 0; //数字默认值开始数

				var drawFrame = function() {
					if(score < 0 || score > 10000) {
						alert('额度只能是0--10000')
						score = 10000;
					}
					ctx.save();
					ctx.clearRect(0, 0, cWidth, cHeight);
					ctx.translate(cWidth / 2, cHeight / 2);
					ctx.rotate(8 * deg0); //160度

					var aim = score * deg1 / mum; //数字对应的弧度数,先确定要走几次,除以mum,然后计算对应的弧度数
					if(angle < aim) {
						angle += deg1;
					}

					if(credit < score) {
						credit += mum; //默认数字间隔是mum
					} else if(credit >= 10000) {
						credit = 10000;
					}
					//信用额度
					ctx.save();
					ctx.rotate(10 * deg0);
					ctx.fillStyle = 'white';
					ctx.font = '28px Microsoft yahei';
					ctx.textAlign = 'center';
					ctx.fillText('信用额度', 0, 50);
					ctx.restore();
					//
					text(credit);

					ctx.save();
					ctx.beginPath();
					ctx.lineWidth = 5;
					ctx.strokeStyle = 'rgba(255, 255, 255, 1)';
					ctx.arc(0, 0, radius, 0, angle, false); //动画圆环
					ctx.stroke();
					ctx.restore();
					ctx.save();
					ctx.rotate(10 * deg0); //200度
					ctx.restore();
					ctx.beginPath();
					ctx.strokeStyle = 'rgba(255, 0, 0, .1)';
					ctx.lineWidth = 5;
					ctx.arc(0, 0, radius, 0, 11 * deg0, false); //设置外圆环220度
					ctx.stroke();
					ctx.restore();

					window.requestAnimFrame(drawFrame);

				}

				function text(process) {
					ctx.save();
					ctx.rotate(10 * deg0); //200度
					ctx.fillStyle = 'red';
					ctx.font = '40px Microsoft yahei';
					ctx.textAlign = 'center';
					ctx.textBaseLine = 'top';
					ctx.fillText("¥:" + process, 0, 10);
					ctx.restore();
				}

				setTimeout(function() {
					document.getElementById("canvas").style.display = "block";
					drawFrame();
				}, 10)

			}
		</script>
	</head>

	<body>
		<canvas id="canvas" width="300" height="300" data-score='8100'></canvas>
	</body>

</html>

 

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			#yibiao {
				width: 400px;
				height: 200px;
				background: white;
				margin: 0 auto;
				position: relative;
				overflow: hidden;
			}
			
			.yuan1 {
				width: 400px;
				height: 400px;
				position: absolute;
				top: 0px;
				left: 0px;
				border-radius: 50%;
				background: black;
				opacity: 0.2;
			}
			
			.yuan2 {
				width: 360px;
				height: 360px;
				position: absolute;
				top: 20px;
				left: 20px;
				border-radius: 50%;
				background: white;
			}
			
			.clip {
				width: 400px;
				height: 400px;
				position: absolute;
				top: 0px;
				left: 0px;
				border-radius: 50%;
				background: blue;
				clip: rect(200px, 400px, 400px, 0px);
				transform: rotate(0deg);
			}
			
			.num {
				position: absolute;
				width: 100%;
				height: 100px;
				top: 100px;
				text-align: center;
				font-size: 100px;
			}
		</style>
		<script type="text/javascript" src=""></script>
		<script type="text/javascript">
			$(function() {
				//默认数字0--10000,默认数字自增步长100
				var buchang = 200;
				var deg = 180 * buchang / 10000; //每个步长代表的度数
				var degs = parseInt($(".num").text()) / buchang * deg; //先计算有几个步长,算出半圆要转的度数
				var du = 0; //起始度数
				var bu = 0; //数字自增步长
				function zhuan() {

					$(".clip").css("transform", "rotate(" + du + "deg)");
					$(".num").text(bu);
					du += deg;

					
					bu += buchang;
					if(du >= degs) {
						 clearInterval(setin);
					}

				}
				var setin = setInterval(zhuan, 30)

			})
		</script>
	</head>

	<body>
		<div id="yibiao">
			<div class="yuan1"></div>
			<div class="clip"></div>
			<div class="yuan2"></div>
			<div class="num">5000</div>
		</div>
	</body>

</html>

 

 

 

<!doctype html>
<html lang="en">

	<head>
		<meta charset="UTF-8" />
		<title>CSS 仪表盘</title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<style type="text/css">
			* {
				margin: 0px;
				padding: 0px;
				border: 0px;
			}
			
			html,
			body {
				width: 100%;
				height: 100%;
				background: -webkit-linear-gradient(top, #0e83f5 0%, #21bdf6 100%);
			}
			
			.sb {
				background: transparent;
				box-sizing: border-box;
				width: 400px;
				height: 272.8px;
				/*272.8px:220度*/
				margin: 0 auto;
				position: relative;
				overflow: hidden;
			}
			
			.deg0 {
				position: absolute;
				width: 400px;
				height: 400px;
				background: red;
				border-radius: 50%;
				top: 0px;
				left: 0px;
			}
			
			.deg1 {
				position: absolute;
				width: 370px;
				height: 370px;
				background: -webkit-linear-gradient(top, #0E83F5 0%, #169BF5 100%);
				border-radius: 50%;
				top: 15px;
				left: 15px;
				z-index: 1000;
			}
			
			.clip1 {
				position: absolute;
				width: 400px;
				height: 400px;
				background: green;
				border-radius: 50%;
				top: 0px;
				left: 0px;
				clip: rect(0px, 200px, 200px, 0px);
				transform: rotate(-113deg);
				/*对应90+23*/
			}
			
			.clip2 {
				position: absolute;
				width: 400px;
				height: 400px;
				background: green;
				border-radius: 50%;
				top: 0px;
				left: 0px;
				clip: rect(0px, 400px, 200px, 200px);
				transform: rotate(113deg);
			}
			
			.clip3 {
				position: absolute;
				width: 400px;
				height: 400px;
				background: green;
				border-radius: 50%;
				top: 0px;
				left: 0px;
				clip: rect(200px, 200px, 400px, 0px);
				transform: rotate(-23deg);
				/*对应20度*/
			}
			
			.clip4 {
				position: absolute;
				width: 400px;
				height: 400px;
				background: green;
				border-radius: 50%;
				top: 0px;
				left: 0px;
				clip: rect(200px, 400px, 400px, 200px);
				transform: rotate(23deg);
				/*对应20度*/
			}
			
			p.num {
				position: absolute;
				width: 400px;
				height: 200px;
				top: 150px;
				color: red;
				text-align: center;
				font-size: 100px;
				z-index: 10000;
			}
		</style>
		<script src="" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			$(function() {
				var sbs = 9000;
				//默认数字0--10000,默认数字自增步长100
				var buchang = 100;
				var deg = 220 * buchang / 10000; //每个步长代表的度数  2.2
				var degs = sbs / buchang * deg; //先计算有几个步长,算出半圆要转的度数
				var du = -23; //起始度数
				var num = 0;
				console.log(degs)
				var sb = setInterval(function() {
					$(".num").text(num);
					if(du <= 67) {
						$(".clip3").css("transform", "rotate(" + du + "deg)");
					} else if(du > 67 && du <= 157) {
						$(".clip3").css("transform", "rotate(67deg)");
						$(".clip1").css("transform", "rotate(" + (-23 + (du - 67)) + "deg)");
					} else if(du > 157 && du <= 220) {
						$(".clip3").css("transform", "rotate(67deg)");
						$(".clip1").css("transform", "rotate(67deg)");
						$(".clip4").css("transform", "rotate(90deg)");
						$(".clip2").css("transform", "rotate(" + (-23 + (du - 157)) + "deg)");
					}

					if(du >= degs || num >= sbs) {
						clearInterval(sb)
					}
					du += deg;

					num += buchang;
				}, 20)
			})
		</script>
	</head>

	<body>
		<div class="sb">
			<div class="deg0">
				<div class="deg1"></div>
			</div>
			<div class="clip1"></div>
			<div class="clip2"></div>
			<div class="clip3"></div>
			<div class="clip4"></div>
			<p class="num">0</p>
		</div>
	</body>

</html>

关于requestAnimationFrame和 cancelAnimationFrame

兼容写法:

window.requestAnimFrame = (function() {
		return window.requestAnimationFrame ||
		       window.webkitRequestAnimationFrame ||
		       window.mozRequestAnimationFrame ||
				function(callback) {
					window.setTimeout(callback, 1000 / 60);     //浏览器默认刷新频率
				};
			})();  

   

基本用法与区别:

  • setTimeout(code, millseconds) 用于延时执行参数指定的代码,如果在指定的延迟时间之前,你想取消这个执行,那么直接用clearTimeout(timeoutId)来清除任务,timeoutID 是 setTimeout 时返回的;
  • setInterval(code, millseconds)用于每隔一段时间执行指定的代码,永无停歇,除非你反悔了,想清除它,可以使用 clearInterval(intervalId),这样从调用 clearInterval 开始,就不会在有重复执行的任务,intervalId 是 setInterval 时返回的;
  • requestAnimationFrame(code),一般用于canvas动画,与 setTimeout 方法类似,区别是 setTimeout 是用户指定的,而 requestAnimationFrame 是浏览器刷新频率决定的,一般遵循 W3C 标准,它在浏览器每次刷新页面之前执行。

     requestAnimationFrame不需要使用者指定循环间隔时间,浏览器会基于当前页面是否可见、CPU的负荷情况等来自行决定最佳的帧速率,从而更合理地使用CPU。

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			window.onload = function() {

				var id = null;
                var i=0;
				function a(time) {
					console.log(i++);
					id = window.requestAnimationFrame(a);
			
				}
                function b(){
                	window.cancelAnimationFrame(id);
                }
				document.getElementById("start").onclick=a;   //相当开始
                document.getElementById("zantin").onclick=b;   //相当暂停
			}
		</script>
	</head>

	<body>
		<button id="start">开始</button>
		<button id="zantin">暂停</button>
	</body>

</html>

点击开始,此时控制台一直计数下去,点击暂停,计数器暂停,再次点击开始会从原来的位置继续计数下去。

 

 

 

 <!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>点击实现冲击波</title>
		<style>
			*{
				margin:0;
				padding:0;
				box-sizing:border-box;
			}
			html,body{
				font-family:"微软雅黑";
			}
			.wave{
				position:relative;
				float:left;
				width:50%;
				height:420px;
			}
			.wave a{
				position:absolute;
				top:50%;
				left:50%;
				display:inline-block;
				width:120px;
				height:50px;
				margin-left:-60px;
				margin-top:-25px;
				line-height:50px;
				text-align:center;
				border-radius:5px;
				color:red;
				font-size:16px;
				cursor:pointer;
				/*overflow:hidden;*/
			    
			}
			#wave1{
				background-color:blue;
			}
			#wave1 a{
				background-color:pink;
			}
			#wave1 a:after{
				 
			    content: "";
			    display: block;
			    position: absolute;
			    left: -40px;
			    top: -75px;
			    width: 200px;
			    height: 200px;
			    background: rgba(255,255,255,0.8);
			    border-radius: 50%;
			    opacity:0;
			    transition: all 1s;
			}
			#wave1 a:active:after{
				 
				width: 0; 
				height: 0; 
				left:60px; 
				top: 25px;
				opacity: 1; 
				transition-duration: 0s;
			}
		</style>
	</head>
	<body>
		 
		<div class="wave" id="wave1">
			<a>点我</a>
		</div>
	</body>
</html>
posted @ 2017-10-23 00:24  最骚的就是你  阅读(...)  评论(...编辑  收藏