如何在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)); });
关键说明
- 文本渲染时机:必须在绘制完当前帧图片后再绘制文本,否则文本会被图片覆盖
- 居中设置:通过
textAlign: 'center'和textBaseline: 'middle'配合Canvas中心坐标,确保文本完全居中 - 样式配置:可以根据需求调整
font(字体大小、类型)和fillStyle(文本颜色)参数 - 帧范围判断:直接在
updateImage函数中根据传入的index判断,无需额外DOM操作
内容的提问来源于stack exchange,提问作者Dannie
相关产品推荐
相关产品推荐

