javascript The final position achieved through requestAnimationFrame is never precise

let pf = document.querySelectorAll('.pf');

for (let i of pf) {
  Object.assign(i.style, {
    left: '400px'
  })
}

function shiftLetters() {
  let start = performance.now();
  let dist = -400;
  let dur = 500;

  const logoAnimate = (timestamp) => {

    var runtime = timestamp - start
    var progress = Math.min(runtime / dur, 1)
    const position = progress * dist;

    if (runtime < dur) {
      for (let i = 0; i < pf.length; i++) {
        (function(i) {
          setTimeout(function() {
            pf[i].style.transform = `translate3d(${position}px,0,0)`
          }, 100 * i)
        })(i);
      }
      requestAnimationFrame(logoAnimate)
    }
  }
  requestAnimationFrame(logoAnimate)
}

document.getElementsByTagName('button')[0].addEventListener('click', shiftLetters);
#wrapper {
  display: flex;
  position: absolute;
  -webkit-transform: translate(-50%, 10%);
  transform: translate(-50%, 10%);
  top: 50%;
  left: 50%;
}

.pf {
  display: inline-block;
  position: relative;
  width: 100px;
  height: 100px;
  margin: 2px;
  background-color: red;
}

button {
  display: block;
  margin-top: 50px;
}
<div id="wrapper">
  <div class="pf"></div>
  <div class="pf"></div>
  <div class="pf"></div>
  <div class="pf"></div>
</div>
<button>animate</button>

Upon clicking the button, I have a set of 4 elements that are supposed to move exactly to the distance specified by the variable "dist" (-400px). However, they end up at random integer positions instead of the intended -400px. I suspect it may be a simple fix related to scope or variable declaration.

Answer №1

The main issue stems from not applying the final transform. In the last loop of shiftLetters, when position reaches -400 and runtime exceeds dur, the if statement is never triggered, preventing the transform from being applied. Below is a slightly modified version of the code for better functionality.

let pf = document.querySelectorAll('.pf');

for (let i of pf) {
  Object.assign(i.style, {
    left: '400px'
  })
}

function shiftLetters() {
  let start = performance.now();
  let dist = -400;
  let dur = 500;

  const logoAnimate = (timestamp) => {

    var runtime = timestamp - start
    var progress = Math.min(runtime / dur, 1)
    const position = progress * dist;

    applyTransform(position);

    if (runtime < dur) {
      requestAnimationFrame(logoAnimate)
    }
  }
  requestAnimationFrame(logoAnimate)
}

function applyTransform(position) {
  for (let i = 0; i < pf.length; i++) {
    setTimeout(function() {
      pf[i].style.transform = `translate3d(${position}px,0,0)`
    }, 100 * i)
  }
}

document.getElementsByTagName('button')[0].addEventListener('click', shiftLetters);
#wrapper {
  display: flex;
  position: absolute;
  -webkit-transform: translate(-50%, 10%);
  transform: translate(-50%, 10%);
  top: 50%;
  left: 50%;
}

.pf {
  display: inline-block;
  position: relative;
  width: 100px;
  height: 100px;
  margin: 2px;
  background-color: red;
}

button {
  display: block;
  margin-top: 50px;
}
<div id="wrapper">
  <div class="pf"></div>
  <div class="pf"></div>
  <div class="pf"></div>
  <div class="pf"></div>
</div>
<button>animate</button>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Real-time chart updates through REST API integration with JavaScript

I am searching for a JavaScript library that is capable of creating line charts and making calls to a REST API every few seconds (such as 5s or 3s) in order to update the line chart dynamically. I have found some libraries that support live chart updatin ...

Struggling to get getInitialProps working in dynamic routes with Next.js?

I am encountering an issue. The return value from the getInitialProps function is not being passed to the parent component. However, when I console.log the values inside the getInitialProps function, they appear to be correct. Here is the code snippet: i ...

Collections of both letters and non-letter characters that are aligned

I am attempting to identify sets of characters that contain a mix of letters and non-letter characters, with many of them being just one or two letters. const match = 'tɕ\'i mɑ mɑ ku ʂ ɪɛ'.match(/\b(p|p\'|m|f|t|t ...

React does not allow objects as children, but what if it's actually an array?

My function is encountering an error message that reads: "Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead." I am struggling to understand why this error is occurring. ...

"Enhance Your Communication: Utilize setTimeout in Ajax

Hey there, I could really use some help with the setTimeout function in my code. No matter what I try, it just doesn't seem to work. I'm currently working on a chat system where I need to send and receive messages (testing by opening 2 browser ...

Attempting to load using ajax, Chrome and jquery-mobile will modify the location of the window through setting window.location.href

I'm encountering a challenge with my mobile application where I need to redirect users to the login page on a 401 ajax call. However, it seems that jQM is attempting to load this via AJAX when the request is sent. This solution works flawlessly for s ...

The jsPDF tool captures only the visible frame in a screenshot instead of printing the entire content on the screen

Recently, I integrated the jsPDF npm module into my Angular application to convert HTML to PDF. However, I encountered an issue where printing a website page to PDF only captures a screenshot of the visible area in Firefox and Chrome, as well as in Interne ...

What is the most efficient method for managing components with dynamic templates and their corresponding data in Vue.js?

I have a question and requirement that I would like to discuss. It involves dynamically rendering templates and data using components. The scenario is as follows: The root Vue instance fetches data from the backend, and let's say the following data i ...

"Enhance Your Website with Javascript: Combining and Incorpor

I'm struggling to assign the selected attribute to the option value that is already rendered within the object. However, despite the values being equal, the selected attribute is not being added. Could this issue be related to the appending process? ...

What is the best way to halt execution in Express.js following an error caught from an Await request?

While searching for a solution, I come across many posts that almost provide the answer I need, but nothing seems to quite work in my case. I have a function that uses asynchronous operations: const doStuff = async (data)=>{ if(data == "a bug& ...

The code encountered an error because it was unable to access the property 'style' of an undefined element on line 13 of the script

Why is it not recognizing styles and showing an error? All paths seem correct, styles and scripts are connected, but it's either not reading them at all (styles) or displaying an error. Here is the html, javascript, css code. How can this error be fix ...

Not quite sure about the best way to showcase the results // using JavaScript

My code is posted below. I am trying to achieve a functionality where, upon clicking the 'Calculate Price' button, the results showing the number of cars, type of cars, and their respective prices are displayed beneath the button. Despite this be ...

Utilizing a created variable within the alert function: A guide

In order to display error messages in my app, I have created the following code: function createTimer(): void { if (!timer.start) { Alert.alert(strings.reminders['date-required']) return; } else if (!timer.end) { Alert.alert(strin ...

What's better in React: using pure components or non-pure components? Is it okay to fetch data in componentDidMount or

Exploring React in Meteor has led me to observe two distinct approaches... Take the meteor leaderboard example, where a list of players displays their names and scores. The pure approach involves fetching all players and passing them into the playersList ...

Puppeteer exhibiting unexpected behavior compared to the Developer Console

My goal is to extract the title of the page using Puppeteer from the following URL: Here's the code snippet I am working with: (async () => { const browser = await puppet.launch({ headless: true }); const page = a ...

Position a component in relation to another component using AngularJS

Utilizing ng-show and ng-hide, I created a descriptive box that appears below text when clicked. However, there is an issue as the description box does not align directly under the text, similar to what is shown in this image https://i.stack.imgur.com/phBh ...

When attempting to declare a functional component in React utilizing styled-components in TypeScript, an error is encountered stating "No overload matches this call."

Playground https://codesandbox.io/s/typescript-type-checking-question-0b42t Sample Code type BadgeTypes = { success: string; secondary: string; alert: string; text: string; }; type Theme = { fonts?: object; borderRadius: string; primary?: o ...

The JSON parsing functionality is not working as expected in my app.js file

app.js: const express = require("express"); const https = require("https"); const app = express(); const port = 3000; app.get("/",function(req,res){ const url ="https://maps.googleapis.com/maps/api/geocode/jsonaddress=1600+Amphitheatre+Parkway,+Mounta ...

How to retrieve values from dynamically generated text boxes using ng-repeat in AngularJS

When using ng-repeat, I am able to display textboxes related to each item. Upon clicking the SaveAll button, I intend to retrieve all textbox values based on ITEM ID and save them to the database. <tr> <td> <table ng-repeat="item in ...

Arrange the object's key-value pairs in ng-repeat by their values

I'm completely new to AngularJS and I am working with an API that returns key-value pairs related to different sports. $scope.sports = { 1: "Soccer", 2: "Tennis", 3: "Basketball" ... }; My challenge is sorting these items by sport name: <ul> ...