html5 canvas制作圆形水波进度条动画特效


效果图

前言:

        伙计儿,来点干货吧!效果看上去还想这么回事,嘻嘻~ canvas也就这么几步,没事自己多研究研究,废话不多说,上代码咯!


<!DOCTYPE html>

<html lang="en">

  <head>

    <meta charset="UTF-8">

    <title>test</title>

    <style>

      body {

        display: flex;

        flex-flow: column wrap;

        justify-content: center;

        align-items: center;

      }

      #c {

        margin-top: 20px;     

      }

      input[type=range]::before {content: attr(min);  color: #000; padding-right: 5px;}

      input[type=range]::after { content: attr(max); color: #000; padding-left: 5px;}

    </style>

  </head>

  <body>

    <canvas id="c">当前浏览器不支持canvas 请升级!</canvas>

    <input type="range" name="range" min="0" max="100" step="1">

  </body>

<script>

  canvas = document.getElementById("c");

  ctx  = canvas.getContext("2d");

  oRange = document.getElementsByName("range")[0];

  M = Math;

  Sin = M.sin;

  Cos = M.cos;

  Sqrt = M.sqrt;

  Pow = M.pow;

  PI = M.PI;

  Round = M.round;

  oW = canvas.width = 200;

  oH = canvas.height = 200;

  // 线宽

  lineWidth = 2;

  // 大半径

  r = (oW / 2);

  cR = r - 10*lineWidth;

  ctx.beginPath();

  ctx.lineWidth = lineWidth;

  // 水波动画初始参数

  axisLength = 2*r - 16*lineWidth;  // Sin 图形长度

  unit = axisLength / 9; // 波浪宽

  range = .4 // 浪幅

  nowrange = range; 

  xoffset = 8*lineWidth; // x 轴偏移量

  data = ~~(oRange.value) / 100;  // 数据量

  sp = 0; // 周期偏移量

  nowdata = 0;

  waveupsp = 0.006; // 水波上涨速度

  // 圆动画初始参数

  arcStack = [];  // 圆栈

  bR = r-8*lineWidth;

  soffset = -(PI/2); // 圆动画起始位置

  circleLock = true; // 起始动画锁

  // 获取圆动画轨迹点集

  for(var i = soffset; i< soffset + 2*PI; i+=1/(8*PI)) {

    arcStack.push([

      r + bR * Cos(i),

      r + bR * Sin(i)

    ])

  }

  // 圆起始点

  cStartPoint = arcStack.shift(); 

  ctx.strokeStyle = "#1c86d1";

  ctx.moveTo(cStartPoint[0],cStartPoint[1]);

  // 开始渲染

  render(); 

  function drawSine () {

    ctx.beginPath();

    ctx.save();

    var Stack = []; // 记录起始点和终点坐标

    for (var i = xoffset; i<=xoffset + axisLength; i+=20/axisLength) {

      var x = sp + (xoffset + i) / unit;

      var y = Sin(x) * nowrange;

      var dx = i;

      var dy = 2*cR*(1-nowdata) + (r - cR) - (unit * y);

      ctx.lineTo(dx, dy);

      Stack.push([dx,dy])

    }

    // 获取初始点和结束点

    var startP = Stack[0]

    var endP = Stack[Stack.length - 1]

    ctx.lineTo(xoffset + axisLength,oW);

    ctx.lineTo(xoffset,oW);

    ctx.lineTo(startP[0], startP[1])

    ctx.fillStyle = "#fbec99";

    ctx.fill();

    ctx.restore();

  }

  function drawText () {

    ctx.globalCompositeOperation = 'source-over';

    var size = 0.2*cR;

    ctx.font = 'bold ' + size + 'px Microsoft Yahei';

    txt = (nowdata.toFixed(2)*100).toFixed(0) + '%';

    var fonty = r + size/2;

    var fontx = r - size * 0.8;

    ctx.fillStyle = "#f6b71e";

    ctx.textAlign = 'center';

    ctx.fillText(txt, r+5, r+5)

  }

  //最外面淡黄色圈

  function drawCircle(){

    ctx.beginPath();

    ctx.lineWidth = 15;

    ctx.strokeStyle = '#fff89d';

    ctx.arc(r, r, cR+7, 0, 2 * Math.PI);

    ctx.stroke();

    ctx.restore();

  }

  //灰色圆圈

  function grayCircle(){

    ctx.beginPath();

    ctx.lineWidth = 6;

    ctx.strokeStyle = '#FBEC99';

    ctx.arc(r, r, cR-5, 0, 2 * Math.PI);

    ctx.stroke();

    ctx.restore();

    ctx.beginPath();

  }

  //橘黄色进度圈

  function orangeCircle(){

    ctx.beginPath();

    ctx.strokeStyle = '#fbdb32';

    //使用这个使圆环两端是圆弧形状

    ctx.lineCap = 'round';

    ctx.arc(r, r, cR-5,0 * (Math.PI / 180.0) - (Math.PI / 2),(nowdata * 360) * (Math.PI / 180.0) - (Math.PI / 2));

    ctx.stroke();

    ctx.save()

  }

  //裁剪中间水圈

  function clipCircle(){

    ctx.beginPath();

    ctx.arc(r, r, cR-15, 0, 2 * Math.PI,false);

    ctx.clip();

  }

  //渲染canvas

  function render () {

    ctx.clearRect(0,0,oW,oH);

    //最外面淡黄色圈

//     drawCircle();

    //灰色圆圈 

    grayCircle();

    //橘黄色进度圈

//     orangeCircle();

    //裁剪中间水圈 

    clipCircle();

    // 控制波幅

    oRange.addEventListener("change", function () {

        data = ~~(oRange.value) / 100;

        console.log("data="+data)

      },0);

    if (data >= 0.85) {

      if (nowrange > range/4) {

        var t = range * 0.01;

        nowrange -= t; 

      }

    } else if (data <= 0.1) {

      if (nowrange < range*1.5) {

        var t = range * 0.01;

        nowrange += t; 

      }

    } else {

      if (nowrange <= range) {

        var t = range * 0.01;

        nowrange += t; 

      }     

      if (nowrange >= range) {

        var t = range * 0.01;

        nowrange -= t;

      }

    }

    if((data - nowdata) > 0) {

      nowdata += waveupsp;     

    }

    if((data - nowdata) < 0){

      nowdata -= waveupsp

    }

    sp += 0.07;

    // 开始水波动画

    drawSine();

    // 写字

    drawText(); 

    requestAnimationFrame(render)

  }

</script>

</html>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容

  • 首先我很鄙视这个书名,因为作者在结尾自己说了不喜欢 Study 这个单词,但是(出版社)却用这个来命名该书,估计是...
    叶安可阅读 659评论 2 0
  • 今天周一,没有周一综合症,因为已经提前到周日。为什么?因为周日加班。加了两个星期了,还要持续两三个月,反正心里觉得...
    盛小树阅读 125评论 0 0
  • cocoapods 安装及导入第三方库 1.打开终端,输入gem sources -l,如果结果显示为https:...
    __WQW阅读 234评论 0 3
  • 七年,是一段说不上长却也不能算短的时间。倘若从三岁对世界存有模糊的记忆后开始算起,我的生命也只走过了两个七年。...
    声声催忆当初阅读 217评论 2 1
  • 注射艺术——当我给病人打针的时候我的脑海里突然出现了这个词。 ——一位护士在业余时间开始用注射器进行绘画创作。 让...
    神秘的大熊阅读 181评论 0 2