Suppose I have a large view with scroll in both x and y direction and instead of scrolling with mouse scroll, I need to drag and move to navigate through the entire view like in google maps
<div id="wrapper">
<div id="dragable_content">
<img src="https://geology.com/world/world-map.gif" style="height:100rem;"/>
</div>
</div>
how do I achieve this? preferably using only pure js
Thanks to the solution provided by #grisuu in the comments
I was able to whip up this:
jsfiddle
var _startX = 0;
var _startY = 0;
var _offsetX = 0;
var _offsetY = 0;
var _dragElement;
document.onmousedown = OnMouseDown;
document.onmouseup = OnMouseUp;
function OnMouseDown(event){
document.onmousemove = OnMouseMove;
_startX = event.clientX;
_startY = event.clientY;
_offsetX = document.getElementById('div1').offsetLeft;
_offsetY = document.getElementById('div1').offsetTop;
_dragElement = document.getElementById('div1');
}
function OnMouseMove(event){
_dragElement.style.left = (_offsetX + event.clientX - _startX) + 'px';
_dragElement.style.top = (_offsetY + event.clientY - _startY) + 'px';
}
function OnMouseUp(event){
document.onmousemove = null;
_dragElement=null;
}
html{
background-color:green;
overflow: hidden;
}
.div1{position:absolute; height:500px; width: 500px; z-index:1;}
<div class="div1" id="div1">
<div style="height:50px;width:50px;background-color:red;"></div>
<div style="position:absolute;top:75px;left:100px;height:50px;width:50px;background-color:blue;"></div>
</div>
I implemanted the same feature for my personal project by editing arsher's answer and I want to share the code I ended up with here.
Here are some notes:
This code does not use css at all, it's using scrollTo instead.
I'm using draggable='false' on the image to prevent browser dragging feature on images.
document.documentElement.scrollTop / .scrollLeft could have some browser support issues, there are many ways to get document scroll position value, many of them didn't work for me and this one did
/* check browser support, tested on Chrome v108
**********************************************************************/
let _startX = 0,
_startY = 0,
_scrollTop = 0,
_scrollLeft = 0;
document.onmousedown = OnMouseDown;
document.onmouseup = OnMouseUp;
function OnMouseDown(event) {
document.onmousemove = OnMouseMove;
_startX = event.clientX;
_startY = event.clientY;
_scrollTop = document.documentElement.scrollTop;
_scrollLeft = document.documentElement.scrollLeft;
}
function OnMouseMove(event) {
window.scrollTo({
left: _scrollLeft + (_startX - event.clientX),
top: _scrollTop + (_startY - event.clientY)
});
}
function OnMouseUp() {
document.onmousemove = null;
}
<div id="wrapper">
<div id="dragable_content">
<img draggable='false' src="https://geology.com/world/world-map.gif" style="height:100rem;" />
</div>
</div>
Related
var bx = document.getElementById("movingbox");
var takeMeBtn = document.getElementById('takeMeBtn');
var letGoBtn = document.getElementById('letGoBtn');
function mouseMov(e) {
bx.style.left = -50 + e.clientX + "px";
bx.style.top = -50 + e.clientY + "px";
bx.style.zIndex = -99;
}
takeMeBtn.clickToggle = function fn(e) {
bx.style.left = -50 + e.clientX + "px";
bx.style.top = -50 + e.clientY + "px";
bx.style.zIndex = -99;
}
letGoBtn.onclick = function() {
bx.style.position = "fixed";
bx.style.top = 50;
bx.style.left = 50;
}
Hey people!
I've been trying to get "movingbox" to move and follow the cursors positions, when I click the button "takeMeBtn".
But, it only places itself in the current position of the cursor, when the "takeMeBtn" is clicked, and then stays there.
I also want to make it go back to its starting position, or anyposition, when I click "letGoBtn", but I think I can manage that one on my own.
I do not want to use jQuery for this.
Superthankful for any help.
Your buttons need to activate a mousemove listener for whatever you want to track the mouse over, probably the document or window. Other than that, you were close. I used inline style, but obviously a separate css document is better outside of this narrow example.
var bx = document.getElementById("movingbox");
var takeMeBtn = document.getElementById('takeMeBtn');
var letGoBtn = document.getElementById('letGoBtn');
function mouseMov(e) {
bx.style.left = -50 + e.clientX + "px";
bx.style.top = -50 + e.clientY + "px";
}
takeMeBtn.onclick = function(e) {
document.addEventListener('mousemove', mouseMov)
}
letGoBtn.onclick = function() {
document.removeEventListener('mousemove', mouseMov)
bx.style.top = "";
bx.style.left = "";
}
<button id="takeMeBtn">click</button>
<button id="letGoBtn">unclick</button>
<div id="movingbox" style="width:30px; height:30px; border: 1px solid black; position:absolute;"></div>
You can do it like this.
HTML:
<button id="takeMeBtn">take me</button>
<button id="letGoBtn">let go</button>
<div id="movingbox"></div>
var bx = document.getElementById("movingbox");
var takeMeBtn = document.getElementById('takeMeBtn');
var letGoBtn = document.getElementById('letGoBtn');
CSS
div {
width: 50px;
height: 50px;
background: red;
position: absolute;
}
JS
// flag: div should/not move
let move = false;
// switch flag
takeMeBtn.addEventListener('click', event => {
move = true;
});
// reset flag and position
letGoBtn.addEventListener('click', event => {
move = false;
bx.style.top = 0;
bx.style.left = 0;
bx.style.zIndex = 0;
});
// change its position on each mousemove event if the flag is set to true
document.addEventListener('mousemove', event => {
if (move === true) {
bx.style.top = event.clientY + 'px';
bx.style.left = event.clientX + 'px';
bx.style.zIndex = -99;
}
});
i am looking to have this cursor effect on the body:
https://www.screenshot-magazine.com/
i do have two separate codes, one for the bloc following the mouse and another to get the xy coords.
But i am too beginner to merge both together or make both work in parallel to have the XY coods printed in the box following my cursor moves.
Someone could help me?
Thanks a lot in advance:)
Anto
here the two codes:
1-bloc following mouse movements
<style>
#divtoshow {
position:absolute;
display:none;
color: #C0C0C0;
background-color: none;
}
<script type="text/javascript">
var divName = 'divtoshow'; // div that is to follow the mouse (must be position:absolute)
var offX = 15; // X offset from mouse position
var offY = 15; // Y offset from mouse position
function mouseX(evt) {if (!evt) evt = window.event; if (evt.pageX) return evt.pageX; else if (evt.clientX)return evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft); else return 0;}
function mouseY(evt) {if (!evt) evt = window.event; if (evt.pageY) return evt.pageY; else if (evt.clientY)return evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); else return 0;}
function follow(evt) {
var obj = document.getElementById(divName).style;
obj.left = (parseInt(mouseX(evt))+offX) + 'px';
obj.top = (parseInt(mouseY(evt))+offY) + 'px';
}
document.onmousemove = follow;
</script>
<body>
<div id='onme' onMouseover='document.getElementById(divName).style.display="block"' onMouseout='document.getElementById(divName).style.display="none"'>
<div id="divtoshow">test</div>
2-get XY coords on body
<script>
function readMouseMove(e){
var result_x = document.getElementById('x_result');
var result_y = document.getElementById('y_result');
result_x.innerHTML = e.clientX;
result_y.innerHTML = e.clientY;
}
document.onmousemove = readMouseMove;
</script>
</head>
<body>
<h2 id="x_result">0</h2>
<h2 id="y_result">0</h3>
</body>
Your CSS is fine. You could have moved #x-result and #y-result into #divtoshow, and then set the left and right in readMouseMove. I've modified your code a bit. I'll explain it on the way
const xResult = document.getElementById("x-result");
const yResult = document.getElementById("y-result");
const divToShow = document.getElementById("divtoshow");
document.onmousemove = function (e) {
let mouse = {
x: e.clientX, // this is 2018, so you can just directly use clientX
y: e.clientY // and clientY
};
divToShow.style.left = `${mouse.x + 16}px`; // add a padding so that the text is not rendered directly below the mouse
divToShow.style.top = `${mouse.y + 16}px`;
xResult.innerHTML = `X: ${mouse.x}`; // write the text into the output divs
yResult.innerHTML = `Y: ${mouse.y}`;
};
#divtoshow {
color: #C0C0C0;
position: absolute;
}
<div id="divtoshow">
<span id="x-result">X: 0</span> <br> // i changed the h2s to spans because h2s have HUGE text
<span id="y-result">Y: 0</span>
</div>
You can add the #onme integration by yourself.
https://jsfiddle.net/f8L300ug/3/
I'm trying to make a simple drag-to-resize function. See the example above.
If the mouse is released outside the <body>, the mouseup event won't be triggered, in contrast to what this post implies: Responding to the onmousemove event outside of the browser window in IE
jsFiddle's drag handler does a good job in this. If the mouse is released outside the element, then unbind the mousemove event; If the mouse is not released outside the element and moves back in, then keep the mousemove event. How can I achieve this?
Here's my code. jsFiddle's resize functionality is not perfect after well. After playing it for a while, I triggered a bug and my CSS panel is gone, so I can't post my CSS code here...
JS:
var initialX;
var leftPanel = document.getElementById("left");
var rightPanel = document.getElementById("right");
var resizePanels = function(e){
var deltaX = e.clientX - initialX;
var bodyWidth = parseInt(window.getComputedStyle(leftPanel).width);
initialX = e.clientX;
var newWidth = bodyWidth + deltaX;
leftPanel.style.width = newWidth + "px";
rightPanel.style.width = (parseInt(window.getComputedStyle(document.body).width) - newWidth)*0.9 + "px";
}
var bodyUnbindResize = function(){
document.body.removeEventListener("mousemove", resizePanels)
document.body.style.cursor = "default";
}
document.getElementById("dragger").addEventListener("mousedown", function(){
document.body.addEventListener("mousemove", resizePanels)
document.body.addEventListener("mouseup", bodyUnbindResize)
document.body.style.cursor = "col-resize";
});
HTML:
<div id="left" class="grid">
</div>
<div id="dragger" class="grid"></div>
<div id="right" class="grid">
</div>
And please improve my code if you have a better way. This is the first time I use vanilla JS to do this, so this might not be the best way. Thanks!
It doesn't seem to work when you attach the listener to document.body, but it does work if you attach it to window. If the mouse isn't released, even when you go out of the bounds of the window, then the browser will still detect the mouse move event, which means it is also able to detect when the mouse is released. This also means that when you go out of the window's bounds, you'll get a negative value. You can easily fix that.
https://jsfiddle.net/f8L300ug/8/
var initialX;
var leftPanel = document.getElementById("left");
var rightPanel = document.getElementById("right");
var resizePanels = function (e) {
// If the mouse is still down when dragging outside,
// to the left of the window, e.clientX will be negative
// and undesired behavior happens.
// To fix this, simply give it a value of 0 when it is below 0 (out of the window)
var clientX = e.clientX < 0 ? 0 : e.clientX;
var deltaX = clientX - initialX;
var bodyWidth = parseInt(window.getComputedStyle(leftPanel).width, 10); // < It's a good idea to always
var newWidth = bodyWidth + deltaX; // specify a radix for parseInt
initialX = clientX;
leftPanel.style.width = newWidth + "px";
rightPanel.style.width = (parseInt(window.getComputedStyle(document.body).width, 10) - newWidth) * 0.9 + "px";
}; // < It's a good idea to always close your `var` statements with a `;`
var bodyUnbindResize = function () {
window.removeEventListener("mousemove", resizePanels);
document.body.style.cursor = "default";
};
document.getElementById("dragger").addEventListener("mousedown", function () {
// Attach the mouse listeners to the window
window.addEventListener("mousemove", resizePanels);
window.addEventListener("mouseup", bodyUnbindResize);
document.body.style.cursor = "col-resize";
});
.grid{
height: 200px;
user-select:none;
webkit-touch-callout: none;
-webkit-user-select: none;
}
#left{
width: 50px;
border-right: 1px solid #ccc;
float:left;
background: black;
}
#dragger{
width: 5px;
float:left;
background-color:#eee;
cursor: col-resize;
}
#right{
width: 100px;
border-left: 1px solid #ccc;
overflow:hidden;
background: blue;
}
<div id="left" class="grid">
</div>
<div id="dragger" class="grid"></div>
<div id="right" class="grid">
</div>
You can also set a maximum width for your elements, so that they don't overflow the body. window.innerWidth gives you the current maximum width of the window.
I would like to know , how to position a div block dynamically to the place where mouse clicks.
I know how to get the value of coordinates of click dynamically.
I want to know how we can move the div block to that coordinate.
I tried the following codes in SO, but nothing is working
document.getElementById('someID').style.position='absolute';
document.getElementById('someID').style.left='500px';
document.getElementById('someID').style.top='90px';
and the below code
var d = document.getElementById('yourDivId');
d.style.position = "absolute";
d.style.left = x_pos;
d.style.top = y_pos;
Can anyone tell me how to do it.
Thanks,
You have missed the units in your position assigning sentence.
To get the mouse position (on click):
(function() {
window.onmousedown = handleMouseMove;
function handleMouseMove(event) {
event = event || window.event; // IE-ism
console.log(event.clientX);
moveDiv(event.clientX,event.clientY);
}
})();
Then send the position to a function to change the position of your div, adding the pixels unit, don't forget it!
function moveDiv(x_pos,y_pos){
var d = document.getElementById('myDiv');
d.style.left = x_pos + "px";
d.style.top = y_pos + "px";
}
Full Code:
(function() {
window.onmousedown = handleMouseMove;
function handleMouseMove(event) {
event = event || window.event; // IE-ism
console.log(event.clientX);
moveDiv(event.clientX,event.clientY);
}
})();
function moveDiv(x_pos,y_pos){
var d = document.getElementById('myDiv');
d.style.left = x_pos + "px";
d.style.top = y_pos + "px";
}
DEMO
try
document.body.addEventListener('click', function(e) {console.log(e)})
you got a mouseevent object where its properties clientX, clientY gives the location of mouse click.
You can then use this to re-position your div.
You need to add px after d.style.left and d.style.top.
Try this:
<style>
#someID {
position:absolute;
left: 0px;
top: 0px;
height: 50px;
width: 50px;
background: red;
}
</style>
<div id="someID">
</div>
<script>
var ele = document.getElementById('someID');
document.onclick = function(e) {
ele.style.top = e.offsetY + "px";
ele.style.left = e.offsetX + "px";
}
</script>
Here is an example: http://jsfiddle.net/s99d4/
JS
var a = document.getElementById('a');
document.onclick = function(e){
a.style.top = e.clientY + 'px';
a.style.left = e.clientX + 'px'
}
CSS
div {
position: absolute;
}
JSFiddle
You can use this simple line of Jquery instead of going those complicated routes.
$("#divId").hide();
$('body').click(function(event) {
$("#divId").show().css( {position:"absolute", top:event.pageY, left: event.pageX});
});
First you hide the div you want to move (OR don't hide it)
Then move it wherever the user clicks. See FIDDLE
EDIT: Never mind, not all of them look so complicated anymore... Goodluck. :)
Hope this helps.
Mike
Use
d.style.position = "absolute";
d.style.top = "980px"; //or whatever
d.style.left = "970px"; //or whatever
Remember that d.style.top is the y-axis and d.style.left is the x-axis.
Therefore,
d.style.top = e.clientY + "px";
d.style.left = e.clientX + "px";
Here is a full function for this code:
document.onmousemove = getCoords;
function getCoords(e) {
e = e || window.event;
var x = e.clientX;
var y = e.clientY;
var div = document.getElementById("MYDIV");
div.style.position = "absolute";
div.style.top = y + "px";
div.style.left = x + "px";
}
Is it possible to make a resizable and draggable div with a fixed surface area?
Example: I have a square div with a surface area of 10000px² (100 x 100px) and then I change the width (with the mouse on the corner or on the edge) to 50px, the heigth should now change automaticly to 200px so the surface area stays 10000px².
Then I´d like to drag it all over the page, resize it again etc...
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet"
href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-
ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-
ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
#draggable { width: 100px; height: 100px; padding: 0.5em; border:
1px solid;}
</style>
<script>
$(function() {
$( "#draggable" ).draggable().resizable();
});
</script>
</head>
<body>
<div id="draggable" class="ui-widget-content">
<p>Drag me around</p>
</div>
</body>
</html>
ok, so here is the code, I have resizable and draggable div but now I need the fixed surface area (eg 10000px²) as I mentioned before...
you can use jquery's UI to do all of this.
use http://jqueryui.com/draggable/ to allow for dragging,
use http://jqueryui.com/resizable/ to allow for resizing
using the resize event, you can have jquery modify the div so it will follow any height/width rules you want.
Try this:
(function(draggable) {
var elm = document.getElementById(draggable);
elm.onmousedown = drag;
function stop() {
document.onmouseup = null;
document.onmousemove = null;
}
function drag(e) {
if (e.target == elm) {
var absX = e.clientX;
var absY = e.clientY;
var left = parseInt(getComputedStyle(elm).left, 10);
var top = parseInt(getComputedStyle(elm).top, 10);
var relX = absX - left;
var relY = absY - top;
document.onmouseup = stop;
document.onmousemove = function(e) {
var absX = e.clientX;
var absY = e.clientY;
elm.style.left = absX - relX + "px";
elm.style.top = absY - relY + "px";
}
}
}
})("box");
(function(resizeable) {
var elm = document.getElementById(resizeable);
var wHandler = elm.childNodes[1];
var hHandler = elm.childNodes[3];
wHandler.onmousedown = resizeW;
hHandler.onmousedown = resizeH;
function stop() {
elm.style.cursor = "";
document.body.style.cursor = "";
document.onmouseup = null;
document.onmousemove = null;
}
var w = 100;
var h = 100;
var area = w * h;
function resizeW(e) {
elm.style.cursor = "w-resize";
document.body.style.cursor = "w-resize";
var left = parseInt(window.getComputedStyle(elm, null)["left"], 10);
document.onmouseup = stop;
document.onmousemove = function(e) {
var absX = e.clientX;
var width = absX - left;
var height = area / width;
elm.style.width = width + "px";
elm.style.height = height + "px";
}
}
function resizeH(e) {
elm.style.cursor = "n-resize";
document.body.style.cursor = "n-resize";
var top = parseInt(window.getComputedStyle(elm, null)["top"], 10);
document.onmouseup = stop;
document.onmousemove = function(e) {
var absY = e.clientY;
var height = absY - top;
var width = area / height;
elm.style.height = height + "px";
elm.style.width = width + "px";
}
}
})("box");
Fiddle
Though there's a small bug, I think. Couldn't fix it. When you resize the width it's ok, but when you resize the height, and then move the div, it lags or w/e. Check the fiddle. Other than this, it's working fine.