1.国际惯例,先上效果

canvas - 炫酷的3D星空-LMLPHP

(⊙o⊙)… 效果图看上去效果并不很炫酷啊,直接戳 这里 看效果吧!

2代码部分

html:

<canvas id="canvas" width="1920" height="1080"></canvas>

css:

*{margin:;padding:;}
/*没啥必须的css*/

js:(这个博主也是够了,那么多的js代码,一点注释都没有,差评!)公子莫慌,由于代码比较多,注释部分就不在这写啦,直接移步 效果展示 查看效果及代码注释。

var Starry = function (canvasId, starCont) {
this.renderLoop = null;
this.framerate = 42;
this.starfield = null;
this.rings_y = 0;
this.altitude = 0;
this.preset = {
radius : 600,
fov : 260,
cruise : 0.01,
angle : 0.006,
vert : -0.001,
rings : 0.2
};
this.state = {
width : document.documentElement.clientWidth,
height : document.documentElement.clientHeight,
altitude : 0,
settings : this.preset,
framerate : 50
};
var S = this
if (!canvasId) return false
S.canvas = document.getElementById(canvasId);
S.canvas.width = document.documentElement.clientWidth;
S.canvas.height = document.documentElement.clientHeight;
S.ctx = S.canvas.getContext('2d');
this.starfield = this.generateStarfield();
}
Starry.prototype = {
reset: function(){
clearTimeout(this.renderLoop)
this.state.width = this.canvas.width = document.documentElement.clientWidth;
this.state.height = this.canvas.height = document.documentElement.clientHeight;
this.init()
},
generateStarfield : function() {
var radius = this.state.settings.radius;
var star_count = Math.min( 1000, Math.round( this.canvas.offsetWidth / 2 ) );
var stars = new Array( star_count );
for (var i = 0; i < stars.length; i++) {
stars[i] = {
x: ( Math.random() * ( radius * 2 ) ) - ( radius ),
y: ( Math.random() * ( radius * 2 ) ) - ( radius ),
z: ( Math.random() * ( radius * 2 ) ) - ( radius )
}
};
return stars;
},
move : function ( stars ) {
var angle = this.state.settings.angle;
var vert = this.state.settings.vert;
var fov = this.state.settings.fov;
var cruise = this.state.settings.cruise;
var radius = this.state.settings.radius;
var cosRX = Math.cos(angle);
var sinRX = Math.sin(angle);
var cosRY = Math.cos(vert);
var sinRY = Math.sin(vert);
return stars.map( function(star){
var tempx = star.x;
var tempy = star.y;
var tempz = star.z + fov; var x = ( tempx * cosRX ) + ( tempz * sinRX );
var y = ( tempy * cosRY ) + ( tempz * sinRY ); // Depth based on X
// var z = ( tempx * -sinRX ) + ( tempz * cosRX ); // Depth based on Y
var z = ( tempy * -sinRY ) + ( tempz * cosRY ) - cruise; var limit = radius; // x
if ( x < -limit ) x = limit;
else if ( x > limit ) x = -limit; // y
if ( y < -limit ) y = limit;
else if ( y > limit ) y = - limit; // z
if ( z < -limit ) z = limit;
else if ( z > limit ) z = -limit; return { x:x, y:y, z: z - fov };
});
},
run: function () {
var S = this;
var width = this.state.width
var height = this.state.height
var fov = this.state.settings.fov
var rings = this.state.settings.rings S.ctx.clearRect(0, 0, width, height);
S.starfield.forEach(function(item, index){ var scale = ( fov / 2 ) / ( fov + item.z );
var x2d = ( item.x * scale ) + ( width / 2 );
var y2d = ( item.y * scale ) + ( height / 2 );
var opacity = Math.min( Math.max( Math.abs( scale ), 0.1 ), 1 ); S.ctx.beginPath();
S.ctx.arc(x2d, y2d, Math.min( Math.abs( scale ), 3 ) , 0, 360);
S.ctx.fillStyle = 'rgba(167,180,224,'+opacity+')';
S.ctx.fill();
}) var ring_radius = height * 1.6;
var ring_center = { x: width / 4, y: height * 2 }; S.ctx.beginPath();
S.ctx.arc( ring_center.x, ring_center.y + this.rings_y, ring_radius, 0, 360);
S.ctx.lineWidth = 1;
S.ctx.strokeStyle = 'rgba(167,180,224,0.15)';
S.ctx.stroke();
S.ctx.beginPath();
S.ctx.arc( ring_center.x + 60, ring_center.y + 60 + ( this.rings_y * 0.8 ), ring_radius, 0, 360);
S.ctx.lineWidth = 1;
S.ctx.strokeStyle = 'rgba(167,180,224,0.05)';
S.ctx.stroke();
this.rings_y += rings;
if( this.rings_y > ( width / 2 ) ) {
this.rings_y = -( width/ 2 )
}; S.starfield = S.move( S.starfield )
var _this = this;
this.renderLoop = setTimeout(function (){_this.run()}, _this.state.framerate)
},
init: function () {
this.run();
},
pause: function () {
var _this = this;
clearTimeout(_this.renderLoop)
}
} var starbg = new Starry ('canvas', 100);
window.onload = function () {
starbg.init();
}
window.onresize = function () {
starbg.reset();
}

(未完)

04-21 03:31