如何将THREE.js脚本封装到类中?

时间:2015-03-31 20:48:32

标签: javascript three.js

我有一个相当复杂的Three.JS脚本,它显示了一个人体3d体,您可以在其中选择片段。

var container;
var camera;
var scene;
var renderer;
var mouse;
var raycaster;
var controls;
var hemiLight;

function init(containerID) {
    // Will setup all needed variables
    container = document.getElementById(containerID);
    camera = new THREE.PerspectiveCamera(1, window.innerWidth / window.innerHeight, 1, 2000);
    camera.position.z = 400;

    // Scene
    scene = new THREE.Scene();
    hemiLight = new THREE.HemisphereLight(0xCC9966, 0xCC9966, 1);
    hemiLight.position.set(0, 500, 0);
    scene.add(hemiLight);

    // Camera behaviour
    controls = new THREE.TrackballControls(camera);
    controls.rotateSpeed = 5.0;
    controls.zoomSpeed = 5;
    controls.panSpeed = 2;
    controls.noZoom = false;
    controls.noPan = false;
    controls.staticMoving = true;
    controls.dynamicDampingFactor = 0.3;
    controls.enabled = false;

    // Model
    var onProgress = function ( xhr ) {
        // Only necessary if the obj-file-size is very large
    };
    var onError = function ( xhr ) {
        // Something went wrong during loading obj-file
        console.log("Error, please report to the devs");
    };

    THREE.Loader.Handlers.add(/\.dds$/i, new THREE.DDSLoader());
    var loader = new THREE.OBJMTLLoader();

    // Load the 3D Files
    loader.load( 'objects/head.obj', 'images/head.mtl', function ( object ) {
        prepareObj( object, "head" );
    }, onProgress, onError );
    loader.load( 'objects/torso.obj', 'images/torso.mtl', function ( object ) {
        prepareObj( object, "torso" );
    }, onProgress, onError );
    loader.load( 'objects/arm_left.obj', 'images/arm_left.mtl', function ( object ) {
        prepareObj( object, "arm_left" );
    }, onProgress, onError );
    loader.load( 'objects/arm_right.obj', 'images/arm_right.mtl', function ( object ) {
        prepareObj( object, "arm_right" );
    }, onProgress, onError );
    loader.load( 'objects/leg_right.obj', 'images/leg_right.mtl', function ( object ) {
        prepareObj( object, "leg_right" );
    }, onProgress, onError );
    loader.load( 'objects/leg_left.obj', 'images/leg_left.mtl', function ( object ) {
        prepareObj( object, "leg_left" );
    }, onProgress, onError );

    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(500, 500);
    renderer.setClearColor(0xffffff, 1);
    container.appendChild(renderer.domElement);

    document.addEventListener("mouseover", function(e) {
        checkBodyActive(e);
    }, false);
    document.addEventListener("click", onClick, false);
    window.addEventListener("resize", onWindowResize, false);

    raycaster = new THREE.Raycaster();
    mouse = new THREE.Vector2();

    camera.aspect = 1;
    camera.updateProjectionMatrix();
    renderer.render(scene, camera);
    animate();
}

function checkBodyActive(event) {
    // Checks, if the current body is active
    if(document.elementFromPoint(event.clientX, event.clientY) == renderer.domElement) {
        animate();
        controls.enabled = true;
    }
    else {
        controls.enabled = false;
    }
}

function changeTexture(part) {
    // Will change the texture of the selected body part
    scene.children[part].traverse( function ( child ) {
        if (child instanceof THREE.Mesh) {
            // Texture must be changed
            if(scene.children[part].children[0].children[0].material.map.sourceFile=="images/texture2.jpg") {
                // Texture2 is already equipped, unequip it
                child.material.map = THREE.ImageUtils.loadTexture("images/texture.jpg");
            } else {
                // Equip texture2
                child.material.map = THREE.ImageUtils.loadTexture("images/texture2.jpg");
            }
            child.material.needsUpdate = true;
        }
    });
}

function onWindowResize() {
    // This function will make sure that all proportions are correct after resizing the window
    camera.aspect = 1;
    camera.updateProjectionMatrix();
}

function onClick(event) {
    // Mouse-Click-Event, used to check if intersects where hit
    //event.preventDefault();
    mouse.x = (getOffset(event).x / renderer.domElement.width) * 2 - 1;
    mouse.y = - (getOffset(event).y / renderer.domElement.height) * 2 + 1;

    // Create intersect raycasting
    raycaster.setFromCamera(mouse, camera);
    var intersects = raycaster.intersectObjects(scene.children, true);
    if(intersects.length) {
        var name = intersects[0].object.parent.parent.name;
        for(var j = 0; j < scene.children.length; j++ ) {
            if(scene.children[j].name == name) {
                // Found same model as the intersects, change texture
                changeTexture(j);
            }
        }
    }
}

function getOffset(event) {
    // Calcs layerX / layerY for the clicked element
    var el = event.target,
        x = 0,
        y = 0;

    while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
        x += el.offsetLeft - el.scrollLeft;
        y += el.offsetTop - el.scrollTop;
        el = el.offsetParent;
    }

    x = event.clientX - x;
    y = event.clientY - y;

    return { x: x, y: y };
}

function prepareObj(object, name){
    // General configuration of the .obj files while loading
    object.position.y = -3;
    object.traverse(function(child) {
        if(child instanceof THREE.Mesh) {
            child.material.map = THREE.ImageUtils.loadTexture("images/texture.jpg");
            child.material.needsUpdate = true;
        }
    });
    object.name = name;
    scene.add(object);
}

function animate() {
    // On every frame we need to calculate the new camera position
    // and have it look exactly at the center of our scene.
    requestAnimationFrame(animate);
    controls.update();
    camera.lookAt(scene.position);
    renderer.render(scene, camera);
}

目前有一种情况,我每页需要2或3个这样的机构。这当前是不可能的,因为如果调用init(“myID”);和init(“myID2”);它会覆盖上面的变量。

所以我的问题是:如何将其重写为一个类?如果以真实类的形式出现这种情况,那么应该没有名称冲突正确吗?我尝试在任何地方添加this.variable并更改结构但总是出错。有没有什么好方法可以将它重写成一个类?谢谢!

0 个答案:

没有答案