【问题标题】:not able to use three.js无法使用three.js
【发布时间】:2016-09-14 22:18:24
【问题描述】:

我在 codepen 上发现了一个很酷的动画,它采用地图 (img) 并用块重建它。所需的 js 文件是 three.min.jsTweenMax.min.js 我从 codepen 中获取链接并将其粘贴到 <script src=""></script> 的脑海中。在复制每个 css 和 html(不多)之后,three.min.js 出现错误(?)。 我打开谷歌浏览器控制台,看到three.min.js:536 Uncaught TypeError: Cannot read property 'width' of null

这是我所指的 codepen 动画: http://codepen.io/Mamboleoo/pres/JYJPJr

我的代码:

<!DOCTYPE html>
<html>
<head>

    <?php include $_SERVER["DOCUMENT_ROOT"] . "/assets/head.php"; ?>
    <title><?php echo $address; ?> - Credits</title>
</head>
<body>
    <?php include $_SERVER["DOCUMENT_ROOT"] . "/navigationbar.php"; ?>

<script>
    var renderer, scene, camera, ww, wh, particles;

ww = window.innerWidth,
wh = window.innerHeight;

var centerVector = new THREE.Vector3(0, 0, 0);
var previousTime = 0;

var getImageData = function(image) {

    var canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(image, 0, 0);

    return ctx.getImageData(0, 0, image.width, image.height);
}

var drawTheMap = function() {

    var geometry = new THREE.Geometry();
    var material = new THREE.PointsMaterial({
        size: 3,
        color: 0x313742,
        sizeAttenuation: false
    });
    for (var y = 0, y2 = imagedata.height; y < y2; y += 2) {
        for (var x = 0, x2 = imagedata.width; x < x2; x += 2) {
            if (imagedata.data[(x * 4 + y * 4 * imagedata.width) + 3] > 128) {

                var vertex = new THREE.Vector3();
                vertex.x = Math.random() * 1000 - 500;
                vertex.y = Math.random() * 1000 - 500;
                vertex.z = -Math.random() * 500;

                vertex.destination = {
                    x: x - imagedata.width / 2,
                    y: -y + imagedata.height / 2,
                    z: 0
                };

                vertex.speed = Math.random() / 200 + 0.015;

                geometry.vertices.push(vertex);
            }
        }
    }
    particles = new THREE.Points(geometry, material);

    scene.add(particles);

    requestAnimationFrame(render);
};

var init = function() {
    THREE.ImageUtils.crossOrigin = '';
    renderer = new THREE.WebGLRenderer({
        canvas: document.getElementById("map"),
        antialias: true
    });
    renderer.setSize(ww, wh);
    renderer.setClearColor(0x1d1f23);

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(50, ww / wh, 0.1, 10000);
    camera.position.set(-100, 0, 220);
    camera.lookAt(centerVector);
    scene.add(camera);

    texture = THREE.ImageUtils.loadTexture("http://mamboleoo.be/lab/transparentMap.png", undefined, function() {
        imagedata = getImageData(texture.image);
        drawTheMap();
    });
  window.addEventListener('resize', onResize, false);

};
var onResize = function(){
    ww = window.innerWidth;
    wh = window.innerHeight;
    renderer.setSize(ww, wh);
    camera.aspect = ww / wh;
    camera.updateProjectionMatrix();
};

var render = function(a) {

    requestAnimationFrame(render);

    for (var i = 0, j = particles.geometry.vertices.length; i < j; i++) {
        var particle = particles.geometry.vertices[i];
        particle.x += (particle.destination.x - particle.x) * particle.speed;
        particle.y += (particle.destination.y - particle.y) * particle.speed;
        particle.z += (particle.destination.z - particle.z) * particle.speed;
    }

    if(a-previousTime>100){
        var index = Math.floor(Math.random()*particles.geometry.vertices.length);
        var particle1 = particles.geometry.vertices[index];
        var particle2 = particles.geometry.vertices[particles.geometry.vertices.length-index];
        TweenMax.to(particle, Math.random()*2+1,{x:particle2.x, y:particle2.y, ease:Power2.easeInOut});
        TweenMax.to(particle2, Math.random()*2+1,{x:particle1.x, y:particle1.y, ease:Power2.easeInOut});
        previousTime = a;
    }

    particles.geometry.verticesNeedUpdate = true;
    camera.position.x = Math.sin(a / 5000) * 100;
    camera.lookAt(centerVector);

    renderer.render(scene, camera);
};

init();
</script>

<style>
    canvas{width:100%;height:100%;padding:0;margin:0;overflow: hidden;}
</style>


<div class="wrapper">
    <canvas id="map"></canvas>
</div>




<div style="position:relative; clear:both;"></div>
        <!--</body>-->
    <?php include $_SERVER["DOCUMENT_ROOT"] . "/footer.php"; ?>
</body>
</html>

【问题讨论】:

  • 听起来您正在尝试在加载画布元素之前解析(在本例中为 ThreeJS)代码。这是我的一个假设,如果您提供当前代码,它可能是一个更精确和有根据的假设
  • @N.J.Dawson 我现在已经在底部添加了我的代码。 head.php 是我存储脚本的地方,我的大多数 css (&lt;script type="text/javascript" src=""&gt;&lt;/script&gt;) 页脚和导航栏都很基本,只包含 html。
  • 我也在谷歌浏览器THREE.WebGLRenderer 72987654330@的错误上面收到了这个
  • 我没有看到除 THREE.WebGLRenderer 72 以外的任何消息
  • 您是否在其他浏览器中遇到未捕获的错误??

标签: javascript jquery three.js


【解决方案1】:

问题已在 cmets 中解决,但为了不让问题在技术上未得到解答,我将为在搜索问题中发布的错误后偶然发现此页面的任何人解释该过程。

在问题中发布的示例中(使用 PHP 加载 Javascript,但这对于手头的实际问题无关紧要)在 DOM 加载 canvas 之前执行与 ThreeJS 相关的 Javascript元素。显然,ThreeJS 需要 Canvas 元素,因为它将各种侦听器和对象附加到它上面,因此当尝试访问与 canvas 元素相关的成员时,它只会得到 undefined

解决这个问题的方法是加载 ThreeJS 和所有与它相关的代码 DOM 加载了元素之后,有多种方法可以做到这一点(你应该搜索,因为我是恐怕我没有时间解释所有这些),但我会强调一个我认为最简单的。方法是将所有 DOM 特定代码(与 DOM 交互的 Javascript)放在 body 标记的 底部 (不在其下方,inside 在最底层。As Vikas Kapadiya pointed out,如果它在它下面,它将不是有效的 HTML)

下面的 sn-p 显示了 Javascript 是如何相对于 DOM 加载的:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script>
            var p = document.getElementById('example');
            console.log("In head " + p);
        </script>
    </head>
    <body>
        <p id="example">Hello</p>
        <script>
            var p = document.getElementById('example');
            console.log("In body " + p.innerHTML);
        </script>
    </body>
</html>

输出:

In head null
In body Hello

如上所示,head 标签内的代码由于被执行之前,无法访问innerHTML(参考p 标签的文本内容) DOM 已加载。 body 标记底部的代码可以,因为 DOM 已加载,然后浏览器偶然发现了 Javascript。

这里有一些相关链接可能比我有更多的信息:

Where should I put <script> tags in HTML markup?

Where to place JavaScript functions: <head>? <body>? or, after </html>?

【讨论】:

    【解决方案2】:

    只需将 wrapper div 移动到 body 标记之后。然后包括所有 js 。

    这样

    <body>
    <div class="wrapper">
        <canvas id="map"></canvas>
    </div>
    

    【讨论】:

    • @N.J.Dawson 在评论区回答了这个问题。他没有将其发布为答案,所以我不能接受。但答案是将脚本移动到 html 下。
    • 你不应该在
    猜你喜欢
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 2018-08-31
    • 2021-12-18
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    相关资源
    最近更新 更多