![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISO1cDNxEDN1ETOxATM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
html代码:
<canvas id='canv'></canvas>
<!--
[ MouseMove / TouchSwipe ]
Omega Centauri is a globular cluster in the constellation of Centaurus, the largest globular cluster in the Milky Way galaxy at a diameter of roughly light-years. It is estimated to contain approximately million stars and a total mass equivalent to million solar masses.
!-->
css代码:
html {
height: %;
background-image: radial-gradient(ellipse farthest-corner at center top, hsla(, %, %, ) %, hsla(, %, %, ) %);
cursor: move;
}
body {
width: %;
margin: ;
overflow: hidden;
}
js代码:
var c = document.getElementById('canv');
var w = c.width = window.innerWidth;
var h = c.height = window.innerHeight;
var $ = c.getContext("2d");
/*
Thanks Jack Rugile for this gradient cache fix for a perf boost -
he's awesome -
y'all should be following him if you're not already...( @jackrugile ;)
*/
var _c = document.createElement('canvas');
var _w = _c.width = ;
var _h = _c.height = ;
var $$ = _c.getContext("2d");
var gc = $$.createRadialGradient(
_w / ,
_h / ,
,
_w / ,
_h / , (_w / ) *
);
gc.addColorStop(, 'hsla(218, 95%, 85%, 1)');
gc.addColorStop(, 'hsla(218, 100%,85%,0.1)');
$$.fillStyle = gc;
$$.beginPath();
$$.arc(_w / , _h / , _w / , , Math.PI * );
$$.fill();
var num = ;
var _x = ;
var _y = ;
var _z = ;
var u = ;
var dtr = function(d) {
return d * Math.PI / ;
};
var rnd = function() {
return Math.sin(Math.floor(Math.random() * ) * Math.PI / );
};
var dst = function(p1, p2, p3) {
return Math.sqrt(Math.pow(p2.x - p1.x, ) + Math.pow(p2.y - p1.y, ) + Math.pow(p2.z - p1.z, ));
};
var cam = {
prime: {
x: _x,
y: _y,
z: _z
},
sub: {
x: ,
y: ,
z:
},
dst: {
x: ,
y: ,
z:
},
ang: {
phic: ,
phis: ,
thetac: ,
thetas:
},
zoom: ,
disp: {
x: w / ,
y: h / ,
z:
},
upd: function() {
cam.dst.x = cam.sub.x - cam.prime.x;
cam.dst.y = cam.sub.y - cam.prime.y;
cam.dst.z = cam.sub.z - cam.prime.z;
cam.ang.phic = -cam.dst.z / Math.sqrt(cam.dst.x * cam.dst.x + cam.dst.z * cam.dst.z);
cam.ang.phis = cam.dst.x / Math.sqrt(cam.dst.x * cam.dst.x + cam.dst.z * cam.dst.z);
cam.ang.thetac = Math.sqrt(cam.dst.x * cam.dst.x + cam.dst.z * cam.dst.z) / Math.sqrt(cam.dst.x * cam.dst.x + cam.dst.y * cam.dst.y + cam.dst.z * cam.dst.z);
cam.ang.thetas = -cam.dst.y / Math.sqrt(cam.dst.x * cam.dst.x + cam.dst.y * cam.dst.y + cam.dst.z * cam.dst.z);
}
};
var trans = {
parts: {
sz: function(p, sz) {
return {
x: p.x * sz.x,
y: p.y * sz.y,
z: p.z * sz.z
};
},
rot: {
x: function(p, rot) {
return {
x: p.x,
y: p.y * Math.cos(dtr(rot.x)) - p.z * Math.sin(dtr(rot.x)),
z: p.y * Math.sin(dtr(rot.x)) + p.z * Math.cos(dtr(rot.x))
};
},
y: function(p, rot) {
return {
x: p.x * Math.cos(dtr(rot.y)) + p.z * Math.sin(dtr(rot.y)),
y: p.y,
z: -p.x * Math.sin(dtr(rot.y)) + p.z * Math.cos(dtr(rot.y))
};
},
z: function(p, rot) {
return {
x: p.x * Math.cos(dtr(rot.z)) - p.y * Math.sin(dtr(rot.z)),
y: p.x * Math.sin(dtr(rot.z)) + p.y * Math.cos(dtr(rot.z)),
z: p.z
};
}
},
pos: function(p, pos) {
return {
x: p.x + pos.x,
y: p.y + pos.y,
z: p.z + pos.z
};
}
},
vp: {
phi: function(p) {
return {
x: p.x * cam.ang.phic + p.z * cam.ang.phis,
y: p.y,
z: p.x * -cam.ang.phis + p.z * cam.ang.phic
};
},
theta: function(p) {
return {
x: p.x,
y: p.y * cam.ang.thetac - p.z * cam.ang.thetas,
z: p.y * cam.ang.thetas + p.z * cam.ang.thetac
};
},
resvp: function(p) {
return {
x: p.x - cam.prime.x,
y: p.y - cam.prime.y,
z: p.z - cam.prime.z
};
}
},
persp: function(p) {
return {
x: p.x * cam.dst.z / p.z * cam.zoom,
y: p.y * cam.dst.z / p.z * cam.zoom,
z: p.z * cam.zoom,
p: cam.dst.z / p.z
};
},
disp: function(p, disp) {
return {
x: p.x + disp.x,
y: -p.y + disp.y,
z: p.z + disp.z,
p: p.p
};
},
calc: function(obj, sz, rot, pos, disp) {
var ret = trans.parts.sz(obj, sz);
ret = trans.parts.rot.x(ret, rot);
ret = trans.parts.rot.y(ret, rot);
ret = trans.parts.rot.z(ret, rot);
ret = trans.parts.pos(ret, pos);
ret = trans.vp.phi(ret);
ret = trans.vp.theta(ret);
ret = trans.vp.resvp(ret);
ret = trans.persp(ret);
ret = trans.disp(ret, disp);
return ret;
}
};
(function() {
var Verts = function(par) {
this.transIn = {};
this.transOut = {};
this.transIn.vtx = (par.vtx);
this.transIn.sz = (par.sz);
this.transIn.rot = (par.rot);
this.transIn.pos = (par.pos);
};
Verts.prototype.updvtx = function() {
this.transOut = trans.calc(
this.transIn.vtx,
this.transIn.sz,
this.transIn.rot,
this.transIn.pos,
cam.disp
);
};
var Obj = function() {
this.vel = ;
this.maxt = ;
this.diff = ;
this.pos = ;
this.tx = _x;
this.ty = _y;
this.u = ;
this.set();
};
Obj.prototype.set = function() {
this.c = c;
this.$ = $;
this.v = [];
this.dist = [];
this.reps = [];
for (var i = , len = num; i < len; i++) {
this.v[i] = new Verts({
vtx: {
x: rnd(),
y: rnd(),
z: rnd()
},
sz: {
x: ,
y: ,
z:
},
rot: {
x: ,
y: -,
z:
},
pos: {
x: this.diff * Math.sin( * Math.random() * Math.PI / ),
y: this.diff * Math.sin( * Math.random() * Math.PI / ),
z: this.diff * Math.sin( * Math.random() * Math.PI / )
}
});
this.reps[i] = {
x: * Math.random(),
y: * Math.random(),
z: * Math.random()
};
}
this.rots = {
x: ,
y: ,
z:
};
this.size = {
x: w / ,
y: h / ,
z: w /
};
};
Obj.prototype.obj = function() {
this.v.push(new Verts({
vtx: {
x: rnd(),
y: rnd(),
z: rnd()
},
sz: {
x: ,
y: ,
z:
},
rot: {
x: ,
y: -,
z:
},
pos: {
x: this.diff * Math.sin( * Math.random() * Math.PI / ),
y: this.diff * Math.sin( * Math.random() * Math.PI / ),
z: this.diff * Math.sin( * Math.random() * Math.PI / )
}
}));
this.reps.push({
x: * Math.random(),
y: * Math.random(),
z: * Math.random()
});
};
Obj.prototype.upd = function() {
cam.prime.x += (this.tx - cam.prime.x) * ;
cam.prime.y += (this.ty - cam.prime.y) * ;
};
Obj.prototype.draw = function() {
this.$.clearRect(, , this.c.width, this.c.height);
cam.upd();
this.rots.x += ;
this.rots.y += ;
this.rots.z += ;
for (var i = ; i < this.v.length; i++) {
for (var val in this.reps[i]) {
if (this.reps[i].hasOwnProperty(val)) {
this.reps[i][val] += this.vel;
if (this.reps[i][val] > this.maxt) this.reps[i][val] = ;
}
}
this.v[i].transIn.pos = {
x: this.diff * Math.cos(this.reps[i].x * Math.PI / ),
y: this.diff * Math.sin(this.reps[i].y * Math.PI / ),
z: this.diff * Math.sin(this.reps[i].z * Math.PI / )
};
this.v[i].transIn.rot = this.rots;
this.v[i].transIn.sz = this.size;
this.v[i].updvtx();
if (this.v[i].transOut.p < ) continue;
this.$.drawImage(_c, this.v[i].transOut.x, this.v[i].transOut.y, this.v[i].transOut.p * , this.v[i].transOut.p * );
}
};
Obj.prototype.loop = function() {
window.requestAnimationFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element) {
window.setTimeout(callback, / );
};
})();
var loop = function() {
this.upd();
this.draw();
window.requestAnimationFrame(loop);
}.bind(this);
loop();
};
Obj.prototype.run = function() {
this.loop();
window.addEventListener('mousemove', function(e) {
this.tx = (e.clientX - this.c.width / ) * -;
this.ty = (e.clientY - this.c.height / ) * ;
}.bind(this));
window.addEventListener('touchmove', function(e) {
e.preventDefault();
this.tx = (e.touches[].clientX - this.c.width / ) * -;
this.ty = (e.touches[].clientY - this.c.height / ) * ;
}.bind(this));
};
var o = new Obj();
o.run();
})();