|

为P5写一个Vue组件库,让页面绚丽多彩

p5.js 是一个JavaScript的函数库,它在制作之初就和Processing有同样的目标。就是让艺术家,设计师,教育工作者和编程初学者能够很容易,很轻松地学习和使用程序设计。并且它也能给现在的网页带来一些新的东西,例如 p5 的官方网站。

定义组件

创建 p5.vue 文件,这个文件是 p5 组件的定义文件,我们主要在这个文件中来实现主要功能。

定义 template 如下:

<template>
    <div ref="p5"></div>
</template>

看起来很简单,只需要一个 div 容器进行包裹,因为 p5 默认会创建一个 canvas 标签,并插入到指定的父容器中,我们这里为 div 设置了 ref 属性就是为了能准确的插入到这个容器。

首先引入 p5.js,p5 的源码可以在官网下载:

import p5 from '../lib/p5'

然后定义组件的功能,可以在 script 中写入:

export default {
    name: 'P5',
    props: {
        sketch: Function,
    },
    methods: {
        defaultSketch(p5) {
            p5.setup = () => {
                p5.createCanvas(100, 100);
            };

            p5.draw = () => {
                p5.background(0);
            };
        }
    },
    mounted() {
        let el = this.refs.p5;
        let p5cv = new p5(this.sketch || this.defaultSketch, el);
        this.emit("created", p5cv);
    }
}

简单分析一下。

这个组件有一个 props 属性为 sketch ,这个属性被定义为一个函数,目的是外部提供一个函数,这个函数就是 p5 绘图函数。

defaultSketch 方法是默认方法,也是默认绘图函数,在组件外部没有提供绘图函数的时候,内部将调用这个默认函数来绘制一个简单的 canvas ,来填充视觉上的空白。

最后来到 mounted 生命周期函数中,p5 画布的挂载和绘图函数都是在这里进行的,所以也在这里挂载即可。

由于这个组件是外部控制的,所以我们不需要定义样式文件。

引用组件

组件定义完成后,只需要在另一个组件中引用当前组件即可。

<template>
    <div class="p5-demo">
        <p5 :sketch="sketch" @created="onP5Created"></p5>
    </div>
</template>

然后定义组件的一些数据和绘图函数。

import p5 from '@/components/P5'

export default {
    name: "webpage",
    components: { p5 },
    data() {
        return {
            p5obj: null
        }
    },
    methods: {
        // p5 绘图函数
        sketch(p5) {

            p5.setup = () => {
                p5.createCanvas(800, 300);
                p5.rectMode(p5.CENTER);
                p5.noStroke();
                p5.angleMode(p5.DEGREES);
            }

            p5.draw = () => {
                p5.background("#fbf7d8");
                p5.push();
                p5.translate(p5.width / 2, p5.height / 2);
                p5.rotate(45);

                p5.fill(237, 34, 93);
                p5.rect(0, 0, 150, 150);
                p5.pop();
                p5.push();
                p5.translate(p5.width / 2, p5.height / 2);
                p5.rotate(30);

                p5.fill(255, 255, 255);
                p5.rect(0, 0, 75, 75);
                p5.pop();
            }
        },
        onP5Created(obj) {
            this.p5obj = obj;
        }
    }
}

然后得到一张图片:

组件优化

可以看到,目前为止,这个组件的绘图函数是在外部组件中定义的,很多时候一个绘图函数会比较长,这样会影响外部组件的阅读,所以我们可以把绘图函数独立起来,放在另一个文件中管理。

假设我们的绘图函数全部放在 /lib/p5/ 下,那么上面的绘图函数就可以这样改写了:

// p5 sketch demo
module.exports = (p5, context) => {

    p5.setup = () => {
        p5.createCanvas(800, 300);
        p5.rectMode(p5.CENTER);
        p5.noStroke();
        p5.angleMode(p5.DEGREES);
    }

    p5.draw = () => {
        p5.background("#fbf7d8");
        p5.push();
        p5.translate(p5.width / 2, p5.height / 2);
        p5.rotate(45);

        p5.fill(237, 34, 93);
        p5.rect(0, 0, 150, 150);
        p5.pop();
        p5.push();
        p5.translate(p5.width / 2, p5.height / 2);
        p5.rotate(30);

        p5.fill(255, 255, 255);
        p5.rect(0, 0, 75, 75);
        p5.pop();
    }
}

然后在外部组件中引入绘图函数。

import p5 from '@/components/P5'
// 引入绘图函数
import p5_demo from '../lib/p5/demo'

export default {
    ...
    methods: {
        sketch(p5) {
            return p5_demo(p5, this);
        }
    }
    ...
}

这样一来,组件就变得清爽了,绘图函数和组件的业务也就可以分离,同时,在绘图函数中也引入了组件的上下文,所以如果有一些数据需要和绘图函数进行同步,则可以通过这个上下文对象来实现。

组件打包

组件开发完成后,则需要将其打包,作为一个独立组件,可以在任何一个 Vue 项目中引用。

修改 package.json ,增加一个打包指令。

"scripts": {
    "lib:p5": "vue-cli-service build --target lib --name p5-vue ./src/components/p5.index.js"
  }

这里的入口文件为 p5.index.js ,所以创建这个文件,在其中注册 p5 组件。

import P5 from './P5.vue'

P5.install = function (Vue) {
    Vue.component(P5.name, P5);
}

// 定义 install 方法
const install = function (Vue) {
    if (install.installed) return;
    install.installed = true;
    // 遍历并注册全局组件
    Vue.component(P5.name, P5);
}

if (typeof window !== 'undefined' && window.Vue) {
    install(window.Vue);
}

export default {
    install,
    P5
}

运行打包:

npm run lib:p5

之后即可在 dist 目录下看到打包好的文件。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注