问题描述
我的上一个问题被标记为重复:A-Frame AR - Set Size of Scene
这是被标记为重复的问题:Aframe and aframe-ar: display video stream in div instead of fullscreen
使用 iframe 对我来说不是最佳解决方案,我需要在我的网页上显示 AR。回答者暗示更改源代码以能够调整场景和摄像机视频的大小。有人可以帮助我实现这一目标吗?
解决方法
tldr。
Afaik arjs 具有硬编码的大小和遍布各处的多个边界,以保持库的通用性(具有不同纵横比的不同设备、移动纵向与横向等......)。
使用“嵌入”选项重新创建这一切将是一个巨大的项目,因此我将重点介绍一个带有不可调整大小的窗口的简单示例。
免责声明:以下大部分内容只是我的看法,主要显示我更改了哪些部分以及原因。所有这些都可以通过许多其他方式来完成。
0。一个包装元素
您可以看到视频和场景都包含在一个 div - #arjs-cell
中。
所以就在命名空间之后,我添加了我的变量来保留我的包装元素和一个 setter,它也将重新设置视频的父级:
var THREEx = THREEx || {}
THREEx.wrapperElement = null;
THREEx.setWrapperElement = function(wrapperEl,video) {
THREEx.wrapperElement = wrapperEl
wrapperEl.appendChild(video);
}
1.视频元素
视频元素在创建时被赋予多个样式属性 (source),如 position
、top
、left
、zIndex
)。在这种情况下,我刚刚抛出了 left
位置并更改了 z-index
。
宽度/高度是一个完全不同的故事。对于前 10000 * 1000
ms arjs
重新计算包括视频大小 (source) 在内的多项内容。这使得“从外部”改变元素变得困难。无论如何,这些重新计算的事情之一是 video
元素大小,它基于 window
维度 (source)
我们可以用我们的包装纸切入:
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.一帧场景
为了调整场景 arjs
将身体尺寸设置为 <video>
元素( (source) 强制更新 a-frame
。因为我们不想弄乱使用 <body>
,让我们在 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() 会弄乱边距,所以让我们注释掉:
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.全部投入使用
现在我们可以等待视频(和 arjs
核心)完全初始化,然后施展我们的魔法:
window.addEventListener("arjs-video-loaded",evt => {
const video = evt.detail.component;
const wrapper = document.querySelector("#arjs-cell")
THREEx.setWrapperElement(wrapper,video)
})
您可以查看here。
不破坏库并使用 iframe
确实会容易得多。您可以通过 iframed
网站轻松调用函数 - 请查看 here