I am doing a drag and drop function in javascript.
I already have the drag and drop working, but I have a question about the cursor's position. When I click on the object, instead of staying in the center of the object, the cursor automatically flies to the left corner of the object. I can still drag it, but I'm dragging it from the corner, not the middle.
The thing is, I don't know how to use Jquery, I'm learning basic javascript. I've tried googling, but things are all for more advanced projects.
This is how I am doing the drag and drop:
thing.on("pressmove", function (evt) {
console.log("mouse down");
evt.currentTarget.x = evt.stageX;
evt.currentTarget.y = evt.stageY;
stage.update();
});
thing.on("pressup", function (evt) {
console.log("mouse up");
});
Thank you for your time.
Related
I have managed to implement a simple JavaScript dragging effect to create "panel windows" inside a webpage, in which I can drag the object from any corner or position. I have only used the onmousedown (to indicate a possible dragging), onmousemove (to perform dragging) and onmouseup (to stop dragging) events.
It works well except when I drag the object too near an edge and move the mouse even at a normal speed. When I move the mouse towards an area outside the object, the dragging fails until I move again to the object's area, and I have to click the object to stop dragging it.
It's like the mouse is too fast, but obviously it doesn't happen in native application windows because they are better implemented.
What checks could I add to my current code so it doesn't fail as much? It currently seems to support a little bit of this problem by somehow handling the onmouseout event, but when it happens the window shakes to return the mouse pointer to the object area, and it doesn't look so good.
JavaScript Simple Dragging Effect
<!doctype html>
<html>
<head>
<title>JavaScript Simple Dragging Effect</title>
<style type="text/css">
.moveableRect {
position:absolute;
width:320px;
height:200px;
background-color:rgba(254, 220, 186, 0.8);
}
</style>
</head>
<body bgcolor="#abcdef">
<span id="span0000" class="moveableRect"><b>Drag Me<hr /></b></span>
<textarea id="txt" cols="40" rows="12"></textarea>
<script>
//Custom variable to indicate that we
//must drag the SPAN:
///
document.getElementById("span0000").myDragFlag = false;
//When we click and hold the mouse down,
//we must activate the dragging process:
///
document.getElementById("span0000").onmousedown = function(e)
{
if(e.button==0)
{
//This is the part of the trick that allows us
//to drag the object from any starting position
//that we click on it:
///
this.startX=(e.pageX-this.offsetLeft);
this.startY=(e.pageY-this.offsetTop);
//This flag indicates that we must drag
//when moving the mouse while the button is pressed:
///
this.myDragFlag=true;
}
};
//When we move the mouse, we must follow
//the mouse cursor around:
///
document.getElementById("span0000").onmousemove = function(e)
{
var bcr=this.getBoundingClientRect();
if(this.myDragFlag)
{
//When we start dragging (moving the mouse
//while the mouse button is pressed)
//we will perform the effect of dragging from any
//initial position in the rectangle:
///
this.style.left = (e.pageX-this.startX)+"px";
this.style.top = (e.pageY-this.startY)+"px";
document.getElementById("txt").value=
"getBoundingClientRect.left="+bcr.left+"\n"+
"getBoundingClientRect.top="+bcr.top+"\n"+
"getBoundingClientRect.width="+bcr.width+"\n"+
"getBoundingClientRect.height="+bcr.height+"\n"+
"getBoundingClientRect.bottom="+bcr.bottom+"\n"+
"getBoundingClientRect.right="+bcr.right+"\n"+
"e.pageX="+e.pageX+"\n"+
"e.pageY="+e.pageY+"\n"+
"this.offsetLeft="+this.offsetLeft+"\n"+
"this.offsetTop="+this.offsetTop+"\n"+
"relatX="+(e.pageX-this.offsetLeft)+"\n"+
"relatY="+(e.pageY-this.offsetTop);
}
};
//When we release the mouse button,
//we must finish the dragging process:
///
document.getElementById("span0000").onmouseup = function(e)
{
if(e.button==0)
this.myDragFlag=false;
};
document.getElementById("span0000").onmouseout = function(e)
{
if(this.myDragFlag==true)
{
//In this code, we basically check that
//when the mouse slips out from the object
//area while we are still dragging, we will
//force moving the object back under the mouse
//pointer. Here we will check from a logical
//edge of 48 pixels, and we will move the object
//back to 90% within those pixels, vertically and/or
//horizontally. It makes look the object shaky
//but at least it is minimally functional:
///
var minEdge=48;
var edgeCorrect=0.90;
var minEdgeCorrect=(minEdge*edgeCorrect)|0;
var bcr=this.getBoundingClientRect();
var bcrw=bcr.width;
var bcrh=bcr.height;
if(this.startX<minEdge)
{
this.style.left = (e.pageX-minEdgeCorrect)+"px";
}
else if(this.startX>bcrw-minEdge)
{
this.style.left = (e.pageX-this.startX+minEdgeCorrect)+"px";
}
if(this.startY<minEdge)
{
this.style.top = (e.pageY-minEdgeCorrect)+"px";
}
else if(this.startY>bcrh-minEdge)
{
this.style.top = (e.pageY-this.startY+minEdgeCorrect)+"px";
}
}
};
</script>
</body>
</html>
Your event listener for onmousemove is placed on the draggable div. So if the mouse goes off of it, the event stops firing. And it goes off while dragging because it fires mousemove events at intervals instead of every pixel.
To fix it, put the mousemove listener on the container.
document.body.onmousemove
And you will probably need to change how you get the coordinates.
There are other ways too I imagine. But that's the easiest.
Edit
Started to doubt myself when I tried to fiddle this but eventually got it working:
http://jsfiddle.net/tg33u8mv/3/
document.body.onmousemove = function (e) {
if (myDragFlag) {
var draggable = document.getElementById("span0000");
var bcr = draggable.getBoundingClientRect();
draggable.style.left = (e.pageX - draggable.startX) + "px";
draggable.style.top = (e.pageY - draggable.startY) + "px";
}
};
And I changed myDragFlag to a scoped variable instead of this.myDragFlag.
Bonus
In this version I add a class when it is dragging. http://jsfiddle.net/tg33u8mv/4/
The CSS for this class currently disables highlighting, significantly improving the look. You could also make it change color or add a shadow for a nice effect.
Im just wondering whether its possible to drag images/elements (whether inside a div or not) where the image/element is dragged to the far left and comes in from the right side of the screen - therefore dragging the image/element left to get the same result, or vice versa.
Similar to the google maps (on zoom level 1) the user can continuously drag the image left or right, and those images are on a continuous loop.
If so, what languages would you recommend using? javascript?
I hope this makes sense.
Many thanks
This is certainly possible using Javascript. Just have two copies of the image, and as you slide the images left, move the second copy to the right side. (Or vice versa if sliding right).
You can add event handlers to any element, including your images, that execute code while dragging. I apologize for not providing a complete working solution, I am pressed for time, I hope this helps as a starting point
var myGlobals = {
state: {
dragging: false;
}
};
$('.carouselImg').on('mousedown', function(e){
myGlobals.state.dragging = true;
});
$(window).on('mouseup', function(e){
// stop movement even if mouseup happens somewhere outside the carousel
myGlobals.state.dragging = false;
});
$(window).on('mousemove', function(e){
// allow user to drag beyond confines of the carousel
if(myGlobals.state.dragging == true){
recalculateCarouselPosition(e);
}
});
function recalculateCarouselPosition(e){
// These fun bits are left as an exercise for the reader
// the event variable `e` gives you the pixel coordinates where the mouse is
// You will have to do some math to determine what you need to do after this drag.
// You may want to store the coordinates of the initial click in
// `myGlobals.dragStart.x, .y` or similar so you can easily compare them
// You will probably set a negative CSS margin-left property on some element
// of your carousel.
// The carousel will probably have overflow:hidden.
// You will also have to manipulate the DOM, by adding a duplicate image to the
// opposite end and deleting the duplicates once they have scrolled out of view
};
on the http://www.associationtsunami.org/ site if i make a mousedown on the document the cube rotates depending on the direction the user moves the mouse.
the code is:
key code ...
).bind('mousedown touchstart', function (evt) {
delete mouse.last;
if ($(evt.target).is('a, iframe')) {
return true;
}
evt.originalEvent.touches ? evt = evt.originalEvent.touches[0] : null;
mouse.start.x = evt.pageX;
mouse.start.y = evt.pageY;
$(document).bind('mousemove touchmove', function (event) {
dragging = 1;
// Only perform rotation if one touch or mouse (e.g. still scale with pinch and zoom)
if (!touch || !(event.originalEvent && event.originalEvent.touches.length > 1)) {
event.preventDefault();
// Get touch co-ords
event.originalEvent.touches ? event = event.originalEvent.touches[0] : null;
$('.viewport').trigger('move-viewport', { x: event.pageX, y: event.pageY });
}
});
$(document).bind('mouseup touchend', function () {
dragging = 0;
$(document).unbind('mousemove touchmove');
});
});
full code https://github.com/AssociationTsunami/tsunami/blob/gh-pages/js/cube.js#L72
i would like to disable this event if a user makes the mousedown on a scrollbar - for example on the 'ONSONPARLA' page there is a TAB with ACCORDIONS, if you open any of the accordion content you get a scrollbar on the edge or within the accordion and if you try to move the scrollbar, this also moves the cube.
what is the correct way to overwrite this in the cube.js so that the cube does not turn if the event is on a scrollbar element?
It can't be done in such manner.
But there is an alternative solution. Use some custom scroll bar plugin to replace classic scroll bar. You will be able to prevent events on him. I understand this is not an excellent solution, but according to you web page you like to take a chance. :)
Here you can find few good plugins.
Good plugin example is here.
how can get x,y when mousedown in image and then mouse move in the image and then mouseup get x,y
(2 x,y 1-x,y when mouse down 2-x,y when mouse up)
all the event in the one image.
and language jquery
this my code by this not working(image stick to mouse and only mouse_d called)
var mx1;
var my1;
$("document").ready(function ()
{
$("img#ground").bind("mousedown",mouse_d);
$("img#ground").bind("mouseup",mouse_u);
$("img#ground").bind("dragstart",mouse_d);
});
function mouse_d(event)
{
mx1=event.pageX;
my1=event.pageY;
}
function mouse_u(e)
{
mx2=e.pageX;
my2=e.pageY;
mx2=mx1-mx2;
my2=my1-my2;
}
Are you trying to achieve a drag and drop effect?
if so this is the ultimate solution:
http://jqueryui.com/demos/draggable/
when using firefox is the isNS variable true? otherwise an mouseup event isn't set.
I've been developing an Image panning tool, and after a kind member directed me to the draggable plugin for jQuery, I have most of it completed. Right now if the user drags the image (contained inside a div of about 300px by 300px), the image will first flicker, then pan. This problems seems to occur after a mouse down event, on the mouse move event. The image will shift into one of the four corners on mouse move, and moving to certain areas will cause another shift. I haven't been able to find anything through google, and I'm relatively new to jQuery still.
I've uploaded the code here, in case my description is too vague:
http://www.studentgroups.ucla.edu/csa/test/zoom.htm
Any ideas or advice is greatly appreciated!
For one, you've made the image draggable both via the jQuery plugin, and your own code. Your code is changing the background-position of the div, and the jQuery plugin is changing the div's actual position. That's bound to cause some problems.
Also, Draggable's containment parameter seems to be designed for draggable items who are smaller than their parent container, not ones who are bigger, like you're trying to do.
Anyways, here's the working code:
$(document).ready(function() {
$(".draggable").draggable().bind('dragstop', function(e, ui) {
if (ui.position.top > 0) {
$(this).css('top', 0);
}
if (ui.position.left > 0) {
$(this).css('left', 0);
}
var bottom = -($(this).height() - $(this).parent().height()),
right = -($(this).width() - $(this).parent().width());
if (ui.position.top < bottom) {
$(this).css('top', bottom);
}
if (ui.position.left < right) {
$(this).css('left', right);
}
});
});
If you don't need edge-snapping, you can get rid of the .bind() function, and just call .draggable().
$(document).ready(function() {
$(".draggable").draggable();
});