未捕获的TypeError:无法读取未定义的属性'render'

时间:2016-01-26 12:29:23

标签: javascript jquery web-audio

每次尝试在animate()函数中渲染场景时,都会弹出我的错误。我不确定我做错了什么,并且对three.js不熟悉。

$(function() {
  // var audioContext = new window.AudioContext();

  var ctx = new AudioContext();
  var audio = document.getElementById('TestAud');
  var audioSrc = ctx.createMediaElementSource(audio);
  var analyser = ctx.createAnalyser();

  audioSrc.connect(analyser);
  audioSrc.connect(ctx.destination);
  var frequencyData = new Uint8Array(analyser.frequencyBinCount);
  var scene, camera, renderer;
  var cube, cubeGeometry, cubeMaterial;
  var sphere, sphereGeo, SphereMaterial;

  function init() {
    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    var renderer = new THREE.WebGLRenderer();

    renderer.setClearColor(0x000000);
    renderer.setSize(window.innerWidth, window.innerHeight);

    // var axis = new THREE.AxisHelper(10);
    // scene.add(axis);

    var cubeGeometry = new THREE.BoxGeometry(10, 6, 8);
    var cubeMaterial = new THREE.MeshBasicMaterial({
      color: 0x00FFFF,
      wireframe: true
    });
    var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

    var SphereGeo = new THREE.SphereGeometry(5, 8, frequencyData);
    var SphereMaterial = new THREE.MeshBasicMaterial({
      color: 0x00FFFF,
      wireframe: true
    });
    var sphere = new THREE.Mesh(SphereGeo, SphereMaterial);

    cube.position.x = 0;
    cube.position.y = 0;
    cube.position.z = 0;
    cube.name = frequencyData.length;

    sphere.position.x = 0;
    sphere.position.x = 0;
    sphere.position.z = 3;

    sphere.name = frequencyData.width;

    scene.add(cube);
    scene.add(sphere);

    camera.position.x = 40;
    camera.position.y = 40;
    camera.position.z = 40;
    camera.lookAt(scene.position);
    // renderer.render(scene, camera);

    $("#webGL-container").append(renderer.domElement);
  }

  function render() {
    analyser.getByteFrequencyData(frequencyData);
    // camera.updateProjectionMatrix();
  }

  function animate() {
    render();
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
  }

  $(window).resize(function(){
    SCREEN_WIDTH = window.innerWidth;
    SCREEN_HEIGHT = window.innerHeight;

    camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
    camera.updateProjectionMatrix();

    renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
  });

  init();
  animate();
  audio.play();
});
`

我似乎收到了这个错误,

  

未捕获的TypeError:无法读取未定义的属性'render'

除非我将代码放在init()函数中。

3 个答案:

答案 0 :(得分:0)

渲染器在init函数中定义,因此您无法在其他函数中使用它。 因此渲染器未定义,并且udefined没有渲染属性。

不要在init函数中声明渲染器,只需使用它。

function init(){
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    renderer = new THREE.WebGLRenderer();
    //...

答案 1 :(得分:0)

您可以在init函数中创建渲染器:

var renderer = new THREE.WebGLRenderer();

使渲染器成为init函数的本地,并在init函数完成后立即丢弃。

稍后,animate函数会尝试使用 undefined 渲染器:

renderer.render(scene, camera);

这就是异常发生的地方。

您应该以这种方式初始化渲染器:

renderer = new THREE.WebGLRenderer();

请注意已删除的var关键字。

相机和场景变量的相同问题(也许还有一些变量)。您可以使用" global"来解决问题。 renderer变量(您在init函数范围之外声明的变量)。请看固定代码。请注意, {init}函数中的var关键字已从渲染器初始化中删除 - 对于相机和场景也是如此。

$(function() {

//  var audioContext = new window.AudioContext();

  var ctx = new AudioContext();
  var audio = document.getElementById('TestAud');
  var audioSrc = ctx.createMediaElementSource(audio);
  var analyser = ctx.createAnalyser();

  audioSrc.connect(analyser);
  audioSrc.connect(ctx.destination);
   var frequencyData = new Uint8Array(analyser.frequencyBinCount);
   var scene, camera, renderer;
   var cube, cubeGeometry, cubeMaterial;
   var sphere, sphereGeo, SphereMaterial;


  function init(){
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  renderer = new THREE.WebGLRenderer();

  renderer.setClearColor(0x000000);
  renderer.setSize(window.innerWidth, window.innerHeight);

//  var axis = new THREE.AxisHelper(10);
  //scene.add(axis);

  var cubeGeometry = new THREE.BoxGeometry(10, 6, 8);
  var cubeMaterial = new THREE.MeshBasicMaterial({
    color: 0x00FFFF,
    wireframe: true
  });
  var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

  var SphereGeo = new THREE.SphereGeometry(5, 8, frequencyData);
  var SphereMaterial = new THREE.MeshBasicMaterial({
    color: 0x00FFFF,
    wireframe: true
  });
  var sphere = new THREE.Mesh(SphereGeo, SphereMaterial);

  cube.position.x = 0;
  cube.position.y = 0;
  cube.position.z = 0;
  cube.name = frequencyData.length;

  sphere.position.x = 0;
  sphere.position.x = 0;
  sphere.position.z = 3;


  sphere.name = frequencyData.width;

  scene.add(cube);
  scene.add(sphere);

  camera.position.x = 40;
  camera.position.y = 40;
  camera.position.z = 40;
  camera.lookAt(scene.position);
//  renderer.render(scene, camera);

    $("#webGL-container").append(renderer.domElement);
//
}

function render(){
  analyser.getByteFrequencyData(frequencyData);
//    camera.updateProjectionMatrix();
}

  function animate(){
    render();
    requestAnimationFrame(animate);
    renderer.render(scene, camera);

  }


  $(window).resize(function(){


      SCREEN_WIDTH = window.innerWidth;
      SCREEN_HEIGHT = window.innerHeight;

      camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
      camera.updateProjectionMatrix();

      renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );



  });

init();
animate();
audio.play();


});

答案 2 :(得分:-1)

正如其他答案所说,您无权访问renderer功能范围之外的init()变量。因此,您的renderer函数中未定义animate(),导致您收到错误。

声明变量超出init()范围,以允许您的其他函数访问它。 (您也应该使用scenecamera变量执行此操作。)

// Declare the necessary variables outside of the scope of init()
var scene, camera, renderer;    

function init(){
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  renderer = new THREE.WebGLRenderer();
  ...
}

// animate() can now see the renderer var, since it's within the scope
function animate() {
  render();
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}