montage.js v0.1.21
montage.js
简介
montage.js 是一个基于 canvas 的绘图库,并且内置了一些鼠标交互功能,在一些需要用到 canvas 的场景下可使用此库来更简单的完成开发,比如拼接图片、简易绘图功能等等
也可以基于此库来开发一些自定义组件,几个常用场景的使用可见 demo 👇
性能测试
大致性能可见下表( Mac Pro, M1, 2020 )
说明: 1. 图案个数指画布中实际存在的图案/连线数量; 1. 响应时长为鼠标 "按下" 至 "抬起" 过程中所花费的响应时间总和; 1. 加载图案上限约为 1.34w 个; 1. 本次测试不包含图片,图片加载/响应时长受图片大小/格式影响,具体性能以实际使用情况为准; 1. 本次测试在设备通电情况下进行,实际使用过程中建议将图案个数控制在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 |
仓库
demo
开发示例,仅供参考
cd example
npm i
npm run serve
快速开始
安装
npm install montage.js
创建第一组图案
- 创建画布
<canvas id="board"></canvas>
- 渲染节点
import Flow from "montage.js";
// 初始化
this.draw = new Flow({
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) })
数据导入及导出
当要将画布中的元素保存下来时,可调用 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 监听某些事件时,请<b>不要直接监听 canvas 元素,推荐监听父级元素</b>,示例如下:
``` html
<div id = 'canvasEvent'>
<canvas id = 'canvas'></canvas>
</div>
document.getElementById('canvasEvent').addEventListener('mousedown', (event) => {
console.log('down', event)
})
需注意:在鼠标按下并选中了某一个元素后,为了防止不必要的重绘,会渲染一层蒙版,所以鼠标抬起时将无法监听 up / move ... 等事件
// 监听鼠标抬起事件建议直接在 document 内添加,为了防止不必要的触发,可以在鼠标按下时做一些处理
// 示例如下:
let isListener = false
document.getElementById('canvasEvent').addEventListener('mousedown', (event) => {
isListener = true
})
document.addEventListener('mouseup', (event) => {
if(isListener){
console.log('up', event)
isListener = false
}
})
节点配置项及方法
画布配置
画布默认为静态画布,只用于展示添加的图案,同时内置了图案的拖拽方法,若需要对画布进行操作,需要将 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 |
方法
名称 | 说明 | 参数类型 | 可选值 | 返回值 | 说明 |
---|---|---|---|---|---|
addNode | 往画布中添加节点 | object | 见节点配置项 | Promise(node) | - |
addConnect | 配置节点间的连接关系 | object | 见连接线配置项 | - | - |
deleteNode | 删除当前画布中选中的节点,或者传入节点ID进行删除 | string | nodeId/null | - | - |
clearable | 清空画布中的所有元素 | - | - | - | - |
setNodeType | 定义图案类型 | ( string, object, object ) | ( rect/circular/line, { 传入自定义属性(可不传)}, { 辅助属性(可不传 } ) | - | 此方法触发后将开启绘制操作,传入图案类型后即可在画布中绘制;自定义属性将添加至图案属性中;辅助属性用于在绘制该图案时改变画布属性(目前仅支持 globalCompositeOperation ) |
setConnectType | 定义连线类型(用于两个图案之间的连线) | string | connectCurve / connectArrowCurveFill | - | - |
getNodes | 获取画布中所有节点信息 | - | - | {nodes: , connects: }nodes: 节点信息;connects: 连接点信息 | - |
getNode | 获取当前所选节点的信息(响应式数据) | string | nodeId | 获取当前所选节点的信息 | - |
reload | 重绘画布 | - | - | - | |
customDrawing | 添加自定义图案start:自定义图案开始的坐标;lineWay:自定义图案的线路点(拐点坐标)fillType:图案类型(实心/空心) | object | start: {x, y}, lineWay:【x,y, x1,y1, ...】, fillType: 'fill/stroke', fillColor: 'color/rgb()/rgba()' | - | * 注意:此方法绘制的图案不具备拖拽/缩放功能,并且不能添加文字 |
节点配置项
对于使用 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 | ----- |
startInfo | 开始节点的信息 | {id: 开始节点的idpos: 开始的位置} |
targetInfo | 目标节点的信息 | {id: 目标节点的idpos: 结束的位置} |
3 months ago
6 months ago
7 months ago
6 months ago
6 months ago
8 months ago
8 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
10 months ago
11 months ago
11 months ago
11 months ago