9 changed files with 866 additions and 0 deletions
-
30projectionscreenPc/src/router.js
-
95projectionscreenPc/src/views/barrage/css/style.css
-
53projectionscreenPc/src/views/barrage/index.vue
-
73projectionscreenPc/src/views/barrage/js/dan.js
-
188projectionscreenPc/src/views/barrage/js/star.js
-
77projectionscreenPc/src/views/line/index.vue
-
193projectionscreenPc/src/views/line/js/index.js
-
57projectionscreenPc/src/views/nightsky/index.vue
-
100projectionscreenPc/src/views/nightsky/js/index.js
@ -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; |
||||
|
} |
||||
@ -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> |
||||
@ -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;*///普通逻辑版
|
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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> |
||||
@ -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*/ |
||||
@ -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> |
||||
@ -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(); |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue