What are some strategies for increasing efficiency in my drag and drop process?

Update #2 Wow, transition was stuck at .35s. My CSS just wasn't updating properly :(

UPDATE: Anyone know if requestAnimationFrame could help with this?

I've got a rotating image reel and I want users to be able to swipe left or right to switch to the next or previous image (rotating through all images in the set).

To achieve this, I'm using the touchmove event and the css property transform: translate to move the image, making the swiping action responsive to touch.

Specifically, between the firing of touchstart and touchend, the touchmove event is used to visually move the image so that users can see it responding. However, it's moving pretty slowly. How can I make it more responsive?

Here's my code snippet:

!(function () {
  "use strict"
  window.addEventListener('load', function (event) {

    var modules = document.querySelectorAll('a.module')
    var interval

    // This function rotates the modules every 7500 milliseconds.
    function initiateInterval () {
      interval = setInterval(function () {
        modules.forEach(function (module) {
          rotateToNext(module)
        })
      }, 2500)
    }

    initiateInterval() // Kick things off on page load.

    //Be ready to manually switch things on click.
    modules.forEach(function (module) {
      module.addEventListener('click', (event) => switchToManual(module) )
    })

    // Disable clicking while adjusting manually.
    // Then reinitiate the iterval and enable clicking again.
    function switchToManual (module) {
      disableButtons()
      clearInterval(interval)
      cycleTargetToCenter(module, function () {
        initiateInterval()
        enableButtons()
      })
    }

    // Rotate on swipe left or right.
    modules.forEach(function (module) {
      var startPoint
      var endPoint
      module.addEventListener('touchstart', function (event) {
        disableButtons()
        clearInterval(interval)
        return startPoint = event.changedTouches[0].screenX
      })
      module.addEventListener('touchmove', function (event) {
        module.style.transform = `translate(${(event.changedTouches[0].screenX - startPoint)}px ,0px)`
      })
      module.addEventListener('touchend', function (event) {
        module.style.transform = ''
        endPoint = event.changedTouches[0].screenX
        if (endPoint > startPoint + 70) modules.forEach( (mod) => rotateToNext(mod) )
        if (endPoint < startPoint - 70) modules.forEach( (mod) => rotateToPrevious(mod) )
        initiateInterval()
        enableButtons()
      })

    })

    function disableButtons () {
      modules.forEach(function (module) {
        module.setAttribute('disabled', 'disabled')
      })
    }

    function enableButtons () {
      modules.forEach(function (module) {
        module.removeAttribute('disabled')
      })
    }

    function cycleTargetToCenter (module, func) {
      var currentPosition = decernCurrentPosition(module)
      if (currentPosition === 'position3') {
        return func()
      } else {
        var spins = decernNumberOfNeededRotations(module)
        for (let i = 0; i < spins; i += 1) {
          modules.forEach( (mod) => rotateToNext(mod) )
        }
        return func()
      }
    }

    function rotateToNext (module) {
      var currentPosition = decernCurrentPosition(module)
      var nextPosition = decernNextPosition(module)
      module.classList.remove(currentPosition)
      module.classList.add(nextPosition)
    }

    function rotateToPrevious (module) {
      var currentPosition = decernCurrentPosition(module)
      var previousPosition = decernPreviousPosition(module)
      module.classList.remove(currentPosition)
      module.classList.add(previousPosition)
    }

    function decernCurrentPosition (module) {
      if (module.classList.contains('position1')) return 'position1'
      if (module.classList.contains('position2')) return 'position2'
      if (module.classList.contains('position3')) return 'position3'
      if (module.classList.contains('position4')) return 'position4'
      if (module.classList.contains('position5')) return 'position5'
    }

    function decernNextPosition (module) {
      if (module.classList.contains('position1')) return 'position2'
      if (module.classList.contains('position2')) return 'position3'
      if (module.classList.contains('position3')) return 'position4'
      if (module.classList.contains('position4')) return 'position5'
      if (module.classList.contains('position5')) return 'position1'
    }

    function decernPreviousPosition (module) {
      if (module.classList.contains('position1')) return 'position5'
      if (module.classList.contains('position2')) return 'position1'
      if (module.classList.contains('position3')) return 'position2'
      if (module.classList.contains('position4')) return 'position3'
      if (module.classList.contains('position5')) return 'position4'
    }

    function decernNumberOfNeededRotations (module) {
      if (module.classList.contains('position1')) return 2
      if (module.classList.contains('position2')) return 1
      if (module.classList.contains('position4')) return 4
      if (module.classList.contains('position5')) return 3
    }

  })
}());
.modules {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  overflow-x: hidden;
  height: 500px;
}
.module {
  font-weight: normal;
  position: absolute;
  top: 5em;
  display: flex;
  justify-content: center;
  text-align: center;
  width: 295px;
  height: 295px;
  flex-shrink: 0;
  margin: 1em;
  transition: 1s;
}
.module div.icon {
  position: absolute;
  left: 50%;
  margin-left: -45px;
  top: -45px;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 90px;
  height: 90px;
  flex-shrink: 0;
  background: #fff;
  border-radius: 50%;
}
.module div.copy {
  padding: 42px 2em 2em 2em;
  background: #fff;
  border-radius: 1em;
}
.module div.copy h2 {
  font-size: 2em;
  margin: 0;
}
.module div.copy h2 p.subtitle {
  font-size: 0.65em;
}
.module.position1 {
  z-index: 1;
  transform: scale(0.6) translate(-270px, -90px);
  filter: drop-shadow(0 0 8px #bababa);
}
.module.position2 {
  z-index: 3;
  transform: scale(0.8) translate(-400px, -10px);
  filter: drop-shadow(0 0 12px #bababa);
}
.module.position3 {
  z-index: 3;
  transform: scale(1);
  filter: drop-shadow(0 0 18px #bababa);
}
.module.position4 {
  z-index: 2;
  transform: scale(0.8) translate(400px, -10px);
  filter: drop-shadow(0 0 12px #bababa);
}
.module.position5 {
  z-index: 1;
  transform: scale(0.6) translate(270px, -90px);
  filter: drop-shadow(0 0 8px #bababa);
}
<section class="modules"><a class="module module1 position1">
    <div class="icon">
      <h2>๐Ÿ’ก</h2>
    </div>
    <div class="copy">
      <h2>Bulbs
        <p class="subtitle">How many light bulbs?</p>
      </h2>
      <p>La la la...</p>
    </div></a><a class="module module2 position2">
    <div class="icon">
      <h2>๐Ÿ—จ๏ธ</h2>
    </div>
    <div class="copy">
      <h2>Words
        <p class="subtitle">How many words?</p>
      </h2>
      <p>La la la</p>
    </div></a><a class="module module3 position3">
    <div class="icon">
      <h2>๐Ÿค”</h2>
    </div>
    <div class="copy">
      <h2>Queries
        <p class="subtitle">How many queries?</p>
      </h2>
      <p>La la la...</p>
    </div></a><a class="module module4 position4">
    <div class="icon">
      <h2>๐Ÿงช</h2>
    </div>
    <div class="copy">
      <h2>Tubes
        <p class="subtitle">Quantas Tubes?</p>
      </h2>
      <p>La la la...</p>
    </div></a><a class="module module5 position5">
    <div class="icon">
      <h2>๐Ÿคธ</h2>
    </div>
    <div class="copy">
      <h2>Actions
        <p class="subtitle">And this too...?</p>
      </h2>
      <p>La la la...</p>
    </div></a></section>

The touch events are really sluggish โ€“ you slide your finger and the object seems to lag behind rather than follow smoothly. What could be causing this delay?

Answer โ„–1

First Step: Remove the touchmove event
Second Step: Adjust transition timing to something like .5s

!(function() {
  "use strict"
  window.addEventListener('load', function(event) {

    var modules = document.querySelectorAll('a.module')
    var interval

    // This function rotates the modules every 7500 milliseconds.
    function initiateInterval() {
      interval = setInterval(function() {
        modules.forEach(function(module) {
          rotateToNext(module)
        })
      }, 2500)
    }

    initiateInterval() // Set things in motion on page load.

    //Ready for manual switching on click.
    modules.forEach(function(module) {
      module.addEventListener('click', (event) => switchToManual(module))
    })

    // Temporarily disable clicking while making manual adjustments.
    // Then restart the interval and allow clicking again.
    function switchToManual(module) {
      disableButtons()
      clearInterval(interval)
      cycleTargetToCenter(module, function() {
        initiateInterval()
        enableButtons()
      })
    }

    // Rotate when swiping left or right.
    modules.forEach(function(module) {
      var startPoint
      var endPoint
      module.addEventListener('touchstart', function(event) {
        disableButtons()
        clearInterval(interval)
        return startPoint = event.changedTouches[0].screenX
      })

      module.addEventListener('touchend', function(event) {
        module.style.transform = ''
        endPoint = event.changedTouches[0].screenX
        if (endPoint > startPoint + 70) modules.forEach((mod) => rotateToNext(mod))
        if (endPoint < startPoint - 70) modules.forEach((mod) => rotateToPrevious(mod))
        initiateInterval()
        enableButtons()
      })

    })

    function disableButtons() {
      modules.forEach(function(module) {
        module.setAttribute('disabled', 'disabled')
      })
    }

    function enableButtons() {
      modules.forEach(function(module) {
        module.removeAttribute('disabled')
      })
    }

    function cycleTargetToCenter(module, func) {
      var currentPosition = decernCurrentPosition(module)
      if (currentPosition === 'position3') {
        return func()
      } else {
        var spins = decernNumberOfNeededRotations(module)
        for (let i = 0; i < spins; i += 1) {
          modules.forEach((mod) => rotateToNext(mod))
        }
        return func()
      }
    }

    function rotateToNext(module) {
      var currentPosition = decernCurrentPosition(module)
      var nextPosition = decernNextPosition(module)
      module.classList.remove(currentPosition)
      module.classList.add(nextPosition)
    }

    function rotateToPrevious(module) {
      var currentPosition = decernCurrentPosition(module)
      var previousPosition = decernPreviousPosition(module)
      module.classList.remove(currentPosition)
      module.classList.add(previousPosition)
    }

    function decernCurrentPosition(module) {
      if (module.classList.contains('position1')) return 'position1'
      if (module.classList.contains('position2')) return 'position2'
      if (module.classList.contains('position3')) return 'position3'
      if (module.classList.contains('position4')) return 'position4'
      if (module.classList.contains('position5')) return 'position5'
    }

    function decernNextPosition(module) {
      if (module.classList.contains('position1')) return 'position2'
      if (module.classList.contains('position2')) return 'position3'
      if (module.classList.contains('position3')) return 'position4'
      if (module.classList.contains('position4')) return 'position5'
      if (module.classList.contains('position5')) return 'position1'
    }

    function decernPreviousPosition(module) {
      if (module.classList.contains('position1')) return 'position5'
      if (module.classList.contains('position2')) return 'position1'
      if (module.classList.contains('position3')) return 'position2'
      if (module.classList.contains('position4')) return 'position3'
      if (module.classList.contains('position5')) return 'position4'
    }

    function decernNumberOfNeededRotations(module) {
      if (module.classList.contains('position1')) return 2
      if (module.classList.contains('position2')) return 1
      if (module.classList.contains('position4')) return 4
      if (module.classList.contains('position5')) return 3
    }

  })
}());
section.modules {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  overflow-x: hidden;
  height: 500px;
}

a.module {
  font-weight: normal;
  position: absolute;
  top: 5em;
  display: flex;
  justify-content: center;
  text-align: center;
  width: 295px;
  height: 295px;
  flex-shrink: 0;
  margin: 1em;
  transition: .5s; // <-- adjust this as needed
}

a.module div.icon {
  position: absolute;
  left: 50%;
  margin-left: -45px;
  top: -45px;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 90px;
  height: 90px;
  flex-shrink: 0;
  background: #fff;
  border-radius: 50%;
}

a.module div.copy {
  padding: 42px 2em 2em 2em;
  background: #fff;
  border-radius: 1em;
}

a.module div.copy h2 {
  font-size: 2em;
  margin: 0;
}

a.module div.copy h2 p.subtitle {
  font-size: 0.65em;
}

a.module.position1 {
  z-index: 1;
  transform: scale(0.6) translate(-270px, -90px);
  filter: drop-shadow(0 0 8px #bababa);
}

a.module.position2 {
  z-index: 3;
  transform: scale(0.8) translate(-400px, -10px);
  filter: drop-shadow(0 0 12px #bababa);
}

a.module.position3 {
  z-index: 3;
  transform: scale(1);
  filter: drop-shadow(0 0 18px #bababa);
}

a.module.position4 {
  z-index: 2;
  transform: scale(0.8) translate(400px, -10px);
  filter: drop-shadow(0 0 12px #bababa);
}

a.module.position5 {
  z-index: 1;
  transform: scale(0.6) translate(270px, -90px);
  filter: drop-shadow(0 0 8px #bababa);
}
<section class="modules">
  <a class="module module1 position1">
    <div class="icon">
      <h2>๐Ÿ’ก</h2>
    </div>
    <div class="copy">
      <h2>Bulbs
        <p class="subtitle">How many light bulbs?</p>
      </h2>
      <p>La la la...</p>
    </div>
  </a>
  <a class="module module2 position2">
    <div class="icon">
      <h2>๐Ÿ—จ๏ธ</h2>
    </div>
    <div class="copy">
      <h2>Words
        <p class="subtitle">How many words?</p>
      </h2>
      <p>La la la</p>
    </div>
  </a>
  <a class="module module3 position3">
    <div class="icon">
      <h2>๐Ÿค”</h2>
    </div>
    <div class="copy">
      <h2>Queries
        <p class="subtitle">How many queries?</p>
      </h2>
      <p>La la la...</p>
    </div>
  </a>
  <a class="module module4 position4">
    <div class="icon">
      <h2>๐Ÿงช</h2>
    </div>
    <div class="copy">
      <h2>Tubes
        <p class="subtitle">Quantas Tubes?</p>
      </h2>
      <p>La la la...</p>
    </div>
  </a>
  <a class="module module5 position5">
    <div class="icon">
      <h2>๐Ÿคธ</h2>
    </div>
    <div class="copy">
      <h2>Actions
        <p class="subtitle">And this too...?</p>
      </h2>
      <p>La la la...</p>
    </div>
  </a>
</section>

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

Error: Jest encounters an unexpected token 'export' when using Material UI

While working on my React project and trying to import { Button } from @material-ui/core using Jest, I encountered a strange issue. The error message suggested adding @material-ui to the transformIgnorePatterns, but that didn't resolve the problem. T ...

Is there a method in CSS animations that allows for endlessly repeating successive animations in a specified sequence?

While working with CSS animations, I encountered a challenge of making two animations occur successively and repeat infinitely without merging keyframes. Is there a way to achieve this using only CSS? If not, how can I accomplish it using JavaScript? I a ...

A guide on how to retrieve POST form fields in Express

My form design is quite simple: <form id="loginformA" action="userlogin" method="post"> <div> <label for="email">Email: </label> <input type="text" id="email" name="email"></input> </div> & ...

Creating trails by following the cursor's movement in KineticJS

Currently, I am working on a drawing application using KineticJS. While I have successfully used it to draw shapes and straight lines by following the method outlined in KineticJS - Drawing Lines with Mouse, I now need to draw a line along the mouse's ...

Adjust the size of the font based on the screen resolution

What is the best way to adjust font size based on screen resolution so that text remains as a single line when the screen is small? For example: http://prntscr.com/2qa9ze <div class="centerbreaking"> <section id="breaking-news"> <div id ...

Using jQuery and HTML to create numerous links that direct to a solitary iframe

I created a basic overlay setup using css, html, and jQuery. Here's how it looks: <a class="activator" id="activator" style="" href="#">hello</a> <div class="overlay" id="overlay" style="display:none;"></div> <div style="d ...

Using Angular to bind the ngModel to a variable's object property

In my application, I am working with a user object that looks like this: let user = {name: "John", dob:"1995-10-15", metadata: {}} The metadata property of the user object is initially empty. I want to add a new property to the metadata object based on u ...

I am experiencing an issue with environment variables not appearing in my Context component on Next.js. Should I adjust the Next.js configuration or set up the Context to properly utilize the variables?

Why are Environment Variables working on every component inside /pages but not in my Context component in Next.js? Do I need to do some configuration in Next.js for this? (Note: The Shopcontext.tsx file is using a class component that I obtained from a tu ...

Using websockets in a React client application

Attempting to establish a connection with a backend layer running on localhost, here is the provided source code: const { createServer } = require("http"); const cors = require("cors"); const photos = require("./photos"); const app = require("express")( ...

Using Selenium with C# to find elements within a chart

I am trying to locate and interact with the stimulusFrequency circles on this chart so that I can click and drag them. <svg class="svg-graph-content graphEventHandler ng-valid" ng-model="hearingGraph" viewBox="0 0 470 355" preserveAspectRatio="none"> ...

SharePoint 2013 only allows the first AJAX request to work successfully, except when in Edit Mode

I am facing a challenge of making two AJAX requests simultaneously on a SharePoint page. One request originates from the current site, while the other comes from a team site. When I use different URLs (/events) and (/travel), each one works fine when use ...

Tips for managing onClick code when a user selects "open link in new tab" within a React js environment

How can I ensure that my tracking code runs when a user clicks a button in my React project, even if they open it in a new tab? Is there a solution for this in React JS? Here's a simple example: var Hello = React.createClass({ render: function( ...

Is there a period, question mark, apostrophe, or space in the input string?

Currently, I am in the process of developing a program that can determine if an input string includes a period, question mark, colon, or space. If these punctuation marks are not present, the program will return "false". However, if any of them are found, ...

Node.js server encountering a cross-domain error

As a beginner exploring node.js, I am embarking on setting up my very first installation. In my server.js file, I am defining a new server with the following code: var app = require('http').createServer(handler), io = require('socket.io&a ...

Dynamic scrolling text for overflowing text display

Here's a scenario I'm facing: Let's say I have three div tags, each 100 pixels wide: <--- DIV WIDTH ---> Text in div 1 Text in div two, it overflows Text in div three <--- DIV WIDTH ---> Currently, I've set the following C ...

Sharing data across multiple paths

route.post('/register',function(req,res){ //completed registration process // token value assigned as 'abc' }) route.post('/verify',function(req,res){ // How can I retrieve the token ('abc') here? }) I' ...

Looking to retrieve the key value or iteration of a specific item within an Angular UI tree?

Here is a snippet of code showcasing how to use angular-ui-tree: <div ui-tree> <ol ui-tree-nodes="" ng-model="list"> <li ng-repeat="item in list" ui-tree-node> <div ui-tree-handle> {{item.title}} </div& ...

Having trouble with Autocomplete not entering cities into the form?

While experimenting with Google's API, I have encountered confusion regarding why cities like Staten Island, Brooklyn, Queens, and various others are not being placed into the form like other cities. According to Google's API, "locality" is suppo ...

Is there a way to run both PHP and HTML code using the eval function?

Is it possible to execute HTML and PHP simultaneously using the eval function? eval ("<center> this is some html </center>"); The above code does not yield the desired output, so I am considering changing it to: echo ("<center> this is ...

Animation of two divs stacked on top of each other

I am trying to replicate the animation seen on this website . I have two divs stacked on top of each other and I've written the following jQuery code: $('div.unternehmen-ahover').hover( function () { $('div.unternehmen-ahover' ...