Vue JS - How do I get WebGL to render via Vue without disappearing?When to use Float32Array instead of Array in JavaScriptHow do you get a timestamp in JavaScript?How to get the children of the $(this) selector?How can I know which radio button is selected via jQuery?How do I modify the URL without reloading the page?How can I get query string values in JavaScript?How do I get the current date in JavaScript?WebGL: difference between vertex shader transform and app/software transformHow to work with framebuffers in webgl?WebGL - two pass renderingtriangle not being shown in basic webgl program
Breaker Mapping Questions
Rent contract say that pets are not allowed. Possible repercussions if bringing the pet anyway?
What's special ammo?
If the Shillelagh cantrip is applied to a club with non-standard damage dice, what is the resulting damage dice?
Billiard balls collision
Semantic difference between regular and irregular 'backen'
How many birds in the bush?
Convergence of series of normally distributed random variables
Who was the most successful German spy against Great Britain in WWII, from the contemporary German perspective?
1mth baby boy keeps peeing through diapers, sometimes diper seems practically unused
Discussing work with supervisor in an invited dinner with his family
How should i charge 3 lithium ion batteries?
Why should a self-financing strategy be previsible?
Did anybody find out it was Anakin who blew up the command center?
Why is the UK so keen to remove the "backstop" when their leadership seems to think that no border will be needed in Northern Ireland?
Redacting URLs as an email-phishing preventative?
Unlock your Lock
Retroactively modifying humans for Earth?
How to gently end involvement with an online community?
What is the loud noise of a helicopter when the rotors are not yet moving?
Can Orcus use Multiattack with any melee weapon?
What is the name of my succulent?
Did Dr. Hannibal Lecter like Clarice or was he attracted to her?
Expanding powers of expressions of the form ax+b
Vue JS - How do I get WebGL to render via Vue without disappearing?
When to use Float32Array instead of Array in JavaScriptHow do you get a timestamp in JavaScript?How to get the children of the $(this) selector?How can I know which radio button is selected via jQuery?How do I modify the URL without reloading the page?How can I get query string values in JavaScript?How do I get the current date in JavaScript?WebGL: difference between vertex shader transform and app/software transformHow to work with framebuffers in webgl?WebGL - two pass renderingtriangle not being shown in basic webgl program
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
Question
I'm trying to use Vue JS to display some very simple WebGL. I use a Vue method call inside my canvas element to start the function that renders the WebGL. It all works fine, except that the rendered image flashes on the screen in a flash, then disappears. The image is a simple triangle that's supposed to just sit onthe screen once rendered. I can't find a solution to it?
As I'm very novice, I might have made some obvious mistakes that are there the problem, there may be I'm guessing some standardised way to incorporate simple, basic WebGl into the HTML via Vue, but I've just not been able to find it?
What are the possible solutions? Unfortunately, I'm supposed to use just basic WebGL (not Three.js or anything), but via basic Vue JS.
I'll explain the details, below.
Background
I'm fairly new to Vue JS, and very new to WebGL. I'm following this series of tutorials on YouTube for my first intro to WebGL, with the particular video linked there containing the code I followed for this problem.
The only, perhaps significantly, different thing to the vid I did was of course to use Vue JS as a UI framework, rather than writing plain HTML and Javascript files, then manually using node js to set up a server.
In the tutorial, he links via a tag in the html a separate .js file containing the WebGL code. In this script, Javascript just uses query selector to grab the canvas and its context, and assign it as the place to output the render.
Inside Vue JS, I wasn't sure how to tell Vue to just run an external script that wasn't a method or computed etc, so I put the WebGL code in a method, and output it to the screen by calling the method inside the canvas tag in the vue template:
<template>
<div id="app">
<canvas> runWebGL() </canvas>
</div>
</template>
export default
methods:
runWebGL()
.
.
//All the WebGLCode from the video - which for brevity I've pasted right at the bottom.
.
.
Now this actually works, and the little red triangle is actually rendered - except as soon as it's rendered to the screen, it disappears.
My Thoughts As To Why
Here's what I think happens: when the vue component first loads, it runs the runWebGL() method I've put there, creates and then displays the lil red triangle in the canvas. When the method has finished however, well it's no longer running so everything in it is destroyed and there's no WebGL to output.
If I put an alert function for example at the end of runWebGL() to prevent the function from automatically ending, you can see the triangle staying outputted to the screen until the user closes the alert.
What I'm assuming then is that when, as the guy has done in the video, you attach some script directly to the html via tags, be they local or externally referenced scripts, once they're finished they don't close. So the data etc in them is still available, even though they've been parsed to the end?
How do I solve this in Vue JS, then? Am I supposed to implement some way of keeping Vue JS methods 'running' even when the code in them has finished executing? Or is there some other, more standardised method for meshing WebGL and Vue JS?
I'm aware that there are some WebGL frameworks out there, and that there are some that try to blend Vue and WebGL, but unfortunately I'm not supposed to use them - I've got to get it as close to native VueJS and plain WebGL as I can.
Thanks very much indeed for your help!
The Javascript and WebGL code, which is identical to the one from the video, which I put inside runWebGL() is here:
const canvas = document.querySelector(`canvas`);
const gl = canvas.getContext(`webgl`);
if (!gl) throw new Error(`webGL not supported`);
/* ***OUTLINE**** */ // load vertexData into Buffer // create vertex SharedArrayBuffer // create program // attach shaders to program // enable vertex attributes // draw
console.log(`Starting...`);
// create a triangle, x,y,z. WebGL uses OpenGL uses Float32 Arrays. // Typically don't use Float32 arrays in JS as per: // https://stackoverflow.com/questions/15823021/when-to-use-float32array-instead-of-array-in-javascript
// changing these points will alter where the corners of your triangle are. max is 1, min is -1
const vertexData = new Float32Array([ 0, 1, 0, 1, -1, 0, -1, -1, 0, ]); const buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// bind this buffer as the current buffer; as an array of vertices
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
// STATIC_DRAW if not rewriting (optomise) common alternative is DYNAMIC_DRAW // Creates the vertex-shader; a mini program that runs on the GPU // this uses the GL shading language (not JS), hence the typed return for the function (ie 'void') // gl_position is the output of the shader; an array of 4 components from the buffer // vec3 indicates the three parts of x,y,z; this is converted to a vec4 by adding "1" to 'position'
const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, ` attribute vec3 position; void main() gl_Position = vec4(position, 1); `); gl.compileShader(vertexShader);
// create a fragment-shader // a fragment shader shades the pixels between vertices // the vec4 is in format RGB-A // try changing some of these numbers and see what happens // eg vec4(0,1,0,.5) gives a transparent green triangle
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, ` void main() gl_FragColor = vec4(1, 0, 0, 1); `); gl.compileShader(fragmentShader);
// create a program that links the two shaders (vertex and fragment) // to the actual vertices
const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program);
// load the attributes. // Currently we just have a single attribute `position` created with the vertex shader // Attributes are disabled by default - so we have to enable it
const positionLocation = gl.getAttribLocation(program, `position`); gl.enableVertexAttribArray(positionLocation);
// how webgl should retrieve data from the currently bound buffer // what is being retrieved? positionLocation // how many elements to read at a time? 3 (x,y,z) // what type are the elements? floating point numbers (from Float32Array) // remaining arguments are not used ('normalise' is an advanced optomisation, not needed here)
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
// create an excutable program on the graphics card // drawArrays, 2nd argument is which vertex to start at, how many to draw? (in this case there are 3 vertices all with 3 attributes (x,y,z))
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);const canvas = document.querySelector(`canvas`);
const gl = canvas.getContext(`webgl`);
if (!gl) throw new Error(`webGL not supported`);
/* ***OUTLINE**** */ // load vertexData into Buffer // create vertex SharedArrayBuffer // create program // attach shaders to program // enable vertex attributes // draw
console.log(`Starting...`);
// create a triangle, x,y,z. WebGL uses OpenGL uses Float32 Arrays. // Typically don't use Float32 arrays in JS as per: // https://stackoverflow.com/questions/15823021/when-to-use-float32array-instead-of-array-in-javascript
// changing these points will alter where the corners of your triangle are. max is 1, min is -1
const vertexData = new Float32Array([ 0, 1, 0, 1, -1, 0, -1, -1, 0, ]); const buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// bind this buffer as the current buffer; as an array of vertices
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
// STATIC_DRAW if not rewriting (optomise) common alternative is DYNAMIC_DRAW // Creates the vertex-shader; a mini program that runs on the GPU // this uses the GL shading language (not JS), hence the typed return for the function (ie 'void') // gl_position is the output of the shader; an array of 4 components from the buffer // vec3 indicates the three parts of x,y,z; this is converted to a vec4 by adding "1" to 'position'
const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, ` attribute vec3 position; void main() gl_Position = vec4(position, 1); `); gl.compileShader(vertexShader);
// create a fragment-shader // a fragment shader shades the pixels between vertices // the vec4 is in format RGB-A // try changing some of these numbers and see what happens // eg vec4(0,1,0,.5) gives a transparent green triangle
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, ` void main() gl_FragColor = vec4(1, 0, 0, 1); `); gl.compileShader(fragmentShader);
// create a program that links the two shaders (vertex and fragment) // to the actual vertices
const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program);
// load the attributes. // Currently we just have a single attribute `position` created with the vertex shader // Attributes are disabled by default - so we have to enable it
const positionLocation = gl.getAttribLocation(program, `position`); gl.enableVertexAttribArray(positionLocation);
// how webgl should retrieve data from the currently bound buffer // what is being retrieved? positionLocation // how many elements to read at a time? 3 (x,y,z) // what type are the elements? floating point numbers (from Float32Array) // remaining arguments are not used ('normalise' is an advanced optomisation, not needed here)
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
// create an excutable program on the graphics card // drawArrays, 2nd argument is which vertex to start at, how many to draw? (in this case there are 3 vertices all with 3 attributes (x,y,z))
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);
javascript vue.js vuejs2 webgl webgl2
add a comment |
Question
I'm trying to use Vue JS to display some very simple WebGL. I use a Vue method call inside my canvas element to start the function that renders the WebGL. It all works fine, except that the rendered image flashes on the screen in a flash, then disappears. The image is a simple triangle that's supposed to just sit onthe screen once rendered. I can't find a solution to it?
As I'm very novice, I might have made some obvious mistakes that are there the problem, there may be I'm guessing some standardised way to incorporate simple, basic WebGl into the HTML via Vue, but I've just not been able to find it?
What are the possible solutions? Unfortunately, I'm supposed to use just basic WebGL (not Three.js or anything), but via basic Vue JS.
I'll explain the details, below.
Background
I'm fairly new to Vue JS, and very new to WebGL. I'm following this series of tutorials on YouTube for my first intro to WebGL, with the particular video linked there containing the code I followed for this problem.
The only, perhaps significantly, different thing to the vid I did was of course to use Vue JS as a UI framework, rather than writing plain HTML and Javascript files, then manually using node js to set up a server.
In the tutorial, he links via a tag in the html a separate .js file containing the WebGL code. In this script, Javascript just uses query selector to grab the canvas and its context, and assign it as the place to output the render.
Inside Vue JS, I wasn't sure how to tell Vue to just run an external script that wasn't a method or computed etc, so I put the WebGL code in a method, and output it to the screen by calling the method inside the canvas tag in the vue template:
<template>
<div id="app">
<canvas> runWebGL() </canvas>
</div>
</template>
export default
methods:
runWebGL()
.
.
//All the WebGLCode from the video - which for brevity I've pasted right at the bottom.
.
.
Now this actually works, and the little red triangle is actually rendered - except as soon as it's rendered to the screen, it disappears.
My Thoughts As To Why
Here's what I think happens: when the vue component first loads, it runs the runWebGL() method I've put there, creates and then displays the lil red triangle in the canvas. When the method has finished however, well it's no longer running so everything in it is destroyed and there's no WebGL to output.
If I put an alert function for example at the end of runWebGL() to prevent the function from automatically ending, you can see the triangle staying outputted to the screen until the user closes the alert.
What I'm assuming then is that when, as the guy has done in the video, you attach some script directly to the html via tags, be they local or externally referenced scripts, once they're finished they don't close. So the data etc in them is still available, even though they've been parsed to the end?
How do I solve this in Vue JS, then? Am I supposed to implement some way of keeping Vue JS methods 'running' even when the code in them has finished executing? Or is there some other, more standardised method for meshing WebGL and Vue JS?
I'm aware that there are some WebGL frameworks out there, and that there are some that try to blend Vue and WebGL, but unfortunately I'm not supposed to use them - I've got to get it as close to native VueJS and plain WebGL as I can.
Thanks very much indeed for your help!
The Javascript and WebGL code, which is identical to the one from the video, which I put inside runWebGL() is here:
const canvas = document.querySelector(`canvas`);
const gl = canvas.getContext(`webgl`);
if (!gl) throw new Error(`webGL not supported`);
/* ***OUTLINE**** */ // load vertexData into Buffer // create vertex SharedArrayBuffer // create program // attach shaders to program // enable vertex attributes // draw
console.log(`Starting...`);
// create a triangle, x,y,z. WebGL uses OpenGL uses Float32 Arrays. // Typically don't use Float32 arrays in JS as per: // https://stackoverflow.com/questions/15823021/when-to-use-float32array-instead-of-array-in-javascript
// changing these points will alter where the corners of your triangle are. max is 1, min is -1
const vertexData = new Float32Array([ 0, 1, 0, 1, -1, 0, -1, -1, 0, ]); const buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// bind this buffer as the current buffer; as an array of vertices
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
// STATIC_DRAW if not rewriting (optomise) common alternative is DYNAMIC_DRAW // Creates the vertex-shader; a mini program that runs on the GPU // this uses the GL shading language (not JS), hence the typed return for the function (ie 'void') // gl_position is the output of the shader; an array of 4 components from the buffer // vec3 indicates the three parts of x,y,z; this is converted to a vec4 by adding "1" to 'position'
const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, ` attribute vec3 position; void main() gl_Position = vec4(position, 1); `); gl.compileShader(vertexShader);
// create a fragment-shader // a fragment shader shades the pixels between vertices // the vec4 is in format RGB-A // try changing some of these numbers and see what happens // eg vec4(0,1,0,.5) gives a transparent green triangle
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, ` void main() gl_FragColor = vec4(1, 0, 0, 1); `); gl.compileShader(fragmentShader);
// create a program that links the two shaders (vertex and fragment) // to the actual vertices
const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program);
// load the attributes. // Currently we just have a single attribute `position` created with the vertex shader // Attributes are disabled by default - so we have to enable it
const positionLocation = gl.getAttribLocation(program, `position`); gl.enableVertexAttribArray(positionLocation);
// how webgl should retrieve data from the currently bound buffer // what is being retrieved? positionLocation // how many elements to read at a time? 3 (x,y,z) // what type are the elements? floating point numbers (from Float32Array) // remaining arguments are not used ('normalise' is an advanced optomisation, not needed here)
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
// create an excutable program on the graphics card // drawArrays, 2nd argument is which vertex to start at, how many to draw? (in this case there are 3 vertices all with 3 attributes (x,y,z))
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);const canvas = document.querySelector(`canvas`);
const gl = canvas.getContext(`webgl`);
if (!gl) throw new Error(`webGL not supported`);
/* ***OUTLINE**** */ // load vertexData into Buffer // create vertex SharedArrayBuffer // create program // attach shaders to program // enable vertex attributes // draw
console.log(`Starting...`);
// create a triangle, x,y,z. WebGL uses OpenGL uses Float32 Arrays. // Typically don't use Float32 arrays in JS as per: // https://stackoverflow.com/questions/15823021/when-to-use-float32array-instead-of-array-in-javascript
// changing these points will alter where the corners of your triangle are. max is 1, min is -1
const vertexData = new Float32Array([ 0, 1, 0, 1, -1, 0, -1, -1, 0, ]); const buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// bind this buffer as the current buffer; as an array of vertices
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
// STATIC_DRAW if not rewriting (optomise) common alternative is DYNAMIC_DRAW // Creates the vertex-shader; a mini program that runs on the GPU // this uses the GL shading language (not JS), hence the typed return for the function (ie 'void') // gl_position is the output of the shader; an array of 4 components from the buffer // vec3 indicates the three parts of x,y,z; this is converted to a vec4 by adding "1" to 'position'
const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, ` attribute vec3 position; void main() gl_Position = vec4(position, 1); `); gl.compileShader(vertexShader);
// create a fragment-shader // a fragment shader shades the pixels between vertices // the vec4 is in format RGB-A // try changing some of these numbers and see what happens // eg vec4(0,1,0,.5) gives a transparent green triangle
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, ` void main() gl_FragColor = vec4(1, 0, 0, 1); `); gl.compileShader(fragmentShader);
// create a program that links the two shaders (vertex and fragment) // to the actual vertices
const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program);
// load the attributes. // Currently we just have a single attribute `position` created with the vertex shader // Attributes are disabled by default - so we have to enable it
const positionLocation = gl.getAttribLocation(program, `position`); gl.enableVertexAttribArray(positionLocation);
// how webgl should retrieve data from the currently bound buffer // what is being retrieved? positionLocation // how many elements to read at a time? 3 (x,y,z) // what type are the elements? floating point numbers (from Float32Array) // remaining arguments are not used ('normalise' is an advanced optomisation, not needed here)
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
// create an excutable program on the graphics card // drawArrays, 2nd argument is which vertex to start at, how many to draw? (in this case there are 3 vertices all with 3 attributes (x,y,z))
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);
javascript vue.js vuejs2 webgl webgl2
I think this is an AB question. What do you think the benefits of using Vue in this instance are? I think you are going to run into more issues using Vue in this case because you are going to accidentally erase your<canvas>
which will kill your GL context. Additionally, I wouldn't use the DOM API to interact with elements within the Vue context, leverage$ref
s. Have you tried this without Vue? Do you still have the same issue?
– zero298
Mar 27 at 20:14
I have tried putting a <script></script> inside the html which vue bundles with its code via webpack etc, and putting the WebGL code in that script - it works. The triangle renders and stays there. However, for other reasons I need to use Vue if I can. It'll actually be much easier to build and deploy the rest of my app if I use Vue. It is just one single component, though - will Vue still erase the canvas even without changing components (or is the problem you're talking about not related to that?). And I'll look at using $ref instead - what's the disadvantage of doing how I have, tho? Thnx!
– TheRealPaulMcCartney
Mar 27 at 21:40
add a comment |
Question
I'm trying to use Vue JS to display some very simple WebGL. I use a Vue method call inside my canvas element to start the function that renders the WebGL. It all works fine, except that the rendered image flashes on the screen in a flash, then disappears. The image is a simple triangle that's supposed to just sit onthe screen once rendered. I can't find a solution to it?
As I'm very novice, I might have made some obvious mistakes that are there the problem, there may be I'm guessing some standardised way to incorporate simple, basic WebGl into the HTML via Vue, but I've just not been able to find it?
What are the possible solutions? Unfortunately, I'm supposed to use just basic WebGL (not Three.js or anything), but via basic Vue JS.
I'll explain the details, below.
Background
I'm fairly new to Vue JS, and very new to WebGL. I'm following this series of tutorials on YouTube for my first intro to WebGL, with the particular video linked there containing the code I followed for this problem.
The only, perhaps significantly, different thing to the vid I did was of course to use Vue JS as a UI framework, rather than writing plain HTML and Javascript files, then manually using node js to set up a server.
In the tutorial, he links via a tag in the html a separate .js file containing the WebGL code. In this script, Javascript just uses query selector to grab the canvas and its context, and assign it as the place to output the render.
Inside Vue JS, I wasn't sure how to tell Vue to just run an external script that wasn't a method or computed etc, so I put the WebGL code in a method, and output it to the screen by calling the method inside the canvas tag in the vue template:
<template>
<div id="app">
<canvas> runWebGL() </canvas>
</div>
</template>
export default
methods:
runWebGL()
.
.
//All the WebGLCode from the video - which for brevity I've pasted right at the bottom.
.
.
Now this actually works, and the little red triangle is actually rendered - except as soon as it's rendered to the screen, it disappears.
My Thoughts As To Why
Here's what I think happens: when the vue component first loads, it runs the runWebGL() method I've put there, creates and then displays the lil red triangle in the canvas. When the method has finished however, well it's no longer running so everything in it is destroyed and there's no WebGL to output.
If I put an alert function for example at the end of runWebGL() to prevent the function from automatically ending, you can see the triangle staying outputted to the screen until the user closes the alert.
What I'm assuming then is that when, as the guy has done in the video, you attach some script directly to the html via tags, be they local or externally referenced scripts, once they're finished they don't close. So the data etc in them is still available, even though they've been parsed to the end?
How do I solve this in Vue JS, then? Am I supposed to implement some way of keeping Vue JS methods 'running' even when the code in them has finished executing? Or is there some other, more standardised method for meshing WebGL and Vue JS?
I'm aware that there are some WebGL frameworks out there, and that there are some that try to blend Vue and WebGL, but unfortunately I'm not supposed to use them - I've got to get it as close to native VueJS and plain WebGL as I can.
Thanks very much indeed for your help!
The Javascript and WebGL code, which is identical to the one from the video, which I put inside runWebGL() is here:
const canvas = document.querySelector(`canvas`);
const gl = canvas.getContext(`webgl`);
if (!gl) throw new Error(`webGL not supported`);
/* ***OUTLINE**** */ // load vertexData into Buffer // create vertex SharedArrayBuffer // create program // attach shaders to program // enable vertex attributes // draw
console.log(`Starting...`);
// create a triangle, x,y,z. WebGL uses OpenGL uses Float32 Arrays. // Typically don't use Float32 arrays in JS as per: // https://stackoverflow.com/questions/15823021/when-to-use-float32array-instead-of-array-in-javascript
// changing these points will alter where the corners of your triangle are. max is 1, min is -1
const vertexData = new Float32Array([ 0, 1, 0, 1, -1, 0, -1, -1, 0, ]); const buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// bind this buffer as the current buffer; as an array of vertices
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
// STATIC_DRAW if not rewriting (optomise) common alternative is DYNAMIC_DRAW // Creates the vertex-shader; a mini program that runs on the GPU // this uses the GL shading language (not JS), hence the typed return for the function (ie 'void') // gl_position is the output of the shader; an array of 4 components from the buffer // vec3 indicates the three parts of x,y,z; this is converted to a vec4 by adding "1" to 'position'
const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, ` attribute vec3 position; void main() gl_Position = vec4(position, 1); `); gl.compileShader(vertexShader);
// create a fragment-shader // a fragment shader shades the pixels between vertices // the vec4 is in format RGB-A // try changing some of these numbers and see what happens // eg vec4(0,1,0,.5) gives a transparent green triangle
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, ` void main() gl_FragColor = vec4(1, 0, 0, 1); `); gl.compileShader(fragmentShader);
// create a program that links the two shaders (vertex and fragment) // to the actual vertices
const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program);
// load the attributes. // Currently we just have a single attribute `position` created with the vertex shader // Attributes are disabled by default - so we have to enable it
const positionLocation = gl.getAttribLocation(program, `position`); gl.enableVertexAttribArray(positionLocation);
// how webgl should retrieve data from the currently bound buffer // what is being retrieved? positionLocation // how many elements to read at a time? 3 (x,y,z) // what type are the elements? floating point numbers (from Float32Array) // remaining arguments are not used ('normalise' is an advanced optomisation, not needed here)
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
// create an excutable program on the graphics card // drawArrays, 2nd argument is which vertex to start at, how many to draw? (in this case there are 3 vertices all with 3 attributes (x,y,z))
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);const canvas = document.querySelector(`canvas`);
const gl = canvas.getContext(`webgl`);
if (!gl) throw new Error(`webGL not supported`);
/* ***OUTLINE**** */ // load vertexData into Buffer // create vertex SharedArrayBuffer // create program // attach shaders to program // enable vertex attributes // draw
console.log(`Starting...`);
// create a triangle, x,y,z. WebGL uses OpenGL uses Float32 Arrays. // Typically don't use Float32 arrays in JS as per: // https://stackoverflow.com/questions/15823021/when-to-use-float32array-instead-of-array-in-javascript
// changing these points will alter where the corners of your triangle are. max is 1, min is -1
const vertexData = new Float32Array([ 0, 1, 0, 1, -1, 0, -1, -1, 0, ]); const buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// bind this buffer as the current buffer; as an array of vertices
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
// STATIC_DRAW if not rewriting (optomise) common alternative is DYNAMIC_DRAW // Creates the vertex-shader; a mini program that runs on the GPU // this uses the GL shading language (not JS), hence the typed return for the function (ie 'void') // gl_position is the output of the shader; an array of 4 components from the buffer // vec3 indicates the three parts of x,y,z; this is converted to a vec4 by adding "1" to 'position'
const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, ` attribute vec3 position; void main() gl_Position = vec4(position, 1); `); gl.compileShader(vertexShader);
// create a fragment-shader // a fragment shader shades the pixels between vertices // the vec4 is in format RGB-A // try changing some of these numbers and see what happens // eg vec4(0,1,0,.5) gives a transparent green triangle
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, ` void main() gl_FragColor = vec4(1, 0, 0, 1); `); gl.compileShader(fragmentShader);
// create a program that links the two shaders (vertex and fragment) // to the actual vertices
const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program);
// load the attributes. // Currently we just have a single attribute `position` created with the vertex shader // Attributes are disabled by default - so we have to enable it
const positionLocation = gl.getAttribLocation(program, `position`); gl.enableVertexAttribArray(positionLocation);
// how webgl should retrieve data from the currently bound buffer // what is being retrieved? positionLocation // how many elements to read at a time? 3 (x,y,z) // what type are the elements? floating point numbers (from Float32Array) // remaining arguments are not used ('normalise' is an advanced optomisation, not needed here)
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
// create an excutable program on the graphics card // drawArrays, 2nd argument is which vertex to start at, how many to draw? (in this case there are 3 vertices all with 3 attributes (x,y,z))
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);
javascript vue.js vuejs2 webgl webgl2
Question
I'm trying to use Vue JS to display some very simple WebGL. I use a Vue method call inside my canvas element to start the function that renders the WebGL. It all works fine, except that the rendered image flashes on the screen in a flash, then disappears. The image is a simple triangle that's supposed to just sit onthe screen once rendered. I can't find a solution to it?
As I'm very novice, I might have made some obvious mistakes that are there the problem, there may be I'm guessing some standardised way to incorporate simple, basic WebGl into the HTML via Vue, but I've just not been able to find it?
What are the possible solutions? Unfortunately, I'm supposed to use just basic WebGL (not Three.js or anything), but via basic Vue JS.
I'll explain the details, below.
Background
I'm fairly new to Vue JS, and very new to WebGL. I'm following this series of tutorials on YouTube for my first intro to WebGL, with the particular video linked there containing the code I followed for this problem.
The only, perhaps significantly, different thing to the vid I did was of course to use Vue JS as a UI framework, rather than writing plain HTML and Javascript files, then manually using node js to set up a server.
In the tutorial, he links via a tag in the html a separate .js file containing the WebGL code. In this script, Javascript just uses query selector to grab the canvas and its context, and assign it as the place to output the render.
Inside Vue JS, I wasn't sure how to tell Vue to just run an external script that wasn't a method or computed etc, so I put the WebGL code in a method, and output it to the screen by calling the method inside the canvas tag in the vue template:
<template>
<div id="app">
<canvas> runWebGL() </canvas>
</div>
</template>
export default
methods:
runWebGL()
.
.
//All the WebGLCode from the video - which for brevity I've pasted right at the bottom.
.
.
Now this actually works, and the little red triangle is actually rendered - except as soon as it's rendered to the screen, it disappears.
My Thoughts As To Why
Here's what I think happens: when the vue component first loads, it runs the runWebGL() method I've put there, creates and then displays the lil red triangle in the canvas. When the method has finished however, well it's no longer running so everything in it is destroyed and there's no WebGL to output.
If I put an alert function for example at the end of runWebGL() to prevent the function from automatically ending, you can see the triangle staying outputted to the screen until the user closes the alert.
What I'm assuming then is that when, as the guy has done in the video, you attach some script directly to the html via tags, be they local or externally referenced scripts, once they're finished they don't close. So the data etc in them is still available, even though they've been parsed to the end?
How do I solve this in Vue JS, then? Am I supposed to implement some way of keeping Vue JS methods 'running' even when the code in them has finished executing? Or is there some other, more standardised method for meshing WebGL and Vue JS?
I'm aware that there are some WebGL frameworks out there, and that there are some that try to blend Vue and WebGL, but unfortunately I'm not supposed to use them - I've got to get it as close to native VueJS and plain WebGL as I can.
Thanks very much indeed for your help!
The Javascript and WebGL code, which is identical to the one from the video, which I put inside runWebGL() is here:
const canvas = document.querySelector(`canvas`);
const gl = canvas.getContext(`webgl`);
if (!gl) throw new Error(`webGL not supported`);
/* ***OUTLINE**** */ // load vertexData into Buffer // create vertex SharedArrayBuffer // create program // attach shaders to program // enable vertex attributes // draw
console.log(`Starting...`);
// create a triangle, x,y,z. WebGL uses OpenGL uses Float32 Arrays. // Typically don't use Float32 arrays in JS as per: // https://stackoverflow.com/questions/15823021/when-to-use-float32array-instead-of-array-in-javascript
// changing these points will alter where the corners of your triangle are. max is 1, min is -1
const vertexData = new Float32Array([ 0, 1, 0, 1, -1, 0, -1, -1, 0, ]); const buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// bind this buffer as the current buffer; as an array of vertices
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
// STATIC_DRAW if not rewriting (optomise) common alternative is DYNAMIC_DRAW // Creates the vertex-shader; a mini program that runs on the GPU // this uses the GL shading language (not JS), hence the typed return for the function (ie 'void') // gl_position is the output of the shader; an array of 4 components from the buffer // vec3 indicates the three parts of x,y,z; this is converted to a vec4 by adding "1" to 'position'
const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, ` attribute vec3 position; void main() gl_Position = vec4(position, 1); `); gl.compileShader(vertexShader);
// create a fragment-shader // a fragment shader shades the pixels between vertices // the vec4 is in format RGB-A // try changing some of these numbers and see what happens // eg vec4(0,1,0,.5) gives a transparent green triangle
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, ` void main() gl_FragColor = vec4(1, 0, 0, 1); `); gl.compileShader(fragmentShader);
// create a program that links the two shaders (vertex and fragment) // to the actual vertices
const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program);
// load the attributes. // Currently we just have a single attribute `position` created with the vertex shader // Attributes are disabled by default - so we have to enable it
const positionLocation = gl.getAttribLocation(program, `position`); gl.enableVertexAttribArray(positionLocation);
// how webgl should retrieve data from the currently bound buffer // what is being retrieved? positionLocation // how many elements to read at a time? 3 (x,y,z) // what type are the elements? floating point numbers (from Float32Array) // remaining arguments are not used ('normalise' is an advanced optomisation, not needed here)
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
// create an excutable program on the graphics card // drawArrays, 2nd argument is which vertex to start at, how many to draw? (in this case there are 3 vertices all with 3 attributes (x,y,z))
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);const canvas = document.querySelector(`canvas`);
const gl = canvas.getContext(`webgl`);
if (!gl) throw new Error(`webGL not supported`);
/* ***OUTLINE**** */ // load vertexData into Buffer // create vertex SharedArrayBuffer // create program // attach shaders to program // enable vertex attributes // draw
console.log(`Starting...`);
// create a triangle, x,y,z. WebGL uses OpenGL uses Float32 Arrays. // Typically don't use Float32 arrays in JS as per: // https://stackoverflow.com/questions/15823021/when-to-use-float32array-instead-of-array-in-javascript
// changing these points will alter where the corners of your triangle are. max is 1, min is -1
const vertexData = new Float32Array([ 0, 1, 0, 1, -1, 0, -1, -1, 0, ]); const buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// bind this buffer as the current buffer; as an array of vertices
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
// STATIC_DRAW if not rewriting (optomise) common alternative is DYNAMIC_DRAW // Creates the vertex-shader; a mini program that runs on the GPU // this uses the GL shading language (not JS), hence the typed return for the function (ie 'void') // gl_position is the output of the shader; an array of 4 components from the buffer // vec3 indicates the three parts of x,y,z; this is converted to a vec4 by adding "1" to 'position'
const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, ` attribute vec3 position; void main() gl_Position = vec4(position, 1); `); gl.compileShader(vertexShader);
// create a fragment-shader // a fragment shader shades the pixels between vertices // the vec4 is in format RGB-A // try changing some of these numbers and see what happens // eg vec4(0,1,0,.5) gives a transparent green triangle
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, ` void main() gl_FragColor = vec4(1, 0, 0, 1); `); gl.compileShader(fragmentShader);
// create a program that links the two shaders (vertex and fragment) // to the actual vertices
const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program);
// load the attributes. // Currently we just have a single attribute `position` created with the vertex shader // Attributes are disabled by default - so we have to enable it
const positionLocation = gl.getAttribLocation(program, `position`); gl.enableVertexAttribArray(positionLocation);
// how webgl should retrieve data from the currently bound buffer // what is being retrieved? positionLocation // how many elements to read at a time? 3 (x,y,z) // what type are the elements? floating point numbers (from Float32Array) // remaining arguments are not used ('normalise' is an advanced optomisation, not needed here)
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
// create an excutable program on the graphics card // drawArrays, 2nd argument is which vertex to start at, how many to draw? (in this case there are 3 vertices all with 3 attributes (x,y,z))
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);
javascript vue.js vuejs2 webgl webgl2
javascript vue.js vuejs2 webgl webgl2
asked Mar 27 at 20:00
TheRealPaulMcCartneyTheRealPaulMcCartney
385 bronze badges
385 bronze badges
I think this is an AB question. What do you think the benefits of using Vue in this instance are? I think you are going to run into more issues using Vue in this case because you are going to accidentally erase your<canvas>
which will kill your GL context. Additionally, I wouldn't use the DOM API to interact with elements within the Vue context, leverage$ref
s. Have you tried this without Vue? Do you still have the same issue?
– zero298
Mar 27 at 20:14
I have tried putting a <script></script> inside the html which vue bundles with its code via webpack etc, and putting the WebGL code in that script - it works. The triangle renders and stays there. However, for other reasons I need to use Vue if I can. It'll actually be much easier to build and deploy the rest of my app if I use Vue. It is just one single component, though - will Vue still erase the canvas even without changing components (or is the problem you're talking about not related to that?). And I'll look at using $ref instead - what's the disadvantage of doing how I have, tho? Thnx!
– TheRealPaulMcCartney
Mar 27 at 21:40
add a comment |
I think this is an AB question. What do you think the benefits of using Vue in this instance are? I think you are going to run into more issues using Vue in this case because you are going to accidentally erase your<canvas>
which will kill your GL context. Additionally, I wouldn't use the DOM API to interact with elements within the Vue context, leverage$ref
s. Have you tried this without Vue? Do you still have the same issue?
– zero298
Mar 27 at 20:14
I have tried putting a <script></script> inside the html which vue bundles with its code via webpack etc, and putting the WebGL code in that script - it works. The triangle renders and stays there. However, for other reasons I need to use Vue if I can. It'll actually be much easier to build and deploy the rest of my app if I use Vue. It is just one single component, though - will Vue still erase the canvas even without changing components (or is the problem you're talking about not related to that?). And I'll look at using $ref instead - what's the disadvantage of doing how I have, tho? Thnx!
– TheRealPaulMcCartney
Mar 27 at 21:40
I think this is an AB question. What do you think the benefits of using Vue in this instance are? I think you are going to run into more issues using Vue in this case because you are going to accidentally erase your
<canvas>
which will kill your GL context. Additionally, I wouldn't use the DOM API to interact with elements within the Vue context, leverage $ref
s. Have you tried this without Vue? Do you still have the same issue?– zero298
Mar 27 at 20:14
I think this is an AB question. What do you think the benefits of using Vue in this instance are? I think you are going to run into more issues using Vue in this case because you are going to accidentally erase your
<canvas>
which will kill your GL context. Additionally, I wouldn't use the DOM API to interact with elements within the Vue context, leverage $ref
s. Have you tried this without Vue? Do you still have the same issue?– zero298
Mar 27 at 20:14
I have tried putting a <script></script> inside the html which vue bundles with its code via webpack etc, and putting the WebGL code in that script - it works. The triangle renders and stays there. However, for other reasons I need to use Vue if I can. It'll actually be much easier to build and deploy the rest of my app if I use Vue. It is just one single component, though - will Vue still erase the canvas even without changing components (or is the problem you're talking about not related to that?). And I'll look at using $ref instead - what's the disadvantage of doing how I have, tho? Thnx!
– TheRealPaulMcCartney
Mar 27 at 21:40
I have tried putting a <script></script> inside the html which vue bundles with its code via webpack etc, and putting the WebGL code in that script - it works. The triangle renders and stays there. However, for other reasons I need to use Vue if I can. It'll actually be much easier to build and deploy the rest of my app if I use Vue. It is just one single component, though - will Vue still erase the canvas even without changing components (or is the problem you're talking about not related to that?). And I'll look at using $ref instead - what's the disadvantage of doing how I have, tho? Thnx!
– TheRealPaulMcCartney
Mar 27 at 21:40
add a comment |
2 Answers
2
active
oldest
votes
You need to learn more about the life cycle of the vue-instance
. For example try the mounted hook
:
<template>
<div id="app">
<canvas></canvas>
</div>
</template>
<script>
export default
...
mounted ()
this.runWebGL()
,
methods:
runWebGL()
...
</script>
[ https://jsfiddle.net/stdob__/fyojs1vn/ ]
Thanks! This worked! Indeed I do need to lear more about the mounted hook. I've tried to pick it up before, but just found the online resources very confusing. I'll have another go, though. I really appreciate it.
– TheRealPaulMcCartney
Mar 28 at 9:59
@TheRealPaulMcCartney You are welcome ))
– stdob--
Mar 28 at 11:04
add a comment |
stdon's answer worked great for getting the WebGL to automatically start, and to stay there, when the Vue app is first loaded. Thanks!
In addition though, what I eventually wanted to do was to have the WebGL not start automatically, but to switch on at the click of a button. Having it start automatically was supposed to be the simpler starting point of my development.
I experimented with this myself then, and just had a button activate the "runWebGL" method when clicked - thus not needing to put runWebGL() inside the canvas tag to call the method automatically - and it worked!
But stdon's answer of using mount was the correct answer for what I originally asked, and deserves the upvotes. Thanks!
My New Setup:
Note, stdon's code from his answer works for setting up the WebGL to run automatically upon loading up the Vue app. Mine below is for the button set up I used.
The HTML
<template>
<div id="app">
<button @click="runWebGL"> Start WebGL </button>
<canvas></canvas>
</div>
</template>
The Javascript
<script>
export default
.
.
methods:
runWebGL()
//The Javascript & WebGL code from my original question
.
.
</script>
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55385538%2fvue-js-how-do-i-get-webgl-to-render-via-vue-without-disappearing%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You need to learn more about the life cycle of the vue-instance
. For example try the mounted hook
:
<template>
<div id="app">
<canvas></canvas>
</div>
</template>
<script>
export default
...
mounted ()
this.runWebGL()
,
methods:
runWebGL()
...
</script>
[ https://jsfiddle.net/stdob__/fyojs1vn/ ]
Thanks! This worked! Indeed I do need to lear more about the mounted hook. I've tried to pick it up before, but just found the online resources very confusing. I'll have another go, though. I really appreciate it.
– TheRealPaulMcCartney
Mar 28 at 9:59
@TheRealPaulMcCartney You are welcome ))
– stdob--
Mar 28 at 11:04
add a comment |
You need to learn more about the life cycle of the vue-instance
. For example try the mounted hook
:
<template>
<div id="app">
<canvas></canvas>
</div>
</template>
<script>
export default
...
mounted ()
this.runWebGL()
,
methods:
runWebGL()
...
</script>
[ https://jsfiddle.net/stdob__/fyojs1vn/ ]
Thanks! This worked! Indeed I do need to lear more about the mounted hook. I've tried to pick it up before, but just found the online resources very confusing. I'll have another go, though. I really appreciate it.
– TheRealPaulMcCartney
Mar 28 at 9:59
@TheRealPaulMcCartney You are welcome ))
– stdob--
Mar 28 at 11:04
add a comment |
You need to learn more about the life cycle of the vue-instance
. For example try the mounted hook
:
<template>
<div id="app">
<canvas></canvas>
</div>
</template>
<script>
export default
...
mounted ()
this.runWebGL()
,
methods:
runWebGL()
...
</script>
[ https://jsfiddle.net/stdob__/fyojs1vn/ ]
You need to learn more about the life cycle of the vue-instance
. For example try the mounted hook
:
<template>
<div id="app">
<canvas></canvas>
</div>
</template>
<script>
export default
...
mounted ()
this.runWebGL()
,
methods:
runWebGL()
...
</script>
[ https://jsfiddle.net/stdob__/fyojs1vn/ ]
answered Mar 27 at 22:15
stdob--stdob--
21.4k4 gold badges38 silver badges53 bronze badges
21.4k4 gold badges38 silver badges53 bronze badges
Thanks! This worked! Indeed I do need to lear more about the mounted hook. I've tried to pick it up before, but just found the online resources very confusing. I'll have another go, though. I really appreciate it.
– TheRealPaulMcCartney
Mar 28 at 9:59
@TheRealPaulMcCartney You are welcome ))
– stdob--
Mar 28 at 11:04
add a comment |
Thanks! This worked! Indeed I do need to lear more about the mounted hook. I've tried to pick it up before, but just found the online resources very confusing. I'll have another go, though. I really appreciate it.
– TheRealPaulMcCartney
Mar 28 at 9:59
@TheRealPaulMcCartney You are welcome ))
– stdob--
Mar 28 at 11:04
Thanks! This worked! Indeed I do need to lear more about the mounted hook. I've tried to pick it up before, but just found the online resources very confusing. I'll have another go, though. I really appreciate it.
– TheRealPaulMcCartney
Mar 28 at 9:59
Thanks! This worked! Indeed I do need to lear more about the mounted hook. I've tried to pick it up before, but just found the online resources very confusing. I'll have another go, though. I really appreciate it.
– TheRealPaulMcCartney
Mar 28 at 9:59
@TheRealPaulMcCartney You are welcome ))
– stdob--
Mar 28 at 11:04
@TheRealPaulMcCartney You are welcome ))
– stdob--
Mar 28 at 11:04
add a comment |
stdon's answer worked great for getting the WebGL to automatically start, and to stay there, when the Vue app is first loaded. Thanks!
In addition though, what I eventually wanted to do was to have the WebGL not start automatically, but to switch on at the click of a button. Having it start automatically was supposed to be the simpler starting point of my development.
I experimented with this myself then, and just had a button activate the "runWebGL" method when clicked - thus not needing to put runWebGL() inside the canvas tag to call the method automatically - and it worked!
But stdon's answer of using mount was the correct answer for what I originally asked, and deserves the upvotes. Thanks!
My New Setup:
Note, stdon's code from his answer works for setting up the WebGL to run automatically upon loading up the Vue app. Mine below is for the button set up I used.
The HTML
<template>
<div id="app">
<button @click="runWebGL"> Start WebGL </button>
<canvas></canvas>
</div>
</template>
The Javascript
<script>
export default
.
.
methods:
runWebGL()
//The Javascript & WebGL code from my original question
.
.
</script>
add a comment |
stdon's answer worked great for getting the WebGL to automatically start, and to stay there, when the Vue app is first loaded. Thanks!
In addition though, what I eventually wanted to do was to have the WebGL not start automatically, but to switch on at the click of a button. Having it start automatically was supposed to be the simpler starting point of my development.
I experimented with this myself then, and just had a button activate the "runWebGL" method when clicked - thus not needing to put runWebGL() inside the canvas tag to call the method automatically - and it worked!
But stdon's answer of using mount was the correct answer for what I originally asked, and deserves the upvotes. Thanks!
My New Setup:
Note, stdon's code from his answer works for setting up the WebGL to run automatically upon loading up the Vue app. Mine below is for the button set up I used.
The HTML
<template>
<div id="app">
<button @click="runWebGL"> Start WebGL </button>
<canvas></canvas>
</div>
</template>
The Javascript
<script>
export default
.
.
methods:
runWebGL()
//The Javascript & WebGL code from my original question
.
.
</script>
add a comment |
stdon's answer worked great for getting the WebGL to automatically start, and to stay there, when the Vue app is first loaded. Thanks!
In addition though, what I eventually wanted to do was to have the WebGL not start automatically, but to switch on at the click of a button. Having it start automatically was supposed to be the simpler starting point of my development.
I experimented with this myself then, and just had a button activate the "runWebGL" method when clicked - thus not needing to put runWebGL() inside the canvas tag to call the method automatically - and it worked!
But stdon's answer of using mount was the correct answer for what I originally asked, and deserves the upvotes. Thanks!
My New Setup:
Note, stdon's code from his answer works for setting up the WebGL to run automatically upon loading up the Vue app. Mine below is for the button set up I used.
The HTML
<template>
<div id="app">
<button @click="runWebGL"> Start WebGL </button>
<canvas></canvas>
</div>
</template>
The Javascript
<script>
export default
.
.
methods:
runWebGL()
//The Javascript & WebGL code from my original question
.
.
</script>
stdon's answer worked great for getting the WebGL to automatically start, and to stay there, when the Vue app is first loaded. Thanks!
In addition though, what I eventually wanted to do was to have the WebGL not start automatically, but to switch on at the click of a button. Having it start automatically was supposed to be the simpler starting point of my development.
I experimented with this myself then, and just had a button activate the "runWebGL" method when clicked - thus not needing to put runWebGL() inside the canvas tag to call the method automatically - and it worked!
But stdon's answer of using mount was the correct answer for what I originally asked, and deserves the upvotes. Thanks!
My New Setup:
Note, stdon's code from his answer works for setting up the WebGL to run automatically upon loading up the Vue app. Mine below is for the button set up I used.
The HTML
<template>
<div id="app">
<button @click="runWebGL"> Start WebGL </button>
<canvas></canvas>
</div>
</template>
The Javascript
<script>
export default
.
.
methods:
runWebGL()
//The Javascript & WebGL code from my original question
.
.
</script>
edited Mar 28 at 9:58
answered Mar 28 at 9:51
TheRealPaulMcCartneyTheRealPaulMcCartney
385 bronze badges
385 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55385538%2fvue-js-how-do-i-get-webgl-to-render-via-vue-without-disappearing%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I think this is an AB question. What do you think the benefits of using Vue in this instance are? I think you are going to run into more issues using Vue in this case because you are going to accidentally erase your
<canvas>
which will kill your GL context. Additionally, I wouldn't use the DOM API to interact with elements within the Vue context, leverage$ref
s. Have you tried this without Vue? Do you still have the same issue?– zero298
Mar 27 at 20:14
I have tried putting a <script></script> inside the html which vue bundles with its code via webpack etc, and putting the WebGL code in that script - it works. The triangle renders and stays there. However, for other reasons I need to use Vue if I can. It'll actually be much easier to build and deploy the rest of my app if I use Vue. It is just one single component, though - will Vue still erase the canvas even without changing components (or is the problem you're talking about not related to that?). And I'll look at using $ref instead - what's the disadvantage of doing how I have, tho? Thnx!
– TheRealPaulMcCartney
Mar 27 at 21:40