Vue
by Erick Petrucelli
HTML
<script src="https://unpkg.com/three"></script>
<script src="https://unpkg.com/vue-gl"></script>
<div id="app">
<nav>
<a v-for="n in 3" :key="n" :href="isExample(n) ? null : `#${n}`" :class="{ disabled: isExample(n) }" @click.prevent="showExample(n)">
Example {{ n }}
</a>
</nav>
<main>
<div v-show="isExample(1)">
<vgl-renderer name="renderer" scene="scene" camera="camera" antialias>
<vgl-box-geometry name="box" />
<vgl-scene name="scene">
<vgl-mesh geometry="box" />
</vgl-scene>
<vgl-perspective-camera name="camera" orbit-position="3 1 0.5" />
</vgl-renderer>
</div>
<div v-show="isExample(2)">
<vgl-renderer name="renderer" scene="scene" camera="camera" antialias>
<vgl-box-geometry name="box" />
<vgl-mesh-standard-material name="material" />
<vgl-scene name="scene">
<vgl-mesh geometry="box" material="material" />
<vgl-directional-light name="light" position="1 2 3" />
</vgl-scene>
<vgl-perspective-camera name="camera" orbit-position="3 1 0.5" />
</vgl-renderer>
</div>
<div v-show="isExample(3)">
<vgl-renderer name="renderer" scene="scene" camera="camera" antialias>
<vgl-scene name="scene" background-color="#999" fog="#999 0.1 20">
<vgl-box-geometry name="boxGeometry" />
<vgl-mesh-standard-material name="boxMaterial" />
<vgl-mesh geometry="boxGeometry" material="boxMaterial" cast-shadow receive-shadow position="0 0.5 0" :rotation="`0 ${boxRotationY} 0 ZYX`" />
<vgl-box-geometry name="groundGeometry" width="50" depth="50" height="0.1" />
<vgl-mesh-phong-material name="groundMaterial" color="#666" />
<vgl-mesh geometry="groundGeometry" material="groundMaterial" cast-shadow receive-shadow position="0 -0.5 0"/>
<vgl-hemisphere-light name="hemisphere" color="#fff" ground-color="#666" intensity="0.2" />
...
CSS
html, body {
height: 100vh;
}
body {
background: #20262e;
font-family: Helvetica, Arial, sans-serif;
margin: 0;
padding: 0;
}
#app {
box-sizing: border-box;
height: 100%;
padding: 1rem;
display: flex;
flex-flow: column;
gap: 0.5rem;
}
nav {
flex: 0;
display: flex;
gap: 0.5rem;
}
a {
padding: 0.25rem;
text-decoration: none;
color: #2795ee;
}
a.disabled {
opacity: 0.3;
cursor: default;
}
main {
flex: 1;
display: flex;
}
main > div {
display: flex;
flex-flow: column;
gap: 1rem;
}
main > div > *:first-child {
/* height: 100%; */ /* fluid size not working */
/* height: 300px; only works when fixing vgl-renderer in pixels */
line-height: 0;
height: 100%;
}
.fade-enter-active, .fade-leave-active {
transition: opacity 0.25s ease-in-out;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
Vue
Object.keys(VueGL).forEach((name) => {
Vue.component(name, VueGL[name]);
});
new Vue({
el: "#app",
data: {
example: 1,
boxRotationY: 0,
},
methods: {
showExample (example) {
this.example = example
},
isExample (example) {
return (this.example === example)
}
}
})