基于滚动进度的文本动画问题:位置计算异常排查
滚动触发的横向飞入动画位置计算问题
- 需求:页面滚动时,当
.marquee元素进入视口,其下的.marquee-row子元素会根据data-position属性(start/end)从对应方向飞入屏幕;当.marquee离开视口时,子元素完全隐藏。文本内容可能超出视口宽度。 - 现有问题:位置计算逻辑存在错误,仅在正方形尺寸的视口下能正常运行,具体问题可查看JavaScript代码中的注释。
- 使用的jQuery版本:3.7.1
HTML代码
<div class="marquee"> <div class="marquee-row" data-position="start"> <div class="marquee-row-data"> <p class="marquee-row-data-text"><span>Mertingen</span></p> </div> <div class="marquee-row-data"> <p class="marquee-row-data-text"><span>Praha</span></p> </div> <div class="marquee-row-data"> <p class="marquee-row-data-text"><span>Budapest</span></p> </div> <div class="marquee-row-data"> <p class="marquee-row-data-text"><span>Bratislava</span></p> </div> <div class="marquee-row-data"> <p class="marquee-row-data-text"><span>Das ist ein cooler und langer Test</span></p> </div> </div> <div class="marquee-row" data-position="end"> <div class="marquee-row-data"> <p class="marquee-row-data-text"><span>Günzburg</span></p> </div> <div class="marquee-row-data"> <p class="marquee-row-data-text"><span>Wroclaw</span></p> </div> <div class="marquee-row-data"> <p class="marquee-row-data-text"><span>Opole</span></p> </div> <div class="marquee-row-data"> <p class="marquee-row-data-text"><span>Hanoi</span></p> </div> </div> </div>
CSS代码
body { padding: 30rem 0; } .marquee { overflow: hidden; background-color: green; } .marquee-row { position: relative; display: flex; width: fit-content; } .marquee-row[data-position="end"] { float: right; } .marquee-row-data { display: flex; overflow: hidden; padding: 0.5rem 0; position: relative; } .marquee-row-data:not(:last-child)::after { content: '/'; color: black; padding: 0 0.5rem; } .marquee-row-data::after, .marquee-row-data-text>* { font-size: 4.5rem; line-height: 5rem; font-weight: 600; } .marquee-row-data-text { position: relative; white-space: nowrap; overflow-x: clip; } .marquee-row-data-text span { color: black; cursor: default; } .marquee-row-data-text a { color: red; }
JavaScript代码
function run() { const marquees = $('.marquee'); if (marquees.length === 0) return; const handleSliding = _ => { $(marquees).each((_, marquee) => { const rows = $(marquee).find('.marquee-row'); if (rows.length === 0) return; const handler = entries => { entries.forEach(entry => { if (entry.isIntersecting) { $(window).on('scroll.marquee', _ => { $(rows).each((i, row) => { const position = $(row).attr('data-position'); if (!position) return; const elementPositionY = row.getBoundingClientRect().top; const percentHeight = 100 / window.innerHeight * elementPositionY; const startPos = 100 / window.innerWidth * $(row).innerWidth() * -1; // 以下是尝试修正的思路注释: // percentHeight = percentHeight < 0 ? 0 : percentHeight > 100 ? 100 : percentHeight; // fullWidth / window.innerHeight; // 100 / (fullWidth / (100 / window.innerHeight * elementPositionY)); // 100 / ((fullWidth / 100) * (100 / window.innerHeight * elementPositionY)); // fullWidth / (window.innerHeight + $(marquee).outerHeight()) const fullWidth = window.innerWidth + $(row).innerWidth(); const percentWidth = fullWidth / window.innerHeight; const percent = startPos + (percentWidth * percentHeight); $(row).css(position === 'start' ? 'left' : 'right', `${percent}vw`); }); }).scroll(); } else $(window).off('scroll.marquee'); }); }; const observer = new IntersectionObserver(handler); observer.observe(marquee); }); }; handleSliding(); } run();
内容的提问来源于stack exchange,提问作者RoyBlunk
相关产品推荐
相关产品推荐

