如何在p5.js中更新环形时钟的数字?
解决p5.js旋转环时钟数字不更新的问题
问题核心
当前代码中,环的旋转依赖millis()持续计时,而数字显示依赖second()取整数值,两者未绑定导致旋转位置与数字内容不匹配,视觉上表现为数字“不更新”;同时原绘制逻辑拆分两个循环,增加了不必要的复杂度。
修复方案
关键修改点
- 旋转角度与时间绑定:将环的旋转角度基于当前时间(秒数+毫秒小数)计算,确保旋转速度与时间完全同步。
- 简化数字绘制逻辑:用单个循环遍历所有显示位置,直接计算每个位置对应的时间偏移量。
- 优化文字朝向:调整每个数字的旋转角度,保证文字始终正向显示。
修改后的完整代码
ring.js
function trueMod(value, modulus) { /* 处理负数的取模运算 */ return ((value % modulus) + modulus) % modulus; } class Ring { /** * @param {number} radius - 环的半径 * @param {number} modulus - 数字的循环模数(如秒环为60) * @param {p5.Color} fillColor - 环的填充色 * @param {Function} update - 获取当前时间值的函数(如second()) */ constructor(radius, modulus, fillColor, update) { this.radius = radius; this.modulus = modulus; this.fillColor = fillColor; this.update = update; this.numSlices = 24; // 环上显示的数字数量 } draw() { push(); // 绘制环形背景 fill(this.fillColor); circle(0, 0, this.radius * 2 + 40); // 计算当前时间对应的旋转角度:秒数+毫秒小数,对应一圈的比例 const currentTime = this.update() + millis() / 1000; const rotation = currentTime * -TAU / this.modulus; rotate(rotation); fill(255); const step = TAU / this.numSlices; // 遍历所有要显示的位置,计算每个位置的偏移量(从-11到+12,共24个位置) for (let i = 0; i < this.numSlices; i++) { const offset = i - this.numSlices / 2 + 1; // 计算当前位置的角度 const angle = -TAU / 4 + i * step; push(); // 移动到环上的对应位置 translate(this.radius * cos(angle), this.radius * sin(angle)); // 旋转文字,使其始终正向显示 rotate(-angle - rotation); // 计算并显示对应的数字,补零到两位 const num = String(trueMod(this.update() + offset, this.modulus)).padStart(2, "0"); text(num, 0, 0); pop(); } pop(); } }
sketch.js
let secondRing; function setup() { createCanvas(windowWidth, windowHeight); secondRing = new Ring( windowHeight * 6 / 16, 60, color(0x57, 0x75, 0x90), second ); } function draw() { background(0); textAlign(CENTER, CENTER); textSize((windowHeight * 1) / 30); fill(255); // 左上角显示当前秒数参考 text(second(), 50, 50); translate(windowWidth / 2, windowHeight / 2); secondRing.draw(); }
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.js"></script>
效果说明
修改后,环的旋转完全同步于当前时间,每个位置的数字会随着时间推移正确更新,且仅显示当前秒数±12范围内的数字,避免了60个数字拥挤的问题。下半部分可通过调整画布或设置裁剪隐藏,符合你的设计需求。
内容的提问来源于stack exchange,提问作者tstrickler
相关产品推荐
相关产品推荐

