How to move this div left based on updated x position value? - javascript

http://codepen.io/leongaban/pen/WvOmwL
This should be pretty simple, trying the answer found here to no avail.
d.style.left = x_pos+'px';
I have a div #carousel-list I want to move left and right based on the < > nav buttons.
Current javascript:
document.getElementById('move-right').addEventListener("click", moveRight, false);
var carousel = document.getElementById("carousel-list");
function getPosX(el) {
// yay readability
for (var lx=0;
el != null;
lx += el.offsetLeft, el = el.offsetParent);
return {x: lx};
}
function moveRight() {
var currentX = getPosX(carousel);
console.log(currentX.x); // returns 0
console.log(currentX - 20); // returns NaN for some reason
carousel.style.left = (currentX - 20)+'px';
console.log(currentX.x); // still returns 0 so div does not move
}
Thoughts on my I can't move the carousel div? Or why (currentX - 20) returns NaN when currentX is the number 0?

Oops, change:
carousel.style.left = (currentX - 20)+'px';
to:
carousel.style.left = (currentX.x - 20)+'px';

Related

Moving div on the page and dropping if div comes in another one with native JS

There is this jsFiddle. If you open it you will see a moveable div, but I also want to add the following thing: if you move this div to 'trash', that moveable div must disappear (you put it in trash). Thanks in advance!
My code for div moving:
var selected = null, // Object of the element to be moved
x_pos = 0, y_pos = 0, // Stores x & y coordinates of the mouse pointer
x_elem = 0, y_elem = 0; // Stores top, left values (edge) of the element
// Will be called when user starts dragging an element
function _drag_init(elem) {
// Store the object of the element which needs to be moved
selected = elem;
x_elem = x_pos - selected.offsetLeft;
y_elem = y_pos - selected.offsetTop;
}
// Will be called when user dragging an element
function _move_elem(e) {
x_pos = document.all ? window.event.clientX : e.pageX;
y_pos = document.all ? window.event.clientY : e.pageY;
if (selected !== null) {
selected.style.left = (x_pos - x_elem) + 'px';
selected.style.top = (y_pos - y_elem) + 'px';
}
}
// Destroy the object when we are done
function _destroy() {
selected = null;
}
// Bind the functions...
document.getElementById('draggable-element').onmousedown = function () {
_drag_init(this);
return false;
};
document.onmousemove = _move_elem;
document.onmouseup = _destroy;
Trash the div if it has more than 50% area in trash
Find x, y co-ordinates of trash and dragged elements
Find overlapped area between them
If the area is more than half of div area , hide it
Code
function getOffset(el) {
var _x = 0;
var _y = 0;
while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
el = el.offsetParent;
}
return {
top: _y,
left: _x
};
}
function shouldTrash() {
var dragged = getOffset(document.getElementById('draggable-element'));
var x11 = dragged.left;
var x12 = dragged.left + 100;
var y11 = dragged.top;
var y12 = dragged.top + 100;
var trashed = getOffset(document.getElementById('trash'));
var x21 = trashed.left;
var x22 = x21 + 100;
var y21 = trashed.top;
var y22 = y21 + 100;
x_overlap = Math.max(0, Math.min(x12, x22) - Math.max(x11, x21));
y_overlap = Math.max(0, Math.min(y12, y22) - Math.max(y11, y21));
overlapArea = x_overlap * y_overlap;
if (overlapArea > 100 * 50) {
document.getElementById('draggable-element').style.display = 'none';
}
}
Implemented here
References :
Retrieve co-ordinates
Find overlapped area
For a working solution check my modification of your jsFiddle
In order to solve the problem, I have taken the overlap function suggested in this answer which uses Element.getBoundingClientRect()
function checkOverlap(element1, element2) {
var rect1 = element1.getBoundingClientRect();
var rect2 = element2.getBoundingClientRect();
return !(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom)
}
// Destroy the object when we are done
function _destroy() {
// check if an element is currently selected
if (selected) {
// check if the selected item overlaps the trash element
if (checkOverlap(selected, document.getElementById('trash'))) {
// remove the selected item from the DOM
selected.parentElement.removeChild(selected);
}
}
selected = null;
}
Here is a quick (not full) implementation of what you asked.
https://jsfiddle.net/dimshik/posm3cwk/4/
I created an function isInTrash(element) that gets an element and returns true if it is in the trash.
The check i did was if the mouse pointer that holds the draggable element is located inside the trash area.
You should also add some kind of a feedback to the user when the element is overlapping the trash while dragging.
you can call the isInTrash function inside your function _move_elem(e) and change the color for example of the draggable element.
Here is the additional functionality of the feedback
https://jsfiddle.net/dimshik/posm3cwk/5/

Stop div scrolling past set position

I adapted this code to create a large div which scrolls horizontally inside a smaller div, depending on the position of the mouse.
You can see my example here.. http://thetally.efinancialnews.com/tallyassets/20years/index.html
What I am trying to achieve is for the inner (yellow) div to stop at a maximum of left:0px, in other words the far left of the yellow div will become stuck to the far left of the outer div if you go that far.
I tried to implement this with an 'if else' statement, however as this piece of code gets run every 30th of a second it creates a strange result, which I can't find a solution for. I'm sure its very simple but its stumped me
You can see my code here...
var x=0,
rate=0,
maxspeed=10;
var backdrop = $('.container');
var years = $('.events');
$('.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;
}
});
backdrop.hover(function(){
var scroller = setInterval( moveBackdrop, 30 );
$(this).data('scroller', scroller);
},
function(){
var scroller = $(this).data('scroller');
clearInterval( scroller );
});
function moveBackdrop(){
if ( parseInt(years.css("left"), 10) <= 0 ) {
x += maxspeed * rate;
var newpos = x+'px';
years.css('left',newpos);
} else {
years.css('left','0');
}
}
The code in question is right here at the end^
Is this what you were trying to do?
function moveBackdrop(){
if ( parseInt(years.css("left"), 10) <= 0 && rate < 0 ) {
// Means that the element is already at left: 0 or less,
// and we are trying to move it even more left with rate being negative.
// So keep the element at left: 0
years.css('left','0');
} else {
x += maxspeed * rate;
var newpos = x+'px';
years.css('left',newpos);
}
}
Extra note for future: parseInt uses base 10 by default :) so parseInt("20px") will equal 20
Final Edit: Ah there is an even better way to do it.
function moveBackdrop(){
x += maxspeed * rate;
if( x < 0 ) x = 0; // If left less than 0, fix it at 0
var newpos = x+'px';
years.css('left',newpos);
}

Changing attribute dynamically of a svg element using setTimeout doesn't work as expected

I am trying to move an SVG to, say, X,Y by having a setTimeout call the moveSelected function recursively. The moveSelected function in turn sets the new x and y a little closer to X,Y to reproduce the animation effect.
Here is my function:
this.moveSelected = function moveSelected(moveToHex) {
//setting new cords on screen
var self=this;
var repeater;
var curX = parseInt(this.selectedEle.getAttribute('cx'));
var curY = parseInt(this.selectedEle.getAttribute('cy'));
//console.log('curX '+curX+'curY ',curY);
if(curX < moveToHex.cx) //moveRight
{
this.selectedEle.setAttribute('cx', curX + .5);
}
if(curX > moveToHex.cx) //moveLeft
{
this.selectedEle.setAttribute('cx',curX-.5);
}
if(curY < moveToHex.cy) //movedown
{
console.log('move down');
this.selectedEle.setAttribute('cy', curY + .5);
}
if(curY > moveToHex.cy) //moveup
{
console.log('move Up');
this.selectedEle.setAttribute('cy', curY - .5);
}
console.log('condition:' + curY + '<' + parseInt(moveToHex.cy));
if((Math.abs(curY - moveToHex.cy)) < 1 &&
(Math.abs(curX - moveToHex.cx) < 1)) {
clearTimeout(repeater);
unitArray[this.selectedUnit.num].hexagon = moveToHex;
console.log('cleared');
}
else if(!repeater) {
repeater = setTimeout(function() {
self.moveSelected(moveToHex)
}, 25);
}
}
Now everything works as expected but the movedown and moveRight conditions, i.e. curY + .5 and curX + .5.
I tried consoling out the values but don't understand why it is behaving like that. I assumed it is typecasting problem but typecasting as curX and curY into int didn't help either
Fiddle:
https://jsfiddle.net/Snedden27/z4xfy6n8/2/ (scroll to the two movable circles at the right)

JS - moving an image horizontally after a period of time

Everything was going smoothly until now. I want to have this hor() function reverse after 20 seconds. The original hor() function grabs an image offscreen and moves it horizontally from the left to the center of the page. I'd like to create a function that does the opposite after 20 seconds. The "after 20 seconds" part is giving me the most grief. If you could show me what a new function would look like or an 'else' addition to the current function that would be great. Thanks.
<script language="JavaScript" type="text/JavaScript">
var x = -500;
var y = 100;
function hor(val) {
if (x <= 500){
x = x + val;
document.getElementById("pos").style.left = x + "px";
setTimeout("hor(5)", 10);
}
}
</script>
<style type="text/css">
<!--
#pos {
position: absolute;
left: -500px;
top: 100px;
z-index: 0;
}
</style>
<body onLoad="setTimeout('hor(5)',5000)">
<div id="pos">
<img src="image.jpg">
</div>
Perhaps you could try changing the script to this:
// Define variables
var x = -500,
y = 100,
direction = 1;
// Function which moves "pos" element
function hor(val) {
// Move by specified value multiplied by direction
x += val * direction;
if(x > 500){
x = 500;
// Reverse direction
direction = -1;
} else if(x < -500){
x = -500;
// Reverse direction, once again
direction = 1;
}
// Move element
document.getElementById("pos").style.left = x + "px";
// Continue loop
setTimeout("hor("+val+")", 10);
}
This code will continue moving the pos element by the specified value until x greater than 500, at which point it will switch direction, then continue until x reaches -500, and so on.
EDIT:
This code will fix that issue with 20 seconds (I had thought that the 500 pixel thing computed to 20 seconds, lol).
// Define variables
var x = -500,
y = 100,
direction = 1;
firstCall = true;
timeElapsed = 0;
// Function which moves "pos" element
function hor(val) {
// Don't let the first call count!
if(!firstCall)timeElapsed += 10;
else firstCall = false;
if(timeElapsed >= 2000){
// Reverse direction
direction *= -1;
timeElapsed = 0;
}
// Move by specified value multiplied by direction
x += val * direction;
// Move element
document.getElementById("pos").style.left = x + "px";
// Continue loop
setTimeout("hor("+val+")", 10);
}
Try this. Here the img is moved horizontally and after sometime it is reverted back to its original position.
<script>
var x = -500;
var y = 100;
var op;
function hor(val) {
if (x <= 500 && x>=-500) {
x = x + val;
document.getElementById("pos").style.left = x + "px";
setTimeout(function(){hor(val);},10);
}
}
$(document).ready(function(){
setTimeout(function(){hor(5);},1000);
setInterval(function(){
setTimeout(function(){hor(-5);},1000);
},2000);
});
</script>
I have changed the timings for testing purpose only, you can change it back.

Div scroll with fixed steps like the select element

I'm trying to make a div to mimick the select-element in some ways but that also allow me to style and layout each item/option in any way I like.
One behaviour I'm trying to copy is the scrolling which is in fixed steps with the select-element.
How can I get this behaviour for a div-element (with any number of child-divs)?
(The child-div height is the same for every element)
The scrollbar should never be able to be put in a non multiple position of the child-div height.
UPDATE
This is the solution I came up with:
var scroller;
var itemHeight = 300;
function init(){
scroller = document.getElementById('scrollDiv');
scroller.onscroll = fixedScroll;
scroller.onmousewheel = mousewheel;
scroller.onkeydown = keydown;
}
function fixedScroll(e){
e.target.scrollTop = Math.round(e.target.scrollTop / itemHeight) * itemHeight;
}
function mousewheel(e){
e.preventDefault();
var sign = e.wheelDelta > 0 ? -1 : 1;
e.target.scrollTop += sign * itemHeight;
}
function keydown(e){
var sign = 0;
if (e.keyCode === 40) sign = 1;
else if (e.keyCode === 38) sign = -1;
e.target.scrollTop += sign * itemHeight;
}
init();
Fiddle:
http://jsfiddle.net/4tj6r/61/
Try this:
EDIT Ah, it called upon itself once changing the scroll position so it ended up breaking the whole thing. This should do.
And a DEMO
var delta;
var scroller;
function init(){
scroller = document.getElementById('scrollDiv');
scroller.onscroll = fixedScroll;
delta = scroller.scrollTop;
}
function fixedScroll(e){
if(delta < e.target.scrollTop)
e.target.scrollTop = delta + 100;
if(delta > e.target.scrollTop)
e.target.scrollTop = delta - 100;
delta = e.target.scrollTop;
}
<body onload="init();">
<div id="scrollDiv" style="overflow:auto;height:100px;"></div>

Categories