博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
canvas - 炫酷的3D星空
阅读量:6920 次
发布时间:2019-06-27

本文共 4999 字,大约阅读时间需要 16 分钟。

1.国际惯例,先上效果

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

2代码部分

 html: 

css:

*{
margin: 0;padding: 0;}/*没啥必须的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();}

 

 (未完)

转载于:https://www.cnblogs.com/hanguozhi/p/8387118.html

你可能感兴趣的文章
Redis笔记系列(二)——Redis安装部署与维护详解
查看>>
Hibernate 持久化上下文总结
查看>>
XPath 与多线程爬虫
查看>>
MariaDB 很酷
查看>>
input和span对齐__笔记
查看>>
MySQL主从复制与读写分离
查看>>
Array类型
查看>>
Apache如何能够把可执行文件当成CGI程序来执行
查看>>
项目启动报 JDBC Driver has been forcibly unregistered
查看>>
【转载】ACID、Data Replication、CAP与BASE
查看>>
不争气的肚子
查看>>
Java并发编程高级篇(二):使用固定大小线程执行器
查看>>
我为什么鼓励工程师写blog
查看>>
Java HashMap实现详解
查看>>
ViewPager背景实现Parallax(平差化)效果
查看>>
JAVA 线程基本知识汇总--ThreadLocal 和 InheritableThreadLoc
查看>>
增加pdo_mysql单独安装
查看>>
怎么查看端口占用情况?
查看>>
nginx反向代理proxy_set_header自定义header头无效
查看>>
小黑小波比.选择文件按钮上传完文件后按钮内容为文件名
查看>>