diff --git a/projectionscreenPc/src/router.js b/projectionscreenPc/src/router.js
index 3d5ae74..fe2861b 100644
--- a/projectionscreenPc/src/router.js
+++ b/projectionscreenPc/src/router.js
@@ -65,6 +65,36 @@ export default new Router({
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',
name: 'login',
diff --git a/projectionscreenPc/src/views/barrage/css/style.css b/projectionscreenPc/src/views/barrage/css/style.css
new file mode 100644
index 0000000..784ae9d
--- /dev/null
+++ b/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;
+}
\ No newline at end of file
diff --git a/projectionscreenPc/src/views/barrage/index.vue b/projectionscreenPc/src/views/barrage/index.vue
new file mode 100644
index 0000000..ebea23f
--- /dev/null
+++ b/projectionscreenPc/src/views/barrage/index.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
欢迎使用彩色星空弹幕
+
扶我起来,这串代码还没封装
+
3点了,总算下班了,呵呵呵````
+
欢迎使用彩色星空弹幕
+
扶我起来,这串代码还没封装
+
3点了,总算下班了,呵呵呵````
+
欢迎使用彩色星空弹幕
+
扶我起来,这串代码还没封装
+
3点了,总算下班了,呵呵呵````
+
欢迎使用彩色星空弹幕
+
扶我起来,这串代码还没封装
+
3点了,总算下班了,呵呵呵````
+
欢迎使用彩色星空弹幕
+
扶我起来,这串代码还没封装
+
3点了,总算下班了,呵呵呵````
+
欢迎使用彩色星空弹幕
+
扶我起来,这串代码还没封装
+
3点了,总算下班了,呵呵呵````
+
欢迎使用彩色星空弹幕
+
扶我起来,这串代码还没封装
+
3点了,总算下班了,呵呵呵````
+
+
+
+
+
+
+
diff --git a/projectionscreenPc/src/views/barrage/js/dan.js b/projectionscreenPc/src/views/barrage/js/dan.js
new file mode 100644
index 0000000..5d20a57
--- /dev/null
+++ b/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;*///普通逻辑版
+}
\ No newline at end of file
diff --git a/projectionscreenPc/src/views/barrage/js/star.js b/projectionscreenPc/src/views/barrage/js/star.js
new file mode 100644
index 0000000..e0d6fd5
--- /dev/null
+++ b/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);
+}
\ No newline at end of file
diff --git a/projectionscreenPc/src/views/line/index.vue b/projectionscreenPc/src/views/line/index.vue
new file mode 100644
index 0000000..cb0e96c
--- /dev/null
+++ b/projectionscreenPc/src/views/line/index.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/projectionscreenPc/src/views/line/js/index.js b/projectionscreenPc/src/views/line/js/index.js
new file mode 100644
index 0000000..bb01205
--- /dev/null
+++ b/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*/
diff --git a/projectionscreenPc/src/views/nightsky/index.vue b/projectionscreenPc/src/views/nightsky/index.vue
new file mode 100644
index 0000000..631841b
--- /dev/null
+++ b/projectionscreenPc/src/views/nightsky/index.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
diff --git a/projectionscreenPc/src/views/nightsky/js/index.js b/projectionscreenPc/src/views/nightsky/js/index.js
new file mode 100644
index 0000000..b88332a
--- /dev/null
+++ b/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();
\ No newline at end of file