<!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>


canvas/CSS实现仪表盘效果_3d


<!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="js/jquery-3.1.1.js" 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

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>



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