Updated version of the Warp Starfield demo. Tracks the mouse to modify the direction of the warp field, plus you can use the mouse scroll-wheel to control warp speed!
d=document.body.style;d.margin="0px";d.overflow="hidden";c=window,d=c.innerWidth,e=c.innerHeight,g=document.getElementById("c"),i=d/2,j=e/2;g.width=d;g.height=e;k=g.getContext("2d");k.globalAlpha=0.3;l=Math,m=l.random,n=l.sin,o=l.floor,p=10,q=[],r=0,s=0.1,V=500,W=190,Q=0.3;function E(n,f){g.addEventListener(n,f,false);}E("mousemove",function(a){i=a.clientX;j=a.clientY});function t(a){var f=0;if(a.detail) f=-a.detail/3;else f=a.wheelDelta/120;if(f>0&&s<1||f<0&&s>0.1)s+=f/25}E("DOMMouseScroll",t);E("mousewheel",t);function u(a){a.x=(m()*d-d*0.5)*p;a.y=(m()*e-e*0.5)*p;a.a=p;a.b=0;a.c=0}for(var v=0,w;v<V;v++){w={};u(w);q.push(w)}setInterval(function(){k.fillStyle="#000";k.fillRect(0,0,d,e);for(a=i-d/2+d/2,f=j-e/2+e/2,h=0;h<V;h++){b=q[h],x=b.x/b.a,y=b.y/b.a,z=1/b.a*5+1,A=n(Q*h+r)*64+W,B=n(Q*h+2+r)*64+W,C=n(Q*h+4+r)*64+W;if(b.b!=0){k.strokeStyle="rgb("+o(A)+","+o(B)+","+o(C)+")";k.lineWidth=z;k.beginPath();k.moveTo(x+a,y+f);k.lineTo(b.b+a,b.c+f);k.stroke()}b.b=x;b.c=y;b.a-=s;if(b.a<s||b.b>d||b.c>e)u(b)}r+=0.1},25);
ZD1kb2N1bWVudC5ib2R5LnN0eWxlO2QubWFyZ2luPSIwcHgiO2Qub3ZlcmZsb3c9ImhpZGRlbiI7Yz13aW5kb3csZD1jLmlubmVyV2lkdGgsZT1jLmlubmVySGVpZ2h0LGc9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImMiKSxpPWQvMixqPWUvMjtnLndpZHRoPWQ7Zy5oZWlnaHQ9ZTtrPWcuZ2V0Q29udGV4dCgiMmQiKTtrLmdsb2JhbEFscGhhPTAuMztsPU1hdGgsbT1sLnJhbmRvbSxuPWwuc2luLG89bC5mbG9vcixwPTEwLHE9W10scj0wLHM9MC4xLFY9NTAwLFc9MTkwLFE9MC4zO2Z1bmN0aW9uIEUobixmKXtnLmFkZEV2ZW50TGlzdGVuZXIobixmLGZhbHNlKTt9RSgibW91c2Vtb3ZlIixmdW5jdGlvbihhKXtpPWEuY2xpZW50WDtqPWEuY2xpZW50WX0pO2Z1bmN0aW9uIHQoYSl7dmFyIGY9MDtpZihhLmRldGFpbCkgZj0tYS5kZXRhaWwvMztlbHNlIGY9YS53aGVlbERlbHRhLzEyMDtpZihmPjAmJnM8MXx8ZjwwJiZzPjAuMSlzKz1mLzI1fUUoIkRPTU1vdXNlU2Nyb2xsIix0KTtFKCJtb3VzZXdoZWVsIix0KTtmdW5jdGlvbiB1KGEpe2EueD0obSgpKmQtZCowLjUpKnA7YS55PShtKCkqZS1lKjAuNSkqcDthLmE9cDthLmI9MDthLmM9MH1mb3IodmFyIHY9MCx3O3Y8Vjt2Kyspe3c9e307dSh3KTtxLnB1c2godyl9c2V0SW50ZXJ2YWwoZnVuY3Rpb24oKXtrLmZpbGxTdHlsZT0iIzAwMCI7ay5maWxsUmVjdCgwLDAsZCxlKTtmb3IoYT1pLWQvMitkLzIsZj1qLWUvMitlLzIsaD0wO2g8VjtoKyspe2I9cVtoXSx4PWIueC9iLmEseT1iLnkvYi5hLHo9MS9iLmEqNSsxLEE9bihRKmgrcikqNjQrVyxCPW4oUSpoKzIrcikqNjQrVyxDPW4oUSpoKzQrcikqNjQrVztpZihiLmIhPTApe2suc3Ryb2tlU3R5bGU9InJnYigiK28oQSkrIiwiK28oQikrIiwiK28oQykrIikiO2subGluZVdpZHRoPXo7ay5iZWdpblBhdGgoKTtrLm1vdmVUbyh4K2EseStmKTtrLmxpbmVUbyhiLmIrYSxiLmMrZik7ay5zdHJva2UoKX1iLmI9eDtiLmM9eTtiLmEtPXM7aWYoYi5hPHN8fGIuYj5kfHxiLmM+ZSl1KGIpfXIrPTAuMX0sMjUpOw==
// remove frame margin and scrollbars when max out size of canvas
var docstyle = document.body.style;
docstyle.margin="0px";
docstyle.overflow="hidden";
// get dimensions of window and resize the canvas to fit
var win = window,
width = win.innerWidth,
height = win.innerHeight,
canvas = document.getElementById("c"),
mousex = width/2, mousey = height/2;
canvas.width=width;
canvas.height=height;
// get 2d graphics context and set global alpha
var G=canvas.getContext("2d");
G.globalAlpha=0.3;
// setup aliases
var M = Math,
Rnd = M.random,
Sin = M.sin,
Floor = M.floor;
// constants and storage for objects that represent star positions
var warpZ = 10,
units = 500,
freq = 0.3,
stars = [],
cycle = 0,
Z = 0.1;
// mouse events
function addCanvasEventListener(name, fn)
{
canvas.addEventListener(name, fn, false);
}
addCanvasEventListener("mousemove", function(e) {
mousex = e.clientX;
mousey = e.clientY;
});
function wheel (e) {
var delta = 0;
if (e.detail)
{
delta = -e.detail / 3;
}
else
{
delta = e.wheelDelta / 120;
}
if (delta > 0 && Z < 1 || delta < 0 && Z > 0.1)
{
Z += (delta/25);
}
}
addCanvasEventListener("DOMMouseScroll", wheel);
addCanvasEventListener("mousewheel", wheel);
// function to reset a star object
function resetstar(a)
{
a.x = (Rnd() * width - (width * 0.5)) * warpZ;
a.y = (Rnd() * height - (height * 0.5)) * warpZ;
a.z = warpZ;
a.px = 0;
a.py = 0
}
// initial star setup
for (var i=0, n; i<units; i++)
{
n = {};
resetstar(n);
stars.push(n);
}
// star rendering anim function
setInterval(function()
{
// clear background
G.fillStyle = "#000";
G.fillRect(0, 0, width, height);
// mouse position to head towards
var cx = (mousex - width / 2) + (width / 2),
cy = (mousey - height / 2) + (height / 2);
// update all stars
for (var i=0; i<units; i++)
{
var n = stars[i], // the star
xx = n.x / n.z, // star position
yy = n.y / n.z,
e = 1.0 / n.z*5+1, // size i.e. z
// rgb colour from a sine wave
r = Sin(freq * i + cycle) * 64 + 190,
g = Sin(freq * i + 2 + cycle) * 64 + 190,
b = Sin(freq * i + 4 + cycle) * 64 + 190;
if (n.px != 0)
{
G.strokeStyle = "rgb(" + Floor(r) + "," + Floor(g) + "," + Floor(b) + ")";
G.lineWidth = e;
G.beginPath();
G.moveTo(xx + cx, yy + cy);
G.lineTo(n.px + cx, n.py + cy);
//G.closePath();
G.stroke();
}
// update star position values with new settings
n.px = xx;
n.py = yy;
n.z -= Z;
// reset when star is out of the view field
if (n.z < Z || n.px > width || n.py > height)
{
// reset star
resetstar(n);
}
}
// colour cycle sinewave rotation
cycle += 0.1;
}, 25);