alobre
alobre

Reputation: 95

Adding image on THREE.js plane

I am trying to put an .png img on my plane, but when I try to load it, it disappears.

It may be that THREE.js is not made for Vue.js, is there any other 3D-Library that supports Vue.js?

I also want to add an SVG, THREE has an SVGLoader which I have not figured out how it works yet.

<template>
    <div id="container"></div>
</template>

<script>
import * as THREE from 'three'
//import { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader.js';
export default {
  name: 'Three',
  data() {
    return {
      camera: null,
      scene: null,
      renderer: null,
      mesh: null,
      shape: null,
      geomarty: null,
      stats: null,
      gui: null,
      guiData: null,
      texture: null
    }
  },
  methods: {
    init(){
        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

        this.renderer = new THREE.WebGLRenderer();
        this.renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( this.renderer.domElement );
        this.geometry = new THREE.PlaneGeometry( 5, 5, 5 );
        this.texture = new THREE.TextureLoader().load('../img/shark.png')
        this.material = new THREE.MeshLambertMaterial({map: this.texture})
        this.mesh = new THREE.Mesh( this.geometry, this.material );
        this.scene.add( this.mesh );
        this.camera.position.z = 5;
    },
    animate() {
    requestAnimationFrame( this.animate );
    this.renderer.render( this.scene, this.camera );
    }
  },
  mounted() {
      this.init();
      this.animate();
      //this.svgLoad();
  }
}
</script>

Upvotes: 1

Views: 373

Answers (1)

TheJim01
TheJim01

Reputation: 8886

Your animation function might be losing context. When you call it via requestAnimationFrame, the this turns into window. When I want to avoid this, I usually bind the animation function to the desired context.

I'm not super-familiar with Vue, but try this...

<script>
import * as THREE from 'three'
let boundAnimation = null
export default {
  //...
  methods:
    // ...
    animate() {
      requestAnimationFrame( boundAnimation );
      this.renderer.render( this.scene, this.camera );
    }
  },
  mounted() {
      this.init();
      boundAnimation = this.animate.bind(this);
      boundAnimation();
  }
}
</script>

Inside mounted, the this should represent the current implementation of the exported object. By assigning boundAnimation in this manner, all calls to boundAnmation will use for context the same this as when the function was bound. Using the bound function in requestAnimationFrame ensures that when that function fires, it will still be using the desired this context.

Upvotes: 1

Related Questions