Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hyperlink 可以在A帧场景中使用HTML图像贴图吗?_Hyperlink_Aframe_Imagemap - Fatal编程技术网

Hyperlink 可以在A帧场景中使用HTML图像贴图吗?

Hyperlink 可以在A帧场景中使用HTML图像贴图吗?,hyperlink,aframe,imagemap,Hyperlink,Aframe,Imagemap,以下是场景: 我有一张360º的世界地图全景图,运行在a型架上 我希望每个大陆都可以点击,重定向到相关的维基百科页面 我的尝试: 我试着像在普通项目中一样使用标记,但是 没有结果 我也读了文档,什么也没找到 有关这一点 我的问题: 我的目标可能实现吗?如果是,怎么做 我的代码: 注:到目前为止,只有非洲大陆有坐标 标签将区域放置在图像上方。它不会像那样将区域投影到三维对象上 我建议您在a-frame自定义组件中重复使用标记中定义的区域 tldr: 我已经制作了一个似乎可以完成这项工作,

以下是场景:

我有一张360º的世界地图全景图,运行在a型架上

我希望每个大陆都可以点击,重定向到相关的维基百科页面

我的尝试:

  • 我试着像在普通项目中一样使用
    标记,但是 没有结果
  • 我也读了文档,什么也没找到 有关这一点
我的问题:

我的目标可能实现吗?如果是,怎么做

我的代码:

注:到目前为止,只有非洲大陆有坐标


标签将区域放置在图像上方。它不会像那样将区域投影到三维对象上

我建议您在a-frame自定义组件中重复使用
标记中定义的区域

tldr:

我已经制作了一个似乎可以完成这项工作,而且使用起来相当简单:

<a-image material="src: #texture" asourcemap="#some-map"></a-image>
<!-- somewhere else -->
<map id="some-map">
   <area shape="rect" alt="rectangle" coords="0,0, 50,50" href="rect.html">
   <area shape="polygon" alt="poly" coords="0,0, 40,50, 25,0">
</map>
保存它们以备日后使用。坐标是逗号分隔的字符串,因此您可能需要
parseInt()
它们,管理顺序(即
[[x1,x1],[x2,y2],[x3,y3]

1。使a-frame实体可交互

单击时做出反应,更重要的是-检查单击发生的位置:

this.el.addEventListener("click", evt => {
   var UVPoint = evt.detail.intersection.uv
})
将帮助我们确定单击纹理上的哪个点。UV的范围为,因此我们需要重新缩放UV点:

// may need waiting for "model-loaded"
let mesh = this.el.getObject3D("mesh")
// this may not be available immidiately
let image = mesh.material.map.image
let x_on_image = UVPoint * image.width
// the y axis goes from <1, 0>
let y_on_image = image.height - UVPoint * image.heigth  
如果您跳过了tldr部分,则上述步骤将在中组合并在中使用

3。老掉牙的尝试

另一种方法是:

  • 接收对a形框架图元的单击
  • 抓取单击的坐标,如图1所示
  • 隐藏场景
  • 检查哪个
    位于
    document.element起点(x,y)的坐标处
  • 展示现场
  • 使用
    document.createEvent(“MouseEvent”)创建鼠标事件
  • 元素上分派它
即使在我的手机上,隐藏/显示技巧也非常有效。我真的很惊讶,场景没有闪烁,没有冻结,甚至没有减速

但是
document.elementFromPoint(x,y)
不适用于firefox,可能任何使其工作的尝试都会比0-2步骤耗费更多的时间。我还相信,这些装饰会变得更大,并取决于具体情况

无论如何,这里有一个古老的答案:

/* SETUP
<a-scene>
 <a-image press-map>
</a-scene>

<image id="image" sourcemap="map">
<map name="map">
  <area ...>
</map>
*/

AFRAME.registerComponent("press-map", {
  init: function() {
    // the underlying image
    this.img = document.querySelector("#image")
    // react on clicks
    this.el.addEventListener("click", evt => {
      // get the point on the UV
      let uvPoint = evt.detail.intersection.uv 
      // the y is inverted
      let pointOnImage = {
        x: uvPoint.x * this.img.width,
        y: this.img.height - uvPoint.y * this.img.height
      }
      
      // the ugly show-hide bits
      this.el.sceneEl.style.display = "none";
      this.img.style.display = "block";
      // !! grab the <area> at the (x,y) position
      var el = document.elementFromPoint(pointOnImage.x, pointOnImage.y);
      this.el.sceneEl.style.display="block"
      this.img.style.display="none"

      // create and dispatch the event
      var ev = document.createEvent("MouseEvent");
      ev.initMouseEvent(
            "click",
            true /* bubble */, false /* cancelable */,
            window, null,
            x, y, 0, 0, /* coordinates */
            false, false, false, false, /* modifier keys */
            0 /*left*/, null
      );
      el.dispatchEvent(ev);
    }
  }
})
/*设置
*/
注册表组件(“按地图”{
init:function(){
//底层图像
this.img=document.querySelector(“图像”)
//对咔哒声作出反应
this.el.addEventListener(“单击”,evt=>{
//获取UV上的点
设uvPoint=evt.detail.intersection.uv
//y是倒转的
设pointOnImage={
x:uvPoint.x*this.img.width,
y:this.img.height-uvPoint.y*this.img.height
}
//丑陋的表演掩盖了一些细节
this.el.sceneEl.style.display=“无”;
this.img.style.display=“block”;
//!!在(x,y)位置抓取传感器
var el=document.elementFromPoint(pointOnImage.x,pointOnImage.y);
this.el.sceneEl.style.display=“block”
this.img.style.display=“无”
//创建并分派事件
var ev=document.createEvent(“MouseEvent”);
ev.initMouseEvent(
“点击”,
true/*气泡*/,false/*可取消*/,
窗口,空,
x、 y,0,0,/*坐标*/
false、false、false、false、/*修改键*/
0/*左*/,空
);
el.调度事件(ev);
}
}
})

这确实是黑客攻击。但它确实起到了作用!但在Firefox中不起作用。知道原因吗?@MikeMichaels没有注意到,似乎
elementFromPoint
在Firefox上没有占据重要位置。不确定原因,尽管如此,似乎最好找到一个非黑客攻击的解决方案,因为它太复杂了:)@MikeMichaels,因为该解决方案不仅是黑客的,而且正如您所注意到的,完全不可靠-我编辑了我的答案,并基于一个应该在任何浏览器/平台上工作的解决方案。如果你喜欢,请告诉我。而且现在已经很晚了,所以如果有不清楚的地方,或者编辑不好的地方,请随时指出。
var point = [x_on_texture, y_on_texture]
for (var i = 0; i < polygons.length; i++) {
   // polygons need to be [[x1, y1], [x2, y2],...[xn, yn]] here
   if (inside(point, polygons[i]) {
      console.log("polygon", i, "clicked!")
   }
}
/* SETUP
<a-scene>
 <a-image press-map>
</a-scene>

<image id="image" sourcemap="map">
<map name="map">
  <area ...>
</map>
*/

AFRAME.registerComponent("press-map", {
  init: function() {
    // the underlying image
    this.img = document.querySelector("#image")
    // react on clicks
    this.el.addEventListener("click", evt => {
      // get the point on the UV
      let uvPoint = evt.detail.intersection.uv 
      // the y is inverted
      let pointOnImage = {
        x: uvPoint.x * this.img.width,
        y: this.img.height - uvPoint.y * this.img.height
      }
      
      // the ugly show-hide bits
      this.el.sceneEl.style.display = "none";
      this.img.style.display = "block";
      // !! grab the <area> at the (x,y) position
      var el = document.elementFromPoint(pointOnImage.x, pointOnImage.y);
      this.el.sceneEl.style.display="block"
      this.img.style.display="none"

      // create and dispatch the event
      var ev = document.createEvent("MouseEvent");
      ev.initMouseEvent(
            "click",
            true /* bubble */, false /* cancelable */,
            window, null,
            x, y, 0, 0, /* coordinates */
            false, false, false, false, /* modifier keys */
            0 /*left*/, null
      );
      el.dispatchEvent(ev);
    }
  }
})