canvas 水滴图、液体进度条、仿加速球、圆球水波图
传送门:https://github.com/guoyoujin/WaterMoire
<!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> let canvas = document.getElementById("c") let ctx = canvas.getContext("2d") let oRange = document.getElementsByName("range")[0]; 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 = 250 let oH = canvas.height = 250 let lineWidth = 2 // 线宽 let r = (oW / 2) // 大半径 let cR = r - 10 * lineWidth ctx.beginPath() ctx.lineWidth = lineWidth // 水波动画初始参数 let axisLength = 2 * r - 16 * lineWidth // Sin 图形长度 let unit = axisLength / 9 // 波浪宽 let range = .4 // 浪幅 let nowrange = range let xoffset = 8 * lineWidth // x 轴偏移量 let data = ~~(oRange.value) / 100 // 数据量 let sp = 0 // 周期偏移量 let nowdata = 0 let waveupsp = 0.006 // 水波上涨速度 // 圆动画初始参数 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 = "#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.4 * cR; ctx.font = 'bold ' + 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 = "#f6b71e"; ctx.textAlign = 'center'; ctx.fillText(txt, r + 5, r + 20) } //最外面淡黄色圈 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 = 10; ctx.strokeStyle = '#eaeaea'; 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 - 10, 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; }, 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>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!