最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Three.js move as group - Stack Overflow

programmeradmin0浏览0评论

It seems like this should be easy, but I have spent nearly a week on this trying every possible bination of how to drag multiple items as a group in Three.js. It started out simple, I used this example / to get the ball working. I thought I could just add some TextGeometry, which of course had some major API changes in the last couple releases rendering most examples obsolete.

After finally getting it to work as a single line, I wanted to add in wordwrap and move it as a group, but I can't seem to do so.

Here you can see it working just fine with the ball, but you can't drag the text /

By swapping around three lines of code (location line 93-99), I can get it to where you can drag the individual lines around, which you can see here: /

function addText(text, fontSize, boundingWidth) {
    var wrapArray;
    wrapArray = text.wordwrap(10,2);
    var loader = new THREE.FontLoader();
    loader.load( '.js-74/examples/fonts/helvetiker_bold.typeface.js',
    function ( font ) {
    group = new THREE.Group();
    group.name = "infoTag";
      for (var i = 0; i < wrapArray.length; i++) {
        var objectID=i;
        var line = wrapArray[objectID];
        var textGeo = new THREE.TextGeometry( line, {font: font,size: fontSize,height: 10,curveSegments: 12,bevelThickness: 0.02,bevelSize: 0.05,bevelEnabled: true});
          textGeoputeBoundingBox();
          var centerOffset = -0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
          var textMaterial = new THREE.MeshPhongMaterial( { color: 0xff0000, specular: 0xffffff } );
          var mesh = new THREE.Mesh( textGeo, textMaterial );
          mesh.position.x = centerOffset +200;
          mesh.position.y = i*fontSize*-1+11;
          mesh.position.z = 280;
          mesh.castShadow = true;
          mesh.receiveShadow = true;
          mesh.geometry.center();
          mesh.lookAt(camera.position);
          mesh.name = i;
          group.add( mesh ); //this should work - ment out and swap for other two lines to see 
          scene.add(mesh); // this should work- ment out and swap for other two lines to see 

        //objects.push(mesh);//works on individual lines if you unment this 
        //scene.add(mesh); //works on individual lines if you unment this
      }
    objects.push( group ); // this should work- ment out and swap for other two lines to see 

    });

}

That "should" be working according to everything I had researched over the last week. I had one moment where it was "working" but because of the size of the group object, the pivot points were wrong, the setLength function didn't work, and it flipped the object away from the camera. All in all it was a mess.

I did try using 2d objects such as canvases and sprites, but for reasons detailed here Three.js TextGeometry Wordwrap - drag as group couldn't get it working.

Please, someone help me!

It seems like this should be easy, but I have spent nearly a week on this trying every possible bination of how to drag multiple items as a group in Three.js. It started out simple, I used this example https://jsfiddle/mz7Lv9dt/1/ to get the ball working. I thought I could just add some TextGeometry, which of course had some major API changes in the last couple releases rendering most examples obsolete.

After finally getting it to work as a single line, I wanted to add in wordwrap and move it as a group, but I can't seem to do so.

Here you can see it working just fine with the ball, but you can't drag the text https://jsfiddle/ajhalls/h05v48wd/

By swapping around three lines of code (location line 93-99), I can get it to where you can drag the individual lines around, which you can see here: https://jsfiddle/ajhalls/t0e2se3x/

function addText(text, fontSize, boundingWidth) {
    var wrapArray;
    wrapArray = text.wordwrap(10,2);
    var loader = new THREE.FontLoader();
    loader.load( 'https://cdn.coursesaver./three.js-74/examples/fonts/helvetiker_bold.typeface.js',
    function ( font ) {
    group = new THREE.Group();
    group.name = "infoTag";
      for (var i = 0; i < wrapArray.length; i++) {
        var objectID=i;
        var line = wrapArray[objectID];
        var textGeo = new THREE.TextGeometry( line, {font: font,size: fontSize,height: 10,curveSegments: 12,bevelThickness: 0.02,bevelSize: 0.05,bevelEnabled: true});
          textGeo.puteBoundingBox();
          var centerOffset = -0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
          var textMaterial = new THREE.MeshPhongMaterial( { color: 0xff0000, specular: 0xffffff } );
          var mesh = new THREE.Mesh( textGeo, textMaterial );
          mesh.position.x = centerOffset +200;
          mesh.position.y = i*fontSize*-1+11;
          mesh.position.z = 280;
          mesh.castShadow = true;
          mesh.receiveShadow = true;
          mesh.geometry.center();
          mesh.lookAt(camera.position);
          mesh.name = i;
          group.add( mesh ); //this should work - ment out and swap for other two lines to see 
          scene.add(mesh); // this should work- ment out and swap for other two lines to see 

        //objects.push(mesh);//works on individual lines if you unment this 
        //scene.add(mesh); //works on individual lines if you unment this
      }
    objects.push( group ); // this should work- ment out and swap for other two lines to see 

    });

}

That "should" be working according to everything I had researched over the last week. I had one moment where it was "working" but because of the size of the group object, the pivot points were wrong, the setLength function didn't work, and it flipped the object away from the camera. All in all it was a mess.

I did try using 2d objects such as canvases and sprites, but for reasons detailed here Three.js TextGeometry Wordwrap - drag as group couldn't get it working.

Please, someone help me!

Share Improve this question edited May 23, 2017 at 12:31 CommunityBot 11 silver badge asked Mar 30, 2016 at 15:27 AlanAlan 2,0962 gold badges23 silver badges48 bronze badges 2
  • Hello, I think that if you use an object for join all meshes could works, create a transparent cube or you could use your sphere as main object, add all items into main objects using '.add', all objects move following at parent because they have relative position, in resume you only must move a main object – Juan Caicedo Commented Mar 30, 2016 at 16:19
  • I dont understand the question.. you want to be able to drag the whole text around? all three lines at once? Because that seems to be working for me in the second example you linked (the one where you say that you only can drag the ball) – micnil Commented Mar 30, 2016 at 23:42
Add a ment  | 

1 Answer 1

Reset to default 4

The issue ended up being with the group. Previously I was creating it, adding objects to it with a position.z which increased the size of the box around the group, then after doing that I moved the box to in front of the camera and did a group.lookAt which meant that when I was dragging it everything including pivot point and looking at it from the back was wrong. The right way was to create the group, position it, face the camera, then add the text.

function addText(text, fontSize, wrapWidth, tagColor, positionX, positionY, positionZ) {
    var wrapArray;
    wrapArray = text.wordwrap(wrapWidth,2);
    var loader = new THREE.FontLoader();
    loader.load( '/js/fonts/helvetiker_bold.typeface.js', function ( font ) {
    group = new THREE.Group();
    group.position.x=positionX;
    group.position.y=positionY;
    group.position.z=positionZ;
    group.lookAt(camera.position);
    group.tourType = "infoTag";
    group.name = "infoTag-" + objects.length;
    group.dataID=objects.length;
    group.textData=text;
        for (var i = 0; i < wrapArray.length; i++) {
            var objectID=i;
            var line = wrapArray[objectID];
            var textGeo = new THREE.TextGeometry( line, {
                    font: font,
                    size: fontSize,
                    height: 1,
                    curveSegments: 12,
                    bevelThickness: 0.02,
                    bevelSize: 0.05,
                    bevelEnabled: true
                });

                textGeo.puteBoundingBox();
                var centerOffset = -0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
                var textMaterial = new THREE.MeshPhongMaterial( { color: tagColor, specular: 0xffffff } );

                var mesh = new THREE.Mesh( textGeo, textMaterial );
                mesh.dataID=objects.length;

                mesh.position.x = 0;
                mesh.position.y = (i*mesh.geometry.boundingBox.max.y*-1)*1.15;
                mesh.position.z = 0;
                mesh.castShadow = true;
                mesh.receiveShadow = true;
                mesh.geometry.center();
                //mesh.lookAt(camera.position);
                mesh.name = "infoTag-mesh-" + objects.length;
                group.add( mesh );
        }
    scene.add(group);
    objects.push( group );
    });
}

Of course there were some changes to be made in the mouse events to take into account that you want to move the parent of the object, which looks something like this:

function onDocumentMouseDown(event) {
  event.preventDefault();
  raycaster.setFromCamera(mouse, camera);
  var intersects = raycaster.intersectObjects(objects, true);
  if (intersects.length > 0) {
        if (intersects[0].object.parent.tourType == 'infoTag') {
            var manipulatingInfoTag = true;

            SELECTED = intersects[0].object.parent;
        }else{
            SELECTED = intersects[0].object;
        }
    var intersects = raycaster.intersectObject(plane);
    if (intersects.length > 0) {
      offset.copy(intersects[0].point).sub(plane.position);
    }
    container.style.cursor = 'move';
  }


  isUserInteracting = true;
  onPointerDownPointerX = event.clientX; onPointerDownPointerY = event.clientY; onPointerDownLon = lon; onPointerDownLat = lat;
}
发布评论

评论列表(0)

  1. 暂无评论