Reputation: 138
Has anyone else tried to mix A-Frame VR with Nuxt.js? I get the error "Window is not defined".
I have so far
Installed A-Frame via NPM
Created a plugin "plugins/aframe.js" with the following
import Vue from 'vue'
import aframe from 'aframe'
Vue.use(aframe)
plugins: [
{ src: '@/plugins/aframe.js', ssr: false }
],
<template>
<a-scene vr-mode-ui="enabled: false">
<a-entity position="0 0 0">
<a-camera></a-camera>
</a-entity>
<a-entity
geometry="primitive: torusKnot;"
scale="2 2 2"
position="0 1.5 -5"
rotation="0 45 0"
material="color:#BBBBBB"
wireframe
>
<a-animation easing="linear" attribute="rotation" repeat="indefinite" dur="30000" to="0 405 0"></a-animation>
</a-entity>
<a-sky color="#FDFDFD"></a-sky>
</a-scene>
</template>
if (process.client) {
Vue.use(require('aframe'))
}
export default {
created () {
aframe.registerComponent('wireframe', {
dependencies: ['material'],
init () {
this.el.components.material.material.wireframe = true
}
})
}
}
And included the component in my default layout
<Aframe />
import Aframe from 'aframe'
export default {
components: {
Aframe
},
Upvotes: 1
Views: 1366
Reputation: 21
I found a clean way to do this using SPA Mode. You will need to create a module that intercepts the router request to the page containing your A-Frame code. This method will make it so A-Frame is only loaded client-side and thus A-Frame will have access to client-side only objects like window.
Step 1: Create a new module, name it whatever you want and make sure it intercepts the call to your page - in this example, the page is named vrdemo.vue under pages. Make sure to put your module in the correct module folder: root->modules->navmodules.js
export default function () {
this.nuxt.hook('render:setupMiddleware', (app) => {
app.use('/vrdemo', (req, res, next) => { //Do NOT load vrdemo on the server-side due to use of client only a-frame JS libraries
res.spa = true
next()
})
})
}
Step 2: Register the module in nuxt.config
modules: [ '~/modules/navmodule'],
Step 3: Import A-Frame in the page your module is intercepting
<template>
//use A-Frame
</template>
<script>
import aframe from "aframe";
export default {
//stuff
};
</script>
I additionally made some components that use A-Frame, as long as I call the component from this page, the A-Frame script is loaded and I can use it.
You will need to make sure you have installed A-Frame (npm install aframe) into your project using npm or yarn for this to work. Good Luck!
Upvotes: 1
Reputation: 138
For anyone else struggling with this here is one way that seems to work.
In nuxt.config.js add a-frame vr as a script tag
script: [
{
src: 'https://aframe.io/releases/0.7.1/aframe.min.js'
}
]
Then in your component add the a-frame scene as data string
export default {
name: 'afvr',
data () {
return {
aframes: [
{
scene: '<a-scene vr-mode-ui="enabled: false" embedded><a-entity position="0 -1 3" scale="0.5 0.5 0.5"><a-camera zoom="0.8" fov="80" near="0.001" far="50"></a-camera></a-entity><a-torus-knot color="#e1e1e1" segments-tubular="124" radius="1" radius-tubular="0.1" wireframe="true"><a-animation easing="linear" attribute="rotation" repeat="indefinite" dur="30000" to="360 360 360"></a-animation></a-torus-knot></a-scene>',
id: 1
}
]
}
}
}
Then render it in the template as raw HTML
<div class="aframe" v-for="aframe in aframes" :key="aframe.id" v-html="aframe.scene" />
Does the trick
Upvotes: 1