在滚动时逐字更改文本颜色。

huangapple go评论81阅读模式
英文:

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 = &quot;manual&quot;;

// 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(&#39;.stickyColor&#39;)]
  .forEach(x =&gt; x.innerHTML = &#39;&lt;span&gt;&#39;
    + x.innerText.trim().split(&#39;&#39;)
      .join(&#39;&lt;/span&gt;&lt;span&gt;&#39;) + &#39;&lt;/span&gt;&#39;);

// listen to the scroll event of the window
window.addEventListener(&#39;scroll&#39;, e =&gt; {
  // if scroll is locked and the user scrolls down 
  // and time enough between coloring characters
  if (lockedAt &amp;&amp; window.scrollY &gt; lockedAt &amp;&amp;
    (!lastColorTime || Date.now() - lastColorTime &gt; minTimeColorCharMs)) {
    // find the first uncolored span
    let span = [...lockedSticky.querySelectorAll(&#39;span&#39;)]
      .find(x =&gt; !x.classList.contains(&#39;newColor&#39;));
    // color it and remember when we did that
    span &amp;&amp; span.classList.add(&#39;newColor&#39;) || (lastColorTime = Date.now());
    // if no more spans to color, release the scroll lock
    !span &amp;&amp; (lockedAt = false);
  }
  // if locked, then don&#39;t allow scroll down
  lockedAt &amp;&amp; window.scrollY &gt; lockedAt &amp;&amp; window.scrollTo(0, lockedAt);
  // get the stickycolor elements
  let stickies = [...document.querySelectorAll(&#39;.stickyColor&#39;)];
  // loop through them
  stickies.forEach((sticky, i) =&gt; {
    // if we have a lock already do nothing
    if (lockedAt) { return; }
    // check if the sticky should stick :)
    if (sticky.getBoundingClientRect().top &lt; stickyAtYPos
      &amp;&amp; !sticky.classList.contains(&#39;locked&#39;)) {
      // remember y pos to lock scroll at + locked sticky
      lockedAt = window.scrollY;
      lockedSticky = sticky;
      // add class signaling that we are locked
      sticky.classList.add(&#39;locked&#39;);
    }
  });
});

<!-- language: lang-css -->

body {
  background-color: black;
  margin: 20px 30px;
  color: white;
}

p.stickyColor {
  font-family: &#39;Verdana&#39;;
  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 -->

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;

&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;title&gt;Sticky Color&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;p&gt;Please scroll down...&lt;/p&gt;
  &lt;p class=&quot;stickyColor&quot;&gt;Hello there! Nice to see you!&lt;/p&gt;
  &lt;p class=&quot;stickyColor&quot;&gt;Let&#39;s play a game of colors...&lt;/p&gt;
  &lt;p class=&quot;stickyColor&quot;&gt;Goodbye everyone! That&#39;s all.&lt;/p&gt;
  &lt;div class=&quot;big&quot;&gt;&lt;/div&gt;
&lt;/body&gt;

&lt;/html&gt;

<!-- 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...

huangapple
  • 本文由 发表于 2023年5月7日 14:07:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76192427.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定