Hibra
Hibra

Reputation: 25

Resizing aframe object in the browser

I am adding some shapes (circular or rectangular) in a 360 video using A-Frame, I can drag the shape to change its position in the video frame, but I need also to be able to resize this shapes to cover a precise object in the video, let's say I want to cover a painting in a video frame with a rectangle, so I want to be able to resize the shape to cover the painting correctly while I am in the web browser mode. I found this post that is asking about rotating the object, and he is saying that he succeeded to do the resize without explaining how exactly he did it. Anyone knows how to do it ?

Upvotes: 0

Views: 435

Answers (1)

Piotr Adam Milewski
Piotr Adam Milewski

Reputation: 14655

You can rescale elements either with the a-frame API:

element.setAttribute("scale", "1 1 1") // replace 1 1 1 with new values

or by accessing the underlying THREE.js API:

element.object3D.scale.multiplyScalar(scaleFactor);

You can easily create a component, which would rescale a "selected" element. Run the snipper, press the mouse over an element and use the scrollwheel:

<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
  // register component
  AFRAME.registerComponent("foo", {
    // init callback
    init: function() {
      // react to press / release events to know if the element is selected
      this.el.addEventListener("mousedown", e => {
        this.selected = true;
      })
      this.el.addEventListener("mouseup", e => {
        this.selected = false;
      })
      // if this is selected, scale up/down when the mouse is scrolled
      this.el.sceneEl.addEventListener("mousewheel", evt => {
        if (!this.selected) return; // ignore when not selected
        const scale_factor = evt.deltaY < 0 ? 1.1 : 0.9 // scale up or down depending on the scroll direction
        this.el.object3D.scale.multiplyScalar(scale_factor);
        evt.preventDefault();
      })
    }
  })

</script>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: .interactable">
  <a-box class="interactable" position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" foo></a-box>
  <a-sphere class="interactable" position="0 1.25 -5" radius="1.25" color="#EF2D5E" foo></a-sphere>
  <a-cylinder class="interactable" position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" foo></a-cylinder>
  <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
</a-scene>

If you're looking for a ready solution, I'd recommend checking out the transform controls


If you want to resize the plane by moving the vertices to make a custom polygon, You can directly change the planes vertices position:

<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
  AFRAME.registerComponent("foo", {
    init: function() {
      // grab the threejs mesh
      const mesh = this.el.getObject3D("mesh");
      // grab the vertices array
      // the array is looking like this: x1, y1, z1, x2, y2, z2, ... xn, yn, zn
      const vertices = mesh.geometry.attributes.position.array;
            
      // manipulate the vertices in fixed intervals 
      setInterval(evt => {
        vertices[0] = vertices[0] === -0.5 ? -1 : -0.5; // primitive x1 toggle
        mesh.geometry.attributes.position.needsUpdate = true; // toggle update flag
      }, 500);
      setInterval(evt => {
        vertices[1] = vertices[1] === 0.5 ? 1 : 0.5; // primitive y1 toggle
        mesh.geometry.attributes.position.needsUpdate = true; // toggle update flag
      }, 250);
    }
  })
</script>
<a-scene>
  <a-plane position="0 1.6 -2" color="green" foo></a-plane>
</a-scene>

Here is an example of moving the vertex around

Upvotes: 1

Related Questions