专业建站公司收费标准,自适应 网站,济南网络公司排行,南海桂城城乡建设局官方网站不知道从什么时候起#xff0c;人们开始喜欢上数字大屏这种“花里胡哨”的东西#xff0c;仿佛只要用上“科技蓝”这样神奇的色调#xff0c;就可以让一家公司焕然一新#xff0c;瞬间变得科技感满满。不管数字大屏的实际意义#xff0c;是用来帮助企业监控和决策#xf…不知道从什么时候起人们开始喜欢上数字大屏这种“花里胡哨”的东西仿佛只要用上“科技蓝”这样神奇的色调就可以让一家公司焕然一新瞬间变得科技感满满。不管数字大屏的实际意义是用来帮助企业监控和决策还是为了方便领导参观和视察抑或是为了向外界展示和宣传。总之自从数字大屏诞生之后它始终就没能摆脱其前任“中国式报表”那种大而全的宿命。追随着 ECharts、Superset、FineBI、DataEase 等数据可视化产品的身影一路走来你会发现人们在追求“花里胡哨”这件事情上永无止境。如今的数据大屏元素多(表格、视频、2D/2.5D/3D地图)、种类多(图表、报表、流程图)、媒介多(PC、平板、电视、LED)主打的就是一个眼花缭乱。 当数字大屏的这股时尚潮流涌向物联网和工业互联网领域以后就不可避免地催生出像上面这样的“数字大屏”需求请原谅我使用如此模糊的措辞因为我实在难以给它一个准确的定义工艺流程图、设备运行监控图、组态图、SCADA…。也许这些名称不见得都能做到全面概括可这些东西的确具备了数字大屏的特征哪怕这些设备元件、管道阀门在科技蓝配色下违和感十足。作为一位低调的程序员我一向不喜欢这种粉饰太平的面子工程所以当设计师同事带着设计图来找我时我当时内心是拒绝的 也许此时你的内心深处会闪过一丝蔑视认为这有什么难度呢我只需要在图片上叠加若干个透明的 div这样不就可以实现图片特定区域的交互逻辑啦我承认这是一个非常好的思路但是在实践过程中你就会发现div 的交互区域通常都是一个标准的矩形而设计师同事常常使用圆角矩形和不规则图形来增强设计感。因此在交互方面可能会存在一些缺陷尤其是在 2.5D 的图片设计稿中交互区域实际上是一个多边形。接下来我将介绍一种基于 HTML5 图片热区特性来实现交互的思路
div classcontainerimg srcDemo-01.jpg usemap#imageMap stylewidth: 600px; height: 315pxmap nameimageMap/map
/div首先准备一张图片以及一个 map 标签并且这个 map 标签通过 usemap 属性与这张图片进行了关联。参照上面的示意图我们定义了两个可交互的区域。其中区域1是矩形区域区域2是圆形区域
const areas [{key: 半泽直树,shape: rect,coords: [0, 0, 308.5, 315]
}, {key: 大和田,shape: circle,coords: [418, 134, 157.5]
}]因为 area 标签需要搭配 map 标签来使用所以我们将通过下面的代码来动态地创建区域同时为每个区域绑定相应的事件
const popup document.getElementById(popup);
const imageMap document.getElementsByName(imageMap)[0];areas.forEach(area {// 创建区域let ele document.createElement(area);ele.shape area.shape;ele.coords area.coords.join(,)ele.setAttribute(data-key, area.key);// 绑定事件ele.onclick function (e) {alert(e.target.dataset.key);};ele.onmousemove function (e) {popup.innerHTML div classcontent${e.target.dataset.key}/div;popup.style.left ${e.x - 75}px;popup.style.top ${e.y - 45}px;popup.style.display block};ele.onmouseover function (e) {popup.style.display display;};// 添加到map标签imageMap.appendChild(ele);
})此时当我们鼠标移动到指定的区域时就可以触发对应的气泡提示如下图所示 这个方案相对于纯 div 标签的思路要稍微好上一点点因为 area 标签里的 shape 属性支持多边形这意味着不规则区域的交互可以继续进行下去。可这种方案本质上并没有摆脱“手工标注”你不得不为每一个区域标注好坐标这对于没有设计感的程序员来说可能是一场折磨更重要的是一旦这个方案运用到数字大屏上面你总要去解决屏幕尺寸变化、全屏/非全屏等一系列问题显然这个时候这些区域的坐标都需要重新计算。这个时候博主就想到了 SVG 这种可缩放的矢量图形这是一种自描述的标记语言无论怎么缩放都不会失真。下面是一个简单的 SVG 图片示例我们可以大致了解到其结构是一个 XML 文件 既然 SVG 中本身就自带着描述位置的坐标信息那么我们是不是可以基于 SVG 来实现相应的交互逻辑呢下面我们以一张中国地图为例来验证这个想法 OK我们希望实现什么样的交互效果呢当鼠标移动到指定的省份时该省份会变成红色高亮状态并且会在鼠标位置触发气泡提示。具体怎么做呢首先我们来准备下面的 HTML 结构
div idpopup classrectangle styledisplay: none;/div
div classcontainer/div接下来我们通过脚本来加载 SVG 图片同时为其绑定相关事件
const popup document.getElementById(popup);fetch(China.svg).then(res res.text()).then(text {const container document.getElementsByClassName(container)[0];container.innerHTML text;// 允许SVG交互const svg document.getElementsByTagName(svg)[0];svg.setAttribute(pointer-events, cursor);// 为每一个路径绑定事件const paths svg.childNodes[0].childNodes;for (var i 0; i paths.length; i) {paths[i].onclick function (e) {alert(${e.target.id})};paths[i].onmouseover function (e) {e.target.setAttribute(fill, red);popup.innerHTML div classcontent${e.target.id}/divpopup.style.left ${e.x - 75}px;popup.style.top ${e.y - 45}px;popup.style.display block};paths[i].onmouseout function (e) {e.target.setAttribute(fill, #eee);popup.style.display none};}})在这个示例中每一个省份对应着 SVG 中的一个 path 节点因此我们只需要在加载完 SVG 以后再去遍历这些节点即可。可能大家会有疑问为什么这里不用 img、embed 或者 object 这些标签来承载一个 SVG 图形呢因为这样我们是没有办法访问 svg 标签及其子节点的。现在我们就可以看到下面的效果 这两个方案你更倾向于哪一个呢从一个程序员的角度来看我更喜欢使用 SVG因为 XML 这种格式不管对人还是机器来说都非常友好。实际上到目前为止这篇博客里对方案可行性的探索业已完成而在现实中更多的挑战往往来自非技术因素。譬如如何让设计师同事适应使用相对普通、朴素的矢量图格式。当然从这篇文章的思路延伸出去无论是复杂的数据大屏还是布局编辑器/低代码、地图、流程图、工作流等问题我们都无法摆脱 DOM、Canvas、WebGL、SVG 等知识体系。特别是当我们需要处理拖拽/平移、缩放、旋转等常规操作时这些都是最具挑战性的部分不是吗