Hunter Estrada
Hunter Estrada

Reputation: 41

AFrame - Set Size of Camera Feed

My last question was marked as duplicate: A-Frame AR - Set Size of Scene

Here is the question that it was marked duplicate of: Aframe and aframe-ar: display video stream in div instead of fullscreen

Using iframe is not the optimal solution for me, I need the AR to be present on my webpage. The answerer alludes to changing the source code to be able to resize the scene and camera video. Can someone help me achieve this?

Upvotes: 1

Views: 2368

Answers (1)

Piotr Adam Milewski
Piotr Adam Milewski

Reputation: 14655

tldr.

Afaik arjs has hardcoded sizes and multiple boundaries all over the place to keep the library universal (different devices with different aspect ratios, mobile portrait vs landscape etc...).

Re-creating it all with "embedding" options would be a huge project so I'll focus on a simple example with a non - resizable window.

Disclaimer: most of the following is just my take, mostly showing which parts I changed and why. All of this could be done in many other ways.

0. a wrapper element

So the idea is to be able to embed the video + scene into some div, like here enter image description here

You can see both the video and scene are contained within a div - #arjs-cell. So just after the namespace I've added my variable for keeping my wrapper element, and a setter, which will also reparent the video:

var THREEx = THREEx || {}
THREEx.wrapperElement = null;
THREEx.setWrapperElement = function(wrapperEl, video) {
  THREEx.wrapperElement = wrapperEl
  wrapperEl.appendChild(video);
}

1. The video element

Upon creation the video element is given multiple style attributes (source) like position, top, left, zIndex). In this case I've just threw out the left position and changed the z-index.

The width / height is a completely different story. For the first 10000 * 1000ms arjs recalculates multiple things including the video size (source). It makes it difficult to change the elements "from the outside". Anyway one of those recalculated things is the video element size, which is based on the window dimensions (source)

We can get cut in with our wrapper:

ARjs.Source.prototype.onResizeElement = function () {
// (...)
  var screenWidth = window.innerWidth;
  var screenHeight = window.innerHeight;
  if (THREEx.wrapperElement) {
      const bounds = THREEx.wrapperElement.getBoundingClientRect();
      screenWidth = THREEx.wrapperElement.offsetWidth;
      screenHeight = THREEx.wrapperElement.offsetHeight;
      // by default the video parent is the window, so top is 0;
      this.domElement.style.top = bounds.top + 'px';
  }

2. The a-frame scene

To adjust the scene arjs sets the body dimensions to the <video> element ( (source) forcing an update in a-frame. Since we don't want to mess with the <body>, lets do the same on the wrapperElement:

AFRAME.registerSystem('arjs', {
// (...)
  // ugly kludge to get resize on aframe... not even sure it works
  if (arProfile.contextParameters.trackingBackend !== 'tango' && THREEx.wrapperElement) {
    arSource.copyElementSizeTo(THREEx.wrapperElement)
  }

arSource.copyElementSizeTo() will mess with the margins, so lets comment that out:

ARjs.Source.prototype.copyElementSizeTo = function (otherElement) {
if (window.innerWidth > window.innerHeight) {
   //landscape
   otherElement.style.width = this.domElement.style.width
   otherElement.style.height = this.domElement.style.height
   // otherElement.style.marginLeft = this.domElement.style.marginLeft
   // otherElement.style.marginTop = this.domElement.style.marginTop
}
// (...)

3. Putting it all to use

Now we can wait for the video (and arjs core) to be fully initialized, and do our magic:

window.addEventListener("arjs-video-loaded", evt => {
  const video = evt.detail.component;
  const wrapper = document.querySelector("#arjs-cell")
  THREEx.setWrapperElement(wrapper, video)
})

You can check it out here.


It really would be way easier not to break the library and use an iframe. You can easily call functions withing the iframed website - check it out here

Upvotes: 3

Related Questions