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 @@ + + + + + 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