Auto scroll div based on mouse position - javascript

I want to automatically scroll a div based on mouse position using jQuery.
If you see this fiddle here, you can see a number of images that are horizontally ordered in a div that is scrollable:
<div id="parent">
<div id="propertyThumbnails">
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
</div>
</div>
CSS:
#parent {
height: 300px;
width: 100%;
background: #ddd;
}
#propertyThumbnails {
background: #666;
height: 80px;
white-space: nowrap;
overflow: scroll;
}
#propertyThumbnails img {
width: 125px;
height: 80px;
display: inline-block;
margin: 3px;
margin-right: 0;
opacity: 0.6;
}
I found out that you can use $("#container").scrollLeft(position) to set the position of the scroller but I want to do it based on the mouse position of the parent. So that when the mouse is fully to the right hand side, the right most image displays, and when the mouse is fully left, the left most image displays.
How can I do this?

A slightly different way to achieve what you need:
jQuery(function($) {
$(window).load(function() {
var $gal = $("#propertyThumbnails"),
galW = $gal.outerWidth(true),
galSW = $gal[0].scrollWidth,
wDiff = (galSW / galW) - 1, // widths difference ratio
mPadd = 60, // Mousemove Padding
damp = 20, // Mousemove response softness
mX = 0, // Real mouse position
mX2 = 0, // Modified mouse position
posX = 0,
mmAA = galW - (mPadd * 2), // The mousemove available area
mmAAr = (galW / mmAA); // get available mousemove fidderence ratio
$gal.mousemove(function(e) {
mX = e.pageX - $(this).offset().left;
mX2 = Math.min(Math.max(0, mX - mPadd), mmAA) * mmAAr;
});
setInterval(function() {
posX += (mX2 - posX) / damp; // zeno's paradox equation "catching delay"
$gal.scrollLeft(posX * wDiff);
}, 10);
});
});
#parent {
position: relative;
margin: 0 auto;
width: 60%;
height: 260px;
}
#propertyThumbnails {
position: relative;
overflow: hidden;
background: #444;
width: 100%;
height: 262px;
white-space: nowrap;
}
#propertyThumbnails img {
vertical-align: middle;
height: 100%;
display: inline;
margin-left: -4px;
}
<div id="parent">
<div id="propertyThumbnails">
<img src="//placehold.it/600x400/0bf" />
<img src="//placehold.it/600x400/f0b" />
<img src="//placehold.it/600x400/0fb" />
<img src="//placehold.it/600x400/b0f" />
<img src="//placehold.it/600x400/bf0" />
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
where mPadd is the area (in PX, at the left and right border zone) without any sensitivity to prevent user frustrations :)

this should at least get you headed in the right direction.
var parent = $('#parent');
var img = $('img:first-child');
parent.on('mousemove', function(e) {
mouseX = e.pageX
img.css('margin-left',-mouseX/parent.width()*100);
});
http://jsfiddle.net/xWcXt/4/

Related

How do I hide pointer events but still be able to initiate a drag event?

I have made a simple image cropper, where you move the green box (the area to crop) over the red box (the original image). Here it is:
var crop = document.querySelector(".image .crop");
crop.addEventListener("drag", function() {
var mouseoffset = [event.clientX, event.clientY];
crop.style.left = mouseoffset[0] + "px";
crop.style.top = mouseoffset[1] + "px";
});
crop.addEventListener("dragend", function() {
var mouseoffset = [event.clientX, event.clientY];
crop.style.left = mouseoffset[0] + "px";
crop.style.top = mouseoffset[1] + "px";
});
.image {
position: relative;
width: 400px;
height: 400px;
overflow: hidden;
background: #C00;
}
.image .crop {
position: absolute;
width: 150px;
height: 150px;
background: rgba(64,168,36,1);
}
<div class="image">
<div class="crop" draggable="true"></div>
</div>
But there is a problem: you can notice a pale green box when dragging. I can hide it with pointer-events: none, but this renders the box undraggable. Is there any way I can hide this pale green box while still being able to drag the crop area?
There might be a way to adapt what you have going on with drag events to achieve that result, but I wasn't able to get it working. Here's something doing about the same thing but with mousedown, mouseup, and mousemove.
var crop = document.querySelector(".image .crop");
crop.addEventListener("mousedown", function(event) {
document.onmousemove = function(event) {
moveBox(event);
};
document.onmouseup = function(event) {
stopMoving(event);
}
});
function moveBox(event) {
event.preventDefault();
var mouseoffset = [event.clientX, event.clientY];
crop.style.left = mouseoffset[0] + "px";
crop.style.top = mouseoffset[1] + "px";
}
function stopMoving(event) {
document.onmousemove = null;
document.onmouseup = null;
}
.image {
position: relative;
width: 400px;
height: 400px;
overflow: hidden;
background: #C00;
}
.image .crop {
position: absolute;
width: 150px;
height: 150px;
background: rgba(64, 168, 36, 1);
}
<div class="image">
<div class="crop" draggable="true"></div>
</div>

How to move reposition element in a div

I am trying to re position an element in a div.Basically its a span with background image.I have done the 80% part.Its working perfect when i click on it first time.It move to the desired position. But when i click on it second time it reset to its initial position.Below is my code.
I have a jsfiddle link here. https://jsfiddle.net/6q1q0wmj/
var TransformRequestObj
var TransList
var DragTarget=null;
var Dragging = false;
var OffsetX = 0;
var OffsetY = 0;
jQuery(document).on('mousedown','.bx_reposioned',function(evt){
if(!Dragging) //---prevents dragging conflicts on other draggable elements---
{
DragTarget = evt.target;
//---bring this viewPort to top---
var xcord=evt.clientX;
var ycord = evt.clientY;
OffsetX= OffsetX || xcord;
OffsetY= OffsetY || ycord;
Dragging=true;
}
});
jQuery(document).on('mousemove','.bx_reposioned',function(evt){
if(Dragging)
{
//var pnt = DragTarget.ownerSVGElement.createSVGPoint();
var xcord=evt.clientX;
var ycord = evt.clientY;
xcord -= OffsetX;
ycord -= OffsetY;
jQuery(this).css('transform','translate('+xcord+'px, '+ycord+'px)');
}
});
jQuery(document).on('mouseup','.bx_reposioned',function(evt){
Dragging = false;
var xcord=evt.clientX;
var ycord = evt.clientY;
});
.furniture-sprite {
display: block;
margin: 0 auto;
}
.bed1 {
width: 45px;
height: 53px;
background:red;
}
.bed2 {
width: 45px;
height: 53px;
background:blue;
}
.furniture-sprite {
display: inline-block;
background-repeat: no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="furniture-sprite bed1 ui-draggable ui-draggable-handle ui-draggable-dragging bx_reposioned" style="position: absolute; width: 45px; right: auto; height: 53px; bottom: auto; left: 410.953px; top: 95px;"></span>
<span class="furniture-sprite bed2 ui-draggable ui-draggable-handle ui-draggable-dragging bx_reposioned" style="position: absolute; width: 45px; right: auto; height: 53px; bottom: auto; left: 410.953px; top: 95px;"></span>
</div>
The problem is that the mousedown handler resets OffsetX and OffsetY even if it's already set,
if you do a check before overwriting it, it seems to work fine (line 14):
OffsetX= OffsetX || xcord;
OffsetY= OffsetY || ycord;
https://jsfiddle.net/6q1q0wmj/1/
You are resetting the offset each time. Also, for the mousemove and mouseup you are filtering to only accept the events when they happens over the dragged element.
For the first problem you should keep your offset when you mousedown again and for the second problem just remove the selector filter. You will have a more fluid drag (as it will detect the drag all around the document) and also will detect the mouseup when you move out of the drag area.
Right now you won't notice the "out of the drag area" problem because you have not boundaries set, but you will notice if you add them.
If there are multiple elements, you should keep the offset saved on each element. This is a easy jQuery way of doing it:
Check this:
var Dragging = false;
jQuery(document).on('mousedown','.bx_reposioned',function(evt){
if(!Dragging) //---prevents dragging conflicts on other draggable elements---
{
//---bring this viewPort to top---
var xcord = evt.clientX;
var ycord = evt.clientY;
!$(this).data("_dragOffset") && $(this).data("_dragOffset", {
x: xcord,
y: ycord
}); // This will set the offset only if has no drag offset already saved
Dragging = this;
}
});
jQuery(document).on('mousemove', function(evt){
if(Dragging) {
var xcord = evt.clientX;
var ycord = evt.clientY;
var offset = $(Dragging).data("_dragOffset");
xcord -= offset.x;
ycord -= offset.y;
jQuery(Dragging).css('transform','translate('+xcord+'px, '+ycord+'px)');
}
});
jQuery(document).on('mouseup', function(evt){
Dragging = false;
});
.furniture-sprite {
display: block;
margin: 0 auto;
}
.bed1 {
background-position: 0 -117px;
width: 45px;
height: 53px;
}
.furniture-sprite {
display: inline-block;
background-image: url('http://www.builderux.com/demo5/wp-content/plugins/Builder_UX-combined-code/assets/img/furniture-sprite.png');
background-repeat: no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="furniture-sprite bed1 ui-draggable ui-draggable-handle ui-draggable-dragging bx_reposioned" style="position: absolute; width: 45px; right: auto; height: 53px; bottom: auto; left: 410.953px; top: 95px;"></span>
</div>

Moving css scaled div using javascript

I have posted my problem at http://jsfiddle.net/ugnf4/ as it would be make it easier.
Below is my html / javascript code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="mainContainer">
<div id="pageContainer" style="background: #cdcdcd;"></div>
</div>
<style>
BODY {
margin: 0px;
padding: 0px;
}
#pageContainer {
position: relative;
margin: 10px auto;
-webkit-transform-origin:50% 20%;
-webkit-transform:scale(1.37);
width: 1218px;
height: 774px;
border: 1px solid #000000;
}
#mainContainer {
width: 100%;
overflow: hidden;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</script>
<script type="text/javascript">
$(document).ready(function() {
setHeight();
$(window).resize(setHeight);
});
function setHeight()
{
$('#mainContainer').css({'height': $(window).height()});
}
$('#mainContainer').mousemove(function (e) {
});
</script>
</body>
</html>
Currently #mainContainer div has overflow hidden as i dont want to show scroll bars and #pageContainer div (inner div) is scaled at 1.37 using css3, as in certain cases based on screen / browser width height #pageContainer's content would be hidden because of overflow hidden.
I want to code javascript so that if somebody moves cursor in #mainContainer, based on position of mouse X and Y co-ordinates I would like to move #pageContainer so that similar position of #pageContainer would be visible (I hope it is clear).
I m having problem as I m using -webkit-transform-origin, unable to understand how to move #pageContainer around with respect to mouse co-ordinates of #mainContainer.
UPDATE:
I m looking something like what happens in issuu.com website when you open an ebook and zoom it more than the browser size (Should make it more clear)
I m looking for algo or pointer how to achieve it (how to calculate it) not necessarily a working script.
How can this be achieved.
Below is working html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="mainContainer">
<div id="pageContainer" >
<div id="pageContainerInner"style="background: #cdcdcd;">
</div>
</div>
<style>
BODY {
margin: 0px;
padding: 0px;
}
#pageContainer {
margin: 10px auto;
-webkit-transform-origin:50% 20%;
-webkit-transform:scale(1.37);
width: 1218px;
height: 774px;
}
#mainContainer {
width: 100%;
overflow: hidden;
}
#pageContainerInner {
position: relative;
width: 1218px;
height: 774px;
border: 1px solid #000000;
top: 0;
left: 0;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</script>
<script type="text/javascript">
var pageWidth = 1220;
var pageHeight = 776;
var scale = 1.37;
var scaledDelta = 5; //Percentage mouse position approximation
$(document).ready(function() {
setHeight();
$(window).resize(setHeight);
});
function setHeight()
{
$('#mainContainer').css({'height': $(window).height()});
}
$('#mainContainer').mousemove(function (e) {
// Calculate the offset of scaled Div
var offsetX = $('#pageContainer').offset().left;
var offsetY = $('#pageContainer').offset().top;
// Calculate div origin with respect to screen
var originX = (-1 * offsetX) / scale;
var originY = (-1 * offsetY) / scale;
var wWdt = $(window).width();
var wHgt = $(window).height();
// Now convert screen positions to percentage
var perX = e.pageX * 100 / wWdt;
var perY = e.pageY * 100 / wHgt;
// Div content which should be visible
var pageX = perX * pageWidth / 100;
var pageY = perY * pageHeight / 100;
// Calculate scaled divs new X, Y offset
var shiftX = (originX - pageX) + (e.pageX / scale);
var shiftY = (originY - pageY) + (e.pageY / scale);
$('#pageContainerInner').css({'left': shiftX+'px', 'top': shiftY+'px'});
});
</script>
</body>
</html>
Hope this will help others.
I have posted a probable solution at http://jsfiddle.net/PYP8c/.
Below are the modified styles for your page.
BODY {
margin: 0px;
padding: 0px;
}
#mainContainer {
width: 100%;
overflow: hidden;
position: relative;
margin: 10px auto;
-webkit-transform-origin:50% 20%;
-webkit-transform:scale(1.37);
width: 1218px;
height: 774px;
border: 1px solid #000000;
}
#pageContainer {
position:absolute;
top:0px;
}
This is the javascript code for the same.
$(document).ready(function() {
//setHeight();
//$(window).resize(setHeight);
});
function setHeight()
{
$('#mainContainer').css({'height': $(window).height()});
}
$('#mainContainer').mousemove(function (e) {
var contentHeight = $("#pageContainer").height();
var minTop = 774 - contentHeight;
if(minTop>0)
minTop = 0;
var currTop = ((e.pageY-10)/774.0)*(minTop);
document.getElementById("pageContainer").style.top = currTop+'px';
});
Its just a demo on how you could get the text to move based on the mouse coordinates.
You could make a lot of changes, like adding a scrollbar that fades which gives the user a feedback about how much content is still available in both the vertical directions.
Also I have used hard coded values for height, but in your final version I would recommend you get the height of the mainContainer division dynamically.

JQuery Masonry -- expand div's over other div's

I'm making something similar to an iphone layout (a bunch of tiles with pictures/numbers that you can click on to get more information). After the layout has been set, I'd like a click-event to expand one of the tiles to be full screen. Right now, it moves the tiles so that the layout is re-adjusted. Is it possible to get masonry to stop rendering so that one tile get's enlarged over the other tiles?
The following is what I've tried (but unsuccessfully). Note: It uses d3.js to generate the div's for masonry to use.
function drawGrid(divname,orders)
{
var mydiv = d3.select(divname);
$(divname).masonry({
itemSelector: '.g1',
isAnimated: true,
//isResizable: true
});
var myd = mydiv.selectAll("div");
var mygs = myd.data(orders,function(d){ return d.orderid;})
.enter().append("div")
.attr("class","g1")
.append("g");
var x1 = mygs.append("div")
.attr("class","tickerdiv")
.text(function(d){ return d.ticker; });
var ActiveOrder = "1";
$(divname+' .g1').click(function() {
//$(this).show('maximised');
console.log("clicked")
$(this).animate({"display":"none","position": "absolute",
"top": "0",
"left": "0",
"width": "100%",
"height": "100%",
"z-index": 1000 }, 1000);
});
var x = [];
x.redraw = function(o)
{
x1.text(function(d){ return d.ticker; });
}
return x;
}
and from the css file:
.g1 { min-height:80px; width: 100px; margin: 15px; float: left; background-color: RGB(223,224,224); border-radius: 10px; vertical-align: middle; text-align: center; padding-top: 20px;}
EDIT Ok, my first answer was not useful here - absolute positioning won't work in case of masonry's/Isotope's relatively positioned container with absolute positioned elemens contained therein; the solution is rather to take the content of a masonry/Isotope element out of the DOM on click and append it temporarily to the body. You can see the basic idea in my dirty swedish sandbox
<!-- masonry/Isotope item large -->
<div class="item large">
<div class="header">
<p>Click here</p>
</div>
<div class="minimised">
<p>Preview</p>
</div>
<div class="maximised">
<p>Content</p>
<button id="screen-overlay-on">Screen overlay on</button>
<div id="screen-overlay-background"></div>
<div id="screen-overlay-content">
<p>Content</p>
<button id="screen-overlay-off">Screen overlay off</button>
</div>​
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#screen-overlay-on').click(function(){
var sob = $('#screen-overlay-background').detach();
var soc = $('#screen-overlay-content').detach();
sob.appendTo('body');
soc.appendTo('body');
$('#screen-overlay-background').toggleClass("active");
$('#screen-overlay-content').toggleClass("active");
});
$('#screen-overlay-background, #screen-overlay-off').click(function(){
$('#screen-overlay-background').toggleClass("active");
$('#screen-overlay-content').toggleClass("active");
});
});
</script>
With CSS like
#screen-overlay-background {
display: none;
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-color: #333;
zoom: 1;
filter: alpha(opacity=50);
opacity: 0.5;
z-index: 1000;
}
#screen-overlay-content {
display: none;
position: absolute;
top: 50%;
left: 50%;
height: 240px;
width: 320px;
margin: -120px 0 0 -160px;
background-color: #FFF;
z-index: 1000;
}
#screen-overlay-background.active, #screen-overlay-content.active {
display: block;
}
You can add a :hover to the element in css and change the z-index. You could easily change this on click with a class as well...
.item {
z-index:1
}
.item:hover{
z-index:2500;
}

How can I add limits to a custom scrolling element?

I have a pretty huge image being displayed in a container, the image stretches with the view port as it gets resized, but as the image is so big I have added scroller buttons to the side of the page, up and down, the only problem I have now is that when I press up or down there is no limit, the user can keep going until the image is completely out of sight, how can I stop that from happening?
Here is the code I have thus far,
HTML:
<body>
<div id="wrapper">
<div class="scroll top"></div>
<div id="content">
<div id="zoom_container">
<img id="image" src="8052x2000px" />
</div>
</div>
<div class="scroll bot"></div>
</div>
</body>
CSS:
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#wrapper {
overflow: hidden;
height: 100%;
max-height: 100%;
}
#content {
min-height: 100% !important;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#image {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
jQuery:
//side scroller bar
$('.scroll').live('click', function(){
var direction = $(this).hasClass('top');
var img_pos_top = $("#zoom_container img").position().top;
var inc = 0;
inc = $("#zoom_container img").height() / 10;
if(direction)
{
inc = $("#zoom_container img").position().top + inc;
}
else
{
inc = $("#zoom_container img").position().top - inc;
}
$("#zoom_container img").css({ position: 'relative',top: inc });
});
so as you can see I am incrementing or decrementing the top positioning of the image by 10% of it's height each click, how can I make sure the top of the image will never go further down than the top of the viewport and the bottom of the image never further up than the bottom of the viewport?
Is there a better more efficient way of achieving the same result?
Have a try this one.
<html>
<head>
<title>Canvas Sizing</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
var canvasContext;
resizeCanvas();
$(window).resize(function() { resizeCanvas() });
function resizeCanvas()
{
var w = window.innerWidth - 40;
var h = window.innerHeight - 40;
var canvasString = '<canvas id="mainCanvas" width="' + w + '" height="' + h + '">Canvas is not supported</canvas>';
$('#contentholder').empty();
$(canvasString).appendTo('#contentholder');
canvasContext = $('#mainCanvas').get(0).getContext('2d');
drawOnCanvas();
}
function drawOnCanvas()
{
var x = 15;
var y = 35;
canvasContext.font = "30pt serif";
canvasContext.fillStyle="#0f0";
canvasContext.fillText("Hello World!", x, y);
}
});
</script>
<style>
#mainCanvas
{
background-color: #000;
border: solid 3px #0F0;
}
body
{
background: #000;
}
#contentholder
{
width: 99%;
height: 99%;
margin: auto;
}
</style
</head>
<body>
<div id="contentholder"></div>
</body>

Categories