html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>konva</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}
[class*='ms-'] {
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
<script src="konva.min.js"></script>
<script src="MS.js"></script>
<script>
var ms = new MS({
part: 8,
width: window.innerWidth,
height: window.innerHeight
})
ms.render();
ms.drwaElement({
oneLineShowNam: 4,
data: [{
icon: "dl.svg",
name: 'a1'
}, {
icon: "tw.svg",
name: 'a2'
}, {
icon: "sds.png",
name: 'a3'
}, {
icon: "dl.svg",
name: 'a4'
}, {
icon: "dl.svg",
name: 'a5'
}, {
icon: "dl.svg",
name: 'a6'
}, {
icon: "dl.svg",
name: 'a7'
}, {
icon: "tw.svg",
name: 'a8'
}]
});
</script>
</html>
function MS(options) {
this._init(options)
}
MS.prototype = {
_init(options) {
console.log(options)
this.part = options.part;
this.width = options.width;
this.height = options.height;
this.yStep = 1 / options.part * options.height;
this.xAllwidth = ((options.part - 2) / options.part) * options.width;
},
render() {
//绘制背景层
this.points();
this.stage = new Konva.Stage({
container: 'container',
width: this.width,
height: this.height,
});
this.Bglayer = new Konva.Layer()
var redLine = new Konva.Line({
points: this.pointerArrs,
stroke: 'red',
strokeWidth: 1,
});
redLine.move({
x: 0,
y: 0,
});
this.Bglayer.add(redLine);
this.stage.add(this.Bglayer);
},
drwaElement(options) {
//绘制元素
var xStep = this.xAllwidth / (options.oneLineShowNam + 1);//得到两个元素之间的宽度,使用总宽度除以一行总共显示的个数+1;
console.log(xStep)
var _data = []
for (let i = 0; i < options.data.length; i += options.oneLineShowNam) {
_data.push(options.data.slice(i, i + options.oneLineShowNam))//得到元素展示需要几行,得到一个数组中里面包含几个数组,几个就是行数,数组里面就是一行需要展示的元素
}
console.log(_data)
var _this = this;
for (let i = 0; i < _data.length; i++) {//循环的data[i]是每一行需要展示的数据
console.log(_data[i])
for (let j = 0; j < _data[i].length; j++) {//循环每一行里面的数据,
let img = document.createElement('img')//给每个数据创建一个img对象
img.setAttribute('src', _data[i][j].icon);//为每一个图片添加src地址
img.setAttribute('class', 'ms-' + i + '' + j);//为每个图片添加class类,i表示行数,j表示列
document.body.appendChild(img);//添加加载图片
setTimeout(() => {//添加延迟是因为图片加载是异步的,如果没有延迟,下面获取图片就会取不到,因为图片还没有加载完毕
// 获取图片坐标
//整个线路的最左上角坐标[_this.pointerArrs[0],_this.pointerArrs[1]]
/*
一行数据的x轴坐标是递增的,与‘两个元素之间的宽度’和‘列’成正比,y轴的坐标是与‘行’和‘行和行的距离’成正比
也就是说:行就是i,列就是j
*/
var x = _this.pointerArrs[0] * 1 + xStep * (j + 1) - 25;//减去图片宽度的一半,为了居中
var y = _this.pointerArrs[1] * 1 + _this.yStep * i;
var yoda = new Konva.Image({//设置图片属性
x,
y,
image: document.querySelector('.ms-' + i + j),
width: 50,
height: 50,
draggable: true
});
// add the shape to the layer
_this.Bglayer.add(yoda);
_this.Bglayer.draw();
yoda.on('mousedown', function () {
console.log(_data[i][j])
});
}, 500)
}
}
},
// 获取所有的点坐标
points() {
var arr = [];//存放左边的坐标
var arr1 = [];//存放右边的坐标
for (var i = 0; i < this.part - 1; i++) {//this.part - 1是因为最后是空着的
arr.push([1 / this.part * this.width, (i + 1) / this.part * this.height]);//x轴空了1/8,因为是递增的,所以y就是(i+1)*height
arr1.push([(this.part - 1) / this.part * this.width, (i + 1) / this.part * this.height])//右边的坐标x轴:总共part,左边占了1,所以是part-1;y轴同左边一样道理
}
// 为了将右边的坐标揉进左边
// 循环右边
for (var i = 0; i < arr1.length; i++) {
// 找到绘制线路的点坐标的排序规律
/*
a1 a2
a4 a3
a5 a6
a8 a7
所以a2,a3,a6,a7规律就是
*/
var item = arr1[i * 2];
var itemnext = arr1[i * 2 + 1];
if (i * 2 + 1 <= arr1.length) {
arr.splice(i * 4 + 1, 0, item, itemnext);//从左边坐标数组第一个后边插入,左边就是i*4+1
}
}
this.pointerArrs = arr.toString().split(',').filter(i => { return i !== "" })
}
}