本章分享一下如何使用 Konva 绘制基础图形:矩形、直线、折线,希望大家继续关注和支持哈!
请大家动动小手,给我一个免费的 Star 吧~
大家如果发现了 Bug,欢迎来提 Issue 哟~
矩形
先上效果!
实现方式基本和《前端使用 Konva 实现可视化设计器(21)- 绘制图形(椭圆)》是一致的,主要区别矩形的大小和椭圆形的大小设置方式不一样,特别是矩形无需设置 offset。其它就不再赘述了哈。
直线、折线
先上效果!
简单描述一下上面的交互:
首先,绘制一条直线,淡出画一条直线还是比较简单的,根据记录鼠标按下的位置和鼠标释放的位置,就很容易得到 Konva.Line 的 points 应该设定的值了。
然后,沿用绘制 椭圆形、矩形 的思路,它只有特定的 2 个“调整点”,分别代表 起点 和 终点。
// src/Render/graphs/Line.ts
// 略
/**
* 直线、折线
*/
export class Line extends BaseGraph {
// 略
constructor(render: Types.Render, dropPoint: Konva.Vector2d) {
super(render, dropPoint, {
type: Types.GraphType.Line,
// 定义了 2 个 调整点
anchors: [{
adjustType: 'start' }, {
adjustType: 'end' }].map((o) => ({
adjustType: o.adjustType // 调整点 类型定义
})),
linkAnchors: [
{
x: 0, y: 0, alias: 'start' },
{
x: 0, y: 0, alias: 'end' }
] as Types.AssetInfoPoint[]
})
// 新建 直线、折线
this.line = new Konva.Line({
name: 'graph',
x: 0,
y: 0,
stroke: 'black',
strokeWidth: 1,
hitStrokeWidth: render.toStageValue(5)
})
// 给予 1 像素,防止导出图片 toDataURL 失败
this.group.size({
width: 1,
height: 1
})
// 加入
this.group.add(this.line)
// 鼠标按下位置 作为起点
this.group.position(this.dropPoint)
}
// 实现:拖动进行时
override drawMove(point: Konva.Vector2d): void {
// 鼠标拖动偏移量
const offsetX = point.x - this.dropPoint.x,
offsetY = point.y - this.dropPoint.y
// 起点、终点
const linkPoints = [
[this.line.x(), this.line.y()],
[this.line.x() + offsetX, this.line.y() + offsetY]
]
// 直线、折线 路径
this.line.points(_.flatten(linkPoints))
// 更新 图形 的 调整点 的 锚点位置
Line.updateAnchorShadows(this.group, this.anchorShadows, this.line)
// 更新 图形 的 连接点 的 锚点位置
Line.updateLinkAnchorShadows(this.group, this.linkAnchorShadows, this.line)
// 重绘
this.render.redraw([Draws.GraphDraw.name, Draws.LinkDraw.name, Draws.PreviewDraw.name])
}
// 实现:拖动结束
override drawEnd(): void {
if (this.line.width() <= 1 && this.line.height() <= 1) {
// 加入只点击,无拖动
// 默认大小
const width = Line.size,
height = width
// 起点、终点
const linkPoints = [
[this.line.x(), this.line.y()],
[this.line.x() + width, this.line.y() + height]
]
// 直线、折线 位置大小
this.line.points(_.flatten(linkPoints))
}
// 更新 调整点(拐点)
Line.updateAnchor(this.render, this.group)
// 更新 图形 的 调整点 的 锚点位置
Line.updateAnchorShadows(this.group, this.anchorShadows, this.line)
// 更新 图形 的 连接点 的 锚点位置
Line.updateLinkAnchorShadows(this.group, this.linkAnchorShadows, this.line)
// 对齐线清除
this.render.attractTool.alignLinesClear()
// 更新历史
this.render.updateHistory()
// 重绘
this.render.redraw([Draws.GraphDraw.name, Draws.LinkDraw.name, Draws.PreviewDraw.name])
}
// 略
}
调整点,可以改变 直线、折线 的 起点、终点。
// 略
/**
* 直线、折线
*/
export class Line extends BaseGraph {
// 实现:更新 图形 的 调整点 的 锚点位置
static override updateAnchorShadows(
graph: Konva.Group,
anchorShadows: Konva.Circle[],
shape?: Konva.Line
): void {
if (shape) {
const points = shape.points()
//
for (const shadow of anchorShadows) {
switch (shadow.attrs.adjustType) {
case 'start':
shadow.position({
x: points[0],
y: points[1]
})
break
case 'end':
shadow.position({
x: points[points.length - 2],
y: points[points.length - 1]
})
break
}
}
}
}
// 略
// 实现:生成 调整点
static override createAnchorShapes(
render: Types.Render