Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

157
Visualizações
Best way to render a newsticker in HTML/CSS/Javascript

We have a ticker in the bottom of an HTML page that shows news, just like a news ticker on TV. We currently use requestAnimationFrame for this but we experience that it does not always animate well and I wonder if anyone knows what would be the best practice for this.

Firstly, we tried running it on a Raspberry Pi and it couldn't render it well no matter what we tried.

Secondly, we are running it in a Windows PC in a Chrome browser and generally it works well, but if we play a high resolution video on the same page, then the rendering of the ticker becomes really laggy.

I understand that it's competing for resources but animating a ticker should in principle not require many resources so I think there should be a solution for this.

Here is our current code. It's typescript and not plain javascript, but my question is not so much about troubleshooting details in my current code but more about finding the best approach which I assume is something different than what we are doing now:

  private startTicker() {
    const ticker = document.getElementById(`RssTickerContainer_${this.props.rssTicker?.rssTicker?.url}`);
    if (!ticker || !this.state.items || this.state.items.length === 0) {
      setTimeout(() => {
        if (this.props.rssTicker?.rssTicker?.url) {
          // try to fetch rss content again after 1 second
          this.getRssFeed(this.props.rssTicker?.rssTicker?.url, true);
        }
      }, 1000);
      return;
    }
    console.log("Starting RSS ticker");
    const startPosition = this.state.leftPosition;
    let leftPosition = startPosition;
    let lastFrameCalled = performance.now();
    let fps = 0;
    this.animationFrameID = requestAnimationFrame(() => this.animateTicker(lastFrameCalled, fps, startPosition, leftPosition, ticker));
  }

  private animateTicker(lastFrameCalled: number, fps: number, startPosition: number, leftPosition: number, ticker: HTMLElement) {
    // calculate fps
    const timeSinceLastFrame = (performance.now() - lastFrameCalled) / 1000;
    lastFrameCalled = performance.now();
    fps = 1 / timeSinceLastFrame;
    const containerWidth = ticker.getBoundingClientRect().width;
    if (containerWidth <= 0) {
      // no content, component probably has unmounted
      return;
    }
    if ((leftPosition * -1) > containerWidth) {
      // when leftPosition (inversed, since has negative value) is greater than containerWidth,
      // this means that all elements has passed the screen so we restart the ticker
      console.log("Restarting RSS ticker");
      leftPosition = startPosition;
      ticker.style.left = leftPosition + "px";
      this.getRssFeed(this.props.rssTicker?.rssTicker?.url);
    } else {
      const timeToCross = 25;
      // use fps to set the new position to avoid slow animations on weaker devices
      const step = window.innerWidth / timeToCross / fps;
      leftPosition = leftPosition - step;
      ticker.style.left = leftPosition + "px";
    }
    this.animationFrameID = requestAnimationFrame(() => this.animateTicker(lastFrameCalled, fps, startPosition, leftPosition, ticker));
  }
about 4 years ago · Juan Pablo Isaza
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda