0

我正在构建不同形状的矩形行。它们都有不同的宽度和高度,但我已经从一个 json 对象(整数)中得到它们。

现在我需要把它们都放在相同的高度上,同时保持比例,然后将它们分批对齐。例如:

var data = [{width:724,height:234},{width:345,height:726},{width:853,height:320}];
var xpos = 0;

for (var i=0, s=data.length; i<s; i+=1) {
    var materialBlack = new THREE.MeshPhongMaterial({
        ambient: 0x1b1b1b,
        color: 0x1b1b1b,
        overdraw: false,
        side: THREE.DoubleSide
    });
    var geometry = new THREE.PlaneGeometry( 1, 1, 1, 1 );
    var object = new THREE.Mesh( geometry, materialBlack );
    var scaleFactor = 300/data[i].height; // 300 units height for all
    var scaledWidth = data[i].width*scaleFactor;
    var scaledHeight = data[i].height*scaleFactor;
    xpos += i==0 ? 0 : scaledWidth;
    object.scale.set( scaledWidth, scaledHeight, 1);
    object.position.set( xpos, 0, 0 );
    scene.add( object );
}

现在的问题是,大多数矩形整齐地彼此相邻,而一些矩形稍微向左或向右偏移。它不仅仅是一个单位,更像是整个矩形的八分之一。

当视觉结果关闭时,记录来自对象的设置值会返回正确的值,并且它们都加起来。

我已经尝试将比例值四舍五入,但这并没有什么不同。它总是发生在相同的对象上。我只是无法在这里识别模式。

这是代码中的一个示例,也许有人可以发现我这边明显的错误行为。我完全不知道这是怎么发生的。

JSFIDDLE

这是一个小提琴。你需要 webgl,我只加载 jsfiddle 标志。但是您会注意到闪烁线条中的重叠。

http://jsfiddle.net/7t2AM/2/

更新

当我将“scaleFactor”更改为始终为 1 并以未缩放的大小对齐矩形时,它们会正确对齐。我已经束手无策了,虽然大多数都正确显示并且只有一些被偏移,但我没有得到。

更新 2

这是代码的更完整副本。在这里,我没有使用 1x1 来进行矩形的初始缩放,而是使用我最终需要的值来创建它。结果还是一样。

$(document).ready( function () {
    Content.loadContent("en",function () {
        doStuff();
    });
});

var Config = {
    lang : "de",
    datahost : "http://localhost:3000/proxy?url=DATA_SOURCE_URL",
    imgproxy : "http://localhost:3000/imgproxy?url="
};

var objects = [];
var data;
var camera;
var scene;
var renderer;

function doStuff() {

    renderer = new THREE.WebGLRenderer({ antialias: true });
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 20000 )

    data = Content.data;

    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.domElement.style.position = 'absolute';
    camera.position.z = -1000;

    controls = new THREE.TrackballControls( camera );
    controls.addEventListener( 'change', render );
    controls.rotateSpeed = 0.5;
    controls.maxDistance = 8000;
    controls.target.set(0,0,-2000);

    var ambientLight = new THREE.AmbientLight(0xeeeeee);
    ambientLight.castShadow = true;
    ambientLight.shadowCameraNear = 200;
    ambientLight.shadowCameraFar = camera.far;
    ambientLight.shadowCameraFov = 50;
    ambientLight.shadowBias = -0.00022;
    ambientLight.shadowDarkness = 0.5;
    ambientLight.shadowMapWidth = 1024;
    ambientLight.shadowMapHeight = 1024;
    scene.add(ambientLight);

    document.getElementById( 'container' ).appendChild( renderer.domElement );

    for ( var i= 0; i<data.length; i++ ) {
        var texture = THREE.ImageUtils.loadTexture(( Config.imgproxy ? Config.imgproxy : "" ) + data[i]["node"]["img"]);
        texture.minFilter = THREE.LinearFilter;
        texture.magFilter = THREE.LinearFilter;

        var material = new THREE.MeshPhongMaterial({
            map: texture,
            overdraw: false,
            side: THREE.FrontSide
        });

        var width = parseInt(data[i]["node"]["img_width"]); // this is coming in as strings... sigh.
        var height = parseInt(data[i]["node"]["img_height"]);
        var scaleFactor = 300 / height;
        var geometry = new THREE.PlaneGeometry( width*scaleFactor, height*scaleFactor, 1, 1 );

        var object = new THREE.Mesh( geometry, material );
        object["nodeObject"] = data[i]["node"];

        scene.add( object );
        objects.push( object );
    }

    var xpos = 0;

    for ( var i = 0, l = objects.length; i < l; i ++ ) {
        var object = objects[i];
        var height = parseInt(objects[i]["nodeObject"]["img_height"]);
        var scaleFactor = 300 / height;
        objects[i].position.set(xpos,0,-4000);
        xpos += (parseInt(objects[i]["nodeObject"]["img_width"])*scaleFactor);
    }

    animate();
}

function animate() {
    requestAnimationFrame( animate );
    controls.update();
    render();
}

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

var Content = {
    data : [],
    loadContent : function (lang,callback) {
        console.log("loading remote data");
        $.ajax(Config.datahost+"/"+lang+"/export/explore", {
            type : "GET",
            dataType : "json",
            success : function (data) {
                if (data["nodes"]) {
                    if (typeof data["nodes"]!=="array") {
                        if (typeof data["nodes"]==="object") {
                            Content.data = new Array();
                            for (var key in data["nodes"]) {
                                Content.data.push(data["nodes"][key]);
                            }
                        } else {
                            console.log("unable to read data. neither array nor object");
                        }
                    } else {
                        Content.data = data["nodes"];
                    }
                };
                if (typeof callback==="function") callback();
            },
            error : function (xhr,stat,err) {
                console.log("error loading data - status: "+stat+" msg: "+err);
            }
        })
    }
};
4

2 回答 2

2
var width = parseInt( objects[ i ][ "nodeObject" ][ "img_width" ] ) * scaleFactor;

objects[ i ].position.set( xpos + ( width / 2 ), 0, 0 );

xpos += width;

http://jsfiddle.net/7t2AM/4/

另外,今后,请尽量提出对他人有帮助的问题。

于 2013-09-19T15:05:31.257 回答
1

我认为问题在于大小PlaneGeometry为 2,而您期望它为 1。

试试这个:

var geometry = new THREE.PlaneGeometry( 0.5, 0.5, 1, 1 );

此外,您可以只创建一个几何体和材料,并在每个网格中重复使用它们。

于 2013-09-19T04:23:45.930 回答