AR-js-org / AR.js

Image tracking, Location Based AR, Marker tracking. All on the Web.
MIT License
5.3k stars 909 forks source link

move arToolkitSource.domElement to another parent? #565

Closed dw-herrmann closed 9 months ago

dw-herrmann commented 10 months ago

Hi there, I want to build arjs into a div, so it's just a frame on my website, instead of full screen. I found out, how to append the video tag to my container, but it still creates a second one inside the body.

arToolkitSource.init(function onReady() {
  frame.appendChild(arToolkitSource.domElement);
})

Html structure:

<body>
  <frame>
      <video />
  </frame>
  <video />
</body>

How can I remove the video element inside the correct way?

Edit: I use the threejs version of it

Platform-Group commented 10 months ago

I do it by putting the arjs code in its own iFrame and embedding that, it also allows me to fetch the device's camera's aspect ratio so I can embed with the correct width and height instead of arjs's default of stretched fullscreen.

You can just use css to fix your video issue

video { display: none; }

As the arjs output is from the canvas anyway so you don't need to see the video element at all

dw-herrmann commented 9 months ago

Thank you. It sounds a bit like a hotfix.

I guess, a cleaner version would be to remove the body>video directly with JS with a "setTimeOut" inside the "arToolkitSource.init(function onReady(){…})"

Platform-Group commented 9 months ago

@dw-herrmann that would break it as the video element stream is being used by the canvas, I'm not sure why it's done that way but it is. The normal AR.js functionality has the canvas fullscreen at a higher z-level so you just never see the video element behind it, setting the video to display none is just another step forward from that.

dw-herrmann commented 9 months ago

@Platform-Group, that's strange. This code works fine for me and breaks nothing

arToolkitSource.current.init(function onReady() {
    nextFrame = requestAnimationFrame(animate);
    frame.appendChild(arToolkitSource.domElement); // move video from body to frame
    setTimeout(() => { // remove video element after 2 seconds
        let videoElement = document.querySelector("body>#arjs-video");
        if (videoElement) videoElement.remove();
    }, 2000);
})
Platform-Group commented 9 months ago

@dw-herrmann that's not the video element's id in my code, at least I've never seen an element called #arjs-video before. It simply looks like: <video autoplay="true" playsinline="true" display="none"></video> to me, and deleting that breaks the video stream.

I've never used arToolkitSource with arjs though, I use aframe and I'm guessing you must be using threex.

Glad you've found a working solution though.

dw-herrmann commented 9 months ago

Ah, that's the difference! I should have said that in the beginning :D

At first, I tried aframe but noticed, there is no way to make a react-component out of it, because it puts everything into the body.