【问题标题】:three.js OrbitControls conflicting with HTML5 Canvas?three.js OrbitControls 与 HTML5 Canvas 冲突?
【发布时间】:2015-11-16 01:32:38
【问题描述】:

我有一个 HTML5 画布(在本例中使用 Fabric.js)和一个 three.js 对象。当使用 OrbitControls 旋转我的 3D 图像时,会出现两个奇怪的行为。

1) 下拉字段和动态滑块不下拉或不滑动

2) 当我在页面上有另一个画布并在该画布上移动图像时,three.js 画布中的 3D 图像与图像的移动同步移动。如果我移动 3D 图像,画布中的图像不会同步移动/不受影响

如果我在“Box Controller - Collada Files”控制器中注释掉/或删除我的旋转控件,下拉菜单会起作用,并且正如预期的那样,画布中的图像和渲染的 3D 图像之间没有“链接移动”由three.js(很可能是因为移除了旋转控件)。

如何获得此信息,以使 OrbitControls 不会停止下拉菜单和其他项目以使图像的移动与 3D 对象同步/取消同步?

这是我的示例 HTML:

<!DOCTYPE html>
<html lang="en" data-ng-app="appControllersBox">
<head>
<title>three.js webgl - loaders - collada loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

<!-- Core files (jQuery, Angular, etc.) -->
<script src="js/scripts/jquery-2.1.4.min.js"></script>
<!-- Switch to AngularUI if appropriate -->
<script src="js/scripts/bootstrap.min.js"></script>
<script src="js/scripts/angular.min.js"></script>

<!-- Three.js: http://threejs.org/ -->
<script src="js/scripts/three.min.js"></script>
<script src="js/scripts/ColladaLoader.js"></script>
<script src="js/scripts/OrbitControls.js"></script>

<!-- Fabric.js: http://fabricjs.com/ -->
<script src="js/scripts/fabric.min.js"></script>

<!-- Color Picker JS: https://github.com/buberdds/angular-bootstrap-colorpicker -->
<script src="js/scripts/bootstrap-colorpicker-module.min.js"></script>

<!-- Angular App Specific Files -->
<script src="js/controllers/controllers2.js"></script>

<!-- CSS Files -->
<link href="css/bootstrap.min.css" rel="stylesheet" />
<link href="css/colorpicker.min.css" rel="stylesheet" />
</head>

<body>
<div data-ng-controller="canvasCtrl">
    <div class="row">
        <div class="col-md-6">
            <p>
                <label>Select list</label>
                <select id="myList">
                    <option value="1">one</option>
                    <option value="2">two</option>
                    <option value="3">three</option>
                    <option value="4">four</option>
                </select>

            </p>
            <p>
                <input type="file" id="imageLoader" name="imageLoader" />
                <button id="textCreate" class="primaryButton" data-ng-click="textMe()">
                    Create Text
                </button>
            </p>
        </div>
    </div>
    <div class="col-md-6">
        <canvas id="c" style="border:5px solid" height="1023px" width="772px"></canvas>
    </div>
</div>
<div class="col-md-12" data-ng-controller="3dboxCtrl">
    <div id="webGL-container">
    </div>
</div>
</body>
</html>

这是我的 JS/Controllers2.js 文件(注意有两个 Angular 控制器):

    'use strict';

var appControllersBox = angular.module('appControllersBox', ['colorpicker.module']);

// Box Controller - Canvas
appControllersBox.controller('canvasCtrl', ['$scope', '$timeout', function ($scope, $timeout) {

    // Canvas
    var canvas = new fabric.Canvas('c');

    // Add Text
    $scope.textMe = function () {
        var text = new fabric.IText('hello world', { left: 100, top: 100 });
        canvas.add(text);
    }

    // Load Image
    var imageLoader = document.getElementById('imageLoader');
    imageLoader.addEventListener('change', handleImage, false);
    var ctx = canvas.getContext('2d');


    function handleImage(e) {
        var reader = new FileReader();
        reader.onload = function (event) {
            var imgAdd = new Image();
            imgAdd.onload = function () {
                var img = new fabric.Image(imgAdd);
                canvas.add(img);
            }
            imgAdd.src = event.target.result;
        }
        reader.readAsDataURL(e.target.files[0]);
    }
}]);


// Box Controller - Collada File
appControllersBox.controller('3dboxCtrl', ['$scope', '$timeout', function ($scope, $timeout) {

    // 3D Object
    var scene;
    var camera;
    var renderer;
    var box;
    var controls;

    // instantiate a loader
    var loader = new THREE.ColladaLoader();
    loader.options.convertUpAxis = true;
    loader.load('models/box.dae', function (collada) {

        box = collada.scene;

        box.traverse(function (child) {

            if (child instanceof THREE.SkinnedMesh) {

                var animation = new THREE.Animation(child, child.geometry.animation);
                animation.play();

            }
        });

        box.scale.x = box.scale.y = box.scale.z = .2;
        box.updateMatrix();

        init();
        animate();
    });


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

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

        // Load the box file
        scene.add(box);

        // Lighting
        var light = new THREE.AmbientLight();
        scene.add(light);

        // Camera
        camera.position.x = 40;
        camera.position.y = 40;
        camera.position.z = 40;

        camera.lookAt(scene.position);

        // Rotation Controls
        controls = new THREE.OrbitControls(camera);

        controls.rotateSpeed = 5.0;
        controls.zoomSpeed = 5;

        controls.noZoom = false;
        controls.noPan = false;

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

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

}]);

【问题讨论】:

  • 试试controls = new THREE.OrbitControls( camera, renderer.domElement );
  • 做到了!我需要定位 dom 元素是有道理的

标签: javascript canvas three.js


【解决方案1】:

如果您使用OrbitControlsTrackballControls 并且控件会干扰其他HTML 元素,则需要将domElement 参数添加到控件构造函数中:

controls = new THREE.OrbitControls( camera, renderer.domElement );

三个.js .r71

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-27
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多