如何实现每日递增1/365进度的Canvas圆形轮廓效果?
实现随每日计数器同步填充的Canvas圆弧
Hey Benjamin,很高兴看到你已经搞定了基础的每日计数器和圆形细边框!要让粗轮廓跟着计数器同步填充其实很简单,核心就是根据当前天数占365的比例,绘制部分圆弧来实现进度效果。我帮你调整了代码,同时给你拆解一下关键步骤:
关键思路拆解
- 计算填充比例:用当前天数除以365,得到一个0-1之间的数值,再乘以整个圆的弧度(
2*Math.PI),就能得到需要填充的圆弧角度。 - 分层绘制:先画粗的填充圆弧,再叠加细边框,这样视觉上更整齐。
- 实时更新:把Canvas绘制逻辑放到计数器的
upTime函数里,每次天数更新时重新绘制,保证进度和计数器同步。
修改后的完整代码
HTML部分
<canvas id="canvas" width="500" height="500"></canvas> <p><span id="days">0</span>/365</p>
JavaScript部分
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); // 定义圆弧的基础参数,方便后续调整 const centerX = 250; const centerY = 250; const radius = 200; const thinBorderWidth = 2; const fillBorderWidth = 10; window.onload = function() { // 初始化计数器 upTime('dec,31,2017,00:00:00'); } var today, someday, difference; function upTime(someday) { today = new Date(); someday = new Date(someday); difference = (today - someday); var days = Math.floor(difference / (1000*60*60*24)*1); // 确保天数不超过365(避免跨年之后进度超过100%) days = Math.min(days, 365); document.getElementById('days').innerHTML = days; // 每次更新天数时重新绘制Canvas drawProgressArc(days); clearTimeout(upTime.to); upTime.to = setTimeout(function() { upTime(someday); }, 1000); // 改成每秒更新一次,减少性能消耗 } function drawProgressArc(days) { // 先清空Canvas,避免重复绘制 ctx.clearRect(0, 0, canvas.width, canvas.height); // 1. 绘制粗的填充进度圆弧 ctx.beginPath(); ctx.lineWidth = fillBorderWidth; ctx.strokeStyle = '#4CAF50'; // 填充用的绿色,可自定义 // 计算填充角度:天数/365 * 整个圆的弧度 var fillAngle = (days / 365) * 2 * Math.PI; // 绘制从0到fillAngle的圆弧 ctx.arc(centerX, centerY, radius, 0, fillAngle); ctx.stroke(); // 2. 绘制细边框圆弧 ctx.beginPath(); ctx.lineWidth = thinBorderWidth; ctx.strokeStyle = '#333'; // 细边框颜色,可自定义 ctx.arc(centerX, centerY, radius, 0, 2*Math.PI); ctx.stroke(); }
额外优化说明
- 我把圆弧的参数(圆心、半径、线条宽度)都单独提出来了,以后你要调整样式直接改这些常量就行,不用在代码里到处找。
- 加了
days = Math.min(days, 365)的判断,避免跨年之后天数超过365,进度条不会溢出。 - 把定时器的间隔改成了1000毫秒(每秒更新一次),之前的0毫秒会导致浏览器疯狂触发更新,浪费性能。
这样你运行代码就能看到,随着天数增加,绿色的粗圆弧会慢慢填充整个圆形边框,和计数器完全同步啦!
内容的提问来源于stack exchange,提问作者Benjamin Rowntree
相关产品推荐
相关产品推荐

