I’m trying to implement an effect on overlapping images so when I click and drag a bar the other image underneath should reveal modifying the width. My code works, but it’s kind of buggy. When I click on the bar I have to then release it to make it work, so it’s not really a drag, and it supposed to stop moving when I release the click.
And second, the bar goes right even outside my container. How could I fix my code?
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>
Explanation : When the bar was being slid, the images were acting as draggable elements. To stop that, I set
draggable
attribute tofalse
in both image elements. Besides that, the blue color appearing was highlight because of selection of element. To prevent that, I set CSS propertyuser-select
tonone
for the containerdivs
of images.For browser compatibility, use different versions for
user-select
.My advise is to NOT unregister (remove) the
mousemove
event listener.Below, I used a
barActive
as a "flag" to know if the mouse button is down. The flag is resetted onmouseup
andmouseleave
of thecontainer
.The
mousemove
event is a machinegun… But is still not fast enough to "really" follow the mouse. So if a user moves the bar fast, the cursor often is off the bar (I’m sure you noticed it). So amouseup
has good chances to not fire if themouseup
event listener is on the bar. So the event listener has to be on the container.Now… While
mousemove
is not fast enought to follow the mouse perfectly… It often is too fast and may interfeer with the actions you wish to do with the other events, likemousedown
were you set the "flag". At the same millisecond, you can have themousedown
event and multiplemousemove
events. So to "isolate" it form themousemove
events, I used a real tinysetTimeout
. That is giving enought time for the flag to be set bafore any nextmousemove
to enact.About making sure the bar does not go outside the container, I used a condition on
e.clientX
.I also took the container’s
padding
in account.CodePen