如何在Canvas滚动动画结束后添加可滚动的后续内容?
问题解决:Canvas动画后显示后续内容并保持滚动条
核心问题分析
- CSS中
content选择器写错,遗漏类选择器的点号,导致内容样式完全不生效 .content定位为absolute脱离文档流,无法正常占据页面空间,滚动后看不到内容- 内容区域未设置足够高度,无法保证页面加载时就出现滚动条
修改方案
1. 修正CSS选择器与内容布局
把错误的content选择器改为.content,将定位改为relative让内容回到文档流,同时设置宽度和最小高度,确保页面有足够滚动空间:
.content { position: relative; width: 100%; background: #000; color: #fff; padding: 20px 0; text-align: center; margin-top: 100vh; min-height: 100vh; /* 保证内容至少占一屏高度,加载时就有滚动条 */ opacity: 0; transition: opacity 1s ease-in-out; }
2. 调整层级关系
给Canvas、overlay、内容添加层级,确保动画期间Canvas和overlay在内容上方,动画结束后内容正常显示:
canvas { /* 原有样式 */ z-index: 10; } .overlay { /* 原有样式 */ z-index: 20; } .content { /* 原有样式 */ z-index: 5; }
3. 优化动画结束后的内容显示逻辑
动画结束后隐藏overlay和标题,让内容完全展示:
if (frameIndex === frameCount - 1) { canvas.style.transition = 'opacity 1s ease-in-out'; canvas.style.opacity = '0'; overlay.classList.add('visible'); message.classList.add('visible'); setTimeout(() => { content.classList.add('visible'); overlay.classList.remove('visible'); message.classList.remove('visible'); }, 1000); }
修改后的完整代码
HTML
<canvas width="300" height="200" class="ultragear-scrolling"></canvas> <div class="overlay"> <h1 class="message">Ultra Gear </h1> </div> <div class="content"> <h2>Additional Content</h2> <img src="https://gi.esmplus.com/BLADER01/Hyuk/27gs95qe/27gs95qe_01.png" alt="Additional Image" /> </div>
CSS
html { height: 2000vh; } body { background: #000; height: 2000vh; margin: 0; } canvas { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); max-height: 100vh; max-width: 100vw; z-index: 10; } .overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; opacity: 0; transition: opacity 1s ease-in-out; pointer-events: none; background: #000; z-index: 20; } .message { color: #fff; font-size: 2rem; transform: scale(0); transition: transform 1s ease-in-out; } .overlay.visible { opacity: 1; } .message.visible { transform: scale(1); } .content { position: relative; width: 100%; background: #000; color: #fff; padding: 20px 0; text-align: center; margin-top: 100vh; min-height: 100vh; opacity: 0; transition: opacity 1s ease-in-out; z-index: 5; } .content.visible { opacity: 1; }
JavaScript
const html = document.documentElement; const canvas = document.querySelector('.ultragear-scrolling'); const context = canvas.getContext('2d'); const overlay = document.querySelector('.overlay'); const message = document.querySelector('.message'); const content = document.querySelector('.content'); const currentFrame = index => ( `https://gi.esmplus.com/BLADER01/Hyuk/oled-moon/${index.toString().padStart(0, '1')}.jpg` ); const frameCount = 294; canvas.height = 770; canvas.width = 1158; const images = []; const preloadImages = () => { for (let i = 1; i <= frameCount; i++) { const img = new Image(); img.src = currentFrame(i); images.push(img); } }; preloadImages(); const img = new Image(); img.src = currentFrame(1); img.onload = function() { drawCentered(img); } const updateImage = index => { context.clearRect(0, 0, canvas.width, canvas.height); drawCentered(images[index]); }; function drawCentered(img) { const offsetX = (canvas.width - img.width) / 2; const offsetY = (canvas.height - img.height) / 2; context.drawImage(img, offsetX, offsetY); } let animationFrameId; window.addEventListener('scroll', () => { cancelAnimationFrame(animationFrameId); const scrollTop = html.scrollTop; const maxScrollTop = html.scrollHeight - window.innerHeight; const scrollFraction = scrollTop / maxScrollTop; const frameIndex = Math.min( frameCount - 1, Math.floor(scrollFraction * frameCount) ); animationFrameId = requestAnimationFrame(() => updateImage(frameIndex)); if (frameIndex === frameCount - 1) { canvas.style.transition = 'opacity 1s ease-in-out'; canvas.style.opacity = '0'; overlay.classList.add('visible'); message.classList.add('visible'); setTimeout(() => { content.classList.add('visible'); overlay.classList.remove('visible'); message.classList.remove('visible'); }, 1000); } else { canvas.style.opacity = '1'; overlay.classList.remove('visible'); message.classList.remove('visible'); content.classList.remove('visible'); } });
内容的提问来源于stack exchange,提问作者HK L
相关产品推荐
相关产品推荐

