ShowMeBug 黑科技丨一招快速实现架构绘图之鼠标同步 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ShowMeBug2020
V2EX    推广

ShowMeBug 黑科技丨一招快速实现架构绘图之鼠标同步

  •  
  •   ShowMeBug2020 2021-09-09 11:23:29 +08:00 1179 次点击
    这是一个创建于 1552 天前的主题,其中的信息可能已经有所发展或是发生改变。

    根据工作习惯与经验了解,思维导图和多支线流程图一直面临一个最大的问题:只有作者才能从头到尾全部看懂。

    出现这种问题的原因在于,接收者不能跟上创作者从头到尾的思考创作过程。

    架构绘图就是在这样一个基础问题下产生,绘图库 mxgraph 加上 showmebug 的多端同步黑科技,诞生了 showmebug 独家的架构绘图板块,创作者可以从头到尾展示思考过程给接收者,最大程度突出创作者的特点。

    图层介绍

    mxgraph 含有四个图层,background pane,draw pane,overlay pane,decorator pane,这四个图层分别是四个 <g> 标签。mxgraph 在 mxGraphView 类上提供了获取这四个图层的方法:

    • Background Pane

    背景图层,可以自定义背景图。

    • draw pane

    所有的图形组件都是绘制在这一图层上。

    • overlay pane

    本图层上绘制大部分的工具类元素,例如选中高亮元素,改变图形大小旋转的元素,还有本篇文章中介绍的同步鼠标这一元素。

    • decorator pane

    当鼠标 hover 在组件上的时候,会看到出现了数个可以拉出连线的圆点,这些圆点就是绘制在该层图层上的。

    坐标处理

    • 坐标发送

    mxgraph 封装了白板内部的鼠标事件,通过配置传入

    mouseDown , mouseMove , mouseUp 三个回调函数来调用。回调函数的两个参数分别是事件产生的 mxGraph 和封装后相应事件的 mxMouseEvent 。

    • 节流发送

    Mouse Move 事件是典型的极高触发频率事件,所以在进行处理的时候,最好使用节流函数进行封装发送,这一点很简单,借用 lodash.throttle 即可实现。

    • 坐标转换

    mxgraph 的尺寸在不同尺寸屏幕下是适配的,反而导致鼠标的坐标在不同终端存在映射关系而不会完全相同。对应坐标需要进行下面这样一段映射算法:

    因为每一端白板大小都不同,translate 可以看目前端鼠标位置的矫正位移,去除矫正位移 graphX(Y) - translate.x(y) 之后剩下鼠标在白板上的绝对位置,传递至 remote 端之后,加上本端的矫正位移 x(y) + translate.x(y) ,就能获得鼠标的正确位置。

    鼠标绘制

    • 任务队列

    只有节流发送的话,remote 端可能因为网络波动的原因,可能会在某段时间内收到拥堵的大量信息,这些信息不分先后的执行,导致同步鼠标产生胡乱跳动的现象。因此在 remote 端,使用任务队列的思想来解决这个问题。

    通过 next() 函数控制执行顺序,把异步发送事件触发的任务,强制变为同步任务执行。这种思想在一些 NodeJS 框架里被广泛应用,例如:ExpressJs 中间件等。

    • 平滑滑动

    鼠移动事件是节流后的数据发送到 remote 端,导致 remote 端接收到的坐标信息是跳跃式的,如果只是按照发送事件触发同步鼠标绘制,那绘制出来的动画效果也是跳跃式的,给人十分卡顿的感觉。同事讨论和查找资料后选用

    window.requestAnimationFrame 进行平滑处理。

    原因在于 svg 画布里的 transform: translate(x, y) 与 css 的表现略有不同,svg 内部元素的 transform: translate 会根据最近祖先 svg 元素的 x,y 属性,作为开始位移起始点。

    据此特性,将鼠标图形包裹在一个 svg 标签内部(如上段代码所示),通过设置 pointer-wrapper 的 x/y 属性,确定同步鼠标的绝对位移;一个事件中,同步鼠标产生移动过程中,对 pointer-wrapper 的两个子元素的 transform: translate 属性进行操作,作为相对位移;当这次移动事件结束,再对 pointer-wrapper 设置 x/y 属性为最终坐标,同时对 pointer-wrapper 的两个子元素设置 transform: translate(0, 0),作为最终的绝对位置。

    作者:史翊

    ShowMeBug 是一款数字化驱动的可记录、可分析、可复盘的技术评估与在线 Coding 面试平台。

    点击试用: https://www.showmebug.com/

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5134 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 08:40 PVG 16:40 LAX 00:40 JFK 03:40
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86