34

I've been doing some Googling to find an answer to this, but I've had no luck. It could be because I'm a bit of an amateur and I don't know the proper terms to search for, but maybe someone here can steer me in the right direction or help me out.

Anyway, I'm looking for a way to get a div to randomly, smoothly move around a page. There will be a background color, then this image which I want to seemingly randomly, infinitely move around the page. Much like the background of a DVD player's home screen where "DVD" is just floating around.

Starting point of the div doesn't matter, nor does the ending point. It just needs to randomly move around the page for the duration a user is on that page.

I've got decent HTML and CSS skills, very basic JS skills, and some experience implementing jQuery. Ideally, I'd like something which I can implement myself.

Thanks in advance!!!

0

7 Answers 7

53

The basic premise is to generate positional values, and use jquery's animate() function to move the div. The calculation of the next position is simple, you just need a bit of math. Here's a very basic jsfiddle i just knocked up. It could do with possibly a delay timer, a dynamically calculating speed based on how far its got too move e.c.t. But it gives you a start point i hope.

http://jsfiddle.net/Xw29r/

Updated example code with speed modifier:

http://jsfiddle.net/Xw29r/15/


For some reason this is still getting some attention, so here's an updated answer that uses CSS transitions which should be much smoother.

http://jsfiddle.net/bf9nv1q6/

function RandomObjectMover(obj, container) {	this.$object = obj; this.$container = container; this.container_is_window = container === window; this.pixels_per_second = 250; this.current_position = { x: 0, y: 0 }; this.is_running = false; } // Set the speed of movement in Pixels per Second. RandomObjectMover.prototype.setSpeed = function(pxPerSec) {	this.pixels_per_second = pxPerSec; } RandomObjectMover.prototype._getContainerDimensions = function() { if (this.$container === window) { return { 'height' : this.$container.innerHeight, 'width' : this.$container.innerWidth }; } else { return { 'height' : this.$container.clientHeight, 'width' : this.$container.clientWidth }; } } RandomObjectMover.prototype._generateNewPosition = function() {	// Get container dimensions minus div size var containerSize = this._getContainerDimensions();	var availableHeight = containerSize.height - this.$object.clientHeight; var availableWidth = containerSize.width - this.$object.clientHeight; // Pick a random place in the space var y = Math.floor(Math.random() * availableHeight); var x = Math.floor(Math.random() * availableWidth); return { x: x, y: y }; } RandomObjectMover.prototype._calcDelta = function(a, b) {	var dx = a.x - b.x; var dy = a.y - b.y; var dist = Math.sqrt( dx*dx + dy*dy ); return dist; } RandomObjectMover.prototype._moveOnce = function() {	// Pick a new spot on the page var next = this._generateNewPosition(); // How far do we have to move? var delta = this._calcDelta(this.current_position, next);	// Speed of this transition, rounded to 2DP	var speed = Math.round((delta / this.pixels_per_second) * 100) / 100; //console.log(this.current_position, next, delta, speed); this.$object.style.transition='transform '+speed+'s linear'; this.$object.style.transform='translate3d('+next.x+'px, '+next.y+'px, 0)'; // Save this new position ready for the next call. this.current_position = next; }; RandomObjectMover.prototype.start = function() {	if (this.is_running) {	return; }	// Make sure our object has the right css set this.$object.willChange = 'transform'; this.$object.pointerEvents = 'auto'; this.boundEvent = this._moveOnce.bind(this) // Bind callback to keep things moving this.$object.addEventListener('transitionend', this.boundEvent); // Start it moving this._moveOnce(); this.is_running = true; } RandomObjectMover.prototype.stop = function() {	if (!this.is_running) {	return; } this.$object.removeEventListener('transitionend', this.boundEvent);	this.is_running = false; } // Init it var x = new RandomObjectMover(document.getElementById('a'), window); // Toolbar stuff document.getElementById('start').addEventListener('click', function(){	x.start(); }); document.getElementById('stop').addEventListener('click', function(){	x.stop(); }); document.getElementById('speed').addEventListener('keyup', function(){ if (parseInt(this.value) > 3000 ) {	alert('Don\'t be stupid, stupid'); this.value = 250; }	x.setSpeed(parseInt(this.value)); }); // Start it off x.start();
div#toolbar { position:fixed; background:#20262F; width:100%; text-align:center; padding: 10px } div#a { width: 50px; height:50px; background-color:red; position:absolute; }
<div id="toolbar"> <button id="start">Start</button> <button id="stop">Stop</button> <input type="number" value="250" id="speed" /> </div> <div id='a'></div>

Sign up to request clarification or add additional context in comments.

15 Comments

That speed modifier worked great! (If you lived locally I'd give you a cookie.) Ya know, I understand what's going on in the code when I read it, but I would definitely not have been able to create it myself. You guys are awesome!
So the code worked in jsfiddle, but as soon as I plugged it into Dreamweaver something is off. I've got all my CSS and JQ internally as to only share one file, but something is strange. I literally copied and pasted everything, but it's still not working. Here is a copy of my code (sorry, can't indent on this website): tinytext.org/YmXT# Any idea why it might not be working? I plugged in that alert and it's not even making it into that block for me.
It's a weird one, but do this. the end brace (squiggly bracket } ) on the calcSpeed function. Delete that and re-add it by typing it in on your keyboard. Save it then re-test your script. Looks like it's copied the ending brace on that function in a weird way. So you just need to re-type that character
That worked! A) How did you figure that was the problem? and B) Any idea why/how that happened?
@Ivan I never tested anything but a window container. It's because only window supports innerHeight. I've updated the code snippet to fix the container dimensions to work with non-window. Example here: jsfiddle.net/d67Lztmc
|
8

Try this:

function moveDiv() { var $span = $("#random"); $span.fadeOut(1000, function() { var maxLeft = $(window).width() - $span.width(); var maxTop = $(window).height() - $span.height(); var leftPos = Math.floor(Math.random() * (maxLeft + 1)) var topPos = Math.floor(Math.random() * (maxTop + 1)) $span.css({ left: leftPos, top: topPos }).fadeIn(1000); }); }; moveDiv(); setInterval(moveDiv, 5000); 

Example fiddle

3 Comments

This is exactly what I want, except I need to to be a smooth animation, not jumpy. I'll have to see what everyone else posted, but thanks!!
@Ephraim no problem - I've just updated the code and fiddle so that it fade in and out smoothly.
Great, but how make multiple? if i have 30 images and 5 only must be showed in one time
6

well you'll need to capture the dimensions of the window

then you'll need to generate random numbers <= the height and width of the screen (minus the width/height of the box)

give the box an absolute position, and give the box have the generated x,y coordinates

then set a timer to call this function again.

:)

$(document).ready(function() { randoBox = { width:$("body").width(), height:$("body").height(), x:0, y:0, el:null, time:1000, state:"active", init: function(){ el = $(document.createElement('div')); el.attr("style","position:absolute;left:"+this.x+";top:"+this.y+";"); el.html("DVD") el.height(100); el.width(100); $("body").append(el); }, move:function(){ this.y = Math.random()*this.height+1; this.x = Math.random()*this.width+1; el.attr("style","position:absolute;left:"+this.x+";top:"+this.y+";"); }, run:function(state){ if (this.state == "active" || state){ this.move(); setTimeout(function(){this.run()},this.time); } } } randoBox.init(); randoBox.run(true); }); 

Comments

3

EDIT Added random movement, like DVD idle screen but can bounce anywhere.

http://jsfiddle.net/ryXBM/2/

dirR = "+=2"; dirL = "+=2"; function moveDir() { if (Math.random() > 0.95) { swapDirL(); } if (Math.random() < 0.05) { swapDirR(); } } function swapDirL() { dirL == "+=2" ? dirL = "-=2" : dirL = "+=2"; } function swapDirR() { dirR == "+=2" ? dirR = "-=2" : dirR = "+=2"; } setInterval (function() { $("#d").css("left", dirL); $("#d").css("top", dirR); moveDir(); } , 50)​ 

CSS

#d { position: absolute; left: 100px; top: 100px; width: 100px; height: 100px; background-color: #fce; }​ 

3 Comments

Leaving the randomness implementation to the questioner
Therefore only partially answering the question. If the OP asked how to move an element then this would be an acceptable answer.
This looks petty random to me, which means it will look random to a user. Still not the exact effect I'm looking for though, but I will play around with this code and see what I can tweak. Thanks!!
1

You could use jQuery Slide and Math.random(), generating one random number to use as the distance to move and another random number to base your decision on which direction to move in.

Comments

0

You'll want to specify the borders of the animation - what is the maximum values for the top and left attributes... After that all you need is the .animate() function to be called again and again...

Something like this should work -

var maxLeft = _left_border - $('#selectedElement').width(); // counter intuitively this is actually the right border var maxTop = _top_border - $('#selectedElement').height(); var animationDurration = _duration; function randomAnimation(){ var randomLeft = Math.floor(Math.random()*maxLeft); var randomTop = Math.floor(Math.random()*maxTop); $('#selectedElement').animate({ left: randomLeft, top: randomTop }, animationDurration, function() { randomAnimation(); }); } 

Comments

0
<html> <head> <link rel="stylesheet" href="sample1.css"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $('.btn').mouseover(function(){ $(this).css({ left:(Math.random()*$(window).width()-20), top:(Math.random()*$(window).height()-20), }); }); }); </script> </head> <body> <div class="btn" style="position: absolute">button</div> </body> </html> 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.