【问题标题】:Showing in a browser an interactive 2D floorplan using html5 and javascript在浏览器中显示使用 html5 和 javascript 的交互式 2D 平面图
【发布时间】:2018-09-27 06:31:26
【问题描述】:

我需要更换多年前构建的 Flash 查看器,以显示来自 AutoCAD 的交互式 2D 平面图

目前,AutoCAD 文件被读取并转换为 XML 文件,其中包含代表平面图对象的多边形的 XY 坐标:房间、墙壁、资产等。绘图中的对象是可点击的,并且可以根据主题视图设置为可见或不可见

有时这些平面图可能比较大,有很多点

我已经尝试使用像 LeafletJS 这样的 web 地图控件,因为它已经具有 PAN 和 ZOOM 功能,我可以插入可点击的标记,并管理图层,以便我可以通过主题观点。我已将地图 CRS 设置为指标,并将数据加载为 GeoJSON。不幸的是,对于现实世界的中型平面图,它太而且有时变得反应迟钝

下面的示例由 18630 个线对象组成,在平移时反应不是很明显。

所以现在我想使用 SVGCANVAS 在浏览器中直接绘制平面图。 我更喜欢使用 CANVAS,因为它比 SVG 快得多,如果支持也使用 WebGL,但我必须依赖库才能拥有 事件处理程序以及像 DOM 一样简单的对象管理。

所以现在我要问的是,像 threeJS 这样的库是否可以处理这样的简单任务,即使我需要映射 2D 对象,并且选择它是否是正确的技术。特别是,是否可以使用threeJS:

  1. 要将事件侦听器分配给对象以获取其 ID?
  2. 要将 CSS3 规则应用于对象样式,例如突出显示房间或桌子?
  3. ThreeJS 可以轻松地绘制到 SVG 或 Canvas 元素?
  4. 借助 ThreeJS,我还可以轻松管理平移和缩放吗?
  5. 是否也可以在移动设备上显示? (Android 和 iOS)

如果有人知道更好的库或技术来完成这项任务,我完全可以提出任何建议。

(请注意,我只需要 2D 绘图,因为 3D 已经使用 Revit 的其他技术构建)

【问题讨论】:

  • 使用 SVG 时不需要 JS 或任何库,因为它已经满足您的要求:原生平移和缩放;有一个 DOM;可以使用 XLink 设置可点击对象;原生 CSS 支持;可以在任何现代浏览器中打开而无需进一步依赖等等。我建议直接将CAD文件导出为SVG - JS绘制计划的要求来自哪里? (您显然已经在 CAD 软件中绘制了平面图。只导出它的一些几何图形并重新绘制它听起来很奇怪。)
  • @feeela 是的 SVG 绝对比画布容易,但我读到当有很多点时会有性能问题。也许我可以尝试在问题中绘制相同的平面图并查看结果。我无法直接从 AutoCAD 导出到 SVG,因为我需要根据图层名称支持主题视图、显示/隐藏特定图层为对象分配属性等等……顺便说一句,感谢 SVG 和 XLink 的建议。
  • 你应该根据一个相当大的示例文件自己检查性能。
  • 18000 行对于任何渲染器来说听起来都太多了。我会找到减少或拆分等的方法
  • OK 同意;)对于 SVG 渲染器来说太多了。可以用于硬件加速渲染器;)

标签: javascript html svg canvas three.js


【解决方案1】:

使用 webgl(例如通过 three.js),您可以在支持 GPU 的桌面浏览器上以 60fps 的速度绘制数百万条简单的线条图元。

这是一个使用three.js 将超过一百万行原语组合在一起的人为示例:

https://codesandbox.io/s/0pp3x92n4p

这里:

http://vectorslave.com/wireblueprint/index.html

【讨论】:

  • 我会试一试,确保比较性能、兼容性和实施的难易程度,我会在此处发布结果。
  • 如果你发布了一个完整的样本数据文件,我很想给你写一个简单的查看器;)
  • 但是哪种格式最适合threejs?告诉我您喜欢的结构,我会即时构建 API
  • 这里有一些来自three.js 文档的例子。 threejs.org/docs/#manual/introduction/Drawing-lines 和:threejs.org/examples/?q=lines 在每个示例中您都可以查看源代码。
  • 真的很好!谢谢。我已经用 OrthographicCamera 替换了透视相机,以避免平移失真。顺便说一句,似乎很难实现我需要的所有功能,例如绘制一个可点击的形状并检索其自身的某些属性。我将就此提出一个新问题。谢谢
【解决方案2】:

按照feeela 的建议,我在SVG 中实现了可视化, 绘制由 18630 条线组成的相同模型。

它的加载速度肯定比 GeoJSON Leaflet 度量地图快。

SVG 由查询建筑物和楼层的 API 提供,它以元素(文本/纯文本)的形式返回架构,我将这些元素附加到网页中的元素。

要将字符串路径元素附加到我使用的 SVG DOM 元素 parseSVG library

我还没有找到对 panzoom 的“原生”支持,所以我使用了一个 jQuery 库:Ariutta SVG Pan and Zoom

使用 Ariutta SVG pan&zoom,我还应该能够收听移动事件,例如 pinchtouch

这里是javascript代码:

<div id="mapArea">
     <svg id="map" xmlns="http://www.w3.org/2000/svg" x="0" y="0" style="stroke: #00ff00; stroke-width: 0.2px;background:#000">
     </svg>
</div>

<script type="text/javascript">
    var container = document.getElementById('mapArea'),
        width = container.offsetWidth,
        svgMap = document.getElementById('map');

    svgMap.setAttribute('width', width);
    svgMap.setAttribute('height', width * 0.5);

    $(document).ready(function () {

        $.ajax({
            type: "GET",
            url: "/Public/GetSVGPlan.aspx?building=1423&floor=3",
            dataType: "text",
            success: function (result) {
                svg = parseSVG(result);
                svgMap.appendChild(svg);
                svgPanZoom('#map', {
                    zoomEnabled: true,
                    controlIconsEnabled: true,
                    fit: true,
                    center: true
                });
            },
            error: function (error) {
                console.log(error);
            }
        });
    });
</script>

API 返回的路径元素如下:

<path d="M173.7043 66.758, L173.7054 66.7701" />
<path d="M191.947 64.2563, L191.9198 63.9453" />
<path d="M129.3072 12.2843, L129.3301 12.3702" />
<path d="M129.3301 12.3702, L131.701 11.735" />
<path d="M191.6087 63.9725, L191.636 64.2836" />
<path d="M173.7054 66.77, L172.5553 66.9803" />
<path d="M131.3573 11.735, L129.3072 12.2843" />
<path d="M195.8466 63.9148, L195.8194 63.6037" />
<path d="M172.5553 66.9803, L172.6882 66.9687" />
<path d="M129.3074 12.2841, L129.2449 11.7366" />
<path d="M195.7694 63.6081, L195.8194 63.6037" />
<path d="M172.6882 66.9687, L173.7064 66.7821" />
<path d="M129.2451 11.7368, L129.2451 9.5381" />
<path d="M195.5083 63.631, L201.43 63.1124" />
<path d="M226.9927 14.458, L228.0006 14.4593" />
<path d="M173.7064 66.7821, L173.7075 66.7942" />
<path d="M129.2451 9.5381, L131.6964 9.5381" />
<path d="M201.4572 63.4235, L195.5356 63.9421" />

结果:

Internet Explorer 11 上非常慢,渲染过程使用大量 CPU 大约 15 秒。我认为这更多是由于用于附加路径元素的 js 循环,而不是 SVG 渲染。

在移动设备上(Chrome on Android)具有良好的响应和快速加载/渲染(~3-5s)

即使它按预期工作,也非常欢迎任何提高性能的建议!!

【讨论】:

  • 查看我的答案 :) 60fps,1,000,000 行。
  • @manthrax 非常令人印象深刻,我已经在移动设备上打开了它,它呈现得非常流畅和快速,很好,但是对于threeJS,我的问题中的所有疑问仍然存在。我必须绘制 2D 平面图而不是旋转 3D 随机彩色立方体。代码维护也很重要,最后但并非最不重要的是,浏览器支持!
  • 如果您发布示例文件.. 我也许可以向您展示如何呈现它。你写道: > 它太慢了,有时变得没有反应。 >下面的示例由 18630 个线对象组成,在平移时反应不是很大。我只是想向您展示一个可能的解决方案,用一个数量级的数据来解决您的两个问题。这甚至不包括平铺和 LOD 之类的优化。 three.js 是开源的,用于大数据可视化。过去我曾多次使用 svg 和 canvas api,而 webgl 让这两个 api 都大开眼界。
  • 顺便说一句:我把随机颜色留在了那里,因为它表明不仅有 >1m 线基元,它们也有纹理,表明它们也可以是唯一的颜色。我使用带有一堆随机矩形的画布作为纹理。 ;)
  • @manthrax 顺便说一句,我在 3d 彩色立方体上的 cmets 并非绝对是为了尽量减少你令人印象深刻的例子,更多的是我在使用threeJS 找到一个关于我的问题的更有用的例子时感到沮丧,并澄清我对在 2D 绘图上使用三个,这就是我提出问题的原因:)
猜你喜欢
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 2015-05-03
  • 2012-05-27
  • 1970-01-01
  • 2016-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多