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

Canvas下拉文本动画无限循环实现及绘制优化方案咨询

实现无限循环的文本滚动动画

嘿,我来帮你搞定这个无限滚动的文本动画!先解决循环的问题,再给你介绍更简便的实现方式。

一、修改现有代码实现无限循环

你的原代码里y值一直在累加却没有重置逻辑,所以文本会一直往下跑,不会回到顶部。我们只需要在y增加到单行文本高度时,把它重置为0,就能实现无缝循环——因为你已经把文本重复拼接成了无限长的字符串,重置后内容会完美衔接,看起来就像一直在滚动。

修改后的完整代码:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;

const txtHeight = 10; // 把行高抽成变量,方便后续维护

// fills canvas with given text
function draw(txt, y) {
  var w = Math.ceil(ctx.measureText(txt).width);
  var txt = new Array(w * 2).join(' ' + txt + ' ');
  var totalRows = Math.ceil(canvas.height / txtHeight);
  for (var i = 0; i < totalRows; i++) {
    ctx.fillText(txt, 0, i * txtHeight + y);
  }
}

// animate
var y = 0;
function animate() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  draw('STACK-OVERFLOW', y);
  y += 1;
  // 当y超过单行高度时重置,实现无缝循环
  if (y >= txtHeight) {
    y = 0;
  }
}
setInterval(animate, 50);

二、更简便的实现方式

如果你的需求只是文本滚动,其实有比“持续清除+重绘”更省心的方案:

1. 用Canvas坐标系平移优化

可以通过平移Canvas的坐标系来实现滚动,逻辑更清晰,不需要手动计算y值:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;

const txtHeight = 10;

function draw(txt) {
  var w = Math.ceil(ctx.measureText(txt).width);
  var txt = new Array(w * 2).join(' ' + txt + ' ');
  var totalRows = Math.ceil(canvas.height / txtHeight);
  for (var i = 0; i < totalRows; i++) {
    ctx.fillText(txt, 0, i * txtHeight);
  }
}

let offset = 0;
function animate() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.save(); // 保存当前坐标系状态
  ctx.translate(0, offset); // 向下平移offset像素
  draw('STACK-OVERFLOW');
  ctx.restore(); // 恢复原始坐标系
  offset += 1;
  if (offset >= txtHeight) {
    offset = 0;
  }
}
setInterval(animate, 50);

2. 用CSS动画替代Canvas(推荐)

如果不需要Canvas的复杂绘制能力,用CSS动画会更简单,几乎不需要JavaScript:

<div class="text-container" id="textContainer"></div>
.text-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  font-size: 10px;
  line-height: 10px;
  overflow: hidden;
}

.scrolling-text {
  animation: scrollDown 2s linear infinite;
}

@keyframes scrollDown {
  from { transform: translateY(0); }
  to { transform: translateY(-10px); } /* 移动距离等于行高,实现无缝滚动 */
}
// 仅用JS生成填满视口的重复文本
const text = 'STACK-OVERFLOW';
const container = document.getElementById('textContainer');
const rowCount = Math.ceil(window.innerHeight / 10);
const repeatedText = (' ' + text + ' ').repeat(Math.ceil(window.innerWidth / text.length * 2));
container.innerHTML = Array(rowCount).fill(repeatedText).join('<br>');
container.classList.add('scrolling-text');

这种方式不需要手动处理画布清除和重绘,浏览器会自动优化动画性能,代码也更简洁。

内容的提问来源于stack exchange,提问作者Evangelos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:21:10