首页 / 资讯中心 / 文章详情

Cytoscape.js 视图缩放完全指南:cy.zoom() 用法、边界裁剪与锚点缩放原理

Cytoscape.js 视图缩放完全指南:cy.zoom() 用法、边界裁剪与锚点缩放原理 ★ FEATURED ARTICLE
Cytoscape.js 视图缩放完全指南cy.zoom() 用法、边界裁剪与锚点缩放原理【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址: https://gitcode.com/gh_mirrors/cy/cytoscape.js本文聚焦 Cytoscape.js 核心 API 中的视图缩放能力围绕cy.zoom()的读取/设置语义、缩放级别合法性校验与边界裁剪规则以及围绕指定屏幕坐标或模型坐标进行锚点缩放zoom about a point的完整用法展开讲解并结合仓库源码src/core/viewport.mjs 与 src/math.mjs剖析其底层实现。读完本文你将掌握如何精确控制画布缩放、如何让视野以某个节点或某个屏幕位置为中心缩放以及如何与minZoom()、maxZoom()、viewport()等配套 API 协同工作。一、cy.zoom()的双重身份读取器与设置器在 Cytoscape.js 中cy.zoom()是一个典型的无参取值、有参赋值型核心方法其实现位于 src/core/viewport.mjszoom: function( params ){ if( params undefined ){ // get return this._private.zoom; } else { // set let vp this.getZoomedViewport( params ); let _p this._private; if( vp null || !vp.zoomed ){ return this; } _p.zoom vp.zoom; if( vp.panned ){ _p.pan.x vp.pan.x; _p.pan.y vp.pan.y; } this.emit( zoom ( vp.panned ? pan : ) viewport ); this.notify(viewport); return this; // chaining } },由此可以得到两个基本结论读取当前缩放级别调用cy.zoom()而不传任何参数会返回当前实例的缩放值内部存储在_private.zoom。在实例初始化时该值默认取options.zoom若未显式指定则为1见 src/core/index.mjs。设置缩放级别传入一个数字或一个配置对象方法内部会先经过getZoomedViewport()校验与换算再真正写入_private.zoom并同步触发zoom必要时附带pan与viewport事件最后通过notify(viewport)通知渲染器重绘。设置成功与否可以通过返回值判断若参数非法或缩放未发生方法直接返回this而不做任何改动。由于它采用链式调用风格setter 返回this你可以连续执行cy.zoom(2).pan({ x: 10, y: 20 })之类的组合操作。二、缩放级别合法性规则无效值忽略越界值裁剪文档对cy.zoom()接受的值给出了明确约束这也是理解该方法行为的关键缩放级别必须是正数非数字的缩放级别会被直接忽略例如传null、字符串、对象等都不会生效数字但超出有效缩放范围的级别会被视为最接近的合法缩放级别即自动裁剪clamp到最小或最大边界。从源码看这一规则由getZoomedViewport()落实src/core/viewport.mjs// crop zoom zoom zoom _p.maxZoom ? _p.maxZoom : zoom; zoom zoom _p.minZoom ? _p.minZoom : zoom; // cant zoom with invalid params if( bail || !is.number( zoom ) || zoom currentZoom || ( pos ! null (!is.number( pos.x ) || !is.number( pos.y )) ) ){ return null; }可以看到两层校验类型校验!is.number( zoom )时返回null调用方zoom方法检测到vp null后直接返回参数被忽略范围裁剪合法的数字会先与_p.maxZoom、_p.minZoom比较超出上限取上限、低于下限取下限无效变化检测如果请求的级别与当前级别相同zoom currentZoom同样视为没有缩放而返回null避免无意义的视图更新。这种裁剪而非报错的设计非常实用——你无需在业务代码里先查询当前 min/max 再做边界判断直接传入目标值即可。默认的缩放边界缩放边界的默认值定义在核心初始化逻辑中src/core/index.mjsminZoom: 1e-50, maxZoom: 1e50,即默认情况下最小级别为1e-50几乎可以缩到无限小最大级别为1e50几乎可以无限放大。同时初始化时会调用this.zoomRange({ min: options.minZoom, max: options.maxZoom })src/core/index.mjs因此你可以在创建实例时通过minZoom/maxZoom选项直接收紧这个范围。zoomRange()还会做合法性校验只有当min、max都是数字且min max时才接受见 src/core/viewport.mjs从而保证缩放区间不会出现最小大于最大的倒挂状态。实例缩放级别与边界的关系// 基础设置放大到 2 倍 cy.zoom(2); // 0 在有效范围之外其最接近的合法级别即最小缩放级别 // 因此等同于 cy.zoom( cy.minZoom() ) cy.zoom(0); // Infinity 也在有效范围之外其最接近的合法级别即最大缩放级别 // 因此等同于 cy.zoom( cy.maxZoom() ) cy.zoom(1/0);三、围绕指定点缩放options对象详解当缩放的目标不是整体放大/缩小而是以画面中的某一点为锚点进行缩放时需要传入一个配置对象。文档给出了完整的选项定义共支持两种锚点表达方式。3.1 以渲染坐标屏幕坐标为锚点renderedPosition表示渲染坐标即元素在屏幕上显示的位置以像素为单位已包含当前 zoom 与 pan 的影响cy.zoom({ level: 2.0, // 目标缩放级别 renderedPosition: { x: 100, y: 100 } // 屏幕上的锚点 });3.2 以模型坐标图数据坐标为锚点position表示模型坐标即图数据本身的逻辑坐标不随 zoom/pan 变化例如某个节点的position()返回值cy.zoom({ level: 2.0, // 目标缩放级别 position: { x: 0, y: 0 } // 图数据坐标系的锚点 });3.3 两条关键约束只能二选一文档明确指出你可以围绕某个位置或某个渲染位置缩放但不能同时指定两者You can zoom about a position or a rendered position but not both。在实际实现中getZoomedViewport()优先处理position其次才处理renderedPositionsrc/core/viewport.mjsif( params.position ! null ){ pos math.modelToRenderedPosition( params.position, currentZoom, currentPan ); } else if( params.renderedPosition ! null ){ pos params.renderedPosition; }position会被换算成渲染坐标模型坐标通过 src/math.mjs 中的投影公式转换export const modelToRenderedPosition ( p, zoom, pan ) ({ x: p.x * zoom pan.x, y: p.y * zoom pan.y });即渲染坐标 模型坐标 × 当前缩放 当前平移。这解释了为什么两种锚点最终走的是同一条计算路径。3.4 锚点缩放的底层数学原理拿到锚点的渲染坐标pos后getZoomedViewport()会同时重新计算 zoom 与 pan以保证缩放前后锚点始终钉在屏幕上的同一位置src/core/viewport.mjslet pan2 { x: -zoom2 / zoom1 * (pos.x - pan1.x) pos.x, y: -zoom2 / zoom1 * (pos.y - pan1.y) pos.y };其直觉理解是以旧缩放zoom1、旧平移pan1求出锚点在模型坐标系下的位置再以新缩放zoom2反推需要的新平移pan2使得该模型点在屏幕上的渲染位置仍为pos。因此锚点缩放本质上是一个缩放 平移的组合变换这也是方法内部会同时触发zoom与pan事件this.emit( zoom ( vp.panned ? pan : ) viewport )的原因。另外注意一个细节当传入锚点pos ! null而实例的panningEnabled为false时方法会直接bail true放弃本次缩放src/core/viewport.mjs因为锚点缩放必然伴随平移平移被禁用时无法正确保持锚点不动。四、实战示例以节点为中心缩放文档中的经典场景——围绕某个节点缩放。做法是把cy.getElementById(j).position()的结果直接作为position传入cy.zoom({ level: 1.5, position: cy.getElementById(j).position() });该示例的完整链路为cy.getElementById(j)通过 id 选择器获取节点元素对应 src/core/index.mjs 中的getElementById实现.position()返回该节点在模型坐标系下的坐标{ x, y }该坐标作为position传入cy.zoom()经过modelToRenderedPosition换算后参与锚点平移计算缩放完成后节点j保持在屏幕原位置不动其余内容围绕它放大 1.5 倍。这一模式非常适用于聚焦到某个目标节点的场景例如点击节点后平滑地让视图以其为中心放大无需关心节点当前在屏幕上的像素位置。五、配套 API 一览缩放边界与视图联动5.1minZoom()/maxZoom()/zoomRange()这三个方法用于查询或修改缩放的有效范围src/core/viewport.mjs// 读取 const min cy.minZoom(); const max cy.maxZoom(); // 单独修改某一侧 cy.minZoom( 0.5 ); cy.maxZoom( 4 ); // 同时修改 cy.zoomRange({ min: 0.5, max: 4 });它们与cy.zoom()的边界裁剪直接联动任何超出该区间的cy.zoom()调用都会被裁剪到最近边界。此外fit()自适应视图内部计算出的 zoom 同样会被裁剪到该区间见 src/core/viewport.mjs动画插值过程中的中间帧也通过bound( _p.minZoom, ..., _p.maxZoom )钳制见 src/core/animation/step.mjs保证任何路径都不会越界。5.2viewport()一次性设置 zoom 与 pan如果希望同时设置缩放与平移可以使用viewport()方法src/core/viewport.mjscy.viewport({ zoom: 2, pan: { x: 100, y: 100 } });注意viewport()与cy.zoom()的边界策略略有不同前者在 zoom 超出minZoom/maxZoom时会判定缩放失败zoomFailed true并默认放弃本次整体操作除非显式传入cancelOnFailedZoom: false而后者是静默裁剪。需要精确保留原有视图状态时viewport()是更合适的原子操作入口。5.3 缩放开关zoomingEnabled()/userZoomingEnabled()如果不想让用户通过鼠标滚轮等交互方式缩放可以关闭缩放能力cy.zoomingEnabled( true ); // 启用默认 cy.zoomingEnabled( false ); // 禁用从源码看zoomingEnabled控制的是程序化与交互的整体缩放能力当其为false时getZoomedViewport()会直接bail即cy.zoom()的设置也会被拒绝而userZoomingEnabled仅限制用户交互滚轮、捏合手势等cy.zoom()的程序化调用仍可生效。这两个开关的实现均在 src/core/viewport.mjs。在图表应用中常见的组合是禁用用户缩放、保留程序化缩放用于实现受控的浏览模式。5.4 相关事件监听缩放状态变化会触发事件可用于联动 UI例如显示当前缩放比例cy.on(zoom, () { console.log(当前缩放级别, cy.zoom()); }); cy.on(viewport, () { // zoom 或 pan 任意变化时触发 });事件的具体触发逻辑可在 src/core/viewport.mjs 的zoom实现中看到仅缩放时触发zoom viewport缩放伴随平移即锚点缩放时触发zoom pan viewport。六、要点总结cy.zoom()无参时读取当前缩放值有参时设置缩放设置过程会对非法值静默忽略、对越界值裁剪到最近边界。缩放级别必须是正数0与Infinity1/0这类越界值分别等价于缩放到最小值与最大值。锚点缩放通过options对象实现level指定目标级别position模型坐标与renderedPosition渲染坐标二选一不可同时使用。锚点缩放的底层是缩放 平移的组合变换其数学公式位于 src/math.mjs 与 src/core/viewport.mjs实现上要求panningEnabled为真。配合minZoom()/maxZoom()/zoomRange()可自定义有效缩放区间viewport()提供 zoom 与 pan 的原子化批量设置zoomingEnabled()控制整体缩放能力。【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址: https://gitcode.com/gh_mirrors/cy/cytoscape.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站