【问题标题】:Problems verifying and running javascript (html5 canvas)验证和运行 javascript(html5 画布)的问题
【发布时间】:2024-04-13 17:15:01
【问题描述】:

对于我的一门课程,我需要在 html5 画布中编写一个 3D 应用程序。为此,我选择使用 Three.js。现在,我要做的只是渲染一个简单的平面。我还希望能够通过按住鼠标并拖动来沿 x 轴移动相机。我的代码基于找到的代码 here。它基本上是一架正在旋转的飞机(或者相机正在围绕飞机旋转,不确定是哪个)。我丢弃了动画的所有代码,并添加了 mousedown、mousemove 等事件的代码。当我加载页面时,它可以很好地呈现平面(无生命),但是当我尝试使用鼠标移动它时,它仍然完全没有响应。在我的代码中,您可能已经注意到我更改了一些我可能不应该做的事情(使一些变量成为全局变量并更改了一些函数名称)以使事情正常运行,但结果保持不变。

这是我第一次使用 javascript,我意识到我不能只更改现有代码并期望它能够工作。我查看了 javascript 验证并找到了 JSLint。我下载了notepad++的插件,并试图以这种方式验证我的代码。它不喜欢 html 标签,尤其讨厌我尝试导入的 Three.js 库。当我将它导入为url 时它不会接收它,当我下载它并导入文件时它也不会导入它。当我刚刚将整个库的代码复制到文件中时,它只是给了我很多关于库本身的错误,并且在我的代码开始之前就停止了验证。

总结:我希望在项目本身方面得到一些帮助,但也希望在建立一个愉快的开发环境方面得到帮助(通过不忽略导入的适当验证)。

最后,我的代码:

<!DOCTYPE HTML>
<html>
<head>
<title>Canvas demo</title>
</head> 
<body>
<script type="text/javascript" src="three.js">
</script>
<script type="text/javascript">

var camera;
var scene;
var plane;
var renderer;
var clickX;
var clickY;
var mousedown;

window.onload = function () {
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    //camera
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.y = -450;
    camera.position.z = 400;
    camera.rotation.x = 45;

    //scene
    scene = new THREE.Scene();

    //plane
    plane = new THREE.Mesh(new THREE.PlaneGeometry(300, 300), new THREE.MeshBasicMaterial({color: 0x0000ff}));
    plane.overdraw = true;
    scene.add(plane);   

    rerender(); 
};

window.requestAnimFrame = (function (callback){
        return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function(callback){
            window.setTimeout(callback, 1000 / 60);
        };
})();

function rerender(){
    //render
    renderer.render(scene, camera);

    //request new frame
    requestAnimFrame(function(){
        rerender();
    });
}

$('#canvas').mousedown(function(e){
  clickX = e.pageX - this.offsetLeft;       
  mousedown = true;
});

$('#canvas').mousemove(function(e){
    if(mousedown) {
        var xDiff = e.pageX - this.offsetLeft - clickX;
        camera.position.x = xDiff;      
        rerender();
    }
});

$('#canvas').mouseup(function(e){
  mousedown = false;
});

$('#canvas').mouseleave(function(e){
  mousedown = false;
});

</script>
</body>
</html>

【问题讨论】:

  • 这里没什么大不了的:jsfiddle.net/mplungjan/TVWYn
  • jsFiddle 已修复为同时包含 Three.js 和 jQuery:jsfiddle.net/TVWYn/2 -- 但是,我仍然没有看到任何平面。
  • 我将您放入 html 的 url 更改为库之一(就像我的问题中的那个),它显示的飞机就像在我的浏览器中一样:jsfiddle.net/TVWYn/3

标签: javascript html canvas jslint three.js


【解决方案1】:

您在此处遇到了各种问题,这些问题会阻止您的代码正常运行。我已经完成并修复了它们,您现在可以沿 x 轴移动相机:

http://jsfiddle.net/TVWYn/6/

您的问题是:

  1. 您正在使用 jQuery,但不包括 jQuery 库。美元 符号函数不是 JavaScript 的一部分,它(在这种情况下)是 一个名为 jQuery 的第三方库,可以使用 DOM 更轻松。在不包括 jQuery 库的情况下,您的鼠标处理程序 无法运行。

  2. 即使包含 jQuery,设置功能的顺序 执行不正确。最初你有你的 Three.js 设置 处理,这样它就会在 DOM 初始化后执行。 那挺好的。但是,您试图注册鼠标事件 浏览器获取 JS 后立即处理处理程序。这 不好。您要求 JS 将鼠标事件处理程序附加到当时不存在的 DOM 元素。为了解决这个问题, 您需要确保 DOM 已初始化(例如,在 window.onload 中运行您的设置)并且您的 已插入所需的元素(在这种情况下, #canvas)。或者,将您的事件处理程序直接附加到 DOM 对象(例如renderer.domElement)。

  3. 您在没有设置 id 的情况下引用了 #canvas 画布元素。

关于设置合适的开发环境,我强烈建议您开始使用 Chrome 及其开发者工具(通过 ctrl+shift+j 启动)。

【讨论】:

  • 非常感谢!看起来我现在可以开始工作了 :) 我会将您的答案标记为有用,但我还没有足够的声誉:(
  • 不客气。不用担心投票,我很高兴我们解决了您的问题并且您可以继续开发。使用新语言可能会很棘手,而且 JS 并不是一个容易深入研究的语言。 :)
  • 最新版本是here。它现在同时响应 x 和 y 并记住释放鼠标按钮之前的最后一个鼠标位置(这样平面位置不会在您每次再次单击时重置)。