Skip to content

Instantly share code, notes, and snippets.

@Azgaar
Forked from redblobgames/vue-canvas.js
Created April 16, 2018 18:33
Show Gist options
  • Save Azgaar/cf200722e6d62a7d01ae9b30d99db868 to your computer and use it in GitHub Desktop.
Save Azgaar/cf200722e6d62a7d01ae9b30d99db868 to your computer and use it in GitHub Desktop.
Vue component for canvas with automatic dependency tracking
/** Canvas component
A generic canvas component that calls a draw function to draw the
contents, and automatically calls it again when anything the draw
function depends on changes. Blog entry:
http://simblob.blogspot.com/2018/03/using-vue-with-canvas.html
Example:
<a-canvas width="500" height="200"
:draw="(canvas, ctx) => { ctx.fillRect(x,y,1,1); }" />
This will call the draw function when the canvas is created,
and also update it whenever x or y changes, because the draw
function depends on them. Typical use: pass in a method from the
parent component.
Note:
This function will clear the canvas contents before calling the
draw function. It will wrap the call in save()/restore() to reset
the drawing state back to the default.
*/
Vue.component('a-canvas', {
props: ['width', 'height', 'draw'],
data() { return { ctx: null, }; },
template: `<canvas :data-dummyvalue="ctx &amp;&amp; redraw">`,
mounted() { this.ctx = this.$el.getContext('2d'); },
computed: {
redraw() {
let canvas = this.$el;
canvas.width = this.width;
canvas.height = this.height;
this.ctx.clearRect(0, 0, this.width, this.height);
this.ctx.save();
this.draw(canvas, this.ctx);
this.ctx.restore();
},
},
});
/* Implementation note: I set data-automatic="ctx && redraw" to make
the DOM depend on this computed property. The first time it's calculated,
the canvas doesn't exist yet. Subsequent calculations invoke the computed
property "redraw", which calls the draw function, which sets up the automatic
dependency tracking in Vue. This redraw function also uses the
width, height, and draw properties, so if any of those change, it
will trigger a redraw. */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment