###### tags: `konva`, `canvas`, `javascript`
# 【自學筆記】konva入門 - 箭頭連接練習
`Konva`是個`HTML5 Canvas JavaScript`的框架,透過`2d context`的擴展實現各種圖形功能,正好可以實現最近工作需求,就來研究看看囉
---
[範例程式](https://codepen.io/niodoshaba-the-flexboxer/pen/jOzPgVL?editors=1011)
### Konva的箭頭連接
因為想做個類似流程圖編輯器的東西,所以研究一下`Konva`的箭頭用法,詳細作法直接看程式吧
```htmlembedded=
<body>
<div id="container"></div>
</body>
```
```javascript=
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height,
});
var layer = new Konva.Layer();
stage.add(layer);
// 產生圖形id及座標(先用三個就好)
function GenerateTargetsData() {
var number = 3;
var result = [];
while (result.length < number) {
result.push({
id: 'target-' + result.length,
x: stage.width() * Math.random(),
y: stage.height() * Math.random(),
});
}
return result;
}
var targets = GenerateTargetsData();
// 產生箭頭
function GenerateConnectorsData() {
var number = 3;
var result = [];
while (result.length < number) {
var from = 'target-' + Math.floor(Math.random() * targets.length);
var to = 'target-' + Math.floor(Math.random() * targets.length);
if (from === to) {
continue;
}
result.push({
id: 'connector-' + result.length,
from: from,
to: to,
});
}
return result;
}
// 取得連接點的座標資料(包含偏移計算)
function GetConnectorPointsData(from, to, from_attrs, to_attrs) {
return [
from.x + from_attrs.width/2,
from.y + from_attrs.height,
to.x + to_attrs.width/2,
to.y ,
];
}
var connectors = GenerateConnectorsData();
// 更新連接點位
function UpdateObjects(){
targets.forEach((target) => {
var node = layer.findOne('#' + target.id);
node.x(target.x);
node.y(target.y);
});
connectors.forEach((connect) => {
var line = layer.findOne('#' + connect.id);
var fromNode = layer.findOne('#' + connect.from);
var toNode = layer.findOne('#' + connect.to);
const points = GetConnectorPointsData(
fromNode.position(),
toNode.position(),
fromNode.attrs,
toNode.attrs,
);
line.points(points);
});
}
// 用前方產生的箭頭資料產生箭頭
connectors.forEach((connect) => {
var line = new Konva.Arrow({
stroke: 'black',
id: connect.id,
fill: 'black',
});
layer.add(line);
});
// 用前方產生的圖形資料產生圖形
targets.forEach((target) => {
var node = new Konva.Rect({
id: target.id,
fill: Konva.Util.getRandomColor(),
width: 100,
height: 75,
draggable: true,
});
layer.add(node);
// 拖動時即時更新位置
node.on('dragmove', () => {
target.x = node.x();
target.y = node.y();
UpdateObjects();
});
});
UpdateObjects();
```
---
*參考資料: https://konvajs.org/docs/*
*新手工程師的筆記,純粹記錄學了些啥東西
如果有前輩高人讀了我的文,文中有任何錯誤再麻煩指教指教*