Timing issue with the animation callback

I have been experimenting with creating a bounce effect on my custom scroller by utilizing the translate3d method for scrolling. I managed to successfully implement it, but now I am facing an issue where if you continuously scroll out of bounds (try double scrolling and keep going until it gets stuck), the content remains out of bounds until you scroll back in the opposite direction.

Here is an example: . You can also find the code on this JSFiddle link: JSFiddle.

My Question Is:

How can I create a scrolling bounce effect using JavaScript and CSS?

The following sections are optional to read.

Possible Reason It's Not Working Properly:

I suspect that one reason for this behavior could be related to an animation callback event. If the animation does not occur, meaning the transform value does not change, then the animation callback will not be triggered.

When the content has scrolled all the way to the extreme top or bottom, and you attempt to scroll again before the animation completes (thus the transform value remaining unchanged), the animation callback will not execute and as a result, the content won't bounce back within bounds.

Methods I Have Tried So Far:

One approach I experimented with involved checking if the scroll position changed, and only calling the animation callback function if there was a change detected. However, this method did not yield the desired outcome. Scrolling rapidly out of bounds resulted in a stuttering effect, preventing the content from fully reaching the outer limits before bouncing back. Here is a visual representation: . Link to the corresponding JSFiddle: JSFiddle.

Another strategy I attempted was adjusting the transform value by 0.1 whenever no change in scroll position was detected, thereby ensuring the animation callback would still be invoked. However, this caused a delay in bouncing back when scrolling out of bounds. To address this delay, I reduced the animation duration for cases where scrolling remained consistent, but encountered another issue - a delayed bounce back after excessive consecutive scrolling out of bounds. You can view this scenario in action on this JSFiddle link: JSFiddle.

console.clear();
// More JavaScript code snippets available here...
#outerWrapper {
  height: 400px;
  overflow: hidden;
  display: flex;
  background-color: black;
}
/* More CSS styles here... */
<div id="outerWrapper">
  <div id="innerWrapper">
    <div id="content">
      // Content goes here
    </div>
  </div>
  <div id="scrollbar">
    <div id="scrollbar_thumb"></div>
  </div>
</div>

Answer №1

For a slight variation between each wheel event to trigger transition, the z component can be utilized effectively. Check out this example

var i = 0;
// onmousewheel
.. el.style.transform = `translate3d(0, 40px, ${i^=1}px)` 

// ontransitionend
.. el.style.transform = `translate3d(0, 0, -1px)`

If the previous method seems too complex, an alternative is to perform a costly query to determine the current translation y value and compare it with the bounceAmount (e.g. 40 in this case). If they are nearly identical (difference smaller than Number.EPSILON), then directly call bounceBack().

var m = getComputedStyle(el).transform.match(/,\s*([^,]*?)\s*\)/)
m ? m[1] : 0 // current translation y

Update:

To instantly bounce back content when required, simply disable the onwheel function during motion initiation and re-enable it after the entire motion has finished. This eliminates the need for the z component trick. View the revised implementation in this demo

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

Monitor the number of ng-repeat items altering within a directive

I am using the angular-sly-carousel directive to display some data. The data is dynamically added as the user scrolls down, so I need to reload the sly carousel options after scrolling. Is there a way to detect when the length of ng-repeat elements change ...

uniformly distribute the list items on the horizontal navigation bar

Does anyone know how to properly space out a ul in a navigation bar, with 5px padding on the right and left and the text evenly spaced in between? body { background: #ffffff; text-align: center; font-family: helvetica, arial, san ...

The jQuery UI accordion fails to function properly after refreshing the data

I am facing an issue with my HTML page where data is loaded dynamically into accordions. The accordion functionality is implemented inside a function, which is called at regular intervals to refresh the data. Initially, the accordion displays correctly, bu ...

Tips for generating a document and adding information from an HTML webpage?

My desktop has an html file which requires input. How can I save this input to a file on my computer? Do I need to use a different language like python or javascript, and if so, how do I do it? Additionally, is there a way for javascript to launch an app ...

Trigger the function upon successful completion of Stripe Checkout

I have a requirement in my Nodejs/Express API to execute a series of confirmation code once the checkout process is successfully completed in Stripe by the client. Below is the checkout function responsible for handling the checkout phase: // Checkout con ...

Issue with form action redirection on Node JS Express server not functioning correctly

My EJS application involves using jQuery in the JavaScript code to fetch JSON data from the Google Custom Search API. The app then uses the GET method to navigate to /search, passing the query as the attribute for q. Here's an example of the form&apos ...

Is there a sweet syntax for CSS variables available?

What about using this instead: :root { --primary-color: gray; --secondary-color: lightgray; } var(--pc) Is there a more concise syntax available, perhaps shorter than var(--pc)? ...

What's causing the show/hide feature to malfunction within the for loop in Vue.js?

I've encountered an issue with my for loop where the show/hide functionality doesn't seem to work despite everything else functioning properly. I've been trying to troubleshoot this problem without success. <div id="app"> <ul> ...

Issues with Ajax response being added to the table

I am encountering a technical problem with my university project. The task assigned by the professor is as follows: We need to create a static table that lists 3 domain names in order to enhance the performance of the domain availability API. <table&g ...

Strategies for capturing a 404 error in an Express router

Trying to capture the 404 page not found error in an express router. Using a simple example : const express = require('express'); const app = express(); const router = express.Router(); // ROUTER MID BEFORE router.use((req, res, next) => { ...

Incorporating a feature that displays one show at a time and includes a sliding animation into an

Hey there! I have this show/hide script on my website that's been working well. However, there are a couple of things I need help with. I want to modify the script so that only one div can be shown at a time. When a div appears, I'd love for it ...

Choose the text that appears in the input or textbox field when tapping or clicking on it

Desperately Seeking a Clickable Textbox The Quest: In search of a cross-browser textbox/input field that can select its content on click or tap. An elusive challenge haunting developers for years. The Dilemma: Using a touch device triggers the tap e ...

What is the best way to split up the information and place it into separate text boxes?

I am currently working on a page that allows users to create and edit email structures. To facilitate editing, I added two columns to the page. One of the columns displays information from all the email structures along with two buttons - one for editing ...

Creating a list of identical elements with shared attribute values using nightwatch.js or JavaScript - a step-by-step guide

I have been using nightwatch.js for automating tests on a web application, and I am facing difficulties in creating a list of elements that share common values in their attributes. Below is an example: The first three spans with a common value for the att ...

Tips for looping through each cell in a column of a DataTable to verify its content

I have a table generated using the jquery DataTables API. One of the columns displays word frequencies for each word in the table. If a frequency is less than 40, I want to change that cell to display "unranked" instead of the actual number. How can I ite ...

`Is it possible to remove an empty frame using javascript?`

I have this script that generates a "layer" resembling a frame and I need to remove it. Here is the code for creating the layer: function disableLayer() { var layer = document.getElementsByTagName('div')[0]; d = document.createElement(& ...

Creating a stylish Go URL bar using HTML and CSS

Looking for some guidance in JavaScript as I am new to it. I want to create a go bar similar to the ones found at the top of browsers using HTML and JS. When the button is clicked, it should navigate to the URL entered in the box. Here's an example of ...

Unable to trigger AJAX Complete Handler

Upon completing extensive backend work on my web application, I discovered that the GetMeasure Request was taking up to 10 seconds to finalize. To prevent confusion for potential users, I decided to implement an overlay so that they would not be left stari ...

Confirming an authorization?

I have been working on this code and it is almost perfect, but I am struggling to understand why it needs to validate the 0 or 10 in order to work correctly. The issue I am facing is with a validation where the button should be deactivated when the counte ...

Comparing AngularJS and Node JS in serving web pages, which is better?

Currently, I'm in the process of learning how to develop a web using angular and node JS. One aspect that I am struggling with is determining where to acquire the URLs for links. After doing some research on stack overflow and various tutorials relate ...