Reputation: 741
I have attached snippet where I have an image which is draggable and zoomable inside a div. But there is one issue, when moving image from left to right, it should not be able to move if the corner of image meets the corner of parent for both X and Y. I actually want to know when the corners of image meets with parent div corners because I dont want to allow dragging when this condition meets. Background red color should not be visible when dragging image.
window.repositionImage = function(event){
var element = document.getElementById('img');
element.addEventListener('mousedown', function(e){
e.stopPropagation();
element.style.cursor = "grabbing";
if (e.target != element) return;
var offsetX = e.pageX - element.offsetLeft;
var offsetY = e.pageY - element.offsetTop;
var move = function(e){
element.style.left = e.pageX - offsetX + "px";
element.style.top = e.pageY - offsetY + "px";
}
var stop = function(){
element.style.cursor = "default";
document.removeEventListener("mousemove", move);
document.removeEventListener("mouseup", stop);
}
document.addEventListener("mousemove", move);
document.addEventListener("mouseup", stop);
})
}
window.panChangeHandler = function(e){
var element = document.getElementById('img');
if (e.target.value == 0) {
element.style.left = "0px";
element.style.top = "0px";
}
img.style.transform = `scale(1.${e.target.value})`;
}
.item {
border: 1px solid;
background: red;
width: 300px;
height: 300px;
overflow: hidden;
position:relative;
}
.item img {
position:absolute;
width: 100%;
height: 100%;
-webkit-user-drag: none;
left:0;
top:0;
}
.slider {
z-index: 9;
position: absolute;
left: 0;
top: 0;
margin-left: -20px;
margin-top: 70px;
writing-mode: bt-lr; /* IE */
-webkit-appearance: slider-vertical; /* WebKit */
transform: rotateZ(270deg);
}
.slider input {
width: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='item'>
<span class='slider'>
<input type='range' aria-orientation="vertical"
value="0" min="0" max="9" step="1" oninput="panChangeHandler(event)"
/>
</span>
<img id='img' src="https://images.unsplash.com/photo-1494548162494-384bba4ab999?ixlib=rb-1.2.1&w=1000&q=80" alt='image' onmouseover="repositionImage(event)" />
</div>
Upvotes: 2
Views: 533
Reputation: 741
I managed to solve this issue:
function parseComplexStyleProperty(str) {
var regex = /(\w+)\((.+?)\)/g,
transform = {},
match;
while ((match = regex.exec(str))) transform[match[1]] = match[2];
return transform;
};
window.repositionImage = function(event){
var element = document.getElementById('img');
element.addEventListener('mousedown', function(e){
e.stopPropagation();
element.style.cursor = "grabbing";
if (e.target != element) return;
var offsetX = e.pageX - element.offsetLeft;
var offsetY = e.pageY - element.offsetTop;
var x = 0;
var y = 0;
var move = function(e){
x = e.pageX - offsetX;
y = e.pageY - offsetY;
element.style.left = e.pageX - offsetX + "px";
element.style.top = e.pageY - offsetY + "px";
}
var stop = function(){
element.style.cursor = "default";
var t = parseComplexStyleProperty(element.style.transform);
if (!Object.keys(t).length) {
element.style.left = "0px";
element.style.top = "0px";
}
else {
var imageWidth = element.clientWidth * parseFloat(t.scale);
var imageHeight =
element.clientHeight * parseFloat(t.scale);
var pointToSubX = Math.trunc(
(imageWidth - parent.clientWidth) / 2
);
var pointToSubY = Math.trunc(
(imageHeight - parent.clientHeight) / 2
);
if (x > pointToSubX || x < -pointToSubX) {
if (x > pointToSubX)
element.style.left = pointToSubX + "px";
else element.style.left = -pointToSubX + "px";
}
if (y > pointToSubY || y < -pointToSubY) {
if (y > pointToSubY)
element.style.top = pointToSubY + "px";
else element.style.top = -pointToSubY + "px";
}
document.removeEventListener("mousemove", move);
document.removeEventListener("mouseup", stop);
}
}
document.addEventListener("mousemove", move);
document.addEventListener("mouseup", stop);
})
}
window.panChangeHandler = function(e){
var element = document.getElementById('img');
img.style.transform = `scale(1.${e.target.value})`;
}
document.getElementById("img").disabled = true;
.item {
margin-right: 1px;
height: 200px;
background: white;
overflow: hidden;
position: relative;
}
.item img {
transform: scale(1);
position: relative;
background-color: #eee;
width: 100%;
height: 100%;
-webkit-user-drag: none;
left:0;
top:0;
}
.slider {
z-index: 9;
position: absolute;
left: 0;
top: 0;
margin-left: -20px;
margin-top: 70px;
writing-mode: bt-lr; /* IE */
-webkit-appearance: slider-vertical; /* WebKit */
transform: rotateZ(270deg);
}
.slider input {
width: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='item'>
<span class='slider'>
<input type='range' aria-orientation="vertical"
value="0" min="0" max="9" step="1" oninput="panChangeHandler(event)"
/>
</span>
<img id='img' src="https://images.unsplash.com/photo-1494548162494-384bba4ab999?ixlib=rb-1.2.1&w=1000&q=80" alt='image'
onmouseover="repositionImage(event)" />
</div>
Upvotes: 0
Reputation: 811
There is a simple css
fix you can try but I'm not sure about it's crossbrowser compatibility. Change the .item img
position to sticky
.
window.repositionImage = function(event){
var element = document.getElementById('img');
element.addEventListener('mousedown', function(e){
e.stopPropagation();
element.style.cursor = "grabbing";
if (e.target != element) return;
var offsetX = e.pageX - element.offsetLeft;
var offsetY = e.pageY - element.offsetTop;
var move = function(e){
element.style.left = e.pageX - offsetX + "px";
element.style.top = e.pageY - offsetY + "px";
}
var stop = function(){
element.style.cursor = "default";
document.removeEventListener("mousemove", move);
document.removeEventListener("mouseup", stop);
}
document.addEventListener("mousemove", move);
document.addEventListener("mouseup", stop);
})
}
window.panChangeHandler = function(e){
var element = document.getElementById('img');
img.style.transform = `scale(1.${e.target.value})`;
}
document.getElementById("img").disabled = true;
.item {
border: 1px solid;
background: red;
width: 300px;
height: 300px;
overflow: hidden;
position:relative;
}
.item img {
position: sticky;
width: 100%;
height: 100%;
-webkit-user-drag: none;
left:0;
top:0;
}
.slider {
z-index: 9;
position: absolute;
left: 0;
top: 0;
margin-left: -20px;
margin-top: 70px;
writing-mode: bt-lr; /* IE */
-webkit-appearance: slider-vertical; /* WebKit */
transform: rotateZ(270deg);
}
.slider input {
width: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='item'>
<span class='slider'>
<input type='range' aria-orientation="vertical"
value="0" min="0" max="9" step="1" oninput="panChangeHandler(event)"
/>
</span>
<img id='img' src="https://images.unsplash.com/photo-1494548162494-384bba4ab999?ixlib=rb-1.2.1&w=1000&q=80" alt='image' onmouseover="repositionImage(event)" />
</div>
Upvotes: 1
Reputation: 508
Check
if (e.target.tagName == "DIV" ) return;
On drop event
Upvotes: 0