Search code examples
textrotationaframe

AFRAME text-geometry component rotation from center?


Is there a way to setup the pivot point to be in the center? I am using text-geometry component and it rotates from a corner. i would like to make the text spin from the center.

<a-entity animation="property: rotation; dur: 5000;to: 0 360 0;loop:true;easing:linear" position="0 4 -3" scale="0.6 1.2 1" text-geometry="value: MultiMedia; font: #dawningFont; bevelEnabled: true; bevelSize: 0.1; bevelThickness: 0.1; curveSegments: 1; size: 1.5; height: 0.5;" material="color:yellow; metalness:0.9; roughness: 0.05; sphericalEnvMap: #chrome;"></a-entity>

I have tried adding a parent entity and adding the animation to the parent but it doesn't seem to fix it, instead it starts rotating in a circle path.

enter image description here


Solution

  • Seems that the text-geometry component doesn't have an offsetish property (source here)

    I'd tackle it like this: Once the text mesh is loaded - grab it and manually provide an offset.

    1) You can grab the mesh quite easily:

    let mesh = this.el.getObject3D('mesh');
    

    2) To calculate the offset - get the width from the bounding box.

    let bbox = new THREE.Box3().setFromObject(this.el.object3D);
    let offset = (bbox.min.x - bbox.max.x) / 2 
    mesh.position.set(offset, 0, 0)
    

    You can check it out here.


    Now i have one major issue - maybe i don't know something - but there is no event emitted once the text mesh is loaded. I tried loaded or window/document.onload but they seem to execute just before the text mesh is being really loaded. I need it to load, otherwise the bounding box is infinite - making the offset calculation pretty much useless. In my fiddle i threw the code into a setTimeout().


    Edit

    1) Its good idea to wait with the animation, until the above calculations are set. You can define a startEvent and emit it after repositioning the mesh

    ...
    mesh.position.set()
    this.el.emit("go")
    

    ..

    <a-entity animation="startEvents: go"></a-entity>
    

    2) you need to include the scale when calculating width. This is because the local space size is now different:

    let xscale = this.el.getAttribute('scale').x
    let offset = ((bbox.min.x - bbox.max.x) / xscale ) / 2 
    mesh.position.set(offset, 0, 0)
    

    Check it out here.