AngularJS - draggable bootstrap modal - javascript

I am using an AngularJS directive for modals, to make them draggable.
This is the directive.
In the demo, you can clearly see that if you drag it (especially left and right) it is slower than your mouse. I understand why this happens (the JavaScript calculates position relative to it's starting position, so in my 1920x1080 screen it goes from -1200px to 1920px on the x axis). And I understand there is a need to use offset instead of position, but after many tries I failed to make it that.
This is the relevant JavaScript code:
element.on('mousedown', function (event) {
// Prevent default dragging of selected content
event.preventDefault();
startX = event.screenX - x;
startY = event.screenY - y;
$document.on('mousemove', function mousemove(event) {
y = event.screenY - startY;
x = event.screenX - startX;
element.css({
top: y + 'px',
left: x + 'px'
});
});
});
How can I make it rely on the offset and move together with the mouse and not slower?

Try this one: http://plnkr.co/edit/QxIdGj . I have hardcoded 2 values, which you shouldn't do. Your "mistake" was that you were putting the draggable directive in the wrong element. I added the draggable directive to <div class="modal-content"> which is what I believe is the element that you want moved.
I also changed your element.css({ to
element.css({
top: event.clientY - 30 + 'px',
left: event.clientX - 10 + 'px'
});
It's using .clientX/Y which is the actual position of the mouse, without the need of further calculations.

Related

Right click javascript context menu appears in wrong place

I have a very simple right click context menu in javascript using jquery, implemented using some ul elments.
The menu appears but always in the wrong place on the page. I have tried using offsets etc when setting the X and Y but it always appears out of place.
The blue square is where the right click took place but the menu appears below and right:
This is my snippet:
timelineRef.on('contextmenu', function(props) {
props.event.preventDefault();
var e = props.event;
var x = e.pageX;
var y = e.pageY;
// var x = e.pageX - e.currentTarget.offsetWidth;
// var y = e.pageY - e.currentTarget.offsetHeight;
// var y = e.clientY - e.currentTarget.offsetTop;
// var x = e.clientX - e.currentTarget.offsetLeft;
console.log(x);
console.log(y);
// Show contextmenu in the right position (the mouse)
$wnd.jQuery('#custom-menu-id').finish().toggle(100).css({
//position: "absolute",
top: y + "px",
left: x + "px"
}).addClass("show");
});
The HTML is like this:
<ul class="{style.custom-menu}" id="custom-menu-id">
<li data-action="abc">Edit</li>
<li data-action="ayz">Select All</li>
</ul>
As you see I have tried many variations of setting x and y. I have the feeling it has to do with where the ul is in the page. It has many parents. If I make a simple jfiddle it works ok but then inside this complicated layout it doesn't.
Any help would be great.
Thanks
Old problem, but for me it was because of a relative position of a div.

Change position of div based on mouse pointer

I am trying to position a div based on mouse position, I managed to get it to work 50%.
The problem is that DIV always seems to be much lower than the actual mouse position, I try to minus the offset, no luck.
Basically what I want is to float the div(the NEXT link in jsfiddle) vertically, but the DIV should not be able to go outside of the container it is in(the div that has the image in the jsfiddle)
here is the jsfiddle: http://jsfiddle.net/LYmVH/7/
below is the JS, which is also in the jsfiddle:
$('.post-single-content').mousemove(function(e){
var height=e.pageY,
height1 =$('.content-top').height();
$('.btnNext').css({top: (e.pageY + 50) + "px"});
});
You need measure against the top of the parent element since it's absolutely positioned in it.
Try changing your JS to:
$('.post-single-content').mousemove(function(e){
var top = (e.pageY - $(this).offset().top) + 'px';
$('.btnNext').css({ top: top });
});
Upon reading some comments lemme update, by making use some basic math and create "collision". Somthing like:
$('.post-single-content').mousemove(function(e){
var y = e.pageY, // mouse y axis position
tHeight = $(this).height(), // container height
bHeight = $('.btnNext').height(), // button height
oTop = $(this).offset().top, // offset top position of container
abBot = tHeight - $('.btnNext').height(), // absolute top of button when at bottom
bHalf = bHeight / 2, // half button height
top = y - oTop - bHalf, // initial top pos of button
bot = y - oTop + bHalf; // bottom of button while moving
if (top < 0) top = 0; // ensure button doesn't go to far north
else if (bot > tHeight) top = abBot; // ensure it cant go past south
$('.btnNext').css({ top: top }); // 'px' not neccesary
});
jsFiddle

Why is dragging with css translate jumping?

I am trying to drag a container using transform translate but something is causing a jumpy behavior and I can't figure out what is the cause.
UPDATE: This must work on elements when their container is not always positioned at 0,0 from the document.
http://jsfiddle.net/dML5t/2/
HTML:
<div id=container style="position:absolute;left:50px;top:50px;width:500px;height:500px;background-color:red;">
<div id=tcontainer style="position:relative;left:50px;top:50px;width:400px;height:400px;background-color:green;">
<div id=move style="position:relative;left:20px;top:20px;height:150px;width:150px;background-color:lightgray;">
</div>
</div>
Javascript:
obj = {startPositionX:0,startPositionY:0};
$('#move').on("mousedown",function(){
var move = $(this);
obj.startPositionX=event.offsetX+$('#tcontainer').offset().left;
obj.startPositionY=event.offsetY+$('#tcontainer').offset().top;
$(document).on("mousemove",function(e){
console.log("dragging", e.pageX-obj.startPositionX, e.pageY-obj.startPositionY);
move.css('transform','translate('+(e.pageX-obj.startPositionX)+'px, '+(e.pageY-obj.startPositionY)+'px)');
});
});
$(document).on("mouseup",function(){
$(this).off("mousemove");
});
OffsetX and OffsetY may give you cursor pos relative to an element which is hovered now. You saved initial coordinates in mousedown. When mousemove was triggered your this coordinates changed a little, so when you subtract one from initials you got zeros (or 1px of difference) and your div went to top left corner. After it happaned your cursor hovered body element and in mousemove you get coordinates related to body. So when you subtract your zeros from the new coordinates you get real coordinates and your div go to the right place. Then you will get coordinates related to dragging div and will get zeros again, then real coords and so on.
Use pageX and pageY instead! fiddle
$('.move').on("mousedown",function(me){
var move = $(this);
var lastOffset = move.data('lastTransform');
var lastOffsetX = lastOffset ? lastOffset.dx : 0,
lastOffsetY = lastOffset ? lastOffset.dy : 0;
var startX = me.pageX - lastOffsetX, startY = me.pageY - lastOffsetY;
$(document).on("mousemove",function(e){
var newDx = e.pageX - startX,
newDy = e.pageY - startY;
console.log("dragging", e.pageX-startX, e.pageY-startY);
move.css('transform','translate(' + newDx + 'px, ' + newDy + 'px)');
// we need to save last made offset
move.data('lastTransform', {dx: newDx, dy: newDy });
});
});
$(document).on("mouseup",function(){
$(this).off("mousemove");
});
You need save original coords of your div (move.offset()) and use mouse offset (e.pageX-startX, e.pageY-startY) to get new coords.

Get mouse position within div? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Mouse position relative to div
getting mouse position with javascript within canvas
How can I get the position of the mouse within a canvas that is a fixed size but has an automatic margin?
I can't make its position fixed and can't just use the regular mouse position on the page.
This code works perfectly:
mouseX = e.pageX - div.offsetLeft;
mouseY = e.pageY - div.offsetTop;
Using jQuery:
var divPos = {};
var offset = $("#divid").offset();
$(document).mousemove(function(e){
divPos = {
left: e.pageX - offset.left,
top: e.pageY - offset.top
};
});
Use event.layerX and event.layerY to get mouse position relative to the current element:
$('#canvas').mousemove(function(e){
var mousePos = {'x': e.layerX, 'y': e.layerY};
});
Taken from jQuery site: Jquery Tutorial site
$(document).mousemove(function(e){
$('#status').html(e.pageX +', '+ e.pageY);
});
NOTE: fixed syntax

Scroll div on iPhone from anywhere on screen

I'd like to prevent the default scrolling action on my page on an iPhone with the exception of a single div. Basically, when someone swipes their finger across the screen--anywhere on the screen--this single div ought to move. The code I'm using works fine when someone is directly touching the div element, but otherwise the position of the div is pretty erratic. Where am I messing up? This is a loose modification of what I found in the Safari Developer Library.
<div id="testdiv">
test test test test
</div>
<script type="text/javascript">
var startY = document.getElementById("testdiv").offsetTop;
var curY = startY;
var touchY;
document.addEventListener('touchstart', function(event) {
touchY = event.targetTouches[0].pageY;
}, false);
document.addEventListener('touchmove',function(event) {
event.preventDefault();
curY = event.targetTouches[0].pageY - startY - touchY;
document.getElementById("testdiv").style.webkitTransform = 'translate(0px,' + curY + 'px)';
}, false);
document.addEventListener('touchend',function(event) {
startY = curY;
}, false);
</script>
Change - startY to + startY when changing the value of curY. The problem was not that it only worked when you touched the div. The value of ...pageY - touchY will be the distance the touch has moved since it was first recorded. If the previous offset was 50 pixels and it was moved 20 pixels down, then you want the new offset to be 20 + 50, not 20 − 50. You didn't notice the problem on the first touch because the initial value of startY is close to 0. In fact, the initial value of startY should be 0, and not the offsetTop of the div, since the translation will be applied relative to the starting offset.

Categories

Resources