Last active
April 11, 2023 07:31
-
-
Save redblobgames/fc3717945e9b533496bbc727e8751fe6 to your computer and use it in GitHub Desktop.
Vue component for canvas with automatic dependency tracking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** 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 && 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