Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing onto a canvas with vue.js

I don't think this is necessarily a Vue based issue, but I'm running into some trouble.

I'd like to write to the canvas a Vue variable. If I remove vue, my initial code works fine, however if I add Vue the canvas doesn't actually start up.

Here is my code

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

ctx.fillStyle = "black";
ctx.font="20px Georgia";
ctx.fillText("Hello World!",10,50);

var v = new Vue({
  el: '#app',
  data: {
    'exampleContent': 'This is TEXT'
  },
  watch: {
    exampleContent: function(val, oldVal) {
      ctx.clearRect(0,0,canvas.width,canvas.height);
      ctx.fillStyle = "black";
      ctx.font="20px Georgia";
      ctx.fillText(this.exampleContent,10,50);
    }
  }
});

If I comment out /* var v = new Vue({ ... the initial bit works. If I log the value of exampleContent in the watcher that also works. But something about the canvas isn't working.

Demo to play with: http://codepen.io/EightArmsHQ/pen/EgGbgR?editors=1010

like image 589
Djave Avatar asked Oct 21 '16 13:10

Djave


People also ask

How do I use canvas in VUE JS?

Create a canvasStart off by creating a canvas in your DOM. Let's add a little CSS to keep the canvas' boundaries visible. Instantiate a Vue class and hook it up to you DOM. The trick to managing the canvas is by making it accessible to Vue by declaring a state and passing it the canvas' 2d context.

Is Vue JS good for large projects?

Being a frontend newcomer compared to other big players in the world of JavaScript such as React or Angular, Vue. js is increasingly used in large-scale projects. The growing maturity of the framework and its considerable ecosystem make Vue capable of meeting even the most demanding project requirements.

Does canvas work with JavaScript?

<canvas> is an HTML element which can be used to draw graphics via scripting (usually JavaScript). This can, for instance, be used to draw graphs, combine photos, or create simple animations.

Is Vue JS good for web development?

Vue. js is one of the most popularly used JS frameworks for developing UIs and single-page applications. Developers prefer this progressive framework as it offers easy-to-use syntax and clean formatting styles. Besides, it also gets easily integrated into other infrastructure as well.


2 Answers

Please check this jsFiddle: https://jsfiddle.net/mani04/r4mbh6nu/

EDIT: updated with dynamic text: https://jsfiddle.net/mani04/r4mbh6nu/1/

In the above example, I am able to write into canvas, and also ensure that the input text goes into span as you would expect, all using Vue.js

Coming back to your example, the HTML is:

<div id="app">     <canvas id="canvas" width="800" height="600"></canvas>     <input type="text" v-model="exampleContent" />     <span>{{ exampleContent }}</span> </div> 

Vue.js reads the elements inside #app and keeps it as the template for your Vue app. So your canvas, input and span elements will now be re-rendered by Vue.js when it constructs the DOM.

During this process, your original canvas text - the one you set before initiating the Vue application gets lost.

There is no clear way to solve this issue other than using a directive, as in my jsFiddle example. A Vue directive helps you capture the DOM element.

In my example, I define a Vue directive called insert-message which I use on canvas as v-insert-message. This allows me to capture the DOM element and then do the other steps: getContext and fillText. There is no id required, or no javascript code to getElementById.

One more thing - your canvas is just too large, and therefore you were not able to see your input and span elements. They were working normally in your example also!

EDIT: example for directive bindings

I just found a way to use directives and still write dynamic stuff into canvas.

Check the updated jsFiddle: https://jsfiddle.net/mani04/r4mbh6nu/1/

like image 192
Mani Avatar answered Sep 19 '22 14:09

Mani


Here's an easy way that works with Vuejs 2:

  1. Add the canvas to you template with a reference attribute:

    ref="myCanvas"

  2. You can then access it anywhere inside your component using

    var canvas = this.$refs.myCanvas

like image 40
tariqdaouda Avatar answered Sep 20 '22 14:09

tariqdaouda