I want to create a drag and scroll effect:
-> mouse down
-> drag and mouse move
-> the window will scroll according to the amount of mouse move
-> mouse up
-> scroll stops
Now, the problem I have is when I drag and move, the window DOM elements will shake.
I added a offset check, it mitigates the shaking problem, however not solved.
Can anyone help me?
below is the main code and the full working jsFiddle is at: http://jsfiddle.net/mifeng/sGvA4/1/
container.mousedown(function(e) {
mouseX = e.pageX;
mouseY = e.pageY;
console.log("CON: " + conX + "," + conY);
console.log("DOWN: " + mouseX + "," + mouseY);
container.mousemove(function(e) {
//console.log("INNER-DOWN: " + mouseX + "," + mouseY);
offsetX = e.pageX - mouseX;
offsetY = e.pageY - mouseY;
// offset check
if (offsetX > 10 || offsetX < -10 || offsetY > 10 || offsetY < -10) {
conX -= offsetX;
conY -= offsetY;
window.scrollTo(conX, conY); // scrollTo
mouseX = e.pageX;
mouseY = e.pageY;
}
});
});
Here are 2 plugins that do what you're after.
http://archive.plugins.jquery.com/project/Dragscrollable
http://azoff.github.io/overscroll/
Related
What I want:
I have a div and I want to move it around the canvas but limit it to canvas width and height
What I have:
I'm using p5.dom.js library
P5js code:
let dragging = false;
let offsetX, offsetY, onsetX, onsetY;
let canvasWidth, canvasHeight;
let currentDragDiv;
function setup() {
canvasWidth = windowWidth < 400 ? 400 : windowWidth;
canvasHeight = windowHeight < 400 ? 400 : windowHeight;
canvas = createCanvas(canvasWidth, canvasHeight)
.mousePressed(createDiv);
}
function draw() {
background(200);
if(dragging){
if(mouseX + onsetX < canvasWidth && mouseX + offsetX > 0){
currentDragDiv.position(mouseX + offsetX, currentDragDiv.y);
}
if(mouseY + onsetY < canvasHeight && mouseY + offsetY > 0 ){
currentDragDiv.position(currentDragDiv.x, mouseY + offsetY);
}
}
}
function createDiv(){
let div = createDiv("")
.mousePressed(function(){ dragDiv(div); })
.mouseReleased(function(){ dropDiv(div); })
.position(mouseX, mouseY);
}
function dropDiv(){
dragging = false;
currentDragDiv = null;
}
function dragDiv(d){
currentDragDiv = d;
dragging = true;
offsetX = currentDragDiv.x - mouseX;
offsetY = currentDragDiv.y - mouseY;
onsetX = currentDragDiv.width + offsetX;
onsetY = currentDragDiv.height + offsetY;
}
The Problem:
This code is working great but if the user moves the mouse too quickly, the div doesn't go until the border of the canvas things like this happens (I dragged and moved the div very fast to the right and it stoped in the middle of screen). This problem makes the variable onsetX and onsetY goes wrong and mess up a lit bit deppending on how much the div is away from the canvas border.
Is it possible to remove this "error" and make the div go until the border of canvas?
Observations:
I removed some of the code that I think it's not necessary for this question.
The variables onsetX and onsetY are the oposite of offsetX and offsetY, it's the position of the border from the mouse position, but because english isn't my native language, I didn't know how to name the variable. Recommendations would be good.
In your current code the dragging is completely omitted, if the border of the canvas is exceeded:
if(mouseX + onsetX < canvasWidth && mouseX + offsetX > 0){
currentDragDiv.position(mouseX + offsetX, currentDragDiv.y);
}
if (mouseY + onsetY < canvasHeight && mouseY + offsetY > 0 ){
currentDragDiv.position(currentDragDiv.x, mouseY + offsetY);
}
Instead of that you have to limit the dragging to the range from 0 to canvasWidth respectively 0 to canvasHeight. This means you have to "clamp" the dragging to this range:
function draw() {
let newX, newY;
background(200);
if(dragging){
newX = mouseX + offsetX;
if ( newX > canvasWidth ) {
newX = canvasWidth - currentPostIt.width;
}
if ( newX < 0 ) {
newX = 0;
}
newY = mouseY + offsetY;
if ( newY > canvasHeight ) {
newY = canvasHeight - currentPostIt.height;
}
if ( newY < 0 ) {
newY = 0;
}
currentDragDiv.position(newX, newY);
}
}
I'm currently working on a googly eye that follows your mouse movements. I've been able to center the googly and listen for mouse movements, but I'm having trouble finding the center of the page after I've resized it.
var DrawEye = function(eyecontainer, pupil, eyeposx, eyeposy){
// Initialise core variables
var r = $(pupil).width()/2;
var center = {
x: $(eyecontainer).width()/2 - r,
y: $(eyecontainer).height()/2 - r
};
var distanceThreshold = $(eyecontainer).width()/2.2 - r;
var mouseX = 0, mouseY = 0;
// Listen for mouse movement
$(window).mousemove(function(e){
var d = {
x: e.pageX - r - eyeposx - center.x,
y: e.pageY - r - eyeposy - center.y
};
var distance = Math.sqrt(d.x*d.x + d.y*d.y);
if (distance < distanceThreshold) {
mouseX = e.pageX - eyeposx - r;
mouseY = e.pageY - eyeposy - r;
} else {
mouseX = d.x / distance * distanceThreshold + center.x;
mouseY = d.y / distance * distanceThreshold + center.y;
}
});
// Update pupil location
var pupil = $(pupil);
var xp = 0, yp = 0;
var loop = setInterval(function(){
// change 1 to alter damping/momentum - higher is slower
xp += (mouseX - xp) / 5;
yp += (mouseY - yp) / 5;
pupil.css({left:xp, top:yp});
}, 1);
};
var pariseye1 = new DrawEye("#eyeleft", "#pupilleft", 650, 300);
I'm trying to get it to follow the mouse no matter how big or small the window size is, I'm just having trouble figuring that out.
As of right now, if you resize the page the googly eye still follows the mouse, but it becomes slight ajar and doesn't quite follow the mouse exactly. It seems like where it's actually tracking the mouse stays the same.
I'm fairly new to javascript, so if anyone could help that would be great!
Thanks, James
I have a div#panel which I use to print information about parent elements relative to the element which I clicked on. This means that the div element does not have fixed width and height.
I needed to calculate position for the element div#panel which is positioned using the CSS styles left and top. My goal is to keep the div#panel on the screen, it should not go outside of the current view/screen.
My calculation looks like this:
var ClientW = jQuery(window).width();
var ClientH = jQuery(window).height();
var w = $('div#panel').width();
var h = $('div#panel').height();
var offsetY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
var offsetX = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
var y, x;
if ( e.clientY > ClientH - h )
y = offsetY + ClientH - (e.clientY-ClientH);
else
if ( e.clientY < 0 + h )
y = offsetY + e.clientY + (h-e.clientY);
else
y = e.clientY < ClientH/2 ? offsetY + e.clientY - h/2 : offsetY + ( e.clientY+h/2 > ClientH-h ? ClientH-h : e.clientY+h/2 ) ;
x = (e.clientX > ClientW - w/2 )?offsetX + ClientW-w : offsetX + e.clientX;
$('#panel').css({ left: x, top: y })
It works almost perfectly, but near the bottom of the client area, just above the bottom scrollbar (20-40px), the element does not fit on the screen. When I click too close to the bottom scrollbar so it will disappear bellow the scrollbar. How could I correct or improve the calculation for the y position?
PS: I do not need to correct x at the moment because the calculation should be similar to y ... later.
Finally I have found that the problem was in the first condition, not in the last.
if ( e.clientY > ClientH - h)
y = offsetY + e.clientY - h;
else
if ( e.clientY < 0 + h )
y = offsetY + e.clientY + (h-e.clientY);
else
y = e.clientY < ClientH/2 ? offsetY + e.clientY - h/2 : offsetY + ( e.clientY > ClientH-h? ClientH-h : e.clientY+h/2 ) ;
It should be universal solution. Very useful when you need your box fit to the current view.
I have this code on this URL:
http://emadzedan.com/otlehmobile/changeFlight.html
$(document).ready(function(){
//Fliter Interaction
var xpos = 0;
var ypos = 0;
var oldX = 0;
var oldY = 0;
var newX = 0;
var newY = 0;
$(".headerOfFilter, .filtercontentcell").bind('touchstart mousedown', function(e){
xpos = e.offsetX === undefined ? e.originalEvent.layerX : e.offsetX;
ypos = e.offsetY === undefined ? e.originalEvent.layerY : e.offsetY;
oldX = xpos;
oldY = ypos;
});
$(".headerOfFilter, .filtercontentcell").bind('touchend mouseup', function(e){
xpos = e.offsetX === undefined ? e.originalEvent.layerX : e.offsetX;
ypos = e.offsetY === undefined ? e.originalEvent.layerY : e.offsetY;
newX = xpos;
newY = ypos;
alert("insideUpNew15 " + oldX + "," + oldY + " " + newX + "," + newY);
if((oldX <= newX+20) && (oldX >= newX-20) && (oldY <= newY+20) && (oldY >= newY-20)){
//alert("insideNew15");
$(".headerOfFilter, .filtercontentcell").removeClass("blueBGWithWhiteText");
$(this).addClass("blueBGWithWhiteText");
alert("ddd3");
}
});
});
the problem is that no event is firing on android while iphone and windows is working.
the main problem is that the clicking buttons is on slider which moves so click is not accurate on slider so I made the above code to create a big area for mouse down or touch end. it used to work on android 4 and below but I upgrade my phone to android 5 and my developer upgraded to android 6 and we both can not fire the click event on the slider (I'm a web designer and front end developer)
by the way the slider I'm using is called smoothTouchScroll
http://smoothtouchscroll.com/
any body can help
just if someone else faced the same my code is working but need to remove the if statement in the mouseup event that is all.
I'm creating a website with a rotating wheel. The user should be able to rotate this wheel with dragging it with mouse. I implemented this in jQuery and it works(rotates). But it behaves as expected just between 90 degrees and 180 degrees. When it rotates more or less than this range, I see some unexpected bounces.
This is my code:
$(document).ready(function(){
var isDragging = false;
$("#box").mousemove(function(e){
if(isDragging){
e.preventDefault();
var rx = $(this).width() / 2;
var ry = $(this).height() / 2;
var px = e.clientX - $(this).offset().left - rx;
var py = e.clientY - $(this).offset().top - ry;
var a = Math.atan2(py,px) * 180 / Math.PI + 90;
if(py <= 0 && px < 0){a = 360 + a;}
$(this).css("-webkit-transform","rotate(" + a + "deg)");
}
});
$("#box").mousedown(function(){
isDragging = true;
});
$("*").mouseup(function(){
isDragging = false;
});
});
What is the problem? How to solve it?
You should check out the answer posted here.
How to make object rotate with drag, how to get a rotate point around the origin use sin or cos?
Here is the working fiddle from their answer
http://jsfiddle.net/mgibsonbr/tBgLh/11/
it involves making your html look similar to this.
<div class="draggable_wp">
<div class="el"></div>
<div class="handle"></div>
</div>
Within your if(isDragging) clause:
var element = document.getElementById("rotatable");
var mouseX = e.pageX || e.clientX + document.documentElement.scrollLeft;
var mouseY = e.pageY || e.clientY + document.documentElement.scrollTop;
var rect = element.getBoundingClientRect();
var s_rad = Math.atan2(
mouseY - rect.top - rect.height / 2,
mouseX - rect.left - rect.width / 2
);
var degree = Math.round(90 + (s_rad * (180 / (Math.PI))) / 15) * 15;
element.style.transform = 'rotate(' + degree + 'deg)';