Javascript - setInterval to change element's position - javascript

I'm trying to work out how to move an element across the screen. I don't want to use JQuery's animate() method because I need more precise control. Here is the basic idea:
http://jsfiddle.net/9RLkJ/
setInterval(function() {
var e = document.getElementById("aDiv");
// Increase the top position by 1 pixel
e.style.top = '+1px';
// If the top position is greater than 100px, set it to 100px
if (parseInt(e.style.top) > 100) { e.style.top = '100px'; }
}, 1000);
Thank you.

var e = document.getElementById("aDiv");
var s = 1;
setInterval(function(){
var eLeftPos = e.offsetLeft;
e.style.left = (eLeftPos + s) + 'px';
}, 1000);
The above code will move the box to right;
working demo move the box to bottom

var top= document.getElementById("aDiv").style.top;
setInterval(function() {
top += 1;
var e = document.getElementById("aDiv");
// Increase the top position by 1 pixel
e.style.top = top + 'px';
// If the top position is greater than 100px, set it to 100px
if (parseInt(e.style.top) > 100) { e.style.top = '100px'; }
}, 1000);

Related

generate animation as if it were a marquee

I do not know much about css, but I think this code could help me generate a marquee. basically I want the animation that is done with the boxes, be done with the texts.
My main problem occurs with the animation, it is not very fluid, I want it to be more fluid and it starts from the end of the container to the left. How can I do it? I would be very grateful.
http://jsfiddle.net/joof5dhx/
<div id="horizontalScroller">
<div>it is a message a little more of 100 characteres</div>
<div>it is a message a little more of 110 characteres</div>
<div>it is a message a little more of 120 characteres</div>
<div>it is a message a little more of 130 characteres</div>
</div>
window.horizontalScroller = function($elem) {
var left = parseInt($elem.css("left"));
var temp = -1 * $('#horizontalScroller > div').height();
if(left < temp) {
left = $('#horizontalScroller').height()
$elem.css("left", left);
}
$elem.animate({ left: (parseInt(left)-60) }, 900, function () {
window.horizontalScroller($(this))
});
}
$(document).ready(function() {
var i = 0;
$("#horizontalScroller > div").each(function () {
$(this).css("left", i);
i += 60;
window.horizontalScroller($(this));
});
});
http://jsfiddle.net/hhcbtyyg/
You could just:
window.horizontalScroller = function($elem)
{
var left = parseInt($elem.css("left"));
$elem.animate({ left: (parseInt(left)-60) }, 900, function ()
{
// get the current left of the element
var currentLeft = parseInt($(this).css("left"));
// get the width of the element
var width = $(this).width();
// get the container
var container = $(this).parent("#horizontalScroller");
// get the width of the container
var containerWidth = $(container).width();
// check if the element goes out of the view item X + item w < 0
if ((currentLeft + width) <= 0)
{
// put it on the opposite side: simply container w + item w
$(this).css("left", (containerWidth + width) + "px");
}
window.horizontalScroller($(this))
});
}
I just don't understand why you use height in your code above. If there is something I don't know let me know.
UPDATED:
To make the items appear on the leftmost by default:
$(document).ready(function() {
var container = $("#horizontalScroller");
var children = $(container).children();
var containerW = $(container).width();
// Loop through each item of container
for (var i = 0; i < children.length; i++)
{
var item = children[i];
var itemW = $(item).width();
// this is simply the space between them, remove if you don't need it
var padding = 10 * (i + 1);
// simply: padding + Container Width + (Item Width * (i + 1))
// (Item Width * (i + 1)) because you need to position each element beside each other.
$(item).css("left", (padding + containerW + itemW * (i + 1)) + "px");
window.horizontalScroller($(item));
}
});
your updated fiddle
hope that helps
Hi checked this version of your jsfiddle, i did some modificaitons, since your animation starts from whatever the value of height is your div had. check this I tried to match the height of your css and width in your css, i just noticed that the "left" var in your js gets the height of your element.
CSS:
#horizontalScroller {
position: absolute;
width:300px;
height: 300px;
border: 1px solid red;
overflow: hidden;
}
Maybe you can get some tips how to accomplish it in responsive way.
JSFIDDLE

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);
}

select specific area of a div

I made a carousel using 2 divs named "left" and "right" putting mousemove events on them. I wanted to make it go up and down as well so I created a "top" and "bottom" and noticed that I couldn't make them combine to go the way the cursor goes.
I thus thought of targeting a specific area in the container (i.e top half of my container div) instead of creating divs inside triggering a specific direction, this way (I think) I can trigger all these event altogether. However after now hours of research I couldn't find a way to do so.
How should I proceed ? here is the code : http://jsfiddle.net/pool4/vL5g3/3/
var x=0,
y=0,
rateX=0,
rateY=0,
maxspeed=10;
var backdrop = $('.backdrop');
$('.directionx', backdrop).mousemove(function(e){
var $this = $(this);
var left = $this.is('.left');
var right = $this.is('.right');
if (left){
var w = $this.width();
rateX = (w - e.pageX - $this.offset().left + 1)/w;
}
else if (right){
var w = $this.width();
rateX = -(e.pageX - $this.offset().left + 1)/w;
}
});
$('.directiony', backdrop).mousemove(function(e){
var $this = $(this);
var top = $this.is('.top');
var bottom = $this.is('.bottom');
if (top){
var h = $this.height();
rateY = (h - e.pageY - $this.offset().top + 1)/h;
}
else if (bottom) {
var h = $this.height();
rateY = -(e.pageY - $this.offset().top + 1)/h;
}
});
backdrop.hover(
function(){
var scroller = setInterval( moveBackdrop, 30 );
$(this).data('scroller', scroller);
},
function(){
var scroller = $(this).data('scroller');
clearInterval( scroller );
}
);
function moveBackdrop(){
x += maxspeed * rateX;
y += maxspeed * rateY;
var newpos = x+'px '+y+'px';
backdrop.css('background-position',newpos);
}
Your problem is that the divs that control movement up and down are placed over the ones that control left and right, so the latter do not receive the mousemove event ever. Mouse events do not propagate through layers, even if they're transparent. I changed your code and CSS, so each div is in one of the corners. To make things easier, I've used data-* attributes so the direction controlled by each div is set in a declarative way, without the need to change the code. You'll see that the code is much simpler (and it could be simplified even more).
By the way, you could achieve this witout extra divs, just controlling where the cursor is (to the top, right, left or bottom of the center of the div).
backdrop.on('mousemove', '.dir', function(e){
var $this = $(this);
var direction = $(e.target).attr('data-direction');
var left = direction.indexOf('left') > - 1;
var right = direction.indexOf('right') > - 1;
var top = direction.indexOf('up') > - 1;
var bottom = direction.indexOf('down') > - 1;
if (left){
var w = $this.width();
rateX = (w - e.pageX - $this.offset().left + 1)/w;
}
else if (right){
var w = $this.width();
rateX = -(e.pageX - $this.offset().left + 1)/w;
}
if (top){
var h = $this.height();
rateY = (h - e.pageY - $this.offset().top + 1)/h;
}
else if (bottom) {
var h = $this.height();
rateY = -(e.pageY - $this.offset().top + 1)/h;
}
});
I've updated your fiddle.
EDIT In this new fiddle I do it without extra divs:
var w = backdrop.width() / 2;
var h = backdrop.height() / 2;
var center = {
x: backdrop.offset().left + backdrop.width() / 2,
y: backdrop.offset().top + backdrop.height() / 2
};
backdrop.on('mousemove', function(e){
var offsetX = e.pageX - center.x;
var offsetY = e.pageY - center.y;
rateX = -offsetX / w;
rateY = -offsetY / h;
});
backdrop.hover(
function(){
var scroller = $(this).data('scroller');
if (!scroller) {
scroller = setInterval( moveBackdrop, 30 );
$(this).data('scroller', scroller);
}
},
function(){
var scroller = $(this).data('scroller');
if (scroller) {
clearInterval( scroller );
$(this).data('scroller', null);
}
}
);
As you see, the mousmove handler is considerably simpler.
To avoid issue of children losing event could use just the one.
First HTML from 4 child divs to just one
<div class="backdrop">
<div class="direction"></div>
</div>
<div id="pos"></div>
Next Inside the mousemove find your relative position
//Get Relative Position
var relX = e.pageX - $this.offset().left;
var relY = e.pageY - $this.offset().top;
Get Relative Position as a percentage of width and put 50% of it in negative for direction
var w = $this.width();
rateX = ((relX / w) - 0.5) * -1;
var h = $this.height();
rateY = ((relY / h) - 0.5) * -1;
Fiddle

Fixed sidebar on the scroll stop at div

I try to make sure that a div "filter" becomes fixed when scrolling and then stop when it comes down to "outside_footer_wrapper". use the following script but can not get it to work?
jsfiddle
$(function() {
var top = $('#filter').offset().top - parseFloat($('#filter').css('marginTop').replace(/auto/, 0));
var footTop = $('#outside_footer_wrapper').offset().top - parseFloat($('#outside_footer_wrapper').css('marginTop').replace(/auto/, 0));
var maxY = footTop - $('#filter').outerHeight();
$(window).scroll(function(evt) {
var y = $(this).scrollTop();
if (y > top) {
if (y < maxY) {
$('#filter').addClass('fixed').removeAttr('style');
} else {
$('#filter').removeClass('fixed').css({
position: 'absolute',
top: (maxY - top) + 'px'
});
}
} else {
$('#filter').removeClass('fixed');
}
});
});
If you want to stop the position:fixed after you reach the footer you can do something like this faking with the top:
$(function() {
var top = $('#filter').offset().top,
footTop = $('#outside_footer_wrapper').offset().top,
maxY = footTop - $('#filter').outerHeight();
$(window).scroll(function(evt) {
var y = $(this).scrollTop();
if (y > top) {
$('#filter').addClass('fixed').removeAttr('style');
if (y > maxY-20){
var min = y - maxY + 20;
$('#filter').css('top','-'+min+'px');
}
} else {
$('#filter').removeClass('fixed');
}
});
});
Also take in care with the CSS for the class fixed you need to make that with equal specificity of #filter I made this change:
#sidebar #filter.fixed /*Add #sidebar*/
Check This Demo Fiddle
if you know at which pixel number the filter have to be fixed and at which pixel number the footer starts you can try this function:
scrollTop
Is it something like this?
jsfiddle
// get box div position
var box = document.getElementById('box').offsetTop;
window.onscroll = function(){
// get current scroll position
var scroll_top = document.body.scrollTop || document.documentElement.scrollTop;
document.getElementById('scbox').innerText = scroll_top + ' ' + box;
// if current scroll position >= box div position then box position fixed
if(scroll_top >= box)
document.getElementById('box').style.position = 'fixed';
else
document.getElementById('box').style.position = 'relative';
}
try this:
#sidebar {
position: fixed;
}
jsfiddle here

JS/jQuery delay loop to get desire result (delay() not working)

I'm trying to create an loading icon by moving the css 'background-position' of an image in a loop:
$('#LoginButton').click(function () {
var i = 1, h = 0, top;
for (i = 0; i <= 12; i++) {
h = i * 40;
top = h + 'px';
$('#ajaxLoading').css('background-position', '0 -' + top).delay(800);
}
});
The problem here is that it runs to fast so I don't se the 'animation' of the moving background.
So I added jquerys delay(), but:
delay(800) is not working because delay() only works in jquery animation effects and .css() is not one of those.
How to delay this loop?
I'd suggest using jQuery timer plugin: http://jquery.offput.ca/js/jquery.timers.js
$('#LoginButton').click(function () {
var times = 13;
var delay = 300;
var h = 0, top;
$(document).everyTime(delay, function(i) {
top = h + 'px';
$('#ajaxLoading').css('background-position', '0 -' + top);
h += 40;
}, times);
});
In case you don't want any plugins, use setInterva/clearInterval:
$('#LoginButton').click(function () {
var delay = 300;
var times = 13;
var i = 0, h = 0, top;
doMove = function() {
top = h + 'px';
$('#ajaxLoading').css('background-position', '0 -' + top);
h += 40;
++i;
if( i >= times ) {
clearInterval( interval ) ;
}
}
var interval = setInterval ( "doMove()", delay );
});
Have you looked at using animate() instead of css()? I'm not 100% sure I understand what you're trying to accomplish, so this is kinda a shot in the dark.
http://api.jquery.com/animate/
Chrome, Safari and IE3+ should support background-position-y, so if you're targeting these specific browser, using jquery you could just make a timed animation() on backgroundPositionY property - http://snook.ca/archives/html_and_css/background-position-x-y
(On Firefox the effect won't work)
You can use setTimeout() and clearTimeout() functions in order to accomplish that.
IE:
var GLOBAL_i = 0;
function doAnimation() {
var h = GLOBAL_i * 40;
var top = h + 'px';
$('#ajaxLoading').css('background-position', '0 -' + top);
if (GLOBAL_i < 12) {
GLOBAL_i++;
t=setTimeout(doAnimation, 800);
}
}
$('#LoginButton').click(function () {
doAnimation()
});

Categories