Giter Site home page Giter Site logo

vue-p5's Introduction

vue-p5

Create p5.js instance as a Vue component.

Quick start

Script

<script src="https://unpkg.com/vue@2"></script>
<script src="https://unpkg.com/vue-p5"></script>

<div id="app">
  <vue-p5 v-on="this"></vue-p5>
</div>

<script>
new Vue({
  el: '#app',
  methods: {
    setup(sketch) {
      sketch.background('green');
      sketch.text('Hello p5!', 20, 20);
    }
  }
});
</script>

NPM

npm install --save vue@2 vue-p5
import Vue from 'vue';
import VueP5 from 'vue-p5';

export default {
  methods: {
    setup(sketch) {
      sketch.background('green');
      sketch.text('Hello p5!', 20, 20);
    }
  },
  render(h) {
    return h(VueP5, {on: this});
  }
};

Usage

v-on object syntax

In the examples above v-on="this" and {on: this} are a short (and hacky) way to avoid handling every p5 event explicitly. You might want to use one of the other options:

<vue-p5 v-on="{setup, draw, keypressed}"></vue-p5>
<!-- which is equivalent to: -->
<vue-p5
    @setup="setup"
    @draw="draw"
    @keypressed="keypressed">
</vue-p5>
on: {
  setup: this.setup,
  draw: this.draw,
  keypressed: this.keypressed
}

See also v-on object syntax.

Events - p5 and Vue

Every p5 event is exposed as a Vue event. The first argument is the sketch object used for drawing and everything else:

methods: {
  draw(sk) {
    // draw a line between the previous
    // and the current mouse position
    sk.line(sk.pmouseX, sk.pmouseY, sk.mouseX, sk.mouseY);
  },
  keypressed(sk) {
    // convert the key code to it's string
    // representation and print it
    const key = String.fromCharCode(sk.keyCode);
    sk.print(key);
  }
}

Using methods makes it possible to access the current component:

// green background
data: {
  color: [0, 255, 0]
},
methods: {
  draw(sketch) {
    sketch.background(...this.color);
  }
}

Event names

Each event emitted by vue-p5 has the same name as the corresponding p5 event, but lowercase.

mouseclicked, not mouseClicked.

Missing events

Currently all p5 events are supported, but there is an escape hatch. For example, if windowResized was missing, it's (lowercase) name could be passed to additional-events prop to make vue-p5 aware of it:

<vue-p5
  :additional-events="['windowresized']"
  @windowresized="windowresized"
></vue-p5>

Though please let me know if you ever have to use this.

Importing existing sketches

In addition to p5 events, there's a @sketch event for importing an existing p5 sketch written in instance mode.

<vue-p5 @sketch="sketch"></vue-p5>

<script>
new Vue({
  methods: {
    sketch(sk) {
      const clicks = [];

      sk.mouseClicked = () => {
        // save clicks to array
        clicks.push({ x: sk.mouseX, y: sk.mouseY });
      }

      sk.draw = () => {
        // draw a circle around each clicked position
        clicks.forEach(({ x, y }) => {
          sk.ellipse(x, y, 10, 10);
        });
      }
    }
  }
});
</script>

Remember to use arrow functions if you need this.

@sketch can be used in parallel with other events. Functions defined in the @sketch handler will always be called first.

Examples

Hello world: codepen

Webpack project: vue-p5-example

A game of Snake: vue-p5-snake

Feedback

Feedback is very welcome! Free to open a new issue for any reason.

You can also ping me on twitter or write me an email.

Versioning

This project adheres to semver. Minor changes are breaking.

Use vue-p5@next to get a version with future updates.

License

LGPL-2.1

vue-p5's People

Contributors

kinrany avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-p5's Issues

[Feature Request] P5 Sound

Hi! I see that you are working on p5 1.0 at the moment so I don't want to bother you with this issue. It seems that P5 sound is not in the package. It would be great to able to call p5 sound methods directly from vue-p5.

Critical problem when using ".createGraphics()"

Thanks for your package - it has been quite helpful!

But now i stumbled upon a serious issue with my application.

I am using "createGraphics()" to create an imageMask.
Everything works fine on the first load. But when I leave the route with "vue-p5" of my Vue application and then re-enter it, it seems like p5 crashes:

[Vue warn]: Error in mounted hook: "TypeError: b.prototype._registeredMethods[u].slice is not a function"

found in

VueP5

TypeError: b.prototype._registeredMethods[u].slice is not a function
at new b (vue-p5.js?e25d:24)
at VueComponent.mounted (vue-p5.js?e25d:75)

I've tried to put .createGraphics() into the preload-, the setup, or the draw-method. It's the same everywhere.
On the first load everything works fine - leaving and re-entering the route crashes vue-p5.

This seems closely connected to the usage of createGraphics() - as soon as I am not using this method, the errors are gone.

Element Drop Error: "g.File is not a constructor"

Hello,

I'm trying to use p5.Element/drop. But once I drop the file into the canvas, I get the following error:

Uncaught TypeError: g.File is not a constructor
    at c (vue-p5.js?e25d:29)
    at d.Renderer2D.eval (vue-p5.js?e25d:29)

Here's the code I'm using:

setup(p5){
  let canvas = p5.createCanvas(500, 500)
  p5.background('#DDDDDD')

  canvas.drop(file => {
    this.img = p5.createImg(file.data, '').hide()
  })
},

draw(p5){
  let { img } = this
  
  if(img){
    p5.image(img, 0, 0, img.width, img.height)
  }
}

Automate publishing

Remove /dist/ from the repo; use a Github Action to publish to NPM and to Github Releases.

5 errors on console

I just did a very basic script and got these 5 errors below ...

<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/[email protected]"></script>

<div id="app">
  <vue-p5 v-on="this"></vue-p5>
</div>

<script>
new Vue({
  el: '#app',
  methods: {
    setup(sketch) {
      sketch.createCanvas(400,400);
    },
    draw(sketch) {
        sketch.background('green');
        this.currentTime = Date.now();
        sketch.text(this.currentTime,50,50);
    }
  }
});
</script>

**Errors in console **

vue.js:634 [Vue warn]: Invalid handler for event "$parent": got undefined

found in

---> <VueP5> at D:\Users\Ruslan\Projects\Web\vue-p5\src\p5.vue
       <Root>
warn @ vue.js:634
updateListeners @ vue.js:2209
updateComponentListeners @ vue.js:3793
initEvents @ vue.js:3763
Vue._init @ vue.js:4990
VueComponent @ vue.js:5141
createComponentInstanceForVnode @ vue.js:3290
init @ vue.js:3121
createComponent @ vue.js:5967
createElm @ vue.js:5914
createChildren @ vue.js:6042
createElm @ vue.js:5943
patch @ vue.js:6503
Vue._update @ vue.js:3940
updateComponent @ vue.js:4061
get @ vue.js:4472
Watcher @ vue.js:4461
mountComponent @ vue.js:4068
Vue.$mount @ vue.js:9038
Vue.$mount @ vue.js:11923
Vue._init @ vue.js:5006
Vue @ vue.js:5072
(anonymous) @ (index):9
vue.js:634 [Vue warn]: Invalid handler for event "_inactive": got null

found in

---> <VueP5> at D:\Users\Ruslan\Projects\Web\vue-p5\src\p5.vue
       <Root>
warn @ vue.js:634
updateListeners @ vue.js:2209
updateComponentListeners @ vue.js:3793
initEvents @ vue.js:3763
Vue._init @ vue.js:4990
VueComponent @ vue.js:5141
createComponentInstanceForVnode @ vue.js:3290
init @ vue.js:3121
createComponent @ vue.js:5967
createElm @ vue.js:5914
createChildren @ vue.js:6042
createElm @ vue.js:5943
patch @ vue.js:6503
Vue._update @ vue.js:3940
updateComponent @ vue.js:4061
get @ vue.js:4472
Watcher @ vue.js:4461
mountComponent @ vue.js:4068
Vue.$mount @ vue.js:9038
Vue.$mount @ vue.js:11923
Vue._init @ vue.js:5006
Vue @ vue.js:5072
(anonymous) @ (index):9
vue.js:634 [Vue warn]: Invalid handler for event "_vnode": got null

found in

---> <VueP5> at D:\Users\Ruslan\Projects\Web\vue-p5\src\p5.vue
       <Root>
warn @ vue.js:634
updateListeners @ vue.js:2209
updateComponentListeners @ vue.js:3793
initEvents @ vue.js:3763
Vue._init @ vue.js:4990
VueComponent @ vue.js:5141
createComponentInstanceForVnode @ vue.js:3290
init @ vue.js:3121
createComponent @ vue.js:5967
createElm @ vue.js:5914
createChildren @ vue.js:6042
createElm @ vue.js:5943
patch @ vue.js:6503
Vue._update @ vue.js:3940
updateComponent @ vue.js:4061
get @ vue.js:4472
Watcher @ vue.js:4461
mountComponent @ vue.js:4068
Vue.$mount @ vue.js:9038
Vue.$mount @ vue.js:11923
Vue._init @ vue.js:5006
Vue @ vue.js:5072
(anonymous) @ (index):9
vue.js:634 [Vue warn]: Invalid handler for event "_staticTrees": got null

found in

---> <VueP5> at D:\Users\Ruslan\Projects\Web\vue-p5\src\p5.vue
       <Root>
warn @ vue.js:634
updateListeners @ vue.js:2209
updateComponentListeners @ vue.js:3793
initEvents @ vue.js:3763
Vue._init @ vue.js:4990
VueComponent @ vue.js:5141
createComponentInstanceForVnode @ vue.js:3290
init @ vue.js:3121
createComponent @ vue.js:5967
createElm @ vue.js:5914
createChildren @ vue.js:6042
createElm @ vue.js:5943
patch @ vue.js:6503
Vue._update @ vue.js:3940
updateComponent @ vue.js:4061
get @ vue.js:4472
Watcher @ vue.js:4461
mountComponent @ vue.js:4068
Vue.$mount @ vue.js:9038
Vue.$mount @ vue.js:11923
Vue._init @ vue.js:5006
Vue @ vue.js:5072
(anonymous) @ (index):9
vue.js:634 [Vue warn]: Invalid handler for event "$vnode": got undefined

found in

---> <VueP5> at D:\Users\Ruslan\Projects\Web\vue-p5\src\p5.vue
       <Root>

Usability: Common Constants

Some constants, such as PI, can only be accessed as properties of the sketch object. However, other enum values such as CLOSE (ie for endShape) can be accessed either as a direct property of the sketch object, or as a property of the VueP5 library. Doesn't it make sense to wrap other, non-sketch-specific constants to be accessible through the top-level VueP5?

loadModel() dosen't work in vue

I searched but only found threejs way to load model. A 3d model can't be loaded to be a parameter t in preload().
PLZ HELPP

Add a README section about alternatives to vue-p5

It would be helpful to list other ways of using p5 and Vue together.

Using vue-p5 may be overkill for really simple apps with a single component. It also might be better to roll your own if you know what you're doing. However both cases are more appropriate for experienced users.

Related: #19

TypeError: sketch.createCapture is not a function

Error in v-on handler: "TypeError: sketch.createCapture is not a function"

when i using sketch.createCapture function

    setup(sketch) {
      sketch.createCanvas(960, 540);
      let constraints = {
        video: {
          mandatory: {
            minWidth: 1920,
            minHeight: 1080
          },
          optional: [{ maxFrameRate: 10 }]
        },
        audio: false
      };
      sketch.line(100, 200, 200, 300);
      this.capture = sketch.createCapture(constraints);
    }

`windowResized` may not be called as expected

Hey I'm having an issue with the windowResized event.

        <vue-p5
            :additionalEvents="['windowResized']"
            @setup="setup"
            @draw="draw"
            @windowResized="windowResized"
        ></vue-p5>

These don't work for me. I found this issue thread: #11

In here, you recommended:

            document.addEventListener('resize', () => {
                sketch.resizeCanvas(window.innerWidth, window.innerHeight);
            });

That also doesn't work for me, and the issue is that document.addEventListener() doesn't work. When I change it to window, it starts working and correctly fires the resize event.

I figured I would make an issue for this in case anyone else encounters this. It will probably affect the generic/edge cases around :additionalEvents="[]" if it is calling document. in the library code.

Beyond that, nice work. I just ported over an ancient vanilla JavaScript "sacred geometry" generator, and the code is so much nicer to work with now via vue-p5.

Add Nuxt Support

I've been having trouble getting this to work on Nuxt ssr, pretty sure it is a lifecycle issue. A great feature would be to allow this to be strictly rendered on the client.

Set up for Nuxt

this is a tip that could be added for users who want to work with nuxt.
It could be great to add it in readme

In nuxt.config.js

  plugins: [
    { src: '@/plugins/p5.js', ssr: false },
  ],

plugin set up.

import Vue from 'vue';
import VueP5 from 'vue-p5';

Vue.component('VueP5',VueP5)

Vue component

<template>
  <div>
   <vue-p5 v-on="{setup,draw}"></vue-p5>
  </div>
</template>

<script>

export default {
  data:()=>{
    return{
      name:'andres'
    }
  },
  methods: {
    setup(sketch) {
      sketch.createCanvas(400, 400);
      sketch.background('green');
      sketch.text(this.name, 20, 20);
    },
    draw(sketch){
        sketch.line(sketch.pmouseX, sketch.pmouseY, sketch.mouseX, sketch.mouseY);
    }
  },
  render(h) {
    return h(VueP5, {
      setup: this.setup,
      draw: this.draw,
    });
  }
};
</script>

Not able to use rotate()

Hi, I'm trying to use the p5's method rotate() (https://p5js.org/reference/#/p5/rotate) but I'm just not able. I want the canvas to render already rotated. I tried sketch.rotate(45) inside many methods such as setup(), draw() but it does not rotate the canvas. How can I overcome that?

Fix the cause of `npm run build` failure in vue-p5-example.

UglifyJS error: unexpected ES6+ code in module "vue-p5", full error message:

vendor.1379d7f2.js from UglifyJs
Unexpected token: punc ()) [./node_modules/vue-p5/dist/vue-p5.js:19,0][vendor.1379d7f2.js:9264,16]

 TIP  To fix this, try adding "vue-p5" to "transformModules" option, eg:

// poi.config.js
module.exports = {
  transformModules: ['vue-p5'],
  // ...other config
}

Adding transformModules does fix the issue.

Request for contribution

I do love the idea of adding a vue support for p5 framework!

I noticed that there is a ton of work required, I have setup unit testing for the current implementation and some of the missing features and requirements that we need...

I will be glad for joining!!

Vue is not defined

Hi @Kinrany,

first of all, thank you very much for creating a vue-p5, I'm excited to use it!

At the moment when I try to setup a small example I get the following error:
bildschirmfoto 2018-06-23 um 14 49 15

bildschirmfoto 2018-06-23 um 15 08 15

I set up an empty vue-cli project and included your example component from your repo vue-p5-example.

Can you reproduce the issue on your end?

Thank you!
ccarstens

Remove /dist

Make sure both script and NPM version still work

Utilizing third-party libraries?

There are a fair few extension libraries available for p5.js and I think it would be nice with an example on how to use these with vue-p5.

0.4.x

  • Replace props with events.
  • All events should emit sketch.

p5Events not defined

File: p5.vue
Line: 44
"p5Events() {" should be "p5Events: function() {";
Line: 55
"for (const p5EventName of p5Events) {" should be "for (const p5EventName of this.p5Events) {"

0.5.x

New features:

  • sketch event for compatibility with p5
  • preload event

Breaking changes:

  • rename all events, remove dashes
    e.g. @mouseclicked="mouseClicked"

Documentation:

  • example of using v-bind="this"
  • example of using v-bind="{ setup, draw }"
  • example of using v-bind="{ setup: my_setup, draw: my_draw }"
  • example of using @sketch="sketch"

Testing:

  • make sure preload works

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.