So I have a very wide div within a smaller div. The inner div scrolls left and right depending on mouse position.
I adapted the code from this answer... https://stackoverflow.com/a/6137535/3656408
There are two transparent divs on top of everything, from which the position of the mouse is attained, which gives a speed at which to scroll.
The problem with this is anything underneath these divs is not clickable.
My div has a fixed width and height so I potentially could calculate the scroll speed from where the mouse is on the page ( ie. the page is 620px wide so I know 310 is half way )
Unfortunately my maths is terrible and I can't figure out how to convert my thought process into acceptable working code.
Anyone have any suggestions?
Heres how it currently figures out the rate at which to move the page...
$('.direction', backdrop).mousemove(function(e){
var $this = $(this);
var left = $this.is('.left');
if (left){
var w = $this.width();
rate = (w - e.pageX - $(this).offset().left + 1)/w;
}
else{
var w = $this.width();
rate = -(e.pageX - $(this).offset().left + 1)/w;
}
});
.. and you can see it in action here http://thetally.efinancialnews.com/tallyassets/20years/index.html
OK I figure it out...
$( document ).mousemove(function(e){ //if mouse moves on page
if (e.pageX <= 620 && e.pageY <= 600){ //and if its not outside the extents of the div
if (e.pageX <= 310){ //if its less than half way across
rate = (310 - e.pageX)/50;
} else { // if its more than half way across
rate = -( e.pageX - 310)/50;
}
}
});
Related
I want to achieve a draggable element in vanilla javascript.
I want to make a small circular div draggable within a square div.
To make myself a bit more clear, I do NOT want to:
Create drag and drop,
Use jQuery UI or any other library or plugin to achieve this, just vanilla javascript
I already have a few events for handling dragging:
parent.addEventListener("mousedown", ..),
document.addEventListener("mouseup", ..)
and
document.addEventListener("mousemove", ..)
My question is how can I keep the draggable inside the given bounds of its parent?
Reference: https://codepen.io/ChickenFlavored/pen/rNxRXGo
You may use getBoundingClientRect that gives DOMRect object(an invincible rectangle that encompass the object) with eight properties: left, top, right, bottom, x, y, width, height.
var parent = document.querySelector('.parent');
var parentRect = parent.getBoundingClientRect();
var draggable = document.querySelector('.draggable');
var draggableRect = draggable.getBoundingClientRect();
You can get the mouse (X,Y) coordinates anytime by using e.clientX and e.clientY, so just check if they are outside the bounding rectable of .parent div if so then only update the draggable div's left and top properties
if( (e.clientX >= parentRect.left && (e.clientX+draggableRect.width <= parentRect.right)) &&
(e.clientY >= parentRect.top && (e.clientY+draggableRect.height <= parentRect.bottom))
//+draggableRect.height and +draggableRect.height accounts for the size of ball itself
){
draggable.style.left = `${e.clientX}px`;
draggable.style.top = `${e.clientY}px`;
}
Note that numbers increase down and towards right in graphics world
https://codepen.io/vsk/pen/PozVryr
UPDATE:
To fix the issue mentioned in comment use this
if(/* mouse was moved withing red container's bounds*/)
else{
//if mouse went out of bounds in Horizontal direction
if(e.clientX+draggableRect.width >= parentRect.right){
draggable.style.left = `${parentRect.right-draggableRect.width}px`;
}
//if mouse went out of bounds in Vertical direction
if(e.clientY+draggableRect.height >= parentRect.bottom){
draggable.style.top = `${parentRect.bottom-draggableRect.height}px`;
}
}
And assign mousemove to document insted of the div container
I hope you could provide a code snippet to try to simulate what you want, a codepen url, codesandbox or similar.
I made this sample using what you provided : )
let x = event.clientX - element.offsetLeft
const elementWidth = element.clientWidth
const fullX = x + elementWidth
const containerW = yourContainer.clientWidth
if(fullX > containerW){
//If element will be out of container
x = containerW - elementWidth // So it will be never out of container
}
element.style.transform = "translate("+x+"px, "+y+"px)"
Please help me out here, if bottom of div or full div is visible then i want to scroll to down of next div. Here the code i have tried out,
Mathematically,
var top = $("#myDiv").offset().top;
//top = 1863
var divHeight = $("#myDiv").height();
//divHeight = 571
var total = top + divHeight;
//total = 2434
if($('#myDiv').css('height',total).visible(true))
{
alert('hi');
// I need to alert only if the full div is visible not some part of div
}
else
{
//if height of myDiv is larger window height (my screen height 640 pixels)
}
If all this part of html(from top to divHeight) or bottom of page(here total value) is visible then i need to scroll to next div.
Please note :- the code inside if conditional statement is not correct, i think you got some idea from that.
Given element the jQuery object you want to check, element is fully visible if it is shown and all of the 4 sides of its layout box fall within the window viewport.
Caution: the following solution assumes that there are no element with scrollable overflow between element and the document root, otherwise the calculation becomes way more complicated.
function isFullyVisible(element) {
var offset = element.offset();
var scrollTop = $(document).scrollTop();
var scrollLeft = $(document).scrollLeft();
return element.is(":visible") && // shown
offset.top >= scrollTop && // top
offset.left >= scrollLeft && // left
offset.top + element.outerHeight() <= scrollTop + $(window).height() && // bottom
offset.left + element.outerWidth() <= scrollLeft + $(window).width(); // right
}
If you don't care of sides, you can keep only the corresponding sub-expression.
I have a div with a background image - the div is set to the exact size of the image and my pointer is set to a crosshair over the div.
I want to mark each click with its x and y positions in the div over the image background. This I can do but the mark on the div is always lower and to the left of the actual cursor why is this?
function showClick(x,y)
{
$('.clickable').append('<span id="'+x+y+'_span" style="position: absolute;top:'+y+'px;left:'+x+'px;" class="red">+</span>');
}
$('.clickable').bind('click', function (ev) {
var $div = $(ev.target);
var offset = $div.offset();
var xMargin = ($div.outerWidth() - $div.width()) / 2;
var yMargin = ($div.outerHeight() - $div.height()) / 2;
var x = (ev.pageX + xMargin) - offset.left;
var y = (ev.pageY + yMargin) - offset.top;
showClick(x,y);
});
working example: https://jsfiddle.net/b94ypmae/3/
You are not taking into account the size of the span (and the character inside it).
Your code is working properly, in that a span is being placed in your div at the position of your cursor, but that position is based on the upper left corner
If you put a border around your span you can see it is a perfect alignment of your upper left corner: JSFiddle showing border
You could fix this by taking into account the size of the placed span(if you know it will always be the same you could hard code it as well). Here's an example of getting the size of the placed span and moving it by half it's width and height: Fixed JSFiddle
var placedSpan = $("#" + x + y + "_span");
var width = placedSpan.width();
var height = placedSpan.height();
placedSpan.css('left', x - width / 2 + 'px');
placedSpan.css('top', y - height / 2 + 'px');
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
Trying to create a scrolling div. Wanted to stop (thescrollingdiv) div once it has reached a particular top position and scrolled all the way to the bottom and not overshoot the parent div into infinity scrolling zone. thescrollingdiv does not have any height specified but its parent div does.Thanks.
$('#div a).click(function(e){
e.preventDefault();
$('#thescrollingdiv').stop(true,true).animate({ "top": '-=100px'}, 500)
ScrollTop tells you where you are at. Check the existing top against scrolltop and work the math to set your limits.
var scrollTop = $('#thescrollingdiv').scrollTop();
var newTop = parseFloat($('#thescrollingdiv').css('top')) - 100;
if (scrollTop < 0) {
newTop = 0;
}
$('#thescrollingdiv').stop(true,true).animate({ "top": newTop}, 500)
UPDATE
Something like this.
var topLimit = 0;
var bottomLimit = 800;
var containerTop = parseFloat($('container').css('top'));
var containerBottom = parseFloat($('container').css('height')) + containerTop;
var destination = containerTop - 100;
// compensate for going too far up
destination = (destination < 0) ? 0 : destination;
// compensate for going too far up
destination = (containerBottom > bottomLimit) ? bottomLimit : destination;
// now that you know you are within your custom limits, animate it.
animate(destination);
This is almost pseudo code as I don't know what your code looks like, but it gives you an idea. You have to actually DO THE WORK in setting the limits for your 'newTop', before you call animate in the first place.
You can figure it out. Don't be a lazy programmer, though.