Vue实现炫酷的代码瀑布流背景

本文实例为大家分享了Vue实现代码瀑布流背景的具体代码,供大家参考,具体内容如下

先看一下效果:

代码奉上:

<template>
    <canvas id="canvas" />
</template>

<script>
    export default {
        name: "BackCanvas",
        props: {
            height: {
                type: Number,
                default: 500
            }
        },
        data() {
            return {
                settings: {
                    COL_WIDTH: 15,
                    COL_HEIGHT: 15,
                    // 速度参数 最小值:4 - 最大值:8
                    VELOCITY_PARAMS: {
                        min: 3,
                        max: 8
                    },
                    // 代码长度参数  最小值 20  - 最大值 40
                    CODE_LENGTH_PARAMS: {
                        min: 20,
                        max: 40
                    }
                },
                animation: null,
                c: null,
                ctx: null,
                lineC: null,
                ctx2: null,
                WIDTH: window.innerWidth,
                HEIGHT: window.innerHeight,
                COLUMNS: null,
                canvii: [],
                // font from here https://www.dafont.com/matrix-code-nfi.font
                font: '24px matrix-code',
                letters: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'this', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '$', '+', '-', '*', '/', '=', '%', '"', '\'', '#', '&', '_', '(', ')', ',', '.', ';', ':', '?', '!', '\\', '|', '{', '}', '<', '>', '[', ']', '^', '~'],
                codes: [],
                createCodeLoop: null,
                codesCounter: 0
            }
        },
        mounted() {
            this.init();
        },
        methods: {
            init () {
                this.c = document.getElementById( 'canvas' );
                this.ctx = this.c.getContext( '2d' );
                this.c.width = this.WIDTH;
                this.c.height = this.HEIGHT;

                this.ctx.shadowBlur = 0;
                this.ctx.fillStyle = '#000';
                this.ctx.fillRect(0, 0, this.WIDTH, this.HEIGHT);
                this.ctx.font = this.font;

                this.COLUMNS = Math.ceil(this.WIDTH / this.settings.COL_WIDTH);

                for (let i = 0; i < this.COLUMNS; i++) {
                    this.codes[i] = [];
                    this.codes[i][0] = {
                        'open': true,
                        'position': {'x': 0, 'y': 0},
                        'strength': 0
                    };
                }

                this.loop();

                this.createLines();

                this.createCode();

                window.onresize = function () {
                    window.cancelAnimationFrame(this.animation);
                    this.animation = null;
                    this.ctx.clearRect(0, 0, this.WIDTH, this.HEIGHT);
                    this.codesCounter = 0;

                    this.ctx2.clearRect(0, 0, this.WIDTH, this.HEIGHT);

                    this.WIDTH = window.innerWidth;
                    this.HEIGHT = window.innerHeight;
                    this.init();
                };
            },
            loop () {
                this.animation = requestAnimationFrame( () => { this.loop(); } );
                this.draw();
            },
            draw () {
                let velocity, height, x, y, c, ctx;
                // slow fade BG colour
                this.ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
                this.ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
                this.ctx.fillRect(0, 0, this.WIDTH, this.HEIGHT);
                this.ctx.globalCompositeOperation = 'source-over';
                for (let i = 0; i < this.COLUMNS; i++) {
                    if (this.codes[i][0].canvas) {
                        velocity = this.codes[i][0].velocity;
                        height = this.codes[i][0].canvas.height;
                        x = this.codes[i][0].position.x;
                        y = this.codes[i][0].position.y - height;
                        c = this.codes[i][0].canvas;
                        ctx = c.getContext('2d');

                        this.ctx.drawImage(c, x, y, this.settings.COL_WIDTH, height);

                        if ((this.codes[i][0].position.y - height) < this.HEIGHT){
                            this.codes[i][0].position.y += velocity;
                        } else {
                            this.codes[i][0].position.y = 0;
                        }
                    }
                }
            },
            createCode () {
                if (this.codesCounter > this.COLUMNS) {
                    clearTimeout(this.createCodeLoop);
                    return;
                }
                let randomInterval = this.randomFromInterval(0, 100);
                let column = this.assignColumn();
                if (column) {
                    let codeLength = this.randomFromInterval(this.settings.CODE_LENGTH_PARAMS.min, this.settings.CODE_LENGTH_PARAMS.max);
                    let codeVelocity = (Math.random() * (this.settings.VELOCITY_PARAMS.max - this.settings.VELOCITY_PARAMS.min)) + this.settings.VELOCITY_PARAMS.min;
                    let lettersLength = this.letters.length;

                    this.codes[column][0].position = {'x': (column * this.settings.COL_WIDTH), 'y': 0};
                    this.codes[column][0].velocity = codeVelocity;
                    this.codes[column][0].strength = this.codes[column][0].velocity / this.settings.VELOCITY_PARAMS.max;

                    for (let i = 1; i <= codeLength; i++) {
                        let newLetter = this.randomFromInterval(0, (lettersLength - 1));
                        this.codes[column][i] = this.letters[newLetter];
                    }

                    this.createCanvii(column);

                    this.codesCounter++;
                }
                this.createCodeLoop = setTimeout(this.createCode, randomInterval);

            },
            createCanvii (i) {
                let codeLen = this.codes[i].length - 1;
                let canvHeight = codeLen * this.settings.COL_HEIGHT;
                let velocity = this.codes[i][0].velocity;
                let strength = this.codes[i][0].strength;
                let text, fadeStrength;

                let newCanv = document.createElement('canvas');
                let newCtx = newCanv.getContext('2d');

                newCanv.width = this.settings.COL_WIDTH;
                newCanv.height = canvHeight;

                for (let j = 1; j < codeLen; j++) {
                    text = this.codes[i][j];
                    newCtx.globalCompositeOperation = 'source-over';
                    newCtx.font = '24px matrix-code';

                    if (j < 5) {
                        newCtx.shadowColor = 'hsl(104, 79%, 74%)';
                        newCtx.shadowOffsetX = 0;
                        newCtx.shadowOffsetY = 0;
                        // 设置模糊程度
                        newCtx.shadowBlur = 6;
                        newCtx.fillStyle = 'hsla(104, 79%, ' + (100 - (j * 5)) + '%, ' + strength + ')';
                    } else if (j > (codeLen - 4)) {
                        fadeStrength = j / codeLen;
                        fadeStrength = 1 - fadeStrength;

                        newCtx.shadowOffsetX = 0;
                        newCtx.shadowOffsetY = 0;
                        newCtx.shadowBlur = 0;
                        newCtx.fillStyle = 'hsla(104, 79%, 74%, ' + (fadeStrength + 0.3) + ')';
                    } else {
                        newCtx.shadowOffsetX = 0;
                        newCtx.shadowOffsetY = 0;
                        newCtx.shadowBlur = 0;
                        newCtx.fillStyle = 'hsla(104, 79%, 74%, ' + strength + ')';
                    }

                    newCtx.fillText(text, 0, (canvHeight - (j * this.settings.COL_HEIGHT)));
                }

                this.codes[i][0].canvas = newCanv;

            },
            createLines () {
                this.linesC = document.createElement('canvas');
                this.linesC.width = this.WIDTH;
                this.linesC.height = this.HEIGHT;
                this.linesC.style.position = 'fixed';
                this.linesC.style.top = 0;
                this.linesC.style.left = 0;
                this.linesC.style.zIndex = 10;
                document.body.appendChild(this.linesC);

                let linesYBlack = 0;
                let linesYWhite = 0;
                this.ctx2 = this.linesC.getContext('2d');

                this.ctx2.beginPath();

                this.ctx2.lineWidth = 1;
                this.ctx2.strokeStyle = 'rgba(0, 0, 0, 0.7)';

                while (linesYBlack < this.HEIGHT) {

                    this.ctx2.moveTo(0, linesYBlack);
                    this.ctx2.lineTo(this.WIDTH, linesYBlack);

                    linesYBlack += 5;
                }

                this.ctx2.lineWidth = 0.15;
                this.ctx2.strokeStyle = 'rgba(255, 255, 255, 0)';

                while (linesYWhite < this.HEIGHT) {

                    this.ctx2.moveTo(0, linesYWhite+1);
                    this.ctx2.lineTo(this.WIDTH, linesYWhite+1);

                    linesYWhite += 5;
                }

                this.ctx2.stroke();
            },
            assignColumn () {
                let randomColumn = this.randomFromInterval(0, (this.COLUMNS - 1));

                if (this.codes[randomColumn][0].open) {
                    this.codes[randomColumn][0].open = false;
                } else {
                    return false;
                }

                return randomColumn;
            },
            randomFromInterval (from, to) {
                return Math.floor(Math.random() * (to - from+ 1 ) + from);
            }

        }
    }
</script>

<style scoped>
/** 让这个背景固定在页面不随着滚动而滚动 */
 #canvas {
     position: fixed;
     top: 0;
     left: 0;
 }
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue实现网络图片瀑布流 + 下拉刷新 + 上拉加载更多(步骤详解)

    一.思路分析和效果图 用vue来实现一个瀑布流效果,加载网络图片,同时有下拉刷新和上拉加载更多功能效果.然后针对这几个效果的实现,捋下思路: 根据加载数据的顺序,依次追加标签展示效果: 选择哪种方式实现瀑布流,这里选择绝对定位方式: 关键问题:由于每张图片的宽高不一样,而瀑布流中要求所有图片的宽度一致,高度随宽度等比缩放.而且由于图片的加载是异步延迟.在不知道图片高度的情况下,每个图片所在的item盒子不好绝对定位.因此在渲染页面前先获取所有图片的高度,是解决问题的关键点!这里选择用JS中的Im

  • vue实现瀑布流组件滑动加载更多

    建议先看vue瀑布流组件上拉加载更多再来食用本文,如果直接想看源码文末就是~ 文末新增组件优化,之所以没有删优化前的代码是想让以后自己还能看到走过的路. 上一篇讲到在项目中使用上拉加载更多组件,但是由于实际项目开发中由于需求变更或者说在webview中上拉加载有些机型在上拉时候会把webview也一起上拉导致上拉加载不灵敏等问题,我们有时候也会换成滑动到底部自动加载的功能. 既然都是加载更多,很多代码思想势必相似,主要区别在于上拉和滑动到底部这个操作上,所以,我们需要注意: 1.上拉加载是poi

  • Vue实现无限加载瀑布流

    本文实例为大家分享了Vue实现无限加载瀑布流的具体代码,供大家参考,具体内容如下 我做的这个瀑布流放在了一个嵌套页面里,就是类似管理后台的main content中,如果要改成全屏的也很方便,其实更容易些,因为会避开一些在元素上使用onScroll的坑. 通过这个瀑布流,可以掌握以下几个知识点: 1.在元素上监听scroll事件,相对直接在window上监听麻烦一点点: 2.image.onload事件: 3.promiseAll; 4.vue 的 transition-group 这里使用了m

  • vue瀑布流组件实现上拉加载更多

    最近在做移动端h5页面,所以分页什么的就不能按照传统pc端的分页器的思维去做了,这么小的屏幕去点击也不太方便一般来讲移动端都是上拉加载更多,符合正常使用习惯. 首先简单写一下模板部分的html代码,,很简单清晰的逻辑: <template> <div class="loadmore"> <div class="loadmore__body"> <slot></slot> </div> <d

  • vue实现简单瀑布流布局

    vue简单实现瀑布流布局的一种方式(vue瀑布流组件),供大家参考,具体内容如下 vue中的瀑布流布局组件 需求:图片容器宽度固定,高度根据图片自适应,图片一行不能排列时候,换行依次从左往右排列.(瀑布流概念) 另外结合vue-lazy实现懒加载 ( npm i vue-lazyload --save-dev) 使用也很简单,在需要懒加载的img标签上将:src换成v-lazy 父组件传递数据: waterfallData:[ { e_img: "test.jpg", // 图片 e_

  • 通过vue写一个瀑布流插件代码实例

    这篇文章主要介绍了通过vue写一个瀑布流插件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 效果如图所示: 采用了预先加载图片,再计算高度的办法..网络差的情况下,可能有点卡 新建 vue-water-easy.vue 组件文件 <template> <div class="vue-water-easy" ref="waterWrap"> <div v-for="(i

  • Vue瀑布流插件的使用示例

    我自己写的一个的Vue瀑布流插件,列数自适应,不用设置每个卡片的高度. 测试页面:Page.vue 模板页面:WaterFollow.vue 和 WFColumn.vue 在Page.vue中,修改itemW的值,设置每列的最小宽度.例如:itemW="200"(意为200px).list为数组.高度不用设置,:style="{height:item+'px'}"是我为了创造卡片高度加上去的,不加就显示卡片的原来大小. 经测试,created加载数据正常,mount

  • vue.js组件vue-waterfall-easy实现瀑布流效果

    想必大家应该很多都已经习惯了jquery的DOM操作,jquery的瀑布流实现起来也很容易. 但是,随着时代的发展,随着时代的进步..... 算了算了,扯远了,既然能找到这儿来,肯定是在vue.js上已经有一定的基础了,咱们废话不多说,直接进入主题. vue-waterfall-easy easy! easy! easy! 重要的事情说三遍!!! 所以说,咱们今天用到的不是大家熟知的vue-waterfall,而是vue-waterfall-easy: 一.获取vue-waterfall-eas

  • Vue实现炫酷的代码瀑布流背景

    本文实例为大家分享了Vue实现代码瀑布流背景的具体代码,供大家参考,具体内容如下 先看一下效果: 代码奉上: <template>     <canvas id="canvas" /> </template> <script>     export default {         name: "BackCanvas",         props: {             height: {          

  • Vue编写炫酷的时钟插件

    本文实例为大家分享了Vue编写时钟插件的具体代码,供大家参考,具体内容如下 效果图 代码奉上: <template>     <div class="clock">         <div class="flip">             <div class="digital front" :data-number="nextTimes[0]"></div>  

  • Python&Matlab实现炫酷的3D旋转图

    目录 前言 1.Python爬取美女照片 1.1 留恋忘返的网址 1.2 Python代码 1.3 结果 2.Python实现 2.1 条件准备 2.2 运行展示 2.3 Python实现 3.Matlab实现 3.1 运行展示 3.2 Matlab代码 前言 我们今天的任务很明确,我先系统梳理一下: 1.先用Python爬取一波漂亮的美女照片: 2.然后Python中炫酷的代码实现: 3.最后用matlab伺候,得到相同的结果. 1.Python爬取美女照片 1.1 留恋忘返的网址 站长素材-

  • 基于 Vue 实现一个酷炫的 menu插件

    写在前面 最近看到一个非常酷炫的menu插件,一直想把它鼓捣成vue形式,谁让我是vue的死灰粉呢,如果这都不算爱:pensive:.:laughing:开个小玩耍,我们一起来探索黑魔法吧.观看本教程的读者需要具备一定的vue和css3的知识. 本文结构 1.效果演示 2.使用方法介绍 3.关键步骤讲解 正文 1.效果演示 pic_1 pic2 pic_3 在线演示 live demo 2.使用介绍 项目地址:github.com/MingSeng-W/vue-bloom-menu ,clone

  • vue+canvas实现炫酷时钟效果的倒计时插件(已发布到npm的vue2插件,开箱即用)

    前言: 此事例是在vue组件中,使用canvas实现倒计时动画的效果.其实,实现效果的逻辑跟vue没有关系,只要读懂canvas如何实现效果的这部分逻辑就可以了 canvas动画的原理:利用定时器,给定合理的帧数,不断的清除画布,再重绘图形,即呈现出动画效果. 让我们先看下效果 说明:此gif清晰度很低,因为转成gif图的时候,质量受损,帧数减少,所以倒计时转到红色时候看起来变的很模糊.但是实际在浏览器上效果全程都是很清晰和连贯的 使用 npm npm install vue-canvas-co

随机推荐