We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
最近帮公司网站banner实现了几个动画特效,踩了一些坑,这里mark下,下面给个流星demo:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas梦幻星空背景</title> <style> *{margin: 0;padding: 0;} html,body{height: 100%;} body{background: rgba(0, 0, 0, 0.9);} </style> </head> <body> <script> (function () { var context;//画布上下文 var boundaryHeight;//画布高,边界值 var boundaryWidth;//画布宽,边界值 var starArr = []; var meteorArr = []; var STAR_COUNT = 500;//星星数,常量 var METEOR_COUNT = 4;//流星数,常量 var METEOR_SEPARATE = 300; //流星之间间隔,常量 var meteorCoordinate = [];//存所以流星的坐标 var playMeteorTimeout; var playStarsTimeout; //初始化画布及context function init(container) { starArr = []; meteorArr = []; var canvas = document.createElement("canvas"); container.appendChild(canvas); canvas.width = window.innerWidth; canvas.height = window.innerHeight; boundaryHeight = canvas.height; boundaryWidth = canvas.width; //获取context context = canvas.getContext("2d"); context.fillStyle = "black"; //画星星 for (var i = 0; i < STAR_COUNT; i++) { var star = new Star(); star.init(); star.draw(); starArr.push(star); } //画流星 for (var j = 0; j < METEOR_COUNT; j++) { var rain = new MeteorRain(); rain.init(j); rain.draw(); meteorArr.push(rain); } playStars(); playMeteor(); } //创建一个星星对象 var Star = function () { this.x = boundaryWidth * Math.random();//横坐标 this.y = boundaryHeight * Math.random();//纵坐标 this.color = "";//星星颜色 }; Star.prototype = { constructor: Star, //初始化 init: function() { this.getColor(); }, //产生随机颜色 getColor: function() { var _randomNum = Math.random(); if (_randomNum < 0.5) { this.color = "gray"; } else { this.color = "white"; } }, //绘制 draw: function() { context.beginPath(); //画圆点 context.arc(this.x, this.y, 0.05, 0, 2 * Math.PI); context.strokeStyle = this.color; context.stroke(); context.closePath(); } } //星星闪起来 function playStars() { for (var n = 0; n < STAR_COUNT; n++) { starArr[n].getColor(); starArr[n].draw(); } clearTimeout(playStarsTimeout); playStarsTimeout = setTimeout(playStars, 200); } //创建一个流星对象 var MeteorRain = function () { this.x = -1; this.y = -1; this.length = -1;//长度 this.angle = 30; //倾斜角度 this.width = -1;//流星所占宽度 this.height = -1;//流星所占高度 this.speed = 1;//速度 this.offset_x = -1;//横轴移动偏移量 this.offset_y = -1;//纵轴移动偏移量 this.alpha = 1; //透明度 } MeteorRain.prototype = { constructor: MeteorRain, //初始化 init: function (i) { this.alpha = 1;//透明度 this.angle = 30; //流星倾斜角 this.speed = Math.ceil(Math.random() + 0.5); //流星的速度 var x = Math.random() * 80 + 180; var cos = Math.cos(this.angle * 3.14 / 180); var sin = Math.sin(this.angle * 3.14 / 180) ; this.length = Math.ceil(x);//流星长度 this.width = this.length * cos; //流星所占宽度,及矩形的宽度 this.height = this.length * sin; //流星所占高度,及矩形的高度 this.offset_x = this.speed * cos * 3.5; this.offset_y = this.speed * sin * 3.5; this.getPos(i); }, //计算流星坐标 countPos: function () { //往左下移动,x减少,y增加 this.x = this.x - this.offset_x; this.y = this.y + this.offset_y; }, //获取随机坐标 getPos: function (i) { _this = this; function getCoordinate() { _this.x = Math.random() * boundaryWidth; //x坐标 for (var k = 0; k < meteorCoordinate.length; k++) { if (Math.abs(_this.x - meteorCoordinate[k]) < METEOR_SEPARATE) { //这里如果流星之间距离过小,会把其他流星隔断,严重影响效果。 return getCoordinate(); } } meteorCoordinate[i] = _this.x; } getCoordinate(); this.y = 0.2 * boundaryHeight; //y坐标 }, //画流星 draw: function () { context.save(); context.beginPath(); context.lineWidth = 2.5; //宽度 context.globalAlpha = this.alpha; //设置透明度 //创建横向渐变颜色,起点坐标至终点坐标 var line = context.createLinearGradient(this.x, this.y, this.x + this.width, this.y - this.height); //分段设置颜色 line.addColorStop(0, "rgba(255, 255, 255, 1)"); line.addColorStop(1, "rgba(255, 255,255 , 0)"); if (this.alpha < 0 ) { this.alpha = -this.alpha; } //填充 context.strokeStyle = line; //起点 context.moveTo(this.x, this.y); //终点 context.lineTo(this.x + this.width, this.y - this.height); context.closePath(); context.stroke(); context.restore(); }, move: function () { var x = this.x + this.width - this.offset_x; var y = this.y - this.height; this.alpha -= 0.002; //重新计算位置,往左下移动 this.countPos(); if (this.alpha <= 0) { this.alpha = 0; } else if(this.alpha > 1) { this.alpha = 1; } //画一个矩形去清空流星 context.clearRect(this.x - this.offset_x, y, this.width + this.offset_x, this.height); //重绘 this.draw(); } } //流星动起来 function playMeteor() { for (var n = 0; n < METEOR_COUNT; n++) { var rain = meteorArr[n]; rain.move();//移动 if (rain.y > boundaryHeight + 100) {//超出界限后重来 context.clearRect(rain.x, rain.y - rain.height, rain.width, rain.height); meteorCoordinate[n] = 0;//清空数组坐标具体流星的坐标 meteorArr[n] = new MeteorRain(n); meteorArr[n].init(n); } } clearTimeout(playMeteorTimeout); playMeteorTimeout = setTimeout(playMeteor, 5); } init(document.getElementsByTagName("body")[0]); }());
效果如下:
怎么看起来有点丑!!! gif的问题。。。
The text was updated successfully, but these errors were encountered:
getCoordinate 中 return getCoordinate() ,如果流星距离设置过大,将大量递归,程序直接溢出奔溃了。您项目中没这个问题吗?
Sorry, something went wrong.
@XJIANBIN 这个如果整体宽度小确实会有这个问题,可以通过加保护或者减少流星数量去fixed。
No branches or pull requests
怎么看起来有点丑!!! gif的问题。。。
The text was updated successfully, but these errors were encountered: