How to move reposition element in a div - javascript

I am trying to re position an element in a div.Basically its a span with background image.I have done the 80% part.Its working perfect when i click on it first time.It move to the desired position. But when i click on it second time it reset to its initial position.Below is my code.
I have a jsfiddle link here. https://jsfiddle.net/6q1q0wmj/
var TransformRequestObj
var TransList
var DragTarget=null;
var Dragging = false;
var OffsetX = 0;
var OffsetY = 0;
jQuery(document).on('mousedown','.bx_reposioned',function(evt){
if(!Dragging) //---prevents dragging conflicts on other draggable elements---
{
DragTarget = evt.target;
//---bring this viewPort to top---
var xcord=evt.clientX;
var ycord = evt.clientY;
OffsetX= OffsetX || xcord;
OffsetY= OffsetY || ycord;
Dragging=true;
}
});
jQuery(document).on('mousemove','.bx_reposioned',function(evt){
if(Dragging)
{
//var pnt = DragTarget.ownerSVGElement.createSVGPoint();
var xcord=evt.clientX;
var ycord = evt.clientY;
xcord -= OffsetX;
ycord -= OffsetY;
jQuery(this).css('transform','translate('+xcord+'px, '+ycord+'px)');
}
});
jQuery(document).on('mouseup','.bx_reposioned',function(evt){
Dragging = false;
var xcord=evt.clientX;
var ycord = evt.clientY;
});
.furniture-sprite {
display: block;
margin: 0 auto;
}
.bed1 {
width: 45px;
height: 53px;
background:red;
}
.bed2 {
width: 45px;
height: 53px;
background:blue;
}
.furniture-sprite {
display: inline-block;
background-repeat: no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="furniture-sprite bed1 ui-draggable ui-draggable-handle ui-draggable-dragging bx_reposioned" style="position: absolute; width: 45px; right: auto; height: 53px; bottom: auto; left: 410.953px; top: 95px;"></span>
<span class="furniture-sprite bed2 ui-draggable ui-draggable-handle ui-draggable-dragging bx_reposioned" style="position: absolute; width: 45px; right: auto; height: 53px; bottom: auto; left: 410.953px; top: 95px;"></span>
</div>

The problem is that the mousedown handler resets OffsetX and OffsetY even if it's already set,
if you do a check before overwriting it, it seems to work fine (line 14):
OffsetX= OffsetX || xcord;
OffsetY= OffsetY || ycord;
https://jsfiddle.net/6q1q0wmj/1/

You are resetting the offset each time. Also, for the mousemove and mouseup you are filtering to only accept the events when they happens over the dragged element.
For the first problem you should keep your offset when you mousedown again and for the second problem just remove the selector filter. You will have a more fluid drag (as it will detect the drag all around the document) and also will detect the mouseup when you move out of the drag area.
Right now you won't notice the "out of the drag area" problem because you have not boundaries set, but you will notice if you add them.
If there are multiple elements, you should keep the offset saved on each element. This is a easy jQuery way of doing it:
Check this:
var Dragging = false;
jQuery(document).on('mousedown','.bx_reposioned',function(evt){
if(!Dragging) //---prevents dragging conflicts on other draggable elements---
{
//---bring this viewPort to top---
var xcord = evt.clientX;
var ycord = evt.clientY;
!$(this).data("_dragOffset") && $(this).data("_dragOffset", {
x: xcord,
y: ycord
}); // This will set the offset only if has no drag offset already saved
Dragging = this;
}
});
jQuery(document).on('mousemove', function(evt){
if(Dragging) {
var xcord = evt.clientX;
var ycord = evt.clientY;
var offset = $(Dragging).data("_dragOffset");
xcord -= offset.x;
ycord -= offset.y;
jQuery(Dragging).css('transform','translate('+xcord+'px, '+ycord+'px)');
}
});
jQuery(document).on('mouseup', function(evt){
Dragging = false;
});
.furniture-sprite {
display: block;
margin: 0 auto;
}
.bed1 {
background-position: 0 -117px;
width: 45px;
height: 53px;
}
.furniture-sprite {
display: inline-block;
background-image: url('http://www.builderux.com/demo5/wp-content/plugins/Builder_UX-combined-code/assets/img/furniture-sprite.png');
background-repeat: no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="furniture-sprite bed1 ui-draggable ui-draggable-handle ui-draggable-dragging bx_reposioned" style="position: absolute; width: 45px; right: auto; height: 53px; bottom: auto; left: 410.953px; top: 95px;"></span>
</div>

Related

How do I hide pointer events but still be able to initiate a drag event?

I have made a simple image cropper, where you move the green box (the area to crop) over the red box (the original image). Here it is:
var crop = document.querySelector(".image .crop");
crop.addEventListener("drag", function() {
var mouseoffset = [event.clientX, event.clientY];
crop.style.left = mouseoffset[0] + "px";
crop.style.top = mouseoffset[1] + "px";
});
crop.addEventListener("dragend", function() {
var mouseoffset = [event.clientX, event.clientY];
crop.style.left = mouseoffset[0] + "px";
crop.style.top = mouseoffset[1] + "px";
});
.image {
position: relative;
width: 400px;
height: 400px;
overflow: hidden;
background: #C00;
}
.image .crop {
position: absolute;
width: 150px;
height: 150px;
background: rgba(64,168,36,1);
}
<div class="image">
<div class="crop" draggable="true"></div>
</div>
But there is a problem: you can notice a pale green box when dragging. I can hide it with pointer-events: none, but this renders the box undraggable. Is there any way I can hide this pale green box while still being able to drag the crop area?
There might be a way to adapt what you have going on with drag events to achieve that result, but I wasn't able to get it working. Here's something doing about the same thing but with mousedown, mouseup, and mousemove.
var crop = document.querySelector(".image .crop");
crop.addEventListener("mousedown", function(event) {
document.onmousemove = function(event) {
moveBox(event);
};
document.onmouseup = function(event) {
stopMoving(event);
}
});
function moveBox(event) {
event.preventDefault();
var mouseoffset = [event.clientX, event.clientY];
crop.style.left = mouseoffset[0] + "px";
crop.style.top = mouseoffset[1] + "px";
}
function stopMoving(event) {
document.onmousemove = null;
document.onmouseup = null;
}
.image {
position: relative;
width: 400px;
height: 400px;
overflow: hidden;
background: #C00;
}
.image .crop {
position: absolute;
width: 150px;
height: 150px;
background: rgba(64, 168, 36, 1);
}
<div class="image">
<div class="crop" draggable="true"></div>
</div>

move a large div opposite to mouse movement

I have a table full of data that tends to be larger than the screen.
I put the table in a DIV and set the "overflow" to "auto" in CSS
div.scrolling-comps {
width : 970px;
height : 800px;
overflow : auto;
}
So the DIV can be scrolled up/down, left right using the browser's built-in scroll bars.
Problem is, the table can be WAAY bigger than the screen. And while the mousewheel will scroll it up/down, scrolling left/right is a pain in the hooch.
So, looking for a javascript/jquery or CSS way to scroll the div NATURALLY.
In other words, when someone viewing the huuuge table moves their mouse to the right, the DIV goes to the left (thus scrolling without using the scroll bars).
Something similar to this, but instead of following the mouse, the div would move opposite the mouse...
window.onload = function() {
var bsDiv = document.getElementById("box-shadow-div");
var x, y;
// On mousemove use event.clientX and event.clientY to set the location of the div to the location of the cursor:
window.addEventListener('mousemove', function(event) {
x = event.clientX;
y = event.clientY;
if (typeof x !== 'undefined') {
bsDiv.style.left = x + "px";
bsDiv.style.top = y + "px";
}
}, false);
}
#box-shadow-div {
position: fixed;
width: 1000px;
height: 800px;
border-radius: 0%;
background-color: black;
box-shadow: 0 0 10px 10px black;
top: 49%;
left: 48.85%;
}
<div id="box-shadow-div"></div>
The example you have about using the mouse position is interesting... But it is not what you need to achieve what you described.
In fact... What you need to know is the "ratio" between the div wrapping the table and its scrollWidth
Then, using the X position of the mouse, you can apply a scroll to the div in order to make it "move".
I used jQuery to do it using very few lines.
// Just to fake a big table
var fakeCell = $("<td>Some data</td>");
for(i=0;i<100;i++){
var fakeRow = $("<tr>");
for(k=0;k<50;k++){
fakeRow.append(fakeCell.clone().append(" "+k));
}
$("#test").append(fakeRow.clone());
}
// ---------------------------------------------------
// Calculate the "ratio" of the box-div width versus its scrollable width
var ratio = $("#box-div")[0].scrollWidth / $("#box-div").width();
console.log("Ratio: "+ratio);
// Scroll left/rigth based on mouse movement
$(window).on("mousemove", function(e){
var X = ratio * e.pageX;
// Scroll the div using the mouse position multiplyed by the ratio
$("#box-div").scrollLeft(X);
});
td{
white-space: nowrap;
border: 1px solid black;
}
#box-div{
overflow:auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="box-div">
<table id="test">
</table>
</div>
</body>
So while the user moves the mouse over the div's width, you apply a scroll multiplied by the ratio... The effect is the user can scroll it all from the most left to most right ends easilly.
How about this?
wrap a table in div (i.e. parent-div) which is relatively positioned
Give position absolute to the target div.
And change left & top position of target div on mousemove event.
window.onload = function() {
var bsDiv = document.getElementById("box-shadow-div");
var x, y;
// On mousemove use event.clientX and event.clientY to set the location of the div to the location of the cursor:
window.addEventListener('mousemove', function(event) {
x = event.clientX;
y = event.clientY;
if (typeof x !== 'undefined') {
bsDiv.style.left = -x + "px";
bsDiv.style.top = -y + "px";
}
}, false);
}
.parent-div {
position: relative;
}
#box-shadow-div {
position: absolute;
width: 1000px;
height: 800px;
border-radius: 0%;
background-color: black;
box-shadow: 0 0 10px 10px black;
top: 0;
left: 0;
}
<div class="parent-div">
<div id="box-shadow-div"></div>
</div>
Have you tried changing x to -x? this will technically "invert" the effect.
window.onload = function() {
var bsDiv = document.getElementById("box-shadow-div");
var x, y;
// On mousemove use event.clientX and event.clientY to set the location of the div to the location of the cursor:
window.addEventListener('mousemove', function(event) {
x = event.clientX;
y = event.clientY;
if (typeof x !== 'undefined') {
bsDiv.style.left = -x + "px";
bsDiv.style.top = -y + "px";
}
}, false);
}
#box-shadow-div {
position: fixed;
width: 1000px;
height: 800px;
border-radius: 0%;
background-color: black;
box-shadow: 0 0 10px 10px black;
top: 49%;
left: 48.85%;
}
<div id="box-shadow-div"></div>

How do I make an image move when i scroll down?

Here is an example of what i want to achieve:
https://www.flambette.com/en/
I have tried to change the css properties of images but that effect does not satisfy my needs.
I have tried the following code:
mydocument.on('scroll',function() {
if (mydocument.scrollTop() > 10 && mydocument.scrollTop() < 200 ) {
$('#first').css('top', '320px');
$('#first').css('left', '215px');
$('#first').css('transition', '0.5s');
}
else {
$('#first').css('top', '300px');
$('#first').css('left', '200px');
$('#first').css('transition', '0.5s');
}
});
This is supposed to move an image when you scroll between 10 and 200 px.
var container = document.getElementById('container');
var windowHeight = window.innerHeight;
var windowWidth = window.innerWidth;
var scrollArea = 1000 - windowHeight;
var square1 = document.getElementsByClassName('square')[0];
var square2 = document.getElementsByClassName('square')[1];
// update position of square 1 and square 2 when scroll event fires.
window.addEventListener('scroll', function() {
var scrollTop = window.pageYOffset || window.scrollTop;
var scrollPercent = scrollTop/scrollArea || 0;
square1.style.left = scrollPercent*window.innerWidth + 'px';
square2.style.left = 800 - scrollPercent*window.innerWidth*0.6 + 'px';
});
body {
overflow-x: hidden;
}
.container {
width: 100%;
height: 1000px;
}
.square {
position: absolute;
}
.square-1 {
width: 100px;
height: 100px;
background: red;
top: 600px;
}
.square-2 {
width: 120px;
height: 120px;
background: black;
left: 800px;
top: 800px;
}
<div class="container" id="container">
<div class="square square-1"></div>
<div class="square square-2"></div>
</div>
Hope to help you.
Here you can see more examples about movable elements and scroll events.

Why is clientX reset to 0 on last drag-event and how to solve it?

I'm trying to drag elements along a line. They should push each other, not cross over or under.
To avoid having a shady element float around on drag, I drag a sub-div which then affects the position of the outer one. Works fine except when you release the mouse which triggers the last drag-event with clientX equal to 0 (see CodePen)!
var b = document.querySelector('.box');
var bi = document.querySelector('.box-inner');
var b2 = document.querySelector('.box2');
bi.addEventListener('dragstart', function() {
console.log("dragstart")
}, false);
bi.addEventListener('drag', function(event) {
const bLeft = event.clientX;
const b2Left = b2.offsetLeft;
b.style.left = bLeft + "px";
if (b2Left - 50 <= bLeft) {
b2.style.left = (bLeft + 50) + "px";
}
console.log("drag", event.clientX, event.target.offsetParent.offsetLeft, b2.offsetLeft);
}, false);
bi.addEventListener('dragend', function() {
console.log("dragend")
}, false);
.box {
width: 50px;
height: 50px;
background-color: hotpink;
position: absolute;
top: 0;
left: 0;
}
.box-inner {
width: 100%;
height: 100%;
}
.box2 {
width: 50px;
height: 50px;
background-color: rebeccapurple;
position: absolute;
left: 200px;
top: 0;
}
<div class="box">
<div class="box-inner" draggable="true"></div>
</div>
<div class="box2"></div>
Why is this and what can I do to avoid resetting it?
By default, data/elements cannot be dropped in other elements. To allow a drop, you must prevent the default handling of the element when dragover.
document.addEventListener("dragover", function(event) {
// prevent default to allow drop
event.preventDefault();
}, false);
I just ignore the last event. I don't know why it emits.
// in `drag` event handler
if (event.screenX === 0) {
return;
}
Notice you should use screenX here. When the user zoom in the page, clientX would be a positive value but not zero.

Auto scroll div based on mouse position

I want to automatically scroll a div based on mouse position using jQuery.
If you see this fiddle here, you can see a number of images that are horizontally ordered in a div that is scrollable:
<div id="parent">
<div id="propertyThumbnails">
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
</div>
</div>
CSS:
#parent {
height: 300px;
width: 100%;
background: #ddd;
}
#propertyThumbnails {
background: #666;
height: 80px;
white-space: nowrap;
overflow: scroll;
}
#propertyThumbnails img {
width: 125px;
height: 80px;
display: inline-block;
margin: 3px;
margin-right: 0;
opacity: 0.6;
}
I found out that you can use $("#container").scrollLeft(position) to set the position of the scroller but I want to do it based on the mouse position of the parent. So that when the mouse is fully to the right hand side, the right most image displays, and when the mouse is fully left, the left most image displays.
How can I do this?
A slightly different way to achieve what you need:
jQuery(function($) {
$(window).load(function() {
var $gal = $("#propertyThumbnails"),
galW = $gal.outerWidth(true),
galSW = $gal[0].scrollWidth,
wDiff = (galSW / galW) - 1, // widths difference ratio
mPadd = 60, // Mousemove Padding
damp = 20, // Mousemove response softness
mX = 0, // Real mouse position
mX2 = 0, // Modified mouse position
posX = 0,
mmAA = galW - (mPadd * 2), // The mousemove available area
mmAAr = (galW / mmAA); // get available mousemove fidderence ratio
$gal.mousemove(function(e) {
mX = e.pageX - $(this).offset().left;
mX2 = Math.min(Math.max(0, mX - mPadd), mmAA) * mmAAr;
});
setInterval(function() {
posX += (mX2 - posX) / damp; // zeno's paradox equation "catching delay"
$gal.scrollLeft(posX * wDiff);
}, 10);
});
});
#parent {
position: relative;
margin: 0 auto;
width: 60%;
height: 260px;
}
#propertyThumbnails {
position: relative;
overflow: hidden;
background: #444;
width: 100%;
height: 262px;
white-space: nowrap;
}
#propertyThumbnails img {
vertical-align: middle;
height: 100%;
display: inline;
margin-left: -4px;
}
<div id="parent">
<div id="propertyThumbnails">
<img src="//placehold.it/600x400/0bf" />
<img src="//placehold.it/600x400/f0b" />
<img src="//placehold.it/600x400/0fb" />
<img src="//placehold.it/600x400/b0f" />
<img src="//placehold.it/600x400/bf0" />
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
where mPadd is the area (in PX, at the left and right border zone) without any sensitivity to prevent user frustrations :)
this should at least get you headed in the right direction.
var parent = $('#parent');
var img = $('img:first-child');
parent.on('mousemove', function(e) {
mouseX = e.pageX
img.css('margin-left',-mouseX/parent.width()*100);
});
http://jsfiddle.net/xWcXt/4/

Categories