You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在p5.js中更新环形时钟的数字?

解决p5.js旋转环时钟数字不更新的问题

问题核心

当前代码中,环的旋转依赖millis()持续计时,而数字显示依赖second()取整数值,两者未绑定导致旋转位置与数字内容不匹配,视觉上表现为数字“不更新”;同时原绘制逻辑拆分两个循环,增加了不必要的复杂度。

修复方案

关键修改点

  1. 旋转角度与时间绑定:将环的旋转角度基于当前时间(秒数+毫秒小数)计算,确保旋转速度与时间完全同步。
  2. 简化数字绘制逻辑:用单个循环遍历所有显示位置,直接计算每个位置对应的时间偏移量。
  3. 优化文字朝向:调整每个数字的旋转角度,保证文字始终正向显示。

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 22:41:04