So, im working on displaying multiple videos in a 3D website.
I´ve copy the code from the three.js example :
https://threejs.org/examples/?q=video#webgl_materials_video
I´ve replicated 3 times :
///////////
// VIDEO 1 //
///////////
// create the video element
//document.getElementById("render").innerHTML+= "<video ></video>";
video1 = document.createElement("video");
video1.setAttribute("muted", "muted");
// video.id = 'video';
// video.type = ' video/ogg; codecs="theora, vorbis" ';
video1.src = "videos/selva.mp4";
video1.load(); // must call after setting/changing source
//video.play();
var videoImage = document.createElement("canvas");;
videoImage.width = 1920;
videoImage.height = 1080;
videoImageContext1 = videoImage.getContext( '2d' );
// background color if no video present
videoImageContext1.fillStyle = '#000000';
videoImageContext1.fillRect( 0, 0, videoImage.width, videoImage.height );
videoTexture1 = new THREE.Texture( videoImage );
videoTexture1.minFilter = THREE.LinearFilter;
videoTexture1.magFilter = THREE.LinearFilter;
var movieMaterial = new THREE.MeshBasicMaterial( { map: videoTexture1, overdraw: true, side:THREE.DoubleSide } );
var movieGeometry = new THREE.PlaneGeometry( 20, 10, 0, 0 );
var movieScreen = new THREE.Mesh( movieGeometry, movieMaterial );
movieScreen.position.set(cube.position.x+1,cube.position.y,cube.position.z);
movieScreen.rotation.y = 11;
///////////
// VIDEO 2//
///////////
// create the video element
video2 = document.createElement("video");
video2.setAttribute("muted", "muted");
// video.id = 'video';
// video.type = ' video/ogg; codecs="theora, vorbis" ';
video2.src = "videos/sintel.ogv";
video2.load(); // must call after setting/changing source
//video.play();
var videoImage2 = document.createElement("canvas");
videoImage2.width = 480;
videoImage2.height = 204;
videoImageContext2 = videoImage2.getContext( '2d' );
// background color if no video present
videoImageContext2.fillStyle = '#000000';
videoImageContext2.fillRect( 0, 0, videoImage2.width, videoImage2.height );
videoTexture2 = new THREE.Texture( videoImage2 );
videoTexture2.minFilter = THREE.LinearFilter;
videoTexture2.magFilter = THREE.LinearFilter;
var movieMaterial2 = new THREE.MeshBasicMaterial( { map: videoTexture2, overdraw: true, side:THREE.DoubleSide } );
var movieGeometry2 = new THREE.PlaneGeometry( 20, 10, 0, 0 );
var movieScreen2 = new THREE.Mesh( movieGeometry2, movieMaterial2 );
movieScreen2.position.set(cube2.position.x-1,cube2.position.y,cube2.position.z);
movieScreen2.rotation.y = 11;
///////////
// VIDEO 3//
///////////
// create the video element
video3 = document.createElement("video");
video3.setAttribute("muted", "muted");
// video.id = 'video';
// video.type = ' video/ogg; codecs="theora, vorbis" ';
video3.src = "videos/bird.mp4";
video3.load(); // must call after setting/changing source
//video.play();
var videoImage3 = document.createElement("canvas");;
videoImage3.width = 1280;
videoImage3.height = 720;
videoImageContext3 = videoImage3.getContext( '2d' );
// background color if no video present
videoImageContext3.fillStyle = '#000000';
videoImageContext3.fillRect( 0, 0, videoImage3.width, videoImage3.height );
videoTexture3 = new THREE.Texture( videoImage3 );
videoTexture3.minFilter = THREE.LinearFilter;
videoTexture3.magFilter = THREE.LinearFilter;
var movieMaterial3 = new THREE.MeshBasicMaterial( { map: videoTexture3, overdraw: true, side:THREE.DoubleSide } );
var movieGeometry3 = new THREE.PlaneGeometry( 20, 10, 0, 0 );
var movieScreen3 = new THREE.Mesh( movieGeometry3, movieMaterial3 );
movieScreen3.position.set(cube3.position.x,cube3.position.y,cube3.position.z+1);
//movieScreen3.rotation.y = 11;
scene.add(movieScreen);
scene.add(movieScreen2);
scene.add(movieScreen3);
The same happens with variables :
var video1, videoImageContext1, videoTexture1;
var video2, videoImageContext2, videoTexture2;
var video3, videoImageContext3, videoTexture3;
var videorayscasting1 = false;
var videorayscasting2 = false;
var videorayscasting3 = false;
var videoplaying1 = false;
var videoplaying2 = false;
var videoplaying3 = false;
and with with the update :
if ( video1.readyState === video1.HAVE_ENOUGH_DATA ) {
videoImageContext1.drawImage( video1, 0, 0 );
if ( videoTexture1 ) videoTexture1.needsUpdate = true;
}
if ( video2.readyState === video2.HAVE_ENOUGH_DATA ) {
videoImageContext2.drawImage( video2, 0, 0 );
if ( videoTexture2 ) videoTexture2.needsUpdate = true;
}
if ( video3.readyState === video3.HAVE_ENOUGH_DATA ) {
videoImageContext3.drawImage( video3, 0, 0 );
if ( videoTexture3 ) videoTexture3.needsUpdate = true;
}
This is working correctly, but as you can see, is a lot of code repeated it self 3 times. So I want to make a “class” to make this code reusable(I don´t know if in javascript is the same terminology , im thinking in the terms of c++ and other more tradional OOP languages). Where I can just make an object.
So i´ve made another file for working with “video player class” :
JPvideoplayer = function (_position,_src) {
var position;
var video, videoImageContext, videoTexture;
var videorayscasting;
var videoplaying;
var lala = false;
var scope = this;
/*this.setup = function(){
console.log("ARRANCA VIDEOPLAYER VERGA");
}*/
function start(){
var textureLoader = new THREE.TextureLoader();
var crateTexture = new textureLoader.load("texturas/tele.png");
var geometry = new THREE.BoxGeometry( 21, 11, 0 );
var material = new THREE.MeshPhongMaterial( {color: 0xffffff, map:crateTexture} );
var cube = new THREE.Mesh( geometry, material );
cube.name = "Pantalla_test";
cube.position.x = _position.x;
cube.position.y = _position.y;
cube.position.z = _position.z;
cube.rotation.y = 11;
scene.add( cube );
///////////
// VIDEO 1 //
///////////
// create the video element
//document.getElementById("render").innerHTML+= "<video ></video>";
$("#render").append("<video id='lala'></video>");
video = document.getElementById("lala");
video.setAttribute("muted", "muted");
// video.id = 'video';
// video.type = ' video/ogg; codecs="theora, vorbis" ';
video.src = "videos/sintel.ogv";
video.load(); // must call after setting/changing source
//video.play();
var videoImage = document.createElement("canvas");;
videoImage.width = 1920;
videoImage.height = 1080;
videoImageContext = videoImage.getContext( '2d' );
// background color if no video present
videoImageContext.fillStyle = '#000000';
videoImageContext.fillRect( 0, 0, videoImage.width, videoImage.height );
videoTexture = new THREE.Texture( videoImage );
videoTexture.minFilter = THREE.LinearFilter;
videoTexture.magFilter = THREE.LinearFilter;
var movieMaterial = new THREE.MeshBasicMaterial( { map: videoTexture1, overdraw: true, side:THREE.DoubleSide } );
var movieGeometry = new THREE.PlaneGeometry( 20, 10, 0, 0 );
var movieScreen = new THREE.Mesh( movieGeometry, movieMaterial );
movieScreen.position.set(cube.position.x+1,cube.position.y,cube.position.z);
movieScreen.rotation.y = 11;
scene.add(movieScreen);
//console.log("BRUM BRUM BRUM");
}
start();
this.display = function (){
}
this.updateVideo = function(){
if ( video.readyState === video.HAVE_ENOUGH_DATA ) {
videoImageContext.drawImage( video, 0, 0 );
if ( videoTexture ) videoTexture.needsUpdate = true;
}
/*if(lala){
console.log("LALALA");
}*/
}
//setup();
};
So i call the constructor in a init function where i pass only position and src of video. :
jp_video1 = new JPvideoplayer(new THREE.Vector3( 0, camposy, 0 ),"videos/selva.mp4");
So the cube with the texture to simulate the TV appears and everything works , except for the object video inside my class. When ever i´ve tryed to call a function for playing the video :
if(jp_video1.videorayscasting){
if(jp_video1.videoplaying){
jp_video1.video.pause();
}else{
jp_video1.video.play();
}
jp_video1.videoplaying = !jp_video1.videoplaying;
}
I get this error :
render.js:390 Uncaught TypeError: Cannot read property ‘play’ of undefined
at HTMLDocument.mousePressed (render.js:390)
It seems like i can´t access the variable "video " inside my JPvideoplayer class. I don´t see what im doing wrong, everything else aside the video variable appears when i call the object. And im initiating the video the same way as if it was not inside a “class”.
What im I doing wrong or im not seeing?