Random natural jquery movement

How can I recreate this moving type using jquery for images: http://www.istockphoto.com/stock-video-12805249-moving-particles-loop-soft-green-hd-1080.php

I plan to use it as the background of a web page. If this is not possible with jquery, I will go with as3 flash. But I prefer jquery.

+6
javascript jquery random raphael
source share
4 answers

Edit: Raphael is definitely better suited for this, since it supports IE. The problem with jQuery is that rounded corners are a pain that needs to be done in IE due to CSS limitations ... there is no sweat in the circles of raster browsers Raphael.

jsFiddle with Raphael - all browsers :

(although it may look better accelerated in IE )

(function() { var paper, circs, i, nowX, nowY, timer, props = {}, toggler = 0, elie, dx, dy, rad, cur, opa; // Returns a random integer between min and max // Using Math.round() will give you a non-uniform distribution! function ran(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function moveIt() { for(i = 0; i < circs.length; ++i) { // Reset when time is at zero if (! circs[i].time) { circs[i].time = ran(30, 100); circs[i].deg = ran(-179, 180); circs[i].vel = ran(1, 5); circs[i].curve = ran(0, 1); circs[i].fade = ran(0, 1); circs[i].grow = ran(-2, 2); } // Get position nowX = circs[i].attr("cx"); nowY = circs[i].attr("cy"); // Calc movement dx = circs[i].vel * Math.cos(circs[i].deg * Math.PI/180); dy = circs[i].vel * Math.sin(circs[i].deg * Math.PI/180); // Calc new position nowX += dx; nowY += dy; // Calc wrap around if (nowX < 0) nowX = 490 + nowX; else nowX = nowX % 490; if (nowY < 0) nowY = 490 + nowY; else nowY = nowY % 490; // Render moved particle circs[i].attr({cx: nowX, cy: nowY}); // Calc growth rad = circs[i].attr("r"); if (circs[i].grow > 0) circs[i].attr("r", Math.min(30, rad + .1)); else circs[i].attr("r", Math.max(10, rad - .1)); // Calc curve if (circs[i].curve > 0) circs[i].deg = circs[i].deg + 2; else circs[i].deg = circs[i].deg - 2; // Calc opacity opa = circs[i].attr("fill-opacity"); if (circs[i].fade > 0) { circs[i].attr("fill-opacity", Math.max(.3, opa - .01)); circs[i].attr("stroke-opacity", Math.max(.3, opa - .01)); } else { circs[i].attr("fill-opacity", Math.min(1, opa + .01)); circs[i].attr("stroke-opacity", Math.min(1, opa + .01)); } // Progress timer for particle circs[i].time = circs[i].time - 1; // Calc damping if (circs[i].vel < 1) circs[i].time = 0; else circs[i].vel = circs[i].vel - .05; } timer = setTimeout(moveIt, 60); } window.onload = function () { paper = Raphael("canvas", 500, 500); circs = paper.set(); for (i = 0; i < 30; ++i) { opa = ran(3,10)/10; circs.push(paper.circle(ran(0,500), ran(0,500), ran(10,30)).attr({"fill-opacity": opa, "stroke-opacity": opa})); } circs.attr({fill: "#00DDAA", stroke: "#00DDAA"}); moveIt(); elie = document.getElementById("toggle"); elie.onclick = function() { (toggler++ % 2) ? (function(){ moveIt(); elie.value = " Stop "; }()) : (function(){ clearTimeout(timer); elie.value = " Start "; }()); } }; }());​ 

The first attempt to solve jQuery is below:


This jQuery attempt almost doesn't work in IE and is slow in FF. Chrome and Safari succeed:

JsFiddle example for all browsers (IE is not so good)

(I did not implement fade in IE, and IE does not have rounded corners ... also JS is slower, so it looks pretty bad)

JsFiddle example for Chrome and Safari (only 4 times as many particles)

 (function() { var x, y, $elie, pos, nowX, nowY, i, $that, vel, deg, fade, curve, ko, mo, oo, grow, len; // Returns a random integer between min and max // Using Math.round() will give you a non-uniform distribution! function ran(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function moveIt() { $("div.spec").each(function(i, v) { $elie = $(v); if (! $elie.data("time")) { $elie.data("time", ran(30, 100)); $elie.data("deg", ran(-179, 180)); $elie.data("vel", ran(3, 10)); $elie.data("curve", ran(0, 1)); $elie.data("fade", ran(0, 1)); $elie.data("grow", ran(-2, 2)); } vel = $elie.data("vel"); deg = $elie.data("deg"); fade = $elie.data("fade"); curve = $elie.data("curve"); grow = $elie.data("grow"); len = $elie.width(); if (grow > 0) len = Math.min(len + grow, 50); else len = Math.max(len + grow, 20); $elie.css("-moz-border-radius", len/2); $elie.css("border-radius", len/2); $elie.css("width", len); $elie.css("height", len); pos = $elie.position(); $elie.data("time", $elie.data("time") - 1); if (curve) $elie.data("deg", (deg + 5) % 180); else $elie.data("deg", (deg - 5) % 180); ko = $elie.css("-khtml-opacity"); mo = $elie.css("-moz-opacity"); oo = $elie.css("opacity"); if (fade) { $elie.css("-khtml-opacity", Math.max(ko - .1, .5)); $elie.css("-moz-opacity", Math.max(mo - .1, .5)); $elie.css("opacity", Math.max(oo - .1, .5)); } else { $elie.css("-khtml-opacity", Math.min(ko - -.1, 1)); $elie.css("-moz-opacity", Math.min(mo - -.1, 1)); $elie.css("opacity", Math.min(oo - -.1, 1)); } if (vel < 3) $elie.data("time", 0); else $elie.data("vel", vel - .2); nowX = pos.left; nowY = pos.top; x = vel * Math.cos(deg * Math.PI/180); y = vel * Math.sin(deg * Math.PI/180); nowX = nowX + x; nowY = nowY + y; if (nowX < 0) nowX = 490 + nowX; else nowX = nowX % 490; if (nowY < 0) nowY = 490 + nowY; else nowY = nowY % 490; $elie.css("left", nowX); $elie.css("top", nowY); }); } $(function() { $(document.createElement('div')).appendTo('body').attr('id', 'box'); $elie = $("<div/>").attr("class","spec"); // Note that math random is inclussive for 0 and exclussive for Max for (i = 0; i < 100; ++i) { $that = $elie.clone(); $that.css("top", ran(0, 495)); $that.css("left", ran(0, 495)); $("#box").append($that); } timer = setInterval(moveIt, 60); $("input").toggle(function() { clearInterval(timer); this.value = " Start "; }, function() { timer = setInterval(moveIt, 60); this.value = " Stop "; }); }); }());​ 
+9
source share

[Partial answer, physics only.]

[I just saw the previous answer, mine is somewhat in the same row.]

You can try to simulate some Brownian motion, i.e. motion resulting from a combination of random force and viscous attenuation. Pseudocode:

 initialize: x = random_position(); v_x = random_velocity(); // v_x = velocity along x // and same for y for (each time step) { x += v_x; v_x += random_force() - time_step / damping_time * v_x; // and same for y } 

Hold the decay time (~ 1 s) and the amplitude of the random force is small. Otherwise, the movement may be too jerky.

For an easy-to-use Gaussian random number generator, find Box-Muller on Wikipedia.

+4
source share

For mathematics, you give each object a starting position and speed. "Random walk" is achieved by calculating a random angle, which is limited to a certain amount (experiment). Then change the angle of the velocity vector to this angle. You can also calculate the delta of a random velocity and change the magnitude of the vector by that magnitude. As you work with speed, the movements will be somewhat smooth. A slightly more advanced approach to working with acceleration directly and calculating speed and position based on this.

For your random steering value, a binomial distribution is preferable to a uniform one. Binomial distributions are centered around 0 and not evenly distributed. You can just do random () - random () (psuedocode)

Vector math is widely documented, but if you run into a problem, leave a comment.

+2
source share

a very late answer on my part, but I thought I could give an approach ...

I personally would use the svg vector image. Create a jquery plugin that accepts opacity, size. and makes them move in a random direction. Then do a javascript loop to create a set of these particles (where opacity and size are random and the starting location is random) Then make the jquery plugin initiate a new instance of itself when the particle is unloaded.

(If you look at a small film, you will see that they move in one direction and disappear, then the other disappears.)

The opacity effect will give a perspective of depth.

Not sure if my answer helps, but I would go in that direction.

+1
source share

All Articles