开发工具:Webstorm
技术栈:vue、html、canvas
实现效果(其实这里面的是动态变换的,只是没有截成GIF动图):
实现步骤:
(1)在这里的项目我是用VueCli3脚手架进行搭建的。
(2)关于动态背景的源码则是在github找的源码。
(3)总体是在App.vue中进行背景的添加
(4)因为在这里是在App.vue中添加的,所以在这里给出了不想以这种动态背景为背景的解决方案。
(5)在最后我会附上源码
(6)因为这个是我用来练手的,所以只有前台页面,而且很多不完善,但是大家可以借鉴一下这个代码,然后在这个基础上大家可以自由发挥。如果大家想下载源码文件的话。
需要注意,因为我在登陆的时候与后端进行了交互,大家可以改一下Login.vue的登录的代码即可,修改成直接跳转就可以,因为时间关系,在这里我就不一一阐述了。
1、黑客帝国实现源码:
(1)大家可以创建一个vue文件,将其复制进去即可,给大家贴一个结构目录。
<template><div class="main"><canvas id="vue-matrix-raindrop"></canvas></div></template><script>
export default{
name: 'vue-matrix-raindrop',
props:{
canvasWidth:{
type:Number,default:1900},
canvasHeight:{
type:Number,default:1200},
fontSize:{
type:Number,default:20},
fontFamily:{
type:String,default:'arial'},
textContent:{
type:String,default:'abcdefghijklmnopqrstuvwxyz'
},
textColor:{
type:String,default:'#0F0',
validator:function(value){var colorReg =/^#([0-9a-fA-F]{6})|([0-9a-fA-F]{3})$/g
return colorReg.test(value)}},
backgroundColor:{
type:String,default:'rgba(0,0,0,0.1)',
validator:function(value){var reg =/^[rR][gG][Bb][Aa][\(]((2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?),){2}(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?),?(0\.\d{1,2}|1|0)?[\)]{1}$/;return reg.test(value);}},
speed:{
type:Number,default:2,
validator:function(value){return value%1===0;}}},
mounted:function(){this.initRAF();this.initCanvas();this.initRainDrop();this.animationUpdate();},
methods:{initRAF(){
window.requestAnimationFrame =(function(){return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||function( callback ){
window.setTimeout(callback,1000/60);};})();
window.cancelAnimationFrame =(function (){return window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.oCancelAnimationFrame ||
function (id){
window.clearTimeout(id);};})();},initCanvas(){this.canvas = document.getElementById('vue-matrix-raindrop');//需要判断获取到的canvas是否是真的canvasif(this.canvas.tagName.toLowerCase()!=='canvas'){
console.error("Error! Invalid canvas! Please check the canvas's id!")}this.canvas.width = window.innerWidth;this.canvas.height = window.innerHeight;
console.log(this.canvas.height )this.canvasCtx =this.canvas.getContext('2d');this.canvasCtx.font =this.fontSize+'px '+this.fontFamily;this.columns =this.canvas.width /this.fontSize;},initRainDrop(){for(var i=0;i<this.columns;i++){this.rainDropPositionArray.push(0);}},animationUpdate(){this.speedCnt++;//speed为1最快,越大越慢if(this.speedCnt===this.speed){this.speedCnt =0;//绘制背景this.canvasCtx.fillStyle=this.backgroundColor;this.canvasCtx.fillRect(0,0,this.canvas.width,this.canvas.height);//绘制文字this.canvasCtx.fillStyle=this.textColor;for(var i=0,len=this.rainDropPositionArray.length;i<len;i++){this.rainDropPositionArray[i]++;var randomTextIndex =Math.floor(Math.random()*this.textContent.length);var randomText =this.textContent[randomTextIndex];var textYPostion =this.rainDropPositionArray[i]*this.fontSize;this.canvasCtx.fillText(randomText,i*this.fontSize,textYPostion);if(textYPostion>this.canvasHeight){if(Math.random()>0.9){this.rainDropPositionArray[i]=0;}}}}
window.requestAnimationFrame(this.animationUpdate)}},
data (){return{
canvasCtx:null,
canvas:null,
columns:0,
rainDropPositionArray:[],
speedCnt:0}}}</script><!--Add"scoped" attribute tolimit CSS tothis component only --><style scoped>
canvas {
position: absolute;}.component{
position: absolute;
width:100%;
height:100%;
z-index:1;}.userName {
position: absolute;
top:40%;
left:20%;}</style>
2、对于App.vue文件中的修改:
(1)注意上一个特效文件的路径的修改。
<template><div id="app" style="width: 100%;height:100%"><VueMatrixRaindrop></VueMatrixRaindrop><keep-alive><router-view></router-view></keep-alive></div></template><script>//这里根据自己的前面的特效vue项目的具体目录合理选择importVueMatrixRaindrop from './views/vue-matrix-digit-rain'
export default{
name:'app',
components:{VueMatrixRaindrop,},
methods:{}}</script>
3、但是如果是后台文件不想以这种动态背景为背景,那怎么办呢?
在这里主要借助z-index属性进行解决。在这里我主要以后台的管理页面为例子,来简单说明一下。
效果实现(可以自定义背景):
copyMenu.vue 代码实现:
<template><el-container class="home-container"><!-- 头部区域 --><el-header><div><div class="home"><img src="../assets/logo.png" alt=""/></div><span>电商后台管理系统</span></div><el-button type="info"@click="logout">退出</el-button></el-header><!-- 页面主体区域 --><el-container><!-- 侧边栏 --><el-aside :width="isCollapse ? '64px' : '200px'"><div class="toggle-button"@click="toggleCollapse">|||</div><!-- 侧边栏菜单区域 --><el-menu background-color="#333744" text-color="#fff" active-text-color="#409EFF" unique-opened :collapse="isCollapse":collapse-transition="false" router :default-active="activePath"><!-- 一级菜单 --><el-submenu :index="item.id + ''" v-for="item in menulist":key="item.id"><!-- 一级菜单的模板区域 --><template slot="title"><!-- 图标 --><i :class="iconsObj[item.id]"></i><!-- 文本 --><span>{{ item.authName }}</span></template><!-- 二级菜单 --><el-menu-item :index="'/' + subItem.path" v-for="subItem in item.children":key="subItem.id"@click="saveNavState('/' + subItem.path)"><template slot="title"><!-- 图标 --><i class="el-icon-menu"></i><!-- 文本 --><span>{{ subItem.authName }}</span></template></el-menu-item></el-submenu></el-menu></el-aside><!-- 右侧内容主体 --><el-main><!-- 路由占位符 --><router-view></router-view></el-main></el-container></el-container></template><script>
export default{
name:"copy-menu",data(){return{// 左侧菜单数据
menulist:[],
iconsObj:{'125': 'iconfont icon-user','103': 'iconfont icon-tijikongjian','101': 'iconfont icon-shangpin','102': 'iconfont icon-danju','145': 'iconfont icon-baobiao'
},// 是否折叠
isCollapse:false,// 被激活的链接地址
activePath: ''
}},created(){this.getMenuList()this.activePath = window.sessionStorage.getItem('activePath')},
methods:{logout(){
window.sessionStorage.clear()this.$router.push('/login')},// 获取所有的菜单getMenuList(){
console.log("测试")//const router = useRouter()var bmenus =[{"id":125,"authName":"用户管理","path":"users","children":[{"id":110,"authName":"用户列表","path":"user","children":[],"order":null},{"id":210,"authName":"异步状态","path":"netTick","children":[],"order":null},{"id":211,"authName":"表格测试","path":"table","children":[],"order":null}],"order":1},{"id":103,"authName":"权限管理","path":"rights","children":[{"id":111,"authName":"角色列表","path":"roles","children":[],"order":null},{"id":112,"authName":"权限列表","path":"rights","children":[],"order":null}],"order":2},{"id":101,"authName":"商品管理","path":"goods","children":[{"id":104,"authName":"商品列表","path":"goods","children":[],"order":1},{"id":115,"authName":"分类参数","path":"params","children":[],"order":2},{"id":121,"authName":"商品分类","path":"categories","children":[],"order":3}],"order":3},{"id":102,"authName":"订单管理","path":"orders","children":[{"id":107,"authName":"订单列表","path":"orders","children":[],"order":null}],"order":4},{"id":145,"authName":"数据统计","path":"reports","children":[{"id":146,"authName":"数据报表","path":"reports","children":[],"order":null}],"order":5}];this.menulist = bmenus;//const { data: res } = await this.$http.get('menus')//if (res.meta.status !== 200) return this.$message.error(res.meta.msg)//this.menulist = res.data//console.log(res)},// 点击按钮,切换菜单的折叠与展开toggleCollapse(){this.isCollapse =!this.isCollapse
},// 保存链接的激活状态saveNavState(activePath){
window.sessionStorage.setItem('activePath', activePath)this.activePath = activePath
}}}</script><style lang="less" scoped>.outLine{
width:100%;
height:100%;
z-index:1;}.home-container {
height:100%;
width:100%;
z-index:1;}.el-header {
z-index:1;
background-color: #4a5064;
display: flex;
justify-content: space-between;
padding-left:0;
align-items: center;
color: #fff;
font-size:20px;> div {
display: flex;
align-items: center;
span {
margin-left:15px;}}}.el-aside {
z-index:1;
background-color: #333744;.el-menu {
border-right: none;}}.el-main {
z-index:1;
background-color: #eaedf1;}.iconfont {
margin-right:10px;}.toggle-button {
background-color: #4a5064;
font-size:10px;
line-height:24px;
color: #fff;
text-align: center;
letter-spacing:0.2em;
cursor: pointer;}.home{
width:60px;
height:60px;
img{
width:100%;
height:100%;}}</style>
在这里我将这个练习源码上传到CSDN(不需要积分),大家可以下载下来有时间实现一下。
https://download.csdn.net/download/weixin_43388691/86932762
版权归原作者 紫米粥 所有, 如有侵权,请联系我们删除。