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>