Browse Source

星空弹幕/连线动画

master
石可 5 years ago
parent
commit
bb4b946910
  1. 30
      projectionscreenPc/src/router.js
  2. 95
      projectionscreenPc/src/views/barrage/css/style.css
  3. 53
      projectionscreenPc/src/views/barrage/index.vue
  4. 73
      projectionscreenPc/src/views/barrage/js/dan.js
  5. 188
      projectionscreenPc/src/views/barrage/js/star.js
  6. 77
      projectionscreenPc/src/views/line/index.vue
  7. 193
      projectionscreenPc/src/views/line/js/index.js
  8. 57
      projectionscreenPc/src/views/nightsky/index.vue
  9. 100
      projectionscreenPc/src/views/nightsky/js/index.js

30
projectionscreenPc/src/router.js

@ -65,6 +65,36 @@ export default new Router({
requireAuth: true //不需要验证登录 requireAuth: true //不需要验证登录
} }
}, },
{
path: '/line',
name: 'line',
// 路由级代码拆分,这将为此路由生成单独的块,当路线被访问时延迟加载 (路由懒加载)
component: () => import('./views/line/index'),
meta: {
title: '连线',
requireAuth: true //不需要验证登录
}
},
{
path: '/nightsky',
name: 'nightsky',
// 路由级代码拆分,这将为此路由生成单独的块,当路线被访问时延迟加载 (路由懒加载)
component: () => import('./views/nightsky/index'),
meta: {
title: '夜空背景',
requireAuth: true //不需要验证登录
}
},
{
path: '/barrage',
name: 'barrage',
// 路由级代码拆分,这将为此路由生成单独的块,当路线被访问时延迟加载 (路由懒加载)
component: () => import('./views/barrage/index'),
meta: {
title: '星空弹幕',
requireAuth: true //不需要验证登录
}
},
{ {
path: '/login', path: '/login',
name: 'login', name: 'login',

95
projectionscreenPc/src/views/barrage/css/style.css

@ -0,0 +1,95 @@
@charset "utf-8";
*{
padding: 0;
margin: 0;
}
html,body{
height: 100%;
user-select:none;
}
.screen{
overflow: hidden;
position: relative;
height: 100%;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.send{
position: absolute;
bottom: 0;
width: 100%;
height: 80px;
line-height: 80px;
background-color: rgba(10,10,10,0.6);
text-align: center;
}
.input{
position: absolute;
left: 50%;
top: 50%;
margin: -20px -350px;
font-size: 0;
}
.text{
float: left;
width: 600px;
height: 40px;
border: none;
border-radius: 8px 0 0 8px;
background-color: black;
color: white;
}
.s_show div{
position: absolute;
font-size: 18px;
font-weight: bold;
}
.btn{
float: left;
width: 100px;
background-color:black;
line-height: 40px;
font-size: 18px;
color: #fff;
cursor: pointer;
border-radius: 0 8px 8px 0;
}
html,body {
margin:0;
overflow:hidden;
width:100%;
height:100%;
cursor:none;
background:black;
background:linear-gradient(to bottom,#000000 0%,#5788fe 100%);
}
.filter {
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
background:#fe5757;
animation:colorChange 30s ease-in-out infinite;
animation-fill-mode:both;
mix-blend-mode:overlay;
}
@keyframes colorChange {
0%,100% {
opacity:0;
}
50% {
opacity:.9;
}
}
.landscape {
position:absolute;
bottom:0px;
left:0;
width:100%;
height:100%;
/* background-image:url('img/xkbg.png'); */
background-size:1000px 250px;
background-repeat:repeat-x;
background-position:center bottom;
}

53
projectionscreenPc/src/views/barrage/index.vue

@ -0,0 +1,53 @@
<template>
<div class="screen">
<div class="landscape"></div>
<div class="filter"></div>
<canvas id="canvas"></canvas>
<div class="send">
<div class="input clearfix">
<input type="text" class="text">
<div class="btn">发送弹幕</div>
</div>
</div>
<div class="s_show">
<div class="magictime twisterInUp">欢迎使用彩色星空弹幕</div>
<div class="magictime twisterInUp">扶我起来这串代码还没封装</div>
<div class="magictime twisterInUp">3点了总算下班了呵呵呵````</div>
<div class="magictime twisterInUp">欢迎使用彩色星空弹幕</div>
<div class="magictime twisterInUp">扶我起来这串代码还没封装</div>
<div class="magictime twisterInUp">3点了总算下班了呵呵呵````</div>
<div class="magictime twisterInUp">欢迎使用彩色星空弹幕</div>
<div class="magictime twisterInUp">扶我起来这串代码还没封装</div>
<div class="magictime twisterInUp">3点了总算下班了呵呵呵````</div>
<div class="magictime twisterInUp">欢迎使用彩色星空弹幕</div>
<div class="magictime twisterInUp">扶我起来这串代码还没封装</div>
<div class="magictime twisterInUp">3点了总算下班了呵呵呵````</div>
<div class="magictime twisterInUp">欢迎使用彩色星空弹幕</div>
<div class="magictime twisterInUp">扶我起来这串代码还没封装</div>
<div class="magictime twisterInUp">3点了总算下班了呵呵呵````</div>
<div class="magictime twisterInUp">欢迎使用彩色星空弹幕</div>
<div class="magictime twisterInUp">扶我起来这串代码还没封装</div>
<div class="magictime twisterInUp">3点了总算下班了呵呵呵````</div>
<div class="magictime twisterInUp">欢迎使用彩色星空弹幕</div>
<div class="magictime twisterInUp">扶我起来这串代码还没封装</div>
<div class="magictime twisterInUp">3点了总算下班了呵呵呵````</div>
</div>
</div>
</template>
<script>
export default {
name: 'index3',
created(){
},
mounted(){
require('./js/star.js');
require('./js/dan.js');
}
}
</script>
<style>
@import url("./css/style.css");
</style>

73
projectionscreenPc/src/views/barrage/js/dan.js

@ -0,0 +1,73 @@
//模块化 每个功能函数去做自己相应的事情 代码可维护性 可扩展性
//初始化函数
var aShowList = document.querySelectorAll('.s_show div');//获取元素 H5
var oShow = document.querySelector('.s_show');
var oSend = document.querySelector('.send');
var oBtn = document.querySelector('.btn');
var oText = document.querySelector('.text');
var time = 0;//上一次你发送的时间
var time1 = 0;
//点击发送弹幕
oBtn.onclick = function(){//鼠标点击事件
//oBtn.style.backgroundColor = randomColor();//按钮背景颜色变换
time1 = new Date();
oBtn.style.color = randomColor();//按钮字体颜色变换
if(time1 - time > 3000){//2次发送的时间必须大于2秒
var oDiv = document.createElement('div');//创建div
oDiv.innerHTML = oText.value;//添加弹幕内容
oDiv.className = 'magictime twisterInUp';//弹幕特效
oShow.appendChild(oDiv);//添加一个子节点
init(oDiv);//初始化
oText.value = '';
time = time1;
//console.log(time);
}else{
alert("请稍后再发~");
}
}
for(var i = 0;i < aShowList.length;i++){
init(aShowList[i]);//执行初始化函数
}
function init(obj){//接受弹幕对象
//确定top值的随机区间
var screenHeight = document.documentElement.clientHeight;//获取屏幕可视高度
var maxTop = screenHeight - oSend.offsetHeight - obj.offsetHeight;//高度差范围
obj.style.top = maxTop * Math.random() + 'px';
//控制left值
var screenWidth = document.documentElement.clientWidth;//获取可视宽度
var maxLeft = screenWidth - obj.offsetWidth/* - Math.random() * 800 */;//随机宽度差
obj.style.left = maxLeft + 'px';
//弹幕的随机颜色
obj.style.color = randomColor();
/*setInterval(function(){
move(obj,maxLeft);
},1000);*///普通定时器
move(Math.random()*5+1,obj,maxLeft);
}
//弹幕移动函数
function move(k,obj,maxLeft){
var speed = k;//控制速度的变量
maxLeft -= speed;//往左移动
if(maxLeft > -obj.offsetWidth){
obj.style.left = maxLeft + 'px';
requestAnimationFrame(function(){
move(k,obj,maxLeft);
});//H5新增的动画函数
}else{
init(obj);//重新初始化 营造循环弹幕效果
/* oShow.removeChild(obj);//DOM删除子节点 */
}
}
//随机颜色函数
function randomColor(){
return '#' + Math.random().toString(16).slice(-6);//一行简化版截取后六位
/*var str = '#';
for(var i = 0;i < 6;i++){
str += Math.floor(Math.random() * 16).toString(16);
}
return str;*///普通逻辑版
}

188
projectionscreenPc/src/views/barrage/js/star.js

@ -0,0 +1,188 @@
function Star(id, x, y){
this.id = id;
this.x = x;
this.y = y;
this.r = Math.floor(Math.random()*2)+1;
var alpha = (Math.floor(Math.random()*10)+1)/10/2;
this.color = "rgba(255,255,255,"+alpha+")";
}
Star.prototype.draw = function() {
ctx.fillStyle = this.color;
ctx.shadowBlur = this.r * 2;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
ctx.closePath();
ctx.fill();
}
Star.prototype.move = function() {
this.y -= .15;
if (this.y <= -10) this.y = HEIGHT + 10;
this.draw();
}
Star.prototype.die = function() {
stars[this.id] = null;
delete stars[this.id];
}
function Dot(id, x, y, r) {
this.id = id;
this.x = x;
this.y = y;
this.r = Math.floor(Math.random()*5)+1;
this.maxLinks = 2;
this.speed = .5;
this.a = .5;
this.aReduction = .005;
this.color = "rgba(255,255,255,"+this.a+")";
this.linkColor = "rgba(255,255,255,"+this.a/4+")";
this.dir = Math.floor(Math.random()*140)+200;
}
Dot.prototype.draw = function() {
ctx.fillStyle = this.color;
ctx.shadowBlur = this.r * 2;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
ctx.closePath();
ctx.fill();
}
Dot.prototype.link = function() {
if (this.id == 0) return;
var previousDot1 = getPreviousDot(this.id, 1);
var previousDot2 = getPreviousDot(this.id, 2);
var previousDot3 = getPreviousDot(this.id, 3);
if (!previousDot1) return;
ctx.strokeStyle = this.linkColor;
ctx.moveTo(previousDot1.x, previousDot1.y);
ctx.beginPath();
ctx.lineTo(this.x, this.y);
if (previousDot2 != false) ctx.lineTo(previousDot2.x, previousDot2.y);
if (previousDot3 != false) ctx.lineTo(previousDot3.x, previousDot3.y);
ctx.stroke();
ctx.closePath();
}
function getPreviousDot(id, stepback) {
if (id == 0 || id - stepback < 0) return false;
if (typeof dots[id - stepback] != "undefined") return dots[id - stepback];
else return false;//getPreviousDot(id - stepback);
}
Dot.prototype.move = function() {
this.a -= this.aReduction;
if (this.a <= 0) {
this.die();
return
}
this.color = "rgba(255,255,255,"+this.a+")";
this.linkColor = "rgba(255,255,255,"+this.a/4+")";
this.x = this.x + Math.cos(degToRad(this.dir))*this.speed,
this.y = this.y + Math.sin(degToRad(this.dir))*this.speed;
this.draw();
this.link();
}
Dot.prototype.die = function() {
dots[this.id] = null;
delete dots[this.id];
}
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
WIDTH,
HEIGHT,
mouseMoving = false,
mouseMoveChecker,
mouseX,
mouseY,
stars = [],
initStarsPopulation = 80,
dots = [],
dotsMinDist = 2,
maxDistFromCursor = 50;
setCanvasSize();
init();
function setCanvasSize() {
WIDTH = document.documentElement.clientWidth,
HEIGHT = document.documentElement.clientHeight;
canvas.setAttribute("width", WIDTH);
canvas.setAttribute("height", HEIGHT);
}
function init() {
ctx.strokeStyle = "white";
ctx.shadowColor = "white";
for (var i = 0; i < initStarsPopulation; i++) {
stars[i] = new Star(i, Math.floor(Math.random()*WIDTH), Math.floor(Math.random()*HEIGHT));
//stars[i].draw();
}
ctx.shadowBlur = 0;
animate();
}
function animate() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
for (var i in stars) {
stars[i].move();
}
for (var i in dots) {
dots[i].move();
}
drawIfMouseMoving();
requestAnimationFrame(animate);
}
window.onmousemove = function(e){
mouseMoving = true;
mouseX = e.clientX;
mouseY = e.clientY;
clearInterval(mouseMoveChecker);
mouseMoveChecker = setTimeout(function() {
mouseMoving = false;
}, 100);
}
function drawIfMouseMoving(){
if (!mouseMoving) return;
if (dots.length == 0) {
dots[0] = new Dot(0, mouseX, mouseY);
dots[0].draw();
return;
}
var previousDot = getPreviousDot(dots.length, 1);
var prevX = previousDot.x;
var prevY = previousDot.y;
var diffX = Math.abs(prevX - mouseX);
var diffY = Math.abs(prevY - mouseY);
if (diffX < dotsMinDist || diffY < dotsMinDist) return;
var xVariation = Math.random() > .5 ? -1 : 1;
xVariation = xVariation*Math.floor(Math.random()*maxDistFromCursor)+1;
var yVariation = Math.random() > .5 ? -1 : 1;
yVariation = yVariation*Math.floor(Math.random()*maxDistFromCursor)+1;
dots[dots.length] = new Dot(dots.length, mouseX+xVariation, mouseY+yVariation);
dots[dots.length-1].draw();
dots[dots.length-1].link();
}
//setInterval(drawIfMouseMoving, 17);
function degToRad(deg) {
return deg * (Math.PI / 180);
}

77
projectionscreenPc/src/views/line/index.vue

@ -0,0 +1,77 @@
<template>
<div id="wrapper">
<canvas id="canvas" width="1950px" height="800px"></canvas>
<canvas id="canvasbg" width="1950px" height="800px"></canvas>
</div>
</template>
<script>
export default {
name: 'line',
created(){
},
mounted(){
require('./js/index.js');
}
}
</script>
<style>
html,
body {
overflow: hidden;
height: 100%;
width: 100%;
background: #262b2e
}
#wrapper {
height: 100%;
width: 100%;
text-align: center;
display: table;
position: absolute;
}
#title {
display: table-cell;
vertical-align: middle;
z-index: 999;
}
#title h2 {
color: #fff;
font-size: 45px;
font-family: "museo-slab";
}
#title h3 {
color: #fff;
font-size: 25px;
font-family: "museo-sans";
font-weight: 300
}
#wrapper canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
#canvas {
z-index: 1;
}
#canvasbg {
z-index: -10;
-webkit-filter: blur(3px);
-moz-filter: blur(3px);
-o-filter: blur(3px);
filter: blur(3px);
opacity: 0.6;
}
</style>

193
projectionscreenPc/src/views/line/js/index.js

@ -0,0 +1,193 @@
// min and max radius, radius threshold and percentage of filled circles
var radMin = 5,
radMax = 125,
filledCircle = 60, //percentage of filled circles
concentricCircle = 30, //percentage of concentric circles
radThreshold = 25; //IFF special, over this radius concentric, otherwise filled
//min and max speed to move
var speedMin = 0.3,
speedMax = 2.5;
//max reachable opacity for every circle and blur effect
var maxOpacity = 0.6;
//default palette choice
var colors = ['52,168,83', '117,95,147', '199,108,23', '194,62,55', '0,172,212', '120,120,120'],
bgColors = ['52,168,83', '117,95,147', '199,108,23', '194,62,55', '0,172,212', '120,120,120'],
circleBorder = 10,
backgroundLine = bgColors[0];
var backgroundMlt = 0.85;
//min distance for links
var linkDist = Math.min(canvas.width, canvas.height) / 2.4,
lineBorder = 2.5;
//most importantly: number of overall circles and arrays containing them
var maxCircles = 12,
points = [],
pointsBack = [];
//populating the screen
for (var i = 0; i < maxCircles * 2; i++) points.push(new Circle());
for (var i = 0; i < maxCircles; i++) pointsBack.push(new Circle(true));
//experimental vars
var circleExp = 1,
circleExpMax = 1.003,
circleExpMin = 0.997,
circleExpSp = 0.00004,
circlePulse = false;
//circle class
function Circle(background) {
//if background, it has different rules
this.background = (background || false);
this.x = randRange(-canvas.width / 2, canvas.width / 2);
this.y = randRange(-canvas.height / 2, canvas.height / 2);
this.radius = background ? hyperRange(radMin, radMax) * backgroundMlt : hyperRange(radMin, radMax);
this.filled = this.radius < radThreshold ? (randint(0, 100) > filledCircle ? false : 'full') : (randint(0, 100) >
concentricCircle ? false : 'concentric');
this.color = background ? bgColors[randint(0, bgColors.length - 1)] : colors[randint(0, colors.length - 1)];
this.borderColor = background ? bgColors[randint(0, bgColors.length - 1)] : colors[randint(0, colors.length - 1)];
this.opacity = 0.05;
this.speed = (background ? randRange(speedMin, speedMax) / backgroundMlt : randRange(speedMin,
speedMax)); // * (radMin / this.radius);
this.speedAngle = Math.random() * 2 * Math.PI;
this.speedx = Math.cos(this.speedAngle) * this.speed;
this.speedy = Math.sin(this.speedAngle) * this.speed;
var spacex = Math.abs((this.x - (this.speedx < 0 ? -1 : 1) * (canvas.width / 2 + this.radius)) / this.speedx),
spacey = Math.abs((this.y - (this.speedy < 0 ? -1 : 1) * (canvas.height / 2 + this.radius)) / this.speedy);
this.ttl = Math.min(spacex, spacey);
};
Circle.prototype.init = function() {
Circle.call(this, this.background);
}
//support functions
//generate random int a<=x<=b
function randint(a, b) {
return Math.floor(Math.random() * (b - a + 1) + a);
}
//generate random float
function randRange(a, b) {
return Math.random() * (b - a) + a;
}
//generate random float more likely to be close to a
function hyperRange(a, b) {
return Math.random() * Math.random() * Math.random() * (b - a) + a;
}
//rendering function
function drawCircle(ctx, circle) {
//circle.radius *= circleExp;
var radius = circle.background ? circle.radius *= circleExp : circle.radius /= circleExp;
ctx.beginPath();
ctx.arc(circle.x, circle.y, radius * circleExp, 0, 2 * Math.PI, false);
ctx.lineWidth = Math.max(1, circleBorder * (radMin - circle.radius) / (radMin - radMax));
ctx.strokeStyle = ['rgba(', circle.borderColor, ',', circle.opacity, ')'].join('');
if (circle.filled == 'full') {
ctx.fillStyle = ['rgba(', circle.borderColor, ',', circle.background ? circle.opacity * 0.8 : circle.opacity,
')'
].join('');
ctx.fill();
ctx.lineWidth = 0;
ctx.strokeStyle = ['rgba(', circle.borderColor, ',', 0, ')'].join('');
}
ctx.stroke();
if (circle.filled == 'concentric') {
ctx.beginPath();
ctx.arc(circle.x, circle.y, radius / 2, 0, 2 * Math.PI, false);
ctx.lineWidth = Math.max(1, circleBorder * (radMin - circle.radius) / (radMin - radMax));
ctx.strokeStyle = ['rgba(', circle.color, ',', circle.opacity, ')'].join('');
ctx.stroke();
}
circle.x += circle.speedx;
circle.y += circle.speedy;
if (circle.opacity < (circle.background ? maxOpacity : 1)) circle.opacity += 0.01;
circle.ttl--;
}
//initializing function
function init() {
window.requestAnimationFrame(draw);
}
//rendering function
function draw() {
if (circlePulse) {
if (circleExp < circleExpMin || circleExp > circleExpMax) circleExpSp *= -1;
circleExp += circleExpSp;
}
var ctxfr = document.getElementById('canvas').getContext('2d');
var ctxbg = document.getElementById('canvasbg').getContext('2d');
ctxfr.globalCompositeOperation = 'destination-over';
ctxfr.clearRect(0, 0, canvas.width, canvas.height); // clear canvas
ctxbg.globalCompositeOperation = 'destination-over';
ctxbg.clearRect(0, 0, canvas.width, canvas.height); // clear canvas
ctxfr.save();
ctxfr.translate(canvas.width / 2, canvas.height / 2);
ctxbg.save();
ctxbg.translate(canvas.width / 2, canvas.height / 2);
//function to render each single circle, its connections and to manage its out of boundaries replacement
function renderPoints(ctx, arr) {
for (var i = 0; i < arr.length; i++) {
var circle = arr[i];
//checking if out of boundaries
if (circle.ttl < 0) {}
var xEscape = canvas.width / 2 + circle.radius,
yEscape = canvas.height / 2 + circle.radius;
if (circle.ttl < -20) arr[i].init(arr[i].background);
//if (Math.abs(circle.y) > yEscape || Math.abs(circle.x) > xEscape) arr[i].init(arr[i].background);
drawCircle(ctx, circle);
}
for (var i = 0; i < arr.length - 1; i++) {
for (var j = i + 1; j < arr.length; j++) {
var deltax = arr[i].x - arr[j].x;
var deltay = arr[i].y - arr[j].y;
var dist = Math.pow(Math.pow(deltax, 2) + Math.pow(deltay, 2), 0.5);
//if the circles are overlapping, no laser connecting them
if (dist <= arr[i].radius + arr[j].radius) continue;
//otherwise we connect them only if the dist is < linkDist
if (dist < linkDist) {
var xi = (arr[i].x < arr[j].x ? 1 : -1) * Math.abs(arr[i].radius * deltax / dist);
var yi = (arr[i].y < arr[j].y ? 1 : -1) * Math.abs(arr[i].radius * deltay / dist);
var xj = (arr[i].x < arr[j].x ? -1 : 1) * Math.abs(arr[j].radius * deltax / dist);
var yj = (arr[i].y < arr[j].y ? -1 : 1) * Math.abs(arr[j].radius * deltay / dist);
ctx.beginPath();
ctx.moveTo(arr[i].x + xi, arr[i].y + yi);
ctx.lineTo(arr[j].x + xj, arr[j].y + yj);
var samecolor = arr[i].color == arr[j].color;
ctx.strokeStyle = ["rgba(", arr[i].borderColor, ",", Math.min(arr[i].opacity, arr[j].opacity) * ((
linkDist - dist) / linkDist), ")"].join("");
ctx.lineWidth = (arr[i].background ? lineBorder * backgroundMlt : lineBorder) * ((linkDist - dist) /
linkDist); //*((linkDist-dist)/linkDist);
ctx.stroke();
}
}
}
}
var startTime = Date.now();
renderPoints(ctxfr, points);
renderPoints(ctxbg, pointsBack);
var deltaT = Date.now() - startTime;
ctxfr.restore();
ctxbg.restore();
window.requestAnimationFrame(draw);
}
init();
/*Credits and aknowledgements:
Original Idea and Design by Luca Luzzatti
Optimizing tips from Benjamin K?stner
General tips from Salvatore Previti*/

57
projectionscreenPc/src/views/nightsky/index.vue

@ -0,0 +1,57 @@
<template>
<div>
<canvas id="canvas"></canvas>
</div>
</template>
<script>
export default {
name: 'nightsky',
created(){
},
mounted(){
require('./js/index.js');
}
}
</script>
<style>
body {
background: #060e1b;
overflow: hidden;
}
canvas {
//opacity: 0.5;
}
/* Demo Buttons Style */
.codrops-demos {
font-size: 0.8em;
text-align:center;
position:absolute;
z-index:99;
width:96%;
}
.codrops-demos a {
display: inline-block;
margin: 0.35em 0.1em;
padding: 0.5em 1.2em;
outline: none;
text-decoration: none;
text-transform: uppercase;
letter-spacing: 1px;
font-weight: 700;
border-radius: 2px;
font-size: 110%;
border: 2px solid transparent;
color:#fff;
}
.codrops-demos a:hover,
.codrops-demos a.current-demo {
border-color: #383a3c;
}
</style>

100
projectionscreenPc/src/views/nightsky/js/index.js

@ -0,0 +1,100 @@
"use strict";
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
hue = 217,
stars = [],
count = 0,
maxStars = 1200;
var canvas2 = document.createElement('canvas'),
ctx2 = canvas2.getContext('2d');
canvas2.width = 100;
canvas2.height = 100;
var half = canvas2.width / 2,
gradient2 = ctx2.createRadialGradient(half, half, 0, half, half, half);
gradient2.addColorStop(0.025, '#fff');
gradient2.addColorStop(0.1, 'hsl(' + hue + ', 61%, 33%)');
gradient2.addColorStop(0.25, 'hsl(' + hue + ', 64%, 6%)');
gradient2.addColorStop(1, 'transparent');
ctx2.fillStyle = gradient2;
ctx2.beginPath();
ctx2.arc(half, half, half, 0, Math.PI * 2);
ctx2.fill();
// End cache
function random(min, max) {
if (arguments.length < 2) {
max = min;
min = 0;
}
if (min > max) {
var hold = max;
max = min;
min = hold;
}
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function maxOrbit(x, y) {
var max = Math.max(x, y),
diameter = Math.round(Math.sqrt(max * max + max * max));
return diameter / 2;
}
var Star = function() {
this.orbitRadius = random(maxOrbit(w, h));
this.radius = random(60, this.orbitRadius) / 12;
this.orbitX = w / 2;
this.orbitY = h / 2;
this.timePassed = random(0, maxStars);
this.speed = random(this.orbitRadius) / 900000;
this.alpha = random(2, 10) / 10;
count++;
stars[count] = this;
}
Star.prototype.draw = function() {
var x = Math.sin(this.timePassed) * this.orbitRadius + this.orbitX,
y = Math.cos(this.timePassed) * this.orbitRadius + this.orbitY,
twinkle = random(10);
if (twinkle === 1 && this.alpha > 0) {
this.alpha -= 0.05;
} else if (twinkle === 2 && this.alpha < 1) {
this.alpha += 0.05;
}
ctx.globalAlpha = this.alpha;
ctx.drawImage(canvas2, x - this.radius / 2, y - this.radius / 2, this.radius, this.radius);
this.timePassed += this.speed;
}
for (var i = 0; i < maxStars; i++) {
new Star();
}
function animation() {
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 0.8;
ctx.fillStyle = 'hsla(' + hue + ', 64%, 6%, 1)';
ctx.fillRect(0, 0, w, h)
ctx.globalCompositeOperation = 'lighter';
for (var i = 1, l = stars.length; i < l; i++) {
stars[i].draw();
};
window.requestAnimationFrame(animation);
}
animation();
Loading…
Cancel
Save