sleek lateral scrolling reminiscent of k2.pl

I'm in the process of creating a website with a horizontal scroll similar to k2.pl.

Here's what I have accomplished so far using jQuery animate and scroll:

// Obtaining the X and Y axis and moving the entire page accordingly
$('.scroll').animate( { scrollLeft: '+='+newScroll }

However, my current script only moves the page based on its X axis. What I really want is for the page to automatically scroll to the center when hovering over an element, just like the functionality on k2.pl.

Could someone recommend a jQuery plugin or provide advice on how I can enhance this feature?

Answer №1

Upon visiting the website and moving your mouse, you'll notice that the element being hovered on doesn't perfectly align with the center. The scroll movement is linked to horizontal mouse movements rather than hovering over various list elements.

The concept is straightforward:

  • Create a container that spans the full width of the window with an overflow:hidden property.
  • Within this container, include a second container with the same width as the list of elements.
  • Inside the second container, place a list of elements or inline elements that exceed the window's width.
  • When the mouse hovers over the container, determine the mouse's position within the window and horizontally scroll the container accordingly.

A simplified version looks like this:

$(document).ready(function() {
  
  $(".scroll").on("mousemove", function(e) {
    
    var ww = $(window).width();       // window width
    var uw = $(".scroll ul").width(); // ul width
    var mp = e.clientX;               // mouse position
    var ms = uw - ww;                 // max scroll
    var sc = - ms * mp / ww;          // amount to be scrolled

    $(".scroll > div").stop().animate({ left: sc +"px" }, 600, "easeOutCirc");
    
  });
  
});
html, body { 
  margin:0;
  padding:0;
  border:0;
}

div.scroll {
  width:100%;
  height:400px;
  overflow:hidden;
  background:#f0f0f0;
  position:relative;
}

div.scroll > div {
  width:1400px;
  position:absolute;
  top:0;
  left:0;
}

div.scroll > div > ul {
  width:1400px;
  margin:0;
  padding:0;
}

div.scroll > div > ul > li {
  display:inline-block;
  float:left;
  width:200px;
  height:400px;
  opacity:0.7;
  transition:all 0.5s;
}

div.scroll > div > ul > li:hover {
  opacity:1;
  background:#6699cc;
}

div.scroll > div > ul > li:hover > span {
  color:white;
  background:black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>

<div class="scroll">
  <div>
    <ul>
      <li><span>AAA</span></li>
      <li><span>BBB</span></li>
      <li><span>CCC</span></li>
      <li><span>DDD</span></li>
      <li><span>EEE</span></li>
      <li><span>FFF</span></li>
      <li><span>GGG</span></li>
    </ul>
  </div>
</div>

(Please note: If the window's width exceeds 1400px, the provided code may not function correctly.)

After examining the source code for k2.pl, it's evident that they utilize jQuery, jQuery UI, and Ariel Flesler's scrollTo plugin. To see how scrolling is controlled (in a different manner described above), refer to the script.min.js file (search for mousemove.sapp).

Answer №2

Here is my solution as promised. While Alvaro's solution is effective, using the jQuery animate function can be slow compared to CSS transitions or the GSAP JavaScript animation library. That's why I have implemented a different approach that may interest you.

I personally prefer using GSAP for its ease of use, so I've incorporated it here along with native JS to avoid unnecessary library dependencies:

var wrapper = document.getElementById("wrapper");
var tiles = document.getElementsByClassName("tile");
var tileWidth = tiles[0].getBoundingClientRect().width;
var containingWidth = tileWidth * tiles.length;

wrapper.addEventListener("mousemove", function(e){
  var pos = (e.clientX / (wrapper.getBoundingClientRect().width)) * containingWidth - (tileWidth / 1.5);
  TweenLite.to(wrapper, 1, { scrollLeft: pos, ease: Circ.easeOut })
});
html, body {
  height: 100%;
  overflow: hidden;
  white-space: nowrap;
}

#wrapper {
  height: 100%;
  overflow-y: hidden;
  overflow-x: auto;
}

.tile {
  display: inline-block;
  height: 100%;
  width: 400px;
  transition: background 0.2s ease-in-out;
}

.tile:hover {
  background: transparent !important;
}
<div id="wrapper">
  <div style="background: #6d8745" class="tile"></div>
  <div style="background: #aa715a" class="tile"></div>
  <div style="background: #a25fe3" class="tile"></div>
  <div style="background: #8e84f5" class="tile"></div>
  <div style="background: #259a5c" class="tile"></div>
  <div style="background: #d5b67a" class="tile"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js"></script>

The concept is similar to Alvaro's method. It involves calculating the positioning based on the mouse movement within the viewport and adjusting the scroll position accordingly. The key calculation can be seen in this line of code (with an additional offset):

var pos = (e.clientX / (wrapper.getBoundingClientRect().width)) * containingWidth - (tileWidth / 1.5);

I hope you find this helpful!

View original codepen

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

Creating dynamic pages using user input in Node and Express

Currently, I am facing a challenge in rendering text using node/express. Within my project setup, there is an HTML file containing a form. The file named search.ejs looks like this: $(document).ready(function(){ var userInput; $("#submit-button-i ...

What sets apart Selenium's mouseMove() function from the physical movement of a mouse?

Imagine I have element A and element B on a webpage. Using tools like Selenium or PhantomJS, I can manipulate the mouse via coordinates. By identifying the position of element A (a link) and element B (a submit button), I can create a bezier curve or mimi ...

Transform written content into visual data using canvas technology

Trying to develop a basic application that converts form data into an image. For instance, when the form is filled out dynamically and submitted, the goal is to translate the input into an image. Is it possible to achieve this using just javascript, vue. ...

Tips for resolving the cross-origin resource sharing (CORS) origin error in Jquery when encountering issues with the

Hi Team, I am encountering an error that I cannot resolve. My post method consistently fails when making a REST client request using Visual Studio Code or any other RESTful tool, not just in the browser. jquery.js:9664 POST ->url<- 404 (Not Found) ...

Looking for a simple method to link JSON data to an svg element through Javascript?

Looking to harness the power of SVG for a basic graph creation, but uncertain about the process of assigning JSON data dynamically using a 'for loop' to draw rectangles within SVG. Seeking guidance on setting up 1 loop to assign each value for dr ...

Firefox consistently reports ajax status as error

One of my ajax requests is causing some confusion. $.ajax({ url: webURL, type: 'post', data: somedata, cache: false, datatype: "json", contentType: "application/json", success: successFunc, ...

Trouble with custom font updates in Hugo using Blogdown

Recently, I've been immersing myself in Blogdown to create my own personal data blog: Using the academic theme as a base, I successfully tweaked the color scheme without any hiccups. However, despite making adjustments in my params.yaml file, none o ...

How to use Axios in Vue JS to access an array within a JSON object

Struggling to access arrays inside a JSON object and save them into separate arrays. Despite trying various methods, I have not been successful in retrieving these arrays. I suspect that my approach to accessing arrays within the JSON object is incorrect, ...

Exploring the Concept of Dependency Injection in Angular 2

Below is a code snippet showcasing Angular 2/Typescript integration: @Component({ ... : ... providers: [MyService] }) export class MyComponent{ constructor(private _myService : MyService){ } someFunction(){ this._mySer ...

Implementing a custom body class in AngularJS when utilizing partials

Looking for some help with AngularJS. I have an index.html file, along with controllers and partials. The <body> tag is located in the index.html. I am trying to set the class for the body using my controller. After adding a value to $scope.body_c ...

Issue with webcomponents-lite.js file

Encountering this particular error message in the console while attempting to run the application: webcomponents-lite.js:64Uncaught TypeError: Cannot read property 'getAttribute' of null at webcomponents-lite.js:64 at Object.549 (webcomp ...

trigger opening a bootstrap modal programmatically

I have a modal setup using Bootstrap with the code below: <div className="modal fade" id="exampleModal" aria-labelledby="exampleModalLabel" aria-hidden="true" > &l ...

Placing the labels of checkboxes within a form into a new <p> element

I've spent hours trying, but I can't figure it out on my own. That's why I'm reaching out for help here. Here's the form I'm working with: <form id="ecommerce-form"> <input type="checkbox" id=& ...

Keep some table columns locked in place on your webpage while others are located off-screen, requiring a scroll to access

I have a question regarding an HTML table. There is a windows application that features a vertical scrollable table where some columns are fixed on the page while others remain outside the page. Here is an example: The black border represents the responsi ...

Monitor which image has been selected to alter the content inside

Is there a way to track the image clicked on and modify the inner HTML of the element located above where all the images are displayed? For instance, if I click on St. John The Baptist, I want the title to change to St. John The Baptist. Currently, the fu ...

Is it possible to use uglifyjs to merge multiple files into a single minified file?

I attempted to compress multiple javascript files into one using the uglifyjs tool, but encountered an issue. I ran $node uglifyjs.js to execute the file. Below is the content of the uglify.js file: var fs = require('fs'); var uglifyjs = re ...

Is there a way to ensure my program waits for Firebase's data retrieval before running a specific function?

As a newcomer to Next.js and Firebase, I embarked on creating a login system with roles recently. Leveraging Firebase Authentication, I stored account roles in Firestore and linked the authentication account with Firestore data by utilizing the UID as the ...

What is causing the input tag and button tag to appear on separate lines instead of together?

https://i.sstatic.net/AQiw3.png Here is my HTML and CSS code: <!DOCTYPE html> <html> <head> <title>assignment1</title> <meta charset="utf-8"> <meta name = "description" content="assignment"> <meta name = ...

Struggling with TypeScript errors due to React.HTMLProps for HTMLAnchorElement

When trying to extend a React component with React.HTMLProps without explicitly defining onClick in the attribute list, ESLint complains when passing onClick as an attribute while using the component. Here's an example of the code: The React componen ...

The text enclosed by a span located inside a div and identified by xpath

I am struggling to extract text from a span nested within another text in a div (highlighted in the image). https://i.sstatic.net/8uIWz.png This snippet of code is relevant ... <div id="groupBlock3"> <div class="groupBlockTitle& ...