canvas绘制多边形进度展示图,水波浪效果
参考:
多边形函数:https://www.cnblogs.com/anxia...
canvas画波浪进度球:https://www.cnblogs.com/pagod...
最近项目中需要一个六边形的水波纹进度,在网上只找到了一个进度球的绘制方法,然后结合了一下多边形的绘制方法,代码如下
案例1:
代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <style> body{ position: relative; width:100vw; height: 100vh; margin: 0; } canvas{ position: absolute; left: 50%; top: 50%; margin-left: -150px; margin-top: -150px; border: 1px dashed rgba(0,0,0,0.1) } </style> <body> <canvas id="c"></canvas> <input type="range" id="r" min="0" max="100" step="1"> </body> <script> var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); var range = document.getElementById('r'); //range控件信息 var rangeValue = range.value; var nowRange = 40; //用于做一个临时的range //画布属性 var mW = canvas.width = 350; var mH = canvas.height = 350; var lineWidth = 1; //圆属性 var r = mH / 2; //圆心 var cR = r - 32 * lineWidth; //圆半径 //Sin 曲线属性 var sX = 0; var axisLength = mW; //轴长 var waveWidth = 0.008 ; //波浪宽度,数越小越宽 var waveHeight = 6; //波浪高度,数越大越高 var speed = 0.09; //波浪速度,数越大速度越快 var xOffset = 0; //波浪x偏移量 ctx.lineWidth = lineWidth; //画圈函数 var IsdrawCircled = false; var drawCircle = function(){ // 画多边形函数 function drawPath(x, y, n, r) { var i,ang; ang = Math.PI*2/n //旋转的角度 ctx.save();//保存状态 ctx.fillStyle ='rgba(255,0,0,.3)';//填充红色,半透明 ctx.strokeStyle ='#000)';//填充绿色 ctx.lineWidth = 2;//设置线宽 ctx.translate(x, y);//原点移到x,y处,即要画的多边形中心 ctx.moveTo(0, -r);//据中心r距离处画点 ctx.beginPath(); for(i = 0;i < n; i ++) { ctx.rotate(ang)//旋转 ctx.lineTo(0, -r);//据中心r距离处连线 } ctx.closePath(); ctx.stroke(); ctx.fill(); ctx.restore();//返回原始状态 } drawPath(r, r, 6, cR+1) drawPath(r, r, 6, cR) ctx.clip(); IsdrawCircled = true; } //画sin 曲线函数 var drawSin = function(xOffset, color, waveHeight){ ctx.save(); var points=[]; //用于存放绘制Sin曲线的点 ctx.beginPath(); //在整个轴长上取点 for(var x = sX; x < sX + axisLength; x += 20 / axisLength){ //此处坐标(x,y)的取点,依靠公式 “振幅高*sin(x*振幅宽 + 振幅偏移量)” var y = Math.sin((-sX - x) * waveWidth + xOffset) * 0.8 + 0.1; var dY = mH * (1 - nowRange / 100 ); points.push([x, dY + y * waveHeight]); ctx.lineTo(x, dY + y * waveHeight); } //封闭路径 ctx.lineTo(axisLength, mH); ctx.lineTo(sX, mH); ctx.lineTo(points[0][0],points[0][1]); ctx.fillStyle = color; ctx.fill(); ctx.restore(); }; var render = function(){ ctx.clearRect(0, 0, mW, mH); rangeValue = range.value; console.log(rangeValue); if(IsdrawCircled == false){ drawCircle(); } if(nowRange <= rangeValue){ var tmp = 1; nowRange += tmp; } if(nowRange > rangeValue){ var tmp = 1; nowRange -= tmp; } drawSin(xOffset+Math.PI*0.7, 'rgba(28, 134, 209, 0.5)', 18); drawSin(xOffset, '#1c86d1', 18); drawText(); xOffset += speed; requestAnimationFrame(render); } //写百分比文本函数 var drawText = function(){ ctx.save(); var size = 0.4*cR; ctx.font = size + 'px Microsoft Yahei'; ctx.textAlign = 'center'; ctx.fillStyle = "rgba(06, 85, 128, 0.5)"; ctx.fillText(~~nowRange + '%', r, r + size / 2); ctx.restore(); }; render(); </script> </html>
效果图
案例2:
代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <style> body{ position: relative; width:100vw; height: 100vh; margin: 0; } canvas{ position: absolute; left: 50%; top: 50%; margin-left: -150px; margin-top: -150px; border: 1px dashed rgba(0,0,0,0.1) } </style> <body> <canvas id="c"></canvas> </body> <script> var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); // 初始化参数 let oW = 236, oH = 267, lineWidth = 1, bOffset = 2, border = 3, //X轴偏移量 r, cR, axisLength, unit, // 浪宽 range = .3, // 浪高 nowrange = .3, sp = 0, // 周期偏移量 nowdata = 0, value = 0.5, // 百分比 waveupsp = 0.002; // 水波上涨速度 canvas.width = oW; canvas.height = oH; ctx.lineWidth = lineWidth; var triangleH = Math.ceil(oH/4); // 外六边形 var arcStack = [ [oW/2, 0], [oW-bOffset, triangleH], [oW-bOffset,oH-triangleH], [oW/2, oH], [bOffset, oH-triangleH], [bOffset, triangleH] ]; var cStartPoint = arcStack.shift(); // 内六边形 var arcStackInner = [ [oW/2, border], [oW-border, triangleH + border/2], [oW-border, oH-triangleH-border/2], [oW/2, oH-border], [border, oH - triangleH - border/2], [border,triangleH + border/2] ]; var cStartPointInner = arcStackInner.shift(); r = oW / 2; cR = oH/2 - border - lineWidth; ctx.beginPath(); axisLength = oW - 2*border; unit = axisLength / 20; ctx.beginPath(); renderBorder(); render(); function renderBorder() { ctx.beginPath(); ctx.strokeStyle = "#000000"; ctx.fillStyle = "#000000"; ctx.moveTo(cStartPoint[0], cStartPoint[1]); while (arcStack.length) { var temp = arcStack.shift(); this.ctx.lineTo(temp[0], temp[1]); ctx.stroke(); } ctx.lineTo(cStartPoint[0], cStartPoint[1]); ctx.stroke(); ctx.fill(); ctx.globalCompositeOperation = 'source-over'; ctx.beginPath(); ctx.fillStyle = '#fff' ctx.strokeStyle = '#fff'; ctx.moveTo(cStartPointInner[0], cStartPointInner[1]); while (arcStackInner.length) { var temp = arcStackInner.shift(); this.ctx.lineTo(temp[0], temp[1]); ctx.stroke(); } ctx.lineTo(cStartPointInner[0], cStartPointInner[1]); ctx.stroke(); ctx.fill(); ctx.restore(); ctx.clip(); ctx.save(); ctx.globalCompositeOperation = 'source-over'; } function render() { ctx.clearRect(0,0,oW,oH); if (value >= 0.85) { if (nowrange > range/4) { var t = range * 0.01; nowrange -= t; } } else if (value <= 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((value - nowdata) > 0) { nowdata += waveupsp; } if((value - nowdata) < 0){ nowdata -= waveupsp } sp += 0.07; if(value){ drawSine(); } requestAnimationFrame(render) } function drawSine() { ctx.beginPath(); ctx.save(); var Stack = []; for (let i = border; i <= border+axisLength; i+=20/axisLength) { var x = sp + (border + i) / unit; var y = Math.sin(x) * nowrange; var dx = i; var dy = 2*cR*(1-nowdata) + border - (unit * y); ctx.lineTo(dx, dy); Stack.push([dx,dy]); } var startP = Stack[0] ctx.lineTo(border + axisLength,oH + border); ctx.lineTo(border,oH+border); ctx.lineTo(startP[0], startP[1]) ctx.fillStyle = "#50bff7"; ctx.fill(); ctx.restore(); } function drawText() { ctx.save(); var size = 0.4*cR; ctx.font = size + 'px Microsoft Yahei'; ctx.textAlign = 'center'; ctx.fillStyle = "rgba(06, 85, 128, 0.5)"; let txt = (nowdata.toFixed(2)*100).toFixed(0) + '%'; ctx.fillText(txt, r, r + size / 2); ctx.restore(); } </script> </html>
效果图
相关推荐
jinxiutong 2020-07-26
northwindx 2020-05-31
jinxiutong 2020-05-10
zrtlin 2020-11-09
xuebingnan 2020-11-05
wikiwater 2020-10-27
heheeheh 2020-10-19
Crazyshark 2020-09-15
softwear 2020-08-21
ZGCdemo 2020-08-16
jczwilliam 2020-08-16
littleFatty 2020-08-16
idning 2020-08-03
lanzhusiyu 2020-07-19
Skyline 2020-07-04
xiaofanguan 2020-06-25