0


模仿CSDN黑暗帝国动态背景的vue项目(附源码)

开发工具: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


本文转载自: https://blog.csdn.net/weixin_43388691/article/details/127753757
版权归原作者 紫米粥 所有, 如有侵权,请联系我们删除。

“模仿CSDN黑暗帝国动态背景的vue项目(附源码)”的评论:

还没有评论