Detect mouseMove of X pixels - javascript

I'm trying to trigger an event when the cursor position moves X amount of pixels, say 100px. So, for every 100px the cursor moves in either X or Y direction, I trigger an event. This should continue for every 100px movement.
I've successfully detected the 'current' X and Y position of the cursor, and have set a pixel threshold, but am struggling with the maths on the rest. Can anyone help?
$(window).on('mousemove', function(e){
// Vars
var cursorX = e.clientX;
var cursorY = e.clientY;
var cursorThreshold = 100;
... detect every 100px movement here...
});

You need to keep track of the old cursor positions. Then you can calculate the distance using the Pythagorean theorem:
totalDistance += Math.sqrt(Math.pow(oldCursorY - cursorY, 2) + Math.pow(oldCursorX - cursorX, 2))
This works in any direction.
Example:
Note: Unlike #wayneOS's approach (+1 from me) I do not keep track of the direction.
It's a rather minimalistic implementation.
var totalDistance = 0;
var oldCursorX, oldCursorY;
$(window).on("mousemove", function(e){
var cursorThreshold = 100;
if (oldCursorX) totalDistance += Math.sqrt(Math.pow(oldCursorY - e.clientY, 2) + Math.pow(oldCursorX - e.clientX, 2));
if (totalDistance >= cursorThreshold){
console.log("Mouse moved 100px!");
totalDistance = 0;
}
oldCursorX = e.clientX;
oldCursorY = e.clientY;
});
.d {
width: 0;
height: 0;
border-style: solid;
border-width: 100px 100px 0 0;
border-color: #e54646 transparent transparent transparent;
}
.s { display: flex; }
.p1 { margin-left: 100px; }
.p2 { margin-right: 20px; padding-top: 20px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="p1">100px X</p>
<div class="s">
<p class="p2">100px Y</p>
<div class="d"></div>
</div>

To track mouse-movement for defined steps, you just need to save the last position and than check if the cursor has moved more than the threshold in one direction. Here is an example:
// Vars
var lastCursorX = null;
var lastCursorY = null;
var cursorThreshold = 100;
$(window).on('mousemove', function(e){
//set start-points
if (lastCursorX === null)
lastCursorX = e.clientX;
if (lastCursorY === null)
lastCursorY = e.clientY;
//check for move left
if (e.clientX <= lastCursorX - cursorThreshold) {
lastCursorX = e.clientX;
console.log (cursorThreshold + 'px moved left');
}
//check for move right
if (e.clientX >= lastCursorX + cursorThreshold) {
lastCursorX = e.clientX;
console.log (cursorThreshold + 'px moved right');
}
//check for move up
if (e.clientY <= lastCursorY - cursorThreshold) {
lastCursorY = e.clientY;
console.log (cursorThreshold + 'px moved up');
}
//check for move down
if (e.clientY >= lastCursorY + cursorThreshold) {
lastCursorY = e.clientY;
console.log (cursorThreshold + 'px moved down');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

Making a box move smoothly and slowly to a set position in JavaScript

<html>
<div id="my_box_realtime" style="background-color: red; position: absolute; min-width: 100px; min-height: 100px"></div>
<script type="text/javascript">
var x = bottom
var y = right
var d = document.getElementById('my_box_realtime');
var position = 0;
setInterval(function() {}, 500)
position += 1;
d.style.top = position + 'px';
d.style.left = position + 'px';
function my_box_realtime() {
if (position)
}
</script>
</html>
The box needs to move smoothly and slowly to a set coordinate of bottom 0 and right 0.
Any help would be great. Very new to this and it's an assignment I have.
For your problem, we need to:
maintain top & left values separately
Check on Every Interval if the Boxes Bottom & Right have reached the Target Distance in relation to the window
Update the Top & Left Values if necessary
Finally, when the Box is at the Target Location, Clear the Interval.
var d = document.getElementById('my_box_realtime');
var x = 0; // Bottom Target in px
var y = 0; // Right Target in px
var positionTop = 0;
var positionLeft = 0;
let interval = setInterval(function() {
const {
bottom,
right
} = d.getBoundingClientRect();
const clientW = window.innerWidth;
const clientH = window.innerHeight;
if (clientH - bottom !== x) {
positionTop += 1;
d.style.top = positionTop + 'px';
}
if (clientW - right !== y) {
positionLeft += 1;
d.style.left = positionLeft + 'px';
}
if (right === clientW && bottom === clientH) {
clearInterval(interval);
}
}, 50);
<div id="my_box_realtime" style="background-color: red; position: absolute; min-width: 100px; min-height: 100px"></div>

CSS animated element animates on wrong place after touch-move transform

I am using CSS to define a ball animation with certain class. This works fine when adding the class on click, the ball just jumps on one place.
However, when I add the class after moving the ball using touchmove/mousedrag and transform, the ball jumps on its original position, instead its new position I have moved it to.
Is there any way I can make the ball jump on the new position but still keep the jump animation nicely in the CSS?
Thanks if you're reading this.
fiddle here: https://jsfiddle.net/9bvucd3q/
code here:
<html>
<head>
<!--<meta name="viewport"
content="width=device-width,
initial-scale=1.0,
user-scalable=no" />
<title>Drag/Drop/Bounce</title>-->
<style>
#item {
width: 100px;
height: 100px;
background-color: rgb(245, 230, 99);
border: 10px solid rgba(136, 136, 136, .5);
border-radius: 50%;
touch-action: none;
user-select: none;
position: absolute;
}
.bugout{animation: card-out 0.6s cubic-bezier(.8,.2,.1,0.8);}
#keyframes card-out {
0% { z-index: 20; transform: translateY(0%) rotate(0deg); }
5% { z-index: 20; transform: translateY(-5%) rotate(-4deg); }
49% { z-index:20;transform: translateY(-120%) ; }
100% { z-index:5;transform: translateY(-120%) ; }
}
#box1 {
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<h1>Drag and Drop</h1>
<div id="item"></div>
<div id="box1">
</div>
<script>
var dragItem = document.querySelector("#item");
var box1 = document.querySelector("#box1");
var container = dragItem;
//Declare Variables
var active = false;
var currentX;
var currentY;
var initialX;
var initialY;
var xOffset = 0;
var yOffset = 0;
//Add Event Listeners for Touchscreens
container.addEventListener("touchstart", dragStart, false);
container.addEventListener("touchend", dragEnd, false);
container.addEventListener("touchmove", drag, false);
//Add Event Listeners for Mice
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);
function dragStart(e) { //when the drag starts
if (e.type === "touchstart") { //if its a touchscreen
initialX = e.touches[0].clientX - xOffset; //set initial x-cordinate to where it was before drag started
initialY = e.touches[0].clientY - yOffset; //set initial y-cordinate to where it was before drag started
} else { //if its not a touchscreen (mouse)
initialX = e.clientX - xOffset; //set initial x-cordinate to where it was before drag started
initialY = e.clientY - yOffset; //set initial y-cordinate to where it was before drag started
}
if (e.target === dragItem) { //if user is dragging circle
active = true; //the drag is active
dragItem.classList.remove('bugout');
}
}
function dragEnd(e) { //when the drag ends
const box1Size = box1.getBoundingClientRect(); //the size of box1
const elementSize = dragItem.getBoundingClientRect(); //the size of the circle
if (elementSize.left >= box1Size.left && elementSize.right <= box1Size.right && elementSize.top >= box1Size.top && elementSize.bottom <= box1Size.bottom) { //if the circle is in box1
initialX = currentX; //set the initial x-cordinate to where it is now
initialY = currentY; //set the initial y-cordinate to where it is now
dragItem.classList.add('bugout');
}
else { //if the circle is in neither box1 nor box2
currentX = 0;
currentY = 0;
initialX = 0;
initialY = 0;
xOffset = 0;
yOffset = 0;
setTranslate(0, 0, dragItem);
}
active = false; //the drag is no longer active
}
function drag(e) { //when the circle is being dragged
if (active) { //if the drag is active
e.preventDefault(); //the user cant do anything else but drag
if (e.type === "touchmove") { //if its a touchscreen
currentX = e.touches[0].clientX - initialX; //set current x-cordinate to where it is now
currentY = e.touches[0].clientY - initialY; //set current y-cordinate to where it is now
} else { //if its not a touchscreen (mouse)
currentX = e.clientX - initialX; //set current x-cordinate to where it is now
currentY = e.clientY - initialY; //set current y-cordinate to where it is now
}
//Im not sure what this does but it dosnt work without it
xOffset = currentX;
yOffset = currentY;
setTranslate(currentX, currentY, dragItem);
}
}
function setTranslate(xPos, yPos, el) { //Im not sure what this does but it dosnt work without it
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
</script>
</body>
</html>```
So in the end I have decided to use GSAP, a really fast animation lib which also supports dragging via its Draggable plugin. It's just simpler if I have to code the animations in JS as opposed as to having them nicely in CSS.

How to make drag event move in only one direction in javascript?

I'm using drag event for moving an element, but I didn't find a way to make it only move horizontally, it's there any clue for this? Thanks in advance!
There is three steps we need to do
first we get the current mouse x position
second we calculate the distance it has move and the direction by newX = oldX - e.clientX saying subtract old x with current mouse x this way we get something like -3 or 2 or -1 you see we have the distance the direction - or +
Third step we update the element horizontal position by element.style.left = (element.offsetLeft - newX) + "px"
There are more details in the comments in the code. let me know if its not clear
var oldX = 0, newX = 0; // for storing X (horizontal) positions
var element = document.getElementById("mydiv"); // The element you want to drag
// We do the dragging here
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
newX = oldX - e.clientX; // to calculate how much we have moved
oldX = e.clientX; // store current value to use for next move
element.style.left = (element.offsetLeft - newX) + "px"; // update left position
}
// we do this so there is not multiple event handlers
function closeDragElement() {
document.onmouseup = null;
document.onmousemove = null;
}
// when mouse down on element attach mouse move and mouse up for document
// so that if mouse goes outside element still drags
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
oldX = e.clientX; // store current value to use for mouse move calculation
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
}
element.onmousedown = dragMouseDown;
#mydiv {
position: absolute;
z-index: 9;
background-color: #2196F3;
text-align: center;
border: 1px solid #d3d3d3;
padding: 10px;
cursor: move;
color: #fff;
}
<div id="mydiv">
Click here to move
</div>

Dragover: Can't move to left and top

I have an element which I would like to move with the mouse.
var troll = document.getElementById('troll');
troll.addEventListener('dragover', (e) => {
e.preventDefault();
e.target.style.left = e.clientX + 'px';
e.target.style.top = e.clientY + 'px';
}, false);
img {
width: 100px;
cursor: pointer;
position: absolute;
}
<div id="troll">
<img src="http://images.mmorpg.com/features/7909/images/Troll.png" alt="Troll">
</div>
From left to right and from top to bottom it works OK. Not perfect, since the very first move takes a whole space and it doesn't look smooth. But the main problem is that I can't move from right to left or from bottom to top.
Any help would be appreciated.
You wanna use drag not dragover, and some logic to know where you're going up or down or left or top.
var troll = document.getElementById('troll');
var X,Y = 0;
troll.addEventListener('drag', (e) => {
e.preventDefault();
if (e.clientX > X)
{
e.target.style.left = X + 'px';
}
else if (e.clientX < X)
{
e.target.style.left = X-- + 'px';
}
if (e.clientY > Y)
{
e.target.style.top = Y + 'px';
}
else if (e.clientY < Y)
{
e.target.style.top = Y-- + 'px';
}
X = e.clientX;
Y = e.clientY;
}, false);
img {
width: 100px;
cursor: pointer;
position: absolute;
}
<div id="troll">
<img src="http://images.mmorpg.com/features/7909/images/Troll.png" alt="Troll">
</div>

how to move one div with another in javascript

I am trying to make a web app with two boxes, one contained in the other. The user should be able to click and move the inner box, however, the user should not be able to move this box outside the confines of the outer box. The user can move the outer box by dragging the inner box against one of the edges of the outer box. I know how to move the inner box, but the problem is how to move the other box with this restriction. Can anybody help me please? Here is what I did so far:
<!doctype html>
<head>
<title>JavaScript Game</title>
<style>
#container {
height:400px;
width:600px;
outline: 1px solid black;
position:absolute;
left:50px;
top: 0px;
background-color:green;
}
#guy {
position:absolute;
height:50px;
width:50px;
outline: 1px solid black;
background-color:red;
left: 200px;
top: 200px;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="guy"></div>
<script>
var guy=document.getElementById("guy");
var cont=document.getElementById("container");
var lastX,lastY; // Tracks the last observed mouse X and Y position
guy.addEventListener("mousedown", function(event) {
if (event.which == 1) {
lastX = event.pageX;
lastY = event.pageY;
addEventListener("mousemove", moved);
event.preventDefault(); // Prevent selection
}
});
function buttonPressed(event) {
if (event.buttons == null)
return event.which != 0;
else
return event.buttons != 0;
}
function moved(event) {
if (!buttonPressed(event)) {
removeEventListener("mousemove", moved);
} else {
var distX = event.pageX - lastX;
var distY = event.pageY - lastY;
guy.style.left =guy.offsetLeft + distX + "px";
guy.style.top = guy.offsetTop + distY + "px";
lastX = event.pageX;
lastY = event.pageY;
}
}
</script>
</body>
You could add a check to see if moving the box would break bounds of cont.
try to use getBoundingClientRect()
Check the snippet below for the working code.
View in full screen for best results.
var guy=document.getElementById("guy");
var cont=document.getElementById("container");
var lastX,lastY; // Tracks the last observed mouse X and Y position
guy.addEventListener("mousedown", function(event) {
if (event.which == 1) {
lastX = event.pageX;
lastY = event.pageY;
addEventListener("mousemove", moved);
event.preventDefault(); // Prevent selection
}
});
function buttonPressed(event) {
if (event.buttons == null)
return event.which != 0;
else
return event.buttons != 0;
}
function moved(event) {
if (!buttonPressed(event)) {
removeEventListener("mousemove", moved);
} else {
var distX = event.pageX - lastX;
var distY = event.pageY - lastY;
guy.style.left =guy.offsetLeft + distX + "px";
guy.style.top = guy.offsetTop + distY + "px";
// ********************************************************************
// get bounding box borders
var contBounds = guy.getBoundingClientRect();
var guyBounds = cont.getBoundingClientRect();
// check bottom bounds
if (contBounds.bottom >= guyBounds.bottom){
cont.style.top = cont.offsetTop + distY + "px";
}
// check top bounds
if (contBounds.top <= guyBounds.top){
cont.style.top = cont.offsetTop + distY + "px";
}
// check left bounds
if (contBounds.left <= guyBounds.left){
cont.style.left = cont.offsetLeft + distX + "px";
}
// check right bounds
if (contBounds.right >= guyBounds.right){
cont.style.left = cont.offsetLeft + distX + "px";
}
// ********************************************************************
lastX = event.pageX;
lastY = event.pageY;
}
}
#container {
height:300px;
width:300px;
outline: 1px solid black;
position:absolute;
left:50px;
top: 0px;
background-color:#CCC;
}
#guy {
position:absolute;
height:50px;
width:50px;
outline: 1px solid black;
background-color:#000;
left: 200px;
top: 200px;
}
<div id="container"></div>
<div id="guy"></div>
try this link to get you started as far as keeping the "guy" inside the "contatiner": http://www.w3schools.com/html/html5_draganddrop.asp
their example shows how you can make an element only drop inside another element.
as far as moving the container...i would think that you could add some if else statements into the moved function that will test the position of the guy against the conatiner's outline and say that when they meet to move the container as well.
i am very new to javascript myself but this is just a suggestion from what i think i understand of it.

Categories