英文:
Change color of text letter by letter on scroll
问题
我试图重新创建这个网站上的样式:https://www.polestar.com/us/polestar-1/
在第三部分,标题为“Precision”,那种样式是我想要重新创建的。就像它将段落文字颜色从白色更改为rgb(211, 188, 141)一样,并在完成更改文字颜色后取消粘性位置。
这是如何工作的?
我尝试使用与他们相同的方法,为每个字母使用不同的元素<span>,并在滚动时隐藏白色字母,但我不确定js部分。
英文:
I am trying to recreate this style from a website: https://www.polestar.com/us/polestar-1/
On the third section which is titled as "Precision", thats kind of style I want to recreate.. Like how it changed paragraph text color from white to rgb(211, 188, 141).. and removes the sticky position when it finish changing the text color..
How this works?
I tried to use the same method as they did, using different elements as <span> for each letter and hide the letter white letter as we scroll but I am not sure with the js
答案1
得分: 1
这是一个JavaScript脚本,用于在滚动时改变文本颜色。它的主要功能包括:
- 设置要固定的滚动位置
stickyAtYPos
为 100。 - 设置每个字符着色的最小时间间隔
minTimeColorCharMs
为 50 毫秒。 - 禁用浏览器记住滚动位置的功能。
- 监听窗口的滚动事件。
- 将具有类名
.stickyColor
的段落中的文本分割成一个个字符,并用<span>
包装起来,以便对字符进行单独着色。 - 当用户向下滚动且满足一定条件时,着色文本中的字符。
- 根据页面上
.stickyColor
元素的位置,在特定条件下将其固定。
此外,还提供了一些CSS和HTML用于样式和页面结构。
注意:此脚本应该作为页面的最后一个元素包含在 <body>
内,以确保所有元素都在DOM中时运行。
如果您需要进一步的解释或帮助,请告诉我。
英文:
An example. I have tried to comment everything that happens carefully in the JS.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
// at what yPosition should we stick?
const stickyAtYPos = 100;
// minumum time between coloring a character
const minTimeColorCharMs = 50;
// browser, do not remember scroll positions for me
history.scrollRestoration = "manual";
// a flag that is set later (yPos to lock the scroll at)
// + which sticky that is currently locked
// + lastTime we colored a span
let lockedAt, lockedSticky, lastColorTime = 0;
// divide text inside .stickyColor elements
// into one span per character
[...document.querySelectorAll('.stickyColor')]
.forEach(x => x.innerHTML = '<span>'
+ x.innerText.trim().split('')
.join('</span><span>') + '</span>');
// listen to the scroll event of the window
window.addEventListener('scroll', e => {
// if scroll is locked and the user scrolls down
// and time enough between coloring characters
if (lockedAt && window.scrollY > lockedAt &&
(!lastColorTime || Date.now() - lastColorTime > minTimeColorCharMs)) {
// find the first uncolored span
let span = [...lockedSticky.querySelectorAll('span')]
.find(x => !x.classList.contains('newColor'));
// color it and remember when we did that
span && span.classList.add('newColor') || (lastColorTime = Date.now());
// if no more spans to color, release the scroll lock
!span && (lockedAt = false);
}
// if locked, then don't allow scroll down
lockedAt && window.scrollY > lockedAt && window.scrollTo(0, lockedAt);
// get the stickycolor elements
let stickies = [...document.querySelectorAll('.stickyColor')];
// loop through them
stickies.forEach((sticky, i) => {
// if we have a lock already do nothing
if (lockedAt) { return; }
// check if the sticky should stick :)
if (sticky.getBoundingClientRect().top < stickyAtYPos
&& !sticky.classList.contains('locked')) {
// remember y pos to lock scroll at + locked sticky
lockedAt = window.scrollY;
lockedSticky = sticky;
// add class signaling that we are locked
sticky.classList.add('locked');
}
});
});
<!-- language: lang-css -->
body {
background-color: black;
margin: 20px 30px;
color: white;
}
p.stickyColor {
font-family: 'Verdana';
margin-top: 200px;
top: 100px;
transition: color 1s;
}
p.stickyColor span {
color: white;
transition: color 0.1s;
}
p.stickyColor span.newColor {
color: rgb(192, 143, 35);
}
.big {
height: 1000px;
}
<!-- language: lang-html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sticky Color</title>
</head>
<body>
<p>Please scroll down...</p>
<p class="stickyColor">Hello there! Nice to see you!</p>
<p class="stickyColor">Let's play a game of colors...</p>
<p class="stickyColor">Goodbye everyone! That's all.</p>
<div class="big"></div>
</body>
</html>
<!-- end snippet -->
Note: Although you can't see it here, the script needs to be included as the last element in the body, since all elements need to be in the DOM before it runs and I'm not waiting for document ready...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论