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

Identifying a particular pattern in a JavaScript string

What is the best way to check if a JavaScript String includes the pattern: "@aRandomString.temp" I need to verify if the String includes an @ character followed by any string and finally ".temp". Thank you ...

Learn how to incorporate the prettier command into your coding workflow by adding it as a devDependency before committing code or

I am currently engaged in a React project. I am looking to set up autoformatting on save in my Visual Studio Code. However, I prefer not to adjust the settings within VSCode itself due to the variation in configurations among users. Instead, I want to ach ...

Parsing XML to JSON using JavaScript

I came across this JavaScript function on Stack Overflow that I've been using to convert XML to JSON: function xmlToJson(xml) { try { var obj = {}; if (xml.nodeType == 1) { if (xml.attributes.length > 0) { ...

There seems to be a problem with the JavaScript function as the indexOf property is undefined

function filteredArray(arr, elem) { let newArr = []; Iterating through each element of the multidimensional array. for (let i=0;i<arr.length;i++){ for (let j=0;j<arr[i].length;j++){ If the value matches the argument passed, assi ...

The server node proxy is failing to trigger the API call

update 1: After modifying the api path, I am now able to initiate the api call. However, I encountered the following error: (node:13480) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 4): RangeError: Invalid status code: res ...

Intellij IDEA does not offer auto-completion for TypeScript .d.ts definitions when a function with a callback parameter is used

I've been working on setting up .d.ts definitions for a JavaScript project in order to enable auto-completion in Intellij IDEA. Here is an example of the JavaScript code I'm currently defining: var testObj = { tests: function (it) { ...

Encountered an error while attempting a GET request to 'http://localhost:3000/': The resource failed to load, resulting in a net::ERR_CONNECTION_REFUSED error in delete.js

Every time I attempt to GET '/' through my express server, I encounter an error message indicating "Failed to load resource: net::ERR_CONNECTION_REFUSED ... delete.js". This issue typically arises when I try to submit a form from http://localhost ...

AngularJS: Handling multiple asynchronous calls simultaneously in a function

In my AngularJS function, I need to make two asynchronous calls that are independent of each other. However, the function should only return when both calls have completed and the results are stored in the return variable. I have tried various solutions a ...

Convert a fresh Date() to the format: E MMM dd yyyy HH:mm:ss 'GMT'z

The date and time on my website is currently being shown using "new date()". Currently, it appears as: Thu May 17 2018 18:52:26 GMT+0530 (India Standard Time) I would like it to be displayed as: Thu May 17 2018 18:43:42 GMTIST ...

Unable to retrieve private field using a public getter method through a proxy

When retrieving data from a VueX Module using a Getter, the Object is enclosed within a Proxy that triggers the following error: TypeError: attempted to get private field on non-instance when attempting to access a private property with a public getter. ...

Using a self-invoking function in JavaScript with addEventListener

I'm struggling to get an Event Listener to self invoke a function and work correctly. Although the following code runs the function, the Event Listener is not functioning as expected: window.addEventListener("resize", (function () { document.getElem ...

decide whether to use webpack bundling during development or not

Whenever I save a file, it takes around 30 seconds for the changes to reflect. I am currently using gulp watch and webpack for bundling around a hundred files. Is there any way to speed up the build process? ...

What is the process for converting an Angular UTC timestamp to a local timestamp?

Is it possible to convert a UTC timestamp to a local time timestamp using any function or method? I am sending the timestamp to angular moments, but the server's timestamp is in UTC. ...

The function that can be used in Ajax for setting

I'm currently utilizing Ajax to automatically submit a form when a key is pressed. After the form is submitted, the page displays the resulting information success: function (response){ $("#search_results<?php echo $HoursID ?>").html(response) ...

Delete all offspring nodes from the Google organization chart

I am currently utilizing the Google Organization Chart to create a chart that resembles the attached screenshot. There is a specific method called removeRow(nodeIndex) that I am using to eliminate a node from the chart. However, one issue I faced is that ...

Why does the address bar show value changes in IE when using window.location.hash, but the value doesn't change in the DOM when going

Here is a sample JavaScript code that attempts to detect the back button event: document.location.hash="#1"; document.location.hash="#2"; document.location.hash="#3"; function check() { if("#3"!=window.location.hash) { alert("Back button clic ...

Exclude basic authentication for a specific route

Using node, express and connect for a simple app with basic HTTP auth implemented. The code snippet below shows part of the implementation: var express = require('express'), connect = require('connect'); app.configure = function(){ ...

Using Vuex: Bypassing Action and triggering Mutation directly within Component

When working with a vue.js app and utilizing vuex as the state management store, one may need to update a property's value in vuex. This can be achieved through two methods: One can dispatch an action method, which will then commit a mutation to a ...

Can you clarify the dissimilarity between `knex().select("id").from("users")` and `knex("users").select("id")` in Knex?

I have successfully connected knex with mysql and am working on a login form linked to a mysql database. Currently, I am performing a login check and I'm curious if there is any distinction between the following two queries: knex().select("id").from( ...

A script page in Wordpress generates a numerical value in the URL

I created a script named search.php which utilizes various search engines APIs to display search results. From this file, I have developed a Page template and incorporated the simplePagination plugin The issue arises when I click on a page within the pag ...