Seamless side-to-side navigation

Currently, I am working on a website that has horizontal overflow instead of the common vertical scroll. While everything seems to be functioning properly, I need to enhance the user experience by adjusting the amount scrolled to move larger sections of the screen at a time. However, the issue I am facing is that the code I am using does not provide a smooth transition; the movement appears quite clumsy.

The following is the code snippet I am utilizing, which runs during the mousewheel event:

function scrollHorizontally(e) {
    e = window.event || e;
    var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
    document.documentElement.scrollLeft -= (delta*60); // Multiplied by 60
    document.body.scrollLeft -= (delta*60); // Multiplied by 60
    e.preventDefault();
}

As you can observe, I must adjust the delta * 60 to scroll an adequate amount.

I am interested in finding out if it is feasible to create a seamless transition rather than abruptly moving the user across a fixed pixel amount each time.

I have attempted using

scrollBy({ left: <amount>, behavior: 'smooth' });
, but it does not seem to offer a satisfactory user experience as it slightly eases the movement and feels laggy and inconsistent.

My goal is for the user to smoothly animate to the desired amount. Does anyone know if this is achievable?

This feature is implemented within a Vue 3 application, so I would appreciate any insights on how Vue handles this. Nonetheless, I am open to using vanilla JavaScript as well.

Thank you

Answer №1

In this unique approach, we are experimenting with canceling the scroll event and creating our own physics simulation using animations. By removing the scrollbars, we can avoid any unexpected behavior that may occur when scrolling with the scrollbar in this particular scenario.

let offsetX = 0
let speedX = 0
const deltaMultiplier = 10
const maxSpeed = 160
const friction = 0.85

function scrollHorizontally(ev) {
  ev.preventDefault()
  const delta = -1 * Math.sign(ev.wheelDelta)
  speedX += delta * deltaMultiplier
  speedX = speedX > 0 ? Math.min(speedX, maxSpeed) : Math.max(speedX, -maxSpeed)
  return false;
}

function draw() {
  offsetX += speedX

  const element = document.documentElement
  const maxScrollLeft = element.scrollWidth - element.clientWidth
  offsetX = Math.min(offsetX, maxScrollLeft)
  offsetX = Math.max(offsetX, 0)

  element.scrollLeft = offsetX
  speedX *= friction

  // approximately 60 times per second
  requestAnimationFrame(draw)
}

// must be passive so it can be canceled
addEventListener('mousewheel', scrollHorizontally, {
  passive: false
})


draw()
.div {
  width: 2500px;
  height: 100px;
  background: linear-gradient(0.25turn, green, blue);
  white-space: nobreak;
}

body {
  overflow: hidden;
}
<div class="div">
  <h1>mouse wheel me</h1>
  function scrollHorizontally(e) { e = window.event || e; var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail))); console.log(delta) document.documentElement.scrollLeft -= (delta * 60); // Multiplied by 60 document.body.scrollLeft -= (delta
  * 60); // Multiplied by 60 e.preventDefault(); } addEventListener('mousewheel', scrollHorizontally)
</div>

Answer №2

Here's a method you can try:

<template>
 <div v-scrollHorizontally="scrollHorizontally"></div>
</template>
<script>
export default {
 method: {
  scrollHorizontally(e) {
   e = window.event || e;
   var delta = Math.max(-1, Math.min(1, (e.wheelDelta || - e.detail)));
   var scrollAmount = delta * 60;
   window.scrollBy({ left: scrollAmount, behavior: 'smooth'});
   e.preventDefault();
  }
 }
}
</script>

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

Is there a way to update my profile picture without having to constantly refresh the page after uploading it?

Here is the code for my profile page. I am considering using a callback along with another useEffect function, but I'm unsure. Please help me in finding a solution. For now, let's ignore all the code related to deleting, saving, and handling ingr ...

Having trouble uploading several files with Multer functionality?

I've encountered an issue with Multer in Node.js where I can't seem to select and upload multiple files. In a previous exercise, I had no trouble uploading a single file, but now I'm struggling with enabling multiple uploads. What am I mis ...

Get your hands on large files with ease by utilizing jQuery or exploring alternative methods

Within my User Interface, there exists an Advanced Search section where the user can select from 7 different options as depicted in the diagram. Based on these selections, a web service is triggered. This web service returns search results in JSON format, ...

The appearance of the webkit-scrollbar is not reflecting the intended style

I have successfully created a wrapper for a styled scrollbar in React JS - import styled from '@emotion/styled'; export const ScrollbarWrapper = styled.div(() => ({ maxHeight: '65vh', overflowY: 'auto', '*::-web ...

The waypoints.js snippet seems to be malfunctioning in this specific context

After experimenting with waypoints.js (jQuery.waypoints) for some time, I've been attempting to utilize this library to incorporate animations on children elements within a specific container. Here is the approach I have taken: var waypoints = $( ...

Azure experiencing issue with MUI Datepicker where selected date is shifted by one day

I have developed a unique custom date selection component that utilizes Material UI and Formik. This component passes the selected date value to a parent form component in the following manner: import React from 'react'; import { useField } from ...

React Server Component Warning: Server Functions cannot be invoked during the initial rendering stage

In my project, I have a client component named CampaignTable. This component requires a columns object to render the columns. Within the columns object, I include a server component called CampaignActions. The CampaignActions component is responsible for d ...

Is it necessary to test the main.js file in Vue.js project?

While performing unit tests on components is acceptable, after running coverage analysis I have noticed that certain lines of code in the main.js file remain uncovered. This raises the question: should the main.js file also be included in testing? Specifi ...

What is the best way to send checkbox values to ActionResult in MVC5?

I am working on an MVC5 application and within my view, I have the following code snippet: <div class="form-group"> @Html.LabelFor(model => model.CategoryID, "Category", htmlAttributes: new { @class = "control-label col-md-3" }) <div c ...

Retrieve the link's "href" attribute and its text if they match the specified text

Is there a way to extract the href link and text from a specific type of link? <a href="google.com">boom</a> I am looking to retrieve only the 'google.com' part and the text 'boom' Furthermore, how can I filter out other ...

How to create a self-contained div in VueJS using Tailwind CSS without affecting other elements

I'm feeling completely overwhelmed right now. Attached is a picture showing the issue I'm facing: The user list layout is on the right The chat content in the middle should be scrollable vertically The bottom div should stay fixed in place witho ...

Experiencing an excessive amount of re-renders

Encountering the error of too many re-renders Attempted to utilize useEffect to render only when weather changes function DashboardHeaderContent({ looks, weather }) { const [seasonRange, setSeasonRange] = React.useState(); function renderLook(look) ...

Having trouble accessing and setting the values of a JSON array retrieved using $.get method in JavaScript outside of the function

Executing the following code snippet results in the desired values being displayed in console.log: var q; $.get('/ajax_subscribers', { code: 'qyhskkcnd'}, function(returnedData){ q = returne ...

Using jQuery to append content with a variable as the source

Recently delving into jQuery and encountering an issue with getting my variable inside src when using append. Either it's not functional at all, or just displaying the variable name in string form in the console. Here is the code causing trouble: va ...

How can I set a background image to automatically adjust to the width of the window, be full height, allow for vertical scrolling, and

How can I set a full-screen background image that adjusts to the body width without horizontal scrolling, maintains height proportionate to width, and allows for vertical scrolling? Here is my current code: html, body { margin: 0px; padding: 0px; } bo ...

"Combining Array Elements in jQuery: A Guide to Merging Two Array Objects

enter : var b= [{ "cat_id": "1", "cat_name": "teaching" }]; var a= [ { "username": "r", "password": "r" }]; I desire the following result: [{"username":"r","password":"r","cat_id":"1","cat_name":"teaching"}] ...

Is it possible to remove the "disabled" attribute using JS, but the button remains disabled?

There are two buttons on my page: the first one is currently disabled, and the second one is supposed to enable the first button. That's the plan. Button 1: $(document).ready(function() { $('#click').click(function() { document.getE ...

Pressing the button results in no action

I am currently developing a program that randomly selects 5 words from a database and inserts them into an array. Although the page loads correctly initially, nothing happens when the button is clicked. None of the alerts are triggered, suggesting that the ...

Ways to disseminate arguments when dealing with an array of arrays in JavaScript

Struggling to pass an array as arguments into the join method on path in node, but hitting a roadblock: var path = require("path"); var paths = [__dirname]; var userInput = ["app", "js"]; paths.push(userInput); var target = path.join.apply(null, paths); ...

Developing a dynamic user interface using an Angular framework and populating it with

I am currently learning Angular (version 1) and facing an issue with my layout. I need to dynamically change the navigation based on the type of user that is logged in. To achieve this, I make an API request when the page loads to fetch the user object dat ...