npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

montage.js

v0.1.26

Published

一个基于canvas的绘图库

Downloads

148

Readme

montage.js

简介

montage.js 是一个基于 canvas 的绘图库,并且内置了一些鼠标交互功能,在一些需要用到 canvas 的场景下可使用此库来更简单的完成开发,比如拼接图片、简易绘图功能等等

也可以基于此库来开发一些自定义组件,几个常用场景的使用可见 demo 👇

性能测试

大致性能可见下表( Mac Pro, M1, 2020 )

说明:

  1. 图案个数指画布中实际存在的图案/连线数量;
  2. 响应时长为鼠标 "按下" 至 "抬起" 过程中所花费的响应时间总和;
  3. 加载图案上限约为 1.34w 个;
  4. 本次测试不包含图片,图片加载/响应时长受图片大小/格式影响,具体性能以实际使用情况为准;
  5. 本次测试在设备通电情况下进行,实际使用过程中建议将图案个数控制在 6000 以内,否则会对性能产生较为明显的影响;

| 图案个数 | 加载时长 ms | 响应时长 ms | 测试次数 | | -------- | ----------- | ----------- | -------- | | 60 | 2 | 12 ~ 33 | 6 | | 600 | 23 | 72 ~ 103 | 6 | | 6000 | 650 ~ 662 | 545 ~ 603 | 6 | | 12000 | 2248 ~ 2306 | 1000 ~ 1200 | 6 |

仓库

代码仓库:点此跳转 npm:点此跳转

demo

开发示例,仅供参考

cd example
npm i
npm run serve

快速开始

安装

npm install montage.js

创建第一组图案

    1. 创建画布
<canvas id="board"></canvas>
    1. 渲染节点
import Montage from "montage.js";

// 初始化
this.draw = new Montage(
  {
    drag: true, // 注意:如果要当成画布使用(允许缩放/拖拽),则需要开启 drag ,若只需要生成静态图案,则无需开启此选项
    width: 300,
    height: 300,
  },
  document.getElementById("board")
);

// 添加两个节点
this.draw.addNode({
  type: "rect",
  x: 20,
  y: 50,
  width: 80,
  height: 40,
  zoom: true, // 开启缩放
  connect: true, // 开启连线功能
  textInfo: {
    text: "hello world",
  },
});
this.draw.addNode({
  type: "circular",
  x: 200,
  y: 70,
  radiusX: 50,
  radiusY: 30,
  zoom: true,
  connect: true,
  textInfo: {
    text: "hello world",
  },
});

创建节点后会返回被创建的节点信息

注意:只有在调用 addNode 方法时会返回

// 获取创建的节点信息
this.draw
  .addNode({
    type: "rect",
    x: 100,
    y: 100,
    width: 50,
    height: 50,
  })
  .then((node) => {
    console.log("node: ", node);
  });

效果

image

数据导入及导出

当要将画布中的元素保存下来时,可调用 getNodes 方法,该方法会返回画布中的节点信息和连接线信息,导入时需要将这两组数据分别导入

同理,如果需要将两个图形连接起来,也可以定义一组 connects 进行导入(可参考 demo 中的示例)

// 获取节点信息
let { nodes, connects } = this.draw.getNodes();

// 导入
for (let i of nodes) {
  this.draw.addNode(i);
}
for (let i of connects) {
  this.draw.addConnect(i);
}

事件监听及回调

监听

当需要使用 addEventListener 监听某些事件时,请不要直接监听 canvas 元素,推荐监听父级元素,示例如下:

需注意:在鼠标按下并选中了某一个元素后,为了防止不必要的重绘,会渲染一层蒙版,所以鼠标抬起时将无法监听 up / move ... 等事件

<div id="canvasEvent">
  <canvas id="canvas"></canvas>
</div>
document
  .getElementById("canvasEvent")
  .addEventListener("mousemove", (event) => {
    console.log("move", event);
  });

回调

创建画布时,传入第三个参数作为点击画布的回调,当选中图案时,会将选中的图案作为参数传入

import montage from "montage.js";

function checked(node) => {
  console.log('checked node', node)
}

new Montage({
  drag: true,
  width: 300,
  height: 300,
}, document.getElementById('board'), checked);

节点配置项及方法

画布配置

画布默认为静态画布,只用于展示添加的图案,同时内置了图案的拖拽方法,若需要对画布进行操作,需要将 drag 属性设置为 true

注意:此插件不提供画布整体拖拽 / 缩放功能,整体缩放 / 拖拽的实现可运行 example 后查看示例

| 属性 | 说明 | 可选值 | 默认值 | 类型 | | ------------ | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | width | 画布宽度 | - | - | number | | height | 画布高度 | - | - | number | | drag | 是否开启拖拽操作,如果关闭,则无法更新画布内的图案信息 | true/false | false | boolean | | highlight | 鼠标选中高亮设置(高亮效果取决于节点的 fillType 属性) | fillColor:高亮颜色; | { fillColor: 'rgb(0,217,255)', } | object | | defaultStyle | 默认的元素样式(可配置默认颜色/默认线宽,当使用自带的绘制方法去绘制图形时会非常有用) | fillColor:默认颜色;lineWidth:默认宽度(图案 fillType='stroke'时生效); zoomColor: 缩放框颜色;zoomWidth: 缩放框线宽;rotateColor: 旋转框颜色;rotateWidth: 旋转框宽度; connectColor: 连接点颜色 | { fillColor: 'rgba(0, 0, 0, 1)', lineWidth: 1, zoomColor: 'rgb(30, 0, 255)', zoomWidth: 1, rotateColor: 'rgb(30, 0, 255)', rotateWidth: 1,connectColor: 'rgb(19, 154, 251)' } | object |

画布方法

// 初始化
import Montage from "montage.js";
this.ctx = new Montage(
  {
    drag: true,
    width: 300,
    height: 300,
  },
  document.getElementById("board")
);

addNode: 往画布中添加节点

用于往画布中添加一个新的节点,可选值见节点配置项 type 属性

  addNode(prop: object) // 传入要创建的节点属性

注意:这个操作是异步的,返回创建的节点信息

// prop 见节点配置项
// * 如果指定了节点id,那么在下一次加入相同id节点的时候,将覆盖之前创建的节点
this.ctx.addNode(prop).then((node) => {
  console.log("new node", node);
});

getNode: 获取节点信息

获取当前选中的节点信息,或指定 id 的节点信息

注意:这将返回一个响应式对象,修改其属性时会自动修改画布内此节点的属性

  // 传入节点 id,返回这个节点的实例
  let node = this.ctx.getNode(id: string | null);

getNodes: 获取画布中的所有图案

获取画布当前状态下的所有图案

let {
  nodes, // 当前画布中的所有节点
  connects, // 当前画布中所有的连接线的信息集合
} = this.ctx.getNodes();

deleteNode: 删除某一节点

用于删除某一当前选中的节点,或是根据 id 删除节点

  deleteNode(id: string | null)  // 传入节点id
let nodeId = "id";
this.ctx.deleteNode(nodeId);

clearable: 清空画布中所有元素

清空整个画布

this.ctx.clearable();

reload: 重绘画布

用于重绘当前画布上的所有节点(刷新)

this.ctx.reload();

customDrawing: 创建自定义图案

根据图案路径去绘制自定义图案,区别于 addNode 方法,这个方法用于创建一个纯静态展示的复杂图案

注意:纯静态图案,仅用于展示,更新时需要使用 reload 方法更新画布

  // 传入要绘制的图案路径信息,详见 自定义图案配置项
  this.ctx.customDrawing(node: object)
// 这是一个绘制星星的示例
let custom = {
  start: {
    x: 200,
    y: 200,
  },
  lineWay: [
    [230, 100],
    [260, 200],
    [360, 230],
    [260, 260],
    [230, 360],
    [200, 260],
    [100, 230],
    [200, 200],
  ],
  fillType: "stroke",
  fillColor: "rgba(200,200,100,0.8)",
};
this.ctx.customDrawing(custom);

addConnect: 配置两个不同节点间的连线

将两个图案使用连线进行连接,目前只支持曲线和箭头曲线两种连线

  addConnect(connect: object) // 传入节点的连线信息
let connect = {}; // 详见连接线配置项
this.ctx.addConnect(connect);

setNodeType: 设置图案类型

  // 传入图案类型, 自定义图案属性,及辅助属性, 无返回值
  setNodeType(type: string, customProp: object | null, auxProps: object | null)

注意:只有在手动绘制图案时有效

用于设置即将在画布中绘制的图案类型

  // type可选值为 rect: 矩形 / line: 线 / circular: 圆形
  let type = 'rect';
  // 自定义的节点属性,这些属性将被原封不动的保存在节点中
  let customProp = {
    prop1: 'xx',
    prop2: 'xx',
    ...
  };
  // CanvasRenderingContext2D 的一些属性,实际使用频率较低,逐步开放中
  // 目前仅支持 globalCompositeOperation
  let auxProps = {
    globalCompositeOperation: '', // 设置合成的操作类型,详见 https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
  }
  this.ctx.setNodeType(type, customProp, auxProps)

节点配置项

对于使用 getNode 方法获取的节点对象,插件内部使用 Proxy 来响应外界对节点的操作,为了防止频繁更改节点属性带来不必要的刷新,在节点更改完成后需要调用 reload 方法更新画布的展示效果

关于层级的说明:

  • 图层按照层级从小到大排序,当点击位置包含多个图案,则会优先选中层级较大的图案
  • 由于图片是异步加载,为了防止遮挡其他图案,加载时会置底,但是选取时仍会受到层级影响
  • 当前选中的图案会默认置顶,取消选中后恢复原层级

| 属性 | 说明 | 可选值 | 默认值 | 类型 | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------- | | id | 节点 id,每次添加节点时会自动验证是否重复当未填写 id 时,会自动填充,如果需要固定 id,请指定 | - | - | - | | type | 节点类型 | rect: 矩形circular: 圆形line: 线image: 图片 | - | string | | x, y | 起点 x 坐标, 起点 y 坐标 | - | - | number | | width, height | 图案宽高 | - | - | number | | src | 自定义图片路径(type='image'时生效) | - | - | string | | radiusX, radiusY | 自定义圆的半径(type='circular'时生效) | - | - | number | | endX, endY | 终点坐标(type='line'时生效) | - | - | number | | rotate | 旋转弧度,n*Math.PI | - | 0 | number | | level | 层级 | - | 1 | number | | zoom | 允许缩放/旋转(画布允许拖拽时生效) | true/false | false | boolean | | connect | 允许连线(画布允许拖拽时生效) | true/false | false | boolean | | drag | 允许拖拽(画布允许拖拽时生效) | true/false | true | boolean | | unClick | 禁止选中(当无法被选中时,将无法响应式的更新该图案配置,修改配置后需要先调用 deleteNode 方法删除,再调用 addNode 方法重新加载) | true/false | false | boolean | | unLight | 选中后禁止高亮 | true/false | false | boolean | | fillColor | 填充颜色 | color/rgb()/rgba() | rgb(0,0,0) | string | | fillType | 类别 | fill/stroke | stroke | string | | lineWidth | 宽度(fillType = 'stroke'时生效) | - | 1 | number | | textInfo | 文字信息 * 注意:文字换行可使用 /n 来处理,文字缩进可直接使用空格填充 | text: string, font: string(与 css font 属性用法相同), fillType: 'fill/stroke', fillColor: 'color/rgb()/rgba()' | - | object |

连接线配置项

连线用于配置不同图案之间的连接关系,目前仅支持曲线、剪头曲线;

需要注意:

  • 在实际连线过程中,将每一个图形分成了上右下左四个方位,分别对应 1、2、3、4 号位置,节点中的 pos 属性为此位置的序号
  • 需要确保开始节点和目标节点的已经存在并且 id 完全一致,否则会失效

| 属性 | 说明 | 可选值 | | ---------- | -------------------------------------------------- | ------------------------------------------------- | | id | 连接线 id | ----- | | lineWidth | 连接线宽度(注意:如果使用了箭头,不建议设置过大) | number | | fillColor | 连接线颜色 | string | | startInfo | 开始节点的信息 | {id: 开始节点的 idpos: 开始的位置} | | targetInfo | 目标节点的信息 | {id: 目标节点的 idpos: 结束的位置} |

自定义图案配置项

用于创建一个纯静态的自定义图案,由于是根据路径绘制的,所以这个图案可以是一个复杂图形 | 属性 | 说明 | 可选值 | | --- | --- | ----- | | start | 开始位置 | { x, y } | | lineWay | 绘制的路径,将按照路径顺序进行绘制 | [[x, y], [x1, y1], ...] | | fillType | 图案类型 | fill: 实心 / stroke: 空心 | | fillColor | 图案颜色 | rgba() | | lineWidth | 线宽,在 filleType = 'stroke'时生效 | number |