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

如何在Canvas滚动动画的指定帧中渲染文本?

Canvas滚动帧动画中指定帧范围显示文本的实现方法

问题说明

正在学习用Canvas实现AirPods官网风格的滚动帧动画,已完成滚动切换帧图片的功能。需求是在第50-100帧期间,在屏幕中间显示一段文本,超过100帧后文本消失。尝试用if判断帧范围触发文本显示,但文本出现在文档顶部,不知道如何通过Canvas渲染文本。

实现步骤

  • 不要通过DOM添加文本,直接使用Canvas上下文的文本绘制API
  • 在更新帧图片的函数中,先绘制当前帧图片,再根据帧范围判断是否绘制文本
  • 配置文本样式(字体大小、颜色、对齐方式),确保文本居中显示
  • 通过Canvas的宽高计算中心坐标,定位文本位置

修改后的完整代码

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Image Scrolling Animation</title>
</head>
<body>
    <canvas class="airpods-scrolling"></canvas>
    <script src="main.js"></script>
</body>
</html>

CSS

html{
height: 100vh;
}

body{
background: #000;
height: 400vh;
}

canvas{
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-height: 100vh;
max-width: 100vw;
}

JavaScript

const html = document.documentElement;
const canvas = document.querySelector('.airpods-scrolling');
const context = canvas.getContext('2d');

const currentFrame = index => (
`https://www.apple.com/105/media/us/airpods-pro/2019/1299e2f5_9206_4470_b28e_08307a42f19b/anim/sequence/large/01-hero-lightpass/${index.toString().padStart(4, '0')}.jpg`
);

const frameCount = 147;

canvas.height = 770;
canvas.width = 1158;
const img = new Image();
img.src = currentFrame(1);
img.onload = function(){
    context.drawImage(img, 0, 0);
}

// 更新图像并处理文本渲染
const updateImage = index => {
    // 先绘制当前帧图片,覆盖之前的内容
    img.src = currentFrame(index);
    context.drawImage(img, 0, 0);
    
    // 判断当前帧是否在50-100范围内
    if (index >= 50 && index <= 100) {
        // 设置文本样式
        context.font = '48px Arial';
        context.fillStyle = '#ffffff';
        context.textAlign = 'center';
        context.textBaseline = 'middle';
        
        // 在Canvas中心绘制文本
        const centerX = canvas.width / 2;
        const centerY = canvas.height / 2;
        context.fillText('你的文本内容', centerX, centerY);
    }
}

window.addEventListener('scroll', () =>{
    const scrollTop = html.scrollTop;
    const maxScrollTop = html.scrollHeight - window.innerHeight;
    const scrollFraction = scrollTop / maxScrollTop;
    const frameIndex = Math.min(frameCount - 1, Math.floor(scrollFraction * frameCount));
    requestAnimationFrame( () => updateImage(frameIndex + 1));
});

关键说明

  1. 文本渲染时机:必须在绘制完当前帧图片后再绘制文本,否则文本会被图片覆盖
  2. 居中设置:通过textAlign: 'center'和textBaseline: 'middle'配合Canvas中心坐标,确保文本完全居中
  3. 样式配置:可以根据需求调整font(字体大小、类型)和fillStyle(文本颜色)参数
  4. 帧范围判断:直接在updateImage函数中根据传入的index判断,无需额外DOM操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 16:25:09