Изменить цвет текста буква за буквой при прокрутке

Я пытаюсь воссоздать этот стиль с веб-сайта: https://www.polestar.com/us/polestar-1/ В третьем разделе, который называется «Точность», я хочу воссоздать такой стиль. Например, как он изменил цвет текста абзаца с белого на rgb (211, 188, 141).. и удалил липкую позицию, когда он закончился. изменение цвета текста..

Как это работает?

Я пытался использовать тот же метод, что и они, используя разные элементы для каждой буквы и скрывая белую букву буквы при прокрутке, но я не уверен с js

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пример. Я попытался тщательно прокомментировать все, что происходит в 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');
    }
  });
});
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;
}
<!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>

Примечание. Хотя вы не можете видеть его здесь, скрипт должен быть включен в качестве последнего элемента в тело, поскольку все элементы должны быть в DOM до его запуска, и я не жду, когда документ будет готов...

Хороший. Можете ли вы сбросить его при прокрутке назад?

mplungjan 07.05.2023 13:37

Не будет ли сброс его при прокрутке назад очень раздражающим с точки зрения пользователей? (Я бы так подумал...) Постоянная блокировка прокрутки, когда вы хотите двигаться вверх и вниз по содержимому...

Thomas Frank 07.05.2023 13:47

Это может быть правдой

mplungjan 07.05.2023 14:02

@mplungjan: Это выполнимо, но я уже потратил слишком много времени на это ... так что не я. (Слишком много экранного времени, предупреждение... ;))

Thomas Frank 07.05.2023 14:04

Да, я тоже ответил и был не совсем доволен, поэтому удалил свой ответ, так как ваш был лучше. У меня было два набора пролетов, и я сделал const index = Math.floor(scrollTop / elementHeight); if (normalSpan) normalSpan.style.opacity = (i < index ? 1 : 0); if (colorSpan) colorSpan.style.opacity = (i >= index ? 1 : 0);

mplungjan 07.05.2023 14:04

@mplungjan: Ваш ответ был хорошей отправной точкой (я проголосовал за него)

Thomas Frank 07.05.2023 14:06

Что меня не совсем устраивает в моем, так это то, что при быстрой прокрутке он «трясется» (хуже в этом маленьком «тестовом окне», чем в большом окне просмотра, но: чтобы исправить это, вам нужно добавить прослушиватели событий на колесо, touchstart и touchmove, установите для них значение {passive: false} и вызовите event.preventDefault, но в то же время прочитайте, в каком направлении пользователь хотел выполнить прокрутку (от колеса e.yDelta, при касании, посмотрев на измененный указатель...) Тоже много работы прямо сейчас Но это устранило бы дрожь, я бы сделал это, если буду жить с профессиональной версией.

Thomas Frank 07.05.2023 14:08

Другие вопросы по теме