I'm trying to move a div with the movement of the mouse cursor, but can't understand how to get the newly updated mouse position within my timeout. Maybe there is a simpler way.
var t;
$(document).ready(function(){
$("body").on("mousedown", ".heading", function (e) {
$("body").data("header_click", true);
if ($("body").data("header_click")) {
var container = $("#dialog");
container.css("position", "absolute");
t = setInterval(function(){
//some way to get mouse position
var pos = container.position();
container.css({
top: "",//set based on mouse position
left: "",//set based on mouse position
});
}, 100);
}else{
document.clearInterval(t);
}
});
});
$("body").on("mousedown", ".heading", function (e) {
$("body").data("header_click", false);
});
The solution found here did not work for me.
You will need to bind to the mouse move event and update a document variable.
var currentMousePos = { x: -1, y: -1 };
$(document).on('mousemove', function(event) {
currentMousePos.x = event.pageX;
currentMousePos.y = event.pageY;
});
Then use those positions relative to the absolute positions of the element you are wanting to drag to calculate and update the elements new position.
$(document).ready(function(){
$("body").on("mousedown", ".heading", function (e) {
$("body").data("header_click", true);
if ($("body").data("header_click")) {
var container = $("#dialog");
container.css("position", "absolute");
var containerPos = container.pos();
var mouseTopOffset = containerPos.top - currentMousePos.y;
var mouseLeftOffset = containerPos.left - currentMousePos.x;
container.css("left", mouseTopOffset +"px");
container.css("top", mouseLeftOffset +"px");
}
}
}
I havent really tested this but in theory should do what you need.
Related
I'm trying to create some "flick" like functionality. Instead of just dragging an item across the screen, I'd like to drag and throw/release it to a location. Any idea how to accomplish this?
Sorry I don't have any code snippets here...but I just don't know where to even start.
Thanks!
--moe
You can use the mousedown, mousemove and mouseup event handlers to get the mouse events with the cursor positions at which they happened. You'd need to store the current cursor position (startCursorPos) and the element position (startElementPos) at mousedown. At each mousemove event, you can calculate the difference between the current cursor position and startCursorPos, and add the result to startElementPos, and use the result as new element position. This will implement a basic drag-and-drop behaviour.
To get the flinging, you need to also record the current time at mousedown and mouseup. Combined with the positions, you'll be able to calculate the movement speed, and use this at mouseup to continue the movement for some time (e.g. using setInterval).
var foo=document.getElementById("foo");
var isMoving, startCursorPos, startElementPos, startTime, newPos;
function Point(x,y) {
this.x=x; this.y=y;
}
Point.fromElement=function(el) {
return new Point(parseInt(el.style.left), parseInt(el.style.top));
}
Point.sum = function(a,b) {
return new Point(a.x+b.x, a.y+b.y);
}
Point.difference = function(a,b) {
return new Point(a.x-b.x, a.y-b.y);
}
Point.prototype.multiply = function(factor) {
return new Point(this.x*factor, this.y*factor);
}
Point.prototype.distance = function() {
return Math.sqrt(this.x*this.x + this.y*this.y);
}
Point.prototype.toString = function() {
return this.x + "x" + this.y;
}
Point.prototype.moveElement = function(el) {
el.style.left = this.x + "px"; el.style.top = this.y + "px";
}
foo.addEventListener("mousedown", function(e) {
startCursorPos = new Point(e.pageX, e.pageY);
startElementPos = Point.fromElement(foo);
startTime = +new Date();
isMoving=true;
},false);
window.addEventListener("mousemove", function(e) {
if (isMoving) {
var cursorpos = new Point(e.pageX, e.pageY);
newPos = Point.sum(startElementPos, Point.difference(cursorpos, startCursorPos));
//console.log(startElementPos, cursorpos, newPos);
newPos.moveElement(foo);
}
},false);
window.addEventListener("mouseup", function(e) {
if (isMoving) {
isMoving=false;
var cursorpos = new Point(e.pageX, e.pageY);
var interval = +new Date() - startTime;
var movement = Point.difference(cursorpos, startCursorPos).multiply(1/interval);
var speed = movement.distance();
console.log(interval, speed, ""+movement);
moveOn(newPos, movement, speed);
}
},false);
function moveOn(startPos, movement, speed) {
startPos = Point.sum(startPos, movement.multiply(speed*200))
startPos.moveElement(foo);
if (speed > 10)
setTimeout(function() {
moveOn(startPos, movement, speed/2);
}, 100);
}
#foo { position:absolute; width:50px;height:50px; background:magenta; }
<div id="foo" style="top:50px; left:50px;"></div>
How to delete svg when I click on it? I am using the lib snapsvg. I have plunkered my issue.
The use case is as follows : when user clicks on the svg, I create a circle at the position the user clicked, and if the user clicks on a circle that has been created, I want to delete the circle. I have a strange behavior because the circle is moved but not deleted.
(function() {
var s = Snap("#svg");
s.rect(10, 10, 400, 400);
s.click(handleClick);
function handleClick(event) {
var e = event.target;
var dim = e.getBoundingClientRect();
var x = event.clientX - dim.left;
var y = event.clientY - dim.top;
var c = this.circle(x, y, 10);
c.attr({
fill: '#FFF'
})
c.click(function() {
console.log('click circle');
this.remove();
});
}
})();
I managed to find the solution, the element was not moving, actually it was removed but an other was created. To solve my issue I have just added event.stopPropagation(); inside c.click function :
c.click(function(event) {
console.log('click circle');
this.remove();
event.stopPropagation();
});
When the content goes outside the div, we use scrollbars to see it. How can I scroll the div content by grabbing and dragging its background? I've searched the solution but did not find what I need. Here is my fiddle:
https://jsfiddle.net/vaxobasilidze/xhn49e1j/
Drag any item to the right div and move it outside the container to the right or bottom. scrollbars appear to help you to scroll. Here is an example of what I want to achieve. See the first diagram on the link and drag it:
https://jsplumbtoolkit.com/
Any tips on how to do this?
You should just need to detect when the mouse is down and then when the mouse is moving afterwards you can store the previous mouse coordinates and reference the current coordinates. Finally you can scroll the div in question by an amount based on the difference in drag since the last mousemove call.
var mouseDown = false;
var prevCoords = { x: 0, y: 0 };
$("#mainDiv").mousedown(function() {
mouseDown = true;
}).mousemove(function(e) {
var currentScrollX = $('#mainDiv').scrollLeft();
var currentScrollY = $('#mainDiv').scrollTop();
if(mouseDown) {
$('#mainDiv').scrollLeft(currentScrollX + prevCoords.x - (e.clientX + currentScrollX))
$('#mainDiv').scrollTop(currentScrollY + prevCoords.y - e.clientY)
};
prevCoords.x = e.clientX + currentScrollX;
prevCoords.y = e.clientY;
}).mouseup(function() {
mouseDown = false;
});
https://jsfiddle.net/6rx30muh/
EDIT: Fixed bug with wiggling tables when dragging:
var mouseDown = false;
var prevCoords = { x: 0, y: 0 };
$("#mainDiv").mousedown(function() {
mouseDown = true;
}).mousemove(function(e) {
var currentScrollX = $('#mainDiv').scrollLeft();
var currentScrollY = $('#mainDiv').scrollTop();
if(mouseDown) {
$('#mainDiv').scrollLeft(currentScrollX + prevCoords.x - e.clientX)
$('#mainDiv').scrollTop(currentScrollY + prevCoords.y - e.clientY)
};
prevCoords.x = e.clientX;
prevCoords.y = e.clientY;
}).mouseup(function() {
mouseDown = false;
});
Check for mousemove between mousedown and mouseup on the body element is a good place to start.
element = $('body');
element.addEventListener("mousedown", function(){
flag = 0;
}, false);
element.addEventListener("mousemove", function(){
flag = 1;
}, false);
element.addEventListener("mouseup", function(){
if(flag === 0){
console.log("click");
}
else if(flag === 1){
console.log("drag");
}
}, false);
I'm trying to scroll an image by dragging my cursor. I'm using the Draggable jQuery library but I'm having a problem.
I need to determine the limit of the image so that I can block the drag to avoid showing white space.
Anyone can help me with that?
jsfiddle
<div style="width:100%;height:100%;" id="parent">
<img src="http://cdn.wallpapersafari.com/10/37/Aim58J.jpg" id="draggable"/>
$( "#draggable" ).draggable({
axis: 'x,y',
cursor: "crosshair",
});
If you need scrolling by dragging, do not use dragging. Use simple mouse move instead. Look at the example below. In this case you can scroll any content inside your container.
Hope it would help.
UPDATED:
If you need dragging of some background element, you should to drag it by mousemove and calculate visible area according to container size.
So, in few words - Drag image left till its width minus left offset is bigger than container(window) width, and so on for right, top and down offsets.
// Main script
function run() {
var $image = $('#draggable');
var $window = $(window);
var isStarted = false;
var cursorInitialPosition = {left: 0, top: 0};
var imageInitialPosition = {left: 0, top: 0};
var imageSize = {width: $image.width(), height: $image.height()};
// stop dragging
var stop = function() {
isStarted = false;
$window.unbind('mousemove', update);
};
// update image position
var update = function(event) {
// size of container (window in our case)
var containerSize = {width: $window.width(), height: $window.height()};
var left = imageInitialPosition.left + (event.pageX - cursorInitialPosition.left);
var top = imageInitialPosition.top + (event.pageY - cursorInitialPosition.top);
// don't allow dragging too left or right
if (left <= 0 && imageSize.width + left >= containerSize.width) {
$image.css('left', left);
}
// don't allow dragging too top or down
if (top <= 0 && imageSize.height + top >= containerSize.height) {
$image.css('top', top);
}
};
$window.mousedown(function(event){
var position = $image.position();
cursorInitialPosition.left = event.pageX;
cursorInitialPosition.top = event.pageY;
imageInitialPosition.left = position.left;
imageInitialPosition.top = position.top;
$(window).mousemove(update);
});
$window.mouseout(stop);
$window.mouseup(stop);
}
$(function(){
// wait for image loading because we need it size
var image = new Image;
image.onload = run;
image.src = "http://cdn.wallpapersafari.com/10/37/Aim58J.jpg";
});
https://jsfiddle.net/2hxz49bj/5/
I'm trying to make a jquery function to follow the mouse coursor with a div, when it is on mousedown and when it is on mouseup it stay in the last position it was.
any sugestion.
Why not simply use drag and drop by jquery:
<script>
$(function() {
$( "#draggable" ).draggable();
});
</script>
Jquery draggable
I've put together a simple working example that defines a Draggable object. You specify the drag item (the element that you're moving around), as well as a drag boundary (the space—or element—that you are moving the item inside of). The concept of a boundary is important if you ever want to restrict a draggable item to a certain space on the page (such as a container), or define a relative coordinate system on which to base your math.
My solution isn't the fastest, but it demonstrates the concept:
$(function() {
window.mousedown = 0;
$(window).on('mousedown mouseup', function(e) {
if(e.type == 'mousedown') { this.mousedown++; }
else { this.mousedown--; }
});
var Draggable = function(dragItem, dragBoundary) {
this.item = $(dragItem).css('position', 'absolute');
this.item.on('mousemove', $.proxy(this.handleDragEvent, this));
this.boundary = $(dragBoundary).css('position', 'relative');
};
Draggable.prototype.handleDragEvent = function(e) {
if(window.mousedown) {
var mousePosition = this.mapToBoundary([e.clientX, e.clientY]);
var mouseX = mousePosition[0],
mouseY = mousePosition[1];
if(typeof this.prevMouseX == "undefined") this.prevMouseX = mouseX;
if(typeof this.prevMouseY == "undefined") this.prevMouseY = mouseY;
this.itemX = this.item.offset().left - this.boundary.offset().left;
this.itemY = this.item.offset().top - this.boundary.offset().top;
var deltaX = mouseX - this.prevMouseX,
deltaY = mouseY - this.prevMouseY;
this.item.css({
'left': this.itemX + deltaX,
'top': this.itemY + deltaY
});
this.prevMouseX = mouseX;
this.prevMouseY = mouseY;
}
};
Draggable.prototype.mapToBoundary = function(coord) {
var x = coord[0] - this.boundary.offset().left;
var y = coord[1] - this.boundary.offset().top;
return [x,y];
};
var draggable = new Draggable($('.draggable'), $('.container'));
});
Notice that we are maintaining a mousedown value on global, allowing us to determine when it would be appropriate to drag around our element (we only add a mousemove listener to the drag item itself). I've also included a spacer div above the boundary div to demonstrate how you can move the boundary anywhere around the page and the coordinate system is still accurate. The code to actually restrict a draggable item within its assigned boundary could be written using simple math.
Here is the fiddle: http://jsfiddle.net/bTh9s/3/
EDIT:
Here is the start to some code for restricting a Draggable item within its container.
Draggable.prototype.restrictItemToBoundary = function() {
var position = this.item.position();
position.right = position.left + this.item.outerWidth();
position.bottom = position.top + this.item.outerHeight();
if(position.left <= 0) {
this.item.css('left', 1);
} else if(position.right >= this.boundary.outerWidth()) {
this.item.css('left', this.boundary.outerWidth() - this.item.outerWidth());
}
if(position.top <= 0) {
this.item.css('top', 1);
} else if(position.bottom >= this.boundary.outerHeight()) {
this.item.css('top', this.boundary.outerHeight() - this.item.outerHeight());
}
};
This method should be called inside of Draggable.handleDragEvent just after you update the CSS positioning of the drag item. It seems this solution is glitchy, but it's a start.