Using jQuery to create overlapping images

Currently, I am working on an effect that involves overlapping images. The idea is that when a bar is clicked and dragged, the image underneath should reveal by adjusting its width. While my code functions, there are some glitches present. One issue is that I have to release the click for the effect to work, which defeats the purpose of a smooth drag operation. Additionally, the bar extends beyond the container's boundaries. How can I enhance my code to address these issues?

var up = $("#up");
var bar = $("#bar");
var container = $("#container");

bar.on("mousedown", function () {
    container.on("mousemove", function (e) {
        bar.css("left", e.clientX);
        up.width(e.clientX);
    });
});

$("body").on("mouseup", function () {
    container.off("mousemove");
});

container.on("mouseleave", function () {
    container.off("mousemove");
});
* {
    margin: 0;
    box-sizing: border-box;
}

img {
    height: 400px;
    width: 600px;
    object-fit: cover;
}

#up {
    width: 50%;
}

#bottom,
#up {
    position: absolute;
    overflow: hidden;
}

#container {
    position: relative;
    border: 5px solid cornflowerblue;
    height: 410px;
    width: 610px;
}

#bar {
    position: absolute;
    height: 400px;
    width: 10px;
    background-color: hotpink;
    left: 300px;
    cursor: e-resize;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="stylesheet" href="style.css" />
        <title>Document</title>
    </head>
    <body>
        <div id="container">
            <div id="bottom">
                <img src="https://via.placeholder.com/600x400?text=Image1" alt="image" />
            </div>
            <div id="up">
                <img src="https://via.placeholder.com/600x400?text=Image2" alt="image" />
            </div>
            <div id="bar"></div>
        </div>
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        <script src="script.js"></script>
    </body>
</html>

Answer №1

Clarification: While moving the bar, the images were behaving as draggable elements. To prevent this behavior, I disabled the draggable attribute in both image elements. Additionally, the appearance of a blue color was due to element selection; to avoid this, I set the CSS property user-select to none for the container divs of the images.

To ensure compatibility across browsers, consider utilizing different versions of user-select.

var up = $("#up");
var bar = $("#bar");
var container = $("#container");

bar.on("mousedown", function() {
  container.on("mousemove", function(e) {
    let left = e.clientX;
    let containerWidth = container.width();
    let barWidth = bar.width();

    if((left + barWidth) > containerWidth)
      left = containerWidth - barWidth;

    bar.css("left", left);
    up.width(left);
  });
});


$("body").on("mouseup", function() {
  container.off("mousemove");
});

container.on("mouseleave", function() {
  container.off("mousemove");
});
* {
  margin: 0;
  box-sizing: border-box;
}

img {
  height: 400px;
  width: 600px;
  object-fit: cover;
}

#up {
  width: 50%;
}

#bottom, #up {
  position: absolute;
  overflow: hidden;
  user-select: none;
}

#container {
  position: relative;
  border: 5px solid cornflowerblue;
  height: 410px;
  width: 610px;
}

#bar {
  position: absolute;
  height: 400px;
  width: 10px;
  background-color: hotpink;
  left: 300px;
  cursor: e-resize;
}
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<div id="container">
  <div id="bottom">
    <img src="https://via.placeholder.com/600x400?text=Image1" alt="image" draggable="false"/>
  </div>
  <div id="up">
    <img src="https://via.placeholder.com/600x400?text=Image2" alt="image" draggable="false"/>
  </div>
  <div id="bar"></div>
</div>

Answer №2

It is not recommended to unregister (remove) the mousemove event listener.

To track whether the mouse button is down, I utilized a variable called barActive as a "flag". This flag gets reset on mouseup and mouseleave events for the container.

The mousemove event fires rapidly but may still lag behind real-time mouse movements. When a user moves the bar quickly, the cursor might be off target (which you may have observed). Therefore, having the mouseup event listener on the bar itself increases the likelihood of it not firing when needed. Hence, it's preferable to attach the event listener to the container instead.

Although the mousemove event isn't always accurate in following the mouse, it can sometimes interfere with other events like mousedown where the "flag" is set. In such cases, both the mousedown event and multiple mousemove events can occur simultaneously. To isolate this behavior from subsequent mousemove events, I introduced a very short delay using setTimeout. This allows ample time for the flag to be set before any further mousemove actions take place.

To ensure that the bar stays within the confines of the container, I added a condition based on e.clientX.

I also factored in the container's padding into my considerations.

CodePen Link

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

The functionality of aria-expanded="true" is not functioning properly when accessed on mobile devices

I am facing an issue where "aria-expanded="true" does not work when the user closes the dropdown on mobile devices, but it works perfectly fine on desktop browser pages. Desktop <a class="notifLink" data-toggle="dropdown" aria-haspopup="true" id="noti ...

Experiencing issues with obtaining req.params.id undefined while initiating a put request

Encountering an issue while making a PUT request using Postman, as an error occurs in the VSCode terminal with the message: let product = await Product.findById(req.params.id); ^ TypeError: Cannot read property 'id' of undefined. The request ...

Ways to verify and incorporate https:// in a URL for a MEAN Stack application

When extracting the URL from API data, my code looks like this: <div class="row copy-text"> <a href="{{copy.Url}}" target="_blank" style="text-decoration: underline !important;">{{copy.Title}}</a> </div> I am interested in ve ...

How come my post isn't being saved to the page after I refresh it?

Utilizing Javascript, NodeJS, MongoDB, Express Within my application, a user is expected to enter text in an input field and upon clicking the submit button, the text should appear on the page. I have succeeded in posting text to the page; however, after ...

Extract information stored in a JSON object and input it into an array

I'm struggling to extract data from a multidimensional array. In my .php file, I retrieve data from a database and encode it to JSON. JSON= {"1":{"SME":"0","SAUDE":"0"}.... Desired data structure: array{ 0 => Array{"SME" => 1, ...

If the status of any ticket with is_approved=1 is updated to "2", the field ticket_status will be updated based on the order ID in CodeIgniter

This is the table for requests https://i.sstatic.net/NWT4y.png How can I update the ticket_status field with a value of "2" if at least one of the requests has is_approved=1, based on the orderid? I have attempted the following code, but it is not updat ...

Add new items to an array in mongoose without affecting existing elements within the array

Two different entity structures are in place: Blog Setup: const blogSetup = new mongoose.Schema( { title: { type: String, min: 3, max: 20, required: true }, content: { type: String, required: true }, likes: { type: Number, required: true, de ...

Footer not adhering to the bottom of specific pages

I have been using the code snippet below to ensure that most of my pages stick to the bottom. However, I've noticed that the ones that don't are sub-menu items that contain a contact form with captcha. I'm not sure what's causing this i ...

Safari iOS 8 experiencing issues with loading WebGL image textures

The example mentioned above runs smoothly on all major browsers, including Safari on Mac OS. However, it fails to display the correct image on my iPad running the latest iOS 8. Click here for the example. Similarly, the tutorial provided in the following ...

How can I make sure addEventListener only responds to numbers and not images?

Currently, I am facing a dilemma with implementing a button that features an image on it and needs to be placed within another div. Despite successfully achieving this, I am struggling to comprehend the JavaScript code outlined in a tutorial I followed. Th ...

How come modifications to a node package are not reflected in a React.js application?

After running "npm install" to install node modules, I made some changes to a module. The modifications are highlighted in a red rectangle. https://i.sstatic.net/KXdye.png The "find" command line tool only detected one file with that name. Next, I launc ...

The proper approach is using CSS for linking pseudo-classes

Look what I stumbled upon: Important: Remember, a:hover MUST be placed after a:link and a:visited in the CSS code to work properly!! Remember: Place a:active after a:hover for it to have an effect in the CSS code!! Note: Pseudo-class names are not case- ...

Troubleshooting: Issue with incorporating libraries into my HTML code using Ionic framework and Angular

I am currently working on developing a hybrid app using Ionic and Angular. I attempted to incorporate jQuery UI for drag-and-drop functionality, but unfortunately, it did not work as expected. Despite testing simple examples, the feature still did not func ...

Retrieve the outcome from the PHP webpage

I have recently developed a contact page, but I am experiencing an issue with the submit button's functionality. When I click on the submit button, the form is supposed to send the information to a PHP file on the server-side. However, the button does ...

Leveraging HTML within jQuery UI autocomplete

In the past, I was able to include HTML in the JSON array I used for autocomplete with jQuery UI before version 1.8.4. For example: $row_array['label'] = '<span style="color: red; font-family: courier;">User, Name</span>'; ...

Modifying the cursor appearance during object dragging is a simple task that can enhance

html .container, .container * { cursor: url('img/arrowPointer.png'), auto; } javascript $('html').on('dragstart', function () { $('html').addClass('container'); }); $('html').on('d ...

Troubleshooting height adjustment for header and footer in CSS with dynamic content not functioning properly on Safari for macOS and Safari for iOS (jsBin)

I recently came across a solution by @RokoC.Buljan, which works perfectly on Chrome and Firefox. However, I encountered an issue with Safari where the content section does not scroll properly and the footer sticks to the bottom of the content, making it di ...

Sending intricate JSON object to an ASHX handler using jQuery

I have a dilemma with passing a complex JSON object from the client to the server for processing. Currently, I am utilizing an ashx file and experimenting with jQuery's $.ajax and $.post methods to send the data. I am struggling to figure out the most ...

Vue users are experiencing issues with the functionality of the Chart js plugin annotation

I've been attempting to include a horizontal line in my Chart.js using the annotations plugin, but it's not cooperating. My Chart.js version is 2.9.4, so I had to install it with the command: npm install [email protected] --save After inst ...

Dynamic form population with dropdown selection using Ajax - Coldfusion continuation

Following some valuable feedback from my previous inquiry, I have made progress: Refer to the original post - Coldfusion Populate form with dropdown selection using ajax Currently, I have successfully sent a request to my CFC with a remote function, but I ...