toBalling = () => { // 水球 let canvas = this.refs.c; let ctx = canvas.getContext("2d"); let waterBallValue = this.state.waterBallValue;//水球上显示的数值 let M = Math; let Sin = M.sin; let Cos = M.cos; let Sqrt = M.sqrt; let Pow = M.pow; let PI = M.PI; let Round = M.round; let oW = canvas.width = 300; let oH = canvas.height = 300; // 线宽 let lineWidth = 4; // 大半径 let r = (oW / 2); let cR = r - 8 * lineWidth; ctx.beginPath(); ctx.lineWidth = lineWidth; // 水波动画初始参数 let axisLength = 2 * r - 16 * lineWidth; // Sin 图形长度 let unit = axisLength / 8; // 波浪宽 let range = .2 // 浪幅 let nowrange = range; let xoffset = 8 * lineWidth; // x 轴偏移量 let data = ~~waterBallValue / 100; // 数据量 let sp = 0; // 周期偏移量 let nowdata = 0; let waveupsp = 0.002; // 水波上涨速度 // 圆动画初始参数 let arcStack = []; // 圆栈 let bR = r - 8 * lineWidth; let soffset = -(PI / 2); // 圆动画起始位置 let circleLock = true; // 起始动画锁 // 获取圆动画轨迹点集 for (var i = soffset; i < soffset + 2 * PI; i += 1 / (8 * PI)) { arcStack.push([ r + bR * Cos(i), r + bR * Sin(i) ]) } let cStartPoint = arcStack.shift(); // 圆起始点 ctx.strokeStyle = "#ffffff";//圆环的颜色 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 = "#506be9";//波浪的颜色 ctx.fill() ctx.restore(); } function drawText() { ctx.globalCompositeOperation = 'source-over'; var size = 0.4 * cR; ctx.font = size + 'px Microsoft Yahei'; let txt = (nowdata.toFixed(2) * 100).toFixed(0); var fonty = r + size / 2; var fontx = r - size * 0.8; ctx.fillStyle = "white";//水波字体颜色 ctx.fillText(txt, fontx, fonty) } function render() { ctx.clearRect(0, 0, oW, oH); if (circleLock) { if (arcStack.length) { var temp = arcStack.shift(); ctx.lineTo(temp[0], temp[1]) ctx.stroke(); } else { circleLock = false; ctx.lineTo(cStartPoint[0], cStartPoint[1]) ctx.stroke(); arcStack = null; ctx.globalCompositeOperation = 'destination-over'; ctx.beginPath(); ctx.lineWidth = lineWidth; ctx.arc(r, r, bR, 0, 2 * PI, 1); ctx.beginPath(); ctx.save(); ctx.arc(r, r, r - 16 * lineWidth, 0, 2 * PI, 1); ctx.restore(); ctx.clip(); ctx.fillStyle = "#1c86d1"; } } else { // 开始水波动画 // 控制波幅 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) } // 水球end };
<canvas id="c" ref="c">当前浏览器不支持canvas 请升级!</canvas>