美文网首页
h5 canvas学习之绘制圆形波浪进度条

h5 canvas学习之绘制圆形波浪进度条

作者: 全校最帅的人 | 来源:发表于2018-11-26 10:59 被阅读0次

             之前做android原生开发,现在公司又让搞搞h5,所有就开始学习js的相关知识,canvas是h5的一个重要元素(当然原生的Canvas要好用的多)。都是绘制图形来制作控件。当然了,画图的思想没太大变化,主要是API的不同以及语言区别,需要排坑。希望帮到才入坑的萌新。废话不多说,效果图:

            现在的流程是:画圆、画波浪、画文字、然后就是进度的设置和获取。以及各样式的设置和获取。最后就是封装在一个js文件中。

    1 画圆

    画图形的条件是上下文要存在

    var myCanvas = document.getElementById(id);

    var ctx = myCanvas.getContext("2d");

    if(ctx) {

    //画图

    }

    画圆API

    arc(x, y, radius, startAngle, endAngle, anticlockwise)

    画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle(弧度,弧度=(Math.PI/180)*角度)结束,按照anticlockwise给定的方向(默认为顺时针)来生成。关键代码

    c.beginPath();

    c.arc(X, Y, radius, 0, Math.PI * 2, true);

    c.closePath();

    c.stroke();

    c.clip();

    stroke()就是绘制空心的形状,clip就是裁剪画布,当前是什么形状,之后绘制的图形都只能现在在裁剪的画布上,这里裁剪掉圆之外的图形,

    2 画波浪

    波浪就是曲线,所以画曲线可以使用贝塞尔曲线就很方便了。

    quadraticCurveTo(cp1x, cp1y, x, y)

    绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。

    bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

    绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。

    详细请移步贝塞尔曲线。 

    静态的曲线有了之后再在x轴上不断的移动就形成了大波浪的样子。移动一次要重新绘制一次。

    至于一个圆形内显示几个波,改变下波长即可

    关键代码

    c.moveTo(mWaveDx - 2 * mWaveLength, mWaveDy);

    for(var j = -2; j <= 4; j++)

    {

    if(j % 2 == 0)

    { y = mWaveDy + mWaveheight;

    }

    else {

    y = mWaveDy - mWaveheight;

    }

    c.quadraticCurveTo(mWaveDx + mWaveLength * (2 * j - 1) / 2, y, mWaveDx + mWaveLength * j, mWaveDy);

    }

    c.lineTo(w, h);

    c.lineTo(0, h);

    c.closePath();

    c.fill();

    mWaveDx 就是用来让波浪飞,mWaveDy就是进度的控制。fill()就是填充

    3 画文字

    关键代码

    c.fillStyle = obj.mTextColor;

    c.font = "bold " + obj.mTextSize + "px Microsoft Yahei";

    c.textBaseline = "middle";

    var info = obj.mProgress + "%";

    c.fillText(info, X - c.measureText(info).width / 2, Y, 100);

    绘制文字的方法就是fillText(),参数 (文字 x坐标 y坐标,可选的最大宽度)。

    这里需要注意的是要把文字绘制在圆心(好看点,你非要写在其他地方也可以)。c.measureText(info).width这个方法是测量所绘制文字的宽度的,这样确定x的坐标,y坐标直接这只基线居中即可c.textBaseline = "middle";基线就是文字以那条线作为基准定位。可选的值包括:top, hanging, middle, alphabetic, ideographic, bottom。默认值是 alphabetic。图示(图片侵权的话联系我)

    这样的话基本的图形就绘制号了,现在就可以添加动画了。

    4 添加波浪动画。

    if(window.requestAnimationFrame)

    { if(obj.anim)

    {  cancelAnimationFrame(obj.anim);

    }

    var id = window.requestAnimationFrame(function() {

    //波浪移动 mWaveDx += mWaveSpeed;

    if(mWaveDx >= 2 * mWaveLength)

    { mWaveDx = 0;

    }

    c.clearRect(0, 0, w, h);

    draw(obj);

    });

    obj.anim = id;

    }

    else { if(obj.anim)

    {  clearTimeout(obj.anim);

    }

    var id = window.setTimeout(function()

    { //波浪移动 mWaveDx += mWaveSpeed;

    if(mWaveDx >= 2 * mWaveLength) { mWaveDx = 0;

    }

    c.clearRect(0, 0, w, h); draw(obj);

    }, 20);

    obj.anim = id;

    }

    没什么难度,就是改变x坐标的值然后重绘,方法clearRect就是清除一个矩形区域的图形,requestAnimationFrame方法是专门用来绘制图形的,这个方法要实现循环的话需要像setTimeout那样在函数内部再次调用setTimeout。不过这里调用之后形成递归,无需那样做。简单来说就是不管改变x坐标,清除画布,重新绘制。这样波浪就动起来了。

    5 进度控制

    这个只需要改变波浪的y轴坐标就行了。

    if(pro == 0) {

    mWaveDy = h;

    } else if(pro == obj.mMaxValue)

    { mWaveDy = 0; }

    else if(pro <= obj.mBorderwidth)

    { //进度小于线宽 圆的线过宽会遮住波浪 所以上移一点

    mWaveDy = h - 2 * obj.mBorderwidth;

    }

    else if(pro >= obj.mMaxValue - obj.mBorderwidth)

    {

    //避免遮住 下移一点

    mWaveDy = h - (pro / obj.mMaxValue) * h + 2 * obj.mBorderwidth;

    }

    else { mWaveDy = h - (pro / obj.mMaxValue) * h;

    }

    需要注意的是如果圆的线宽设置了大于1,波浪的高度需要相应的做处理,不然进度太低(比如1)波浪会显示不出,进度太高(比如98),就完全占满圆形了。

    6 封装成一个js。

    封装涉及到js的面向对象设计,大家可以看看JS高级程序设计。

    完整的代码js学习

    相关文章

      网友评论

          本文标题:h5 canvas学习之绘制圆形波浪进度条

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