AnyGraph示例:采用“取色法”实现拾取功能
本示例演示:使用取色法实现几何对象的拾取功能。
实现要点:
1、初始化图形对象时增加 hitGetColor=true 选项
2、在图形对象中增加mouseMove事件;
3、从快照画布中获取鼠标位置的颜色值,并从缓存的viewGeomList清单中获取几何对象;
4、下图的右侧画布为功能演示用,在应用环境中可不显示该画布;
xxxxxxxxxx
<div id="graphWrapper" data-type="graph" style="display:inline-block; width:500px; height:500px; border:solid 1px #CCC;"></div><div id="graphColor" data-type="graph" style="position:absolute; display:inline-block; width:500px; height:500px; border:solid 1px #CCC; background-image: url('../images/transparent.png');"></div>
xxxxxxxxxx
import {
Graph, Layer, VectorSource, BgUtil, Color, MathUtil, Collide, circle2LineRing, getStarLineRing,
GGeometryType, Rect, Point, Circle, Ellipse, Text, Polyline, Polygon, EventType
} from "../../src/index.js";
// graph对象
let graph = new Graph({
"target": "graphWrapper",
"hitGetColor": true
});
// 网格水印层
let bgLayer = BgUtil.generateGrid(Object.assign({ "interval": 10, "graph": graph }, graph.getSize()));
bgLayer.getSource().add(new Text({
"text": "按点拾取(取色法)Demo",
"x": graph.getSize().width / 2,
"y": graph.getSize().height / 2,
"vectorSize": false,
"style": { "fillColor": "#D0D0D0", "fontSize": 30, "fontName": "黑体", "textAlign": "center", "textBaseline": "middle" }
}));
// 新建绘图图层
let layer = graph.addLayer();
// 浮动层
let overLayer = graph.addOverLayer();
let lastPosition = [0, 0];
// pageload
$(document).ready(function () {
let colorCanvas = graph.getRenderer().getHitImage();
$("#graphColor").append(colorCanvas);
// 鼠标移动事件
graph.getRenderObject().on('mousemove', function (e) {
let point = [e.offsetX, e.offsetY];
let coord = graph.getCoordinateFromPixel(point, true);
// 清空浮动层数据
overLayer.getSource().clearData();
// 碰撞检测
_collideCheck(point);
// 鼠标位置点
overLayer.getSource().add(new Point({
"x": coord[0],
"y": coord[1],
"size": -5,
"style": { "fillColor": "blue", "fillStyle": 1, "color": "none" }
}));
lastPosition = [point[0], point[1]];
});
// 取色法进行碰撞检测
function _collideCheck(coord) {
// 显示颜色值
let hitColor = graph.getRenderer().getColor(coord);
if (hitColor) {
if (graph.viewGeomList.has(hitColor)) {
let geom = graph.viewGeomList.get(hitColor).clone();
geom.setStyle({ "fillColor": "#FF2020", "color": "#FF2020", "lineWidth": 4 });
overLayer.getSource().add(geom);
return true;
}
}
return false;
}
// 在颜色Canvas上绘制圆点, 非演示环境不需要该段代码
let tmpCanvas = document.createElement("canvas");
$("#graphColor").append(tmpCanvas)
tmpCanvas.width = colorCanvas.width;
tmpCanvas.height = colorCanvas.height;
tmpCanvas.style.position = "absolute";
tmpCanvas.style.top = 0;
tmpCanvas.style.left = 0;
let ctxColor = tmpCanvas.getContext('2d');
graph.on(EventType.RenderAfter, function (args) {
ctxColor.clearRect(0, 0, ctxColor.canvas.width, ctxColor.canvas.height);
// 绘制圆点
ctxColor.beginPath();
ctxColor.arc(lastPosition[0], lastPosition[1], 3, 0, 2 * Math.PI);
ctxColor.fillStyle = "blue";
ctxColor.fill();
});
// 复选框状态事件:清空或随机生成对象
$("#chkPoint").on("change", function () {
if ($(this).prop("checked")) {
for (let i = 0; i < MathUtil.getRandomNum(6, 10); i++) {
layer.getSource().add(new Point({
"x": MathUtil.getRandomNum(50, 450),
"y": MathUtil.getRandomNum(50, 450),
"size": MathUtil.getRandomNum(10, 20),
"style": { "fillColor": "#FFDFDF", "fillStyle": 1, "lineWidth": 1, "color": "#FFA5E8" }
}));
}
} else {
layer.getSource().clearTypeData(GGeometryType.POINT);
}
graph.render();
});
// 复选框状态事件:清空或随机生成对象
$("#chkRect").on("change", function () {
if ($(this).prop("checked")) {
for (let i = 0; i < MathUtil.getRandomNum(3, 5); i++) {
layer.getSource().add(new Rect({
"x": MathUtil.getRandomNum(50, 450),
"y": MathUtil.getRandomNum(50, 450),
"width": MathUtil.getRandomNum(40, 70),
"height": MathUtil.getRandomNum(20, 40),
"style": { "fillColor": "#FFDFDF", "fillStyle": 1, "lineWidth": 1, "color": "#FFA5E8" }
}));
}
} else {
layer.getSource().clearTypeData(GGeometryType.RECT);
}
graph.render();
});
$("#chkCircle").on("change", function () {
if ($(this).prop("checked")) {
for (let i = 0; i < MathUtil.getRandomNum(3, 5); i++) {
layer.getSource().add(new Circle({
"x": MathUtil.getRandomNum(50, 450),
"y": MathUtil.getRandomNum(50, 450),
"radius": MathUtil.getRandomNum(20, 40),
"style": { "fillColor": "#DFFFBF", "fillStyle": 1, "lineWidth": 1, "color": "#FFA5E8" }
}));
}
} else {
layer.getSource().clearTypeData(GGeometryType.CIRCLE);
}
graph.render();
});
$("#chkText").on("change", function () {
if ($(this).prop("checked")) {
for (let i = 0; i < MathUtil.getRandomNum(3, 5); i++) {
layer.getSource().add(new Text({
"x": MathUtil.getRandomNum(50, 450),
"y": MathUtil.getRandomNum(50, 450),
"rotation": MathUtil.getRandomNum(0, 90),
"text": "碰撞检测文本",
"style": { "fontSize": 24, "fontName": "黑体", "fillColor": "#0000FF", }
}));
}
} else {
layer.getSource().clearTypeData(GGeometryType.TEXT);
}
graph.render();
});
$("#chkEllipse").on("change", function () {
if ($(this).prop("checked")) {
for (let i = 0; i < MathUtil.getRandomNum(2, 4); i++) {
layer.getSource().add(new Ellipse({
"x": MathUtil.getRandomNum(50, 450),
"y": MathUtil.getRandomNum(50, 450),
"radiusX": MathUtil.getRandomNum(20, 40),
"radiusY": MathUtil.getRandomNum(20, 20),
"style": { "fillColor": "#9FFFFF", "fillStyle": 1, "lineWidth": 1, "color": "#FFA5E8" }
}));
}
} else {
layer.getSource().clearTypeData(GGeometryType.ELLIPSE);
}
graph.render();
});
$("#chkPolyline").on("change", function () {
if ($(this).prop("checked")) {
for (let i = 0; i < MathUtil.getRandomNum(3, 5); i++) {
let [x, y] = [MathUtil.getRandomNum(50, 400), MathUtil.getRandomNum(50, 400)];
layer.getSource().add(new Polyline({
"coords": [[x, y], [x + MathUtil.getRandomNum(10, 300), y + MathUtil.getRandomNum(-100, 100)]],
"style": { "lineWidth": 4, "color": "#00957D" }
}));
}
} else {
layer.getSource().clearTypeData(GGeometryType.POLYLINE);
}
graph.render();
});
$("#chkPolygon").on("change", function () {
if ($(this).prop("checked")) {
for (let i = 0; i < MathUtil.getRandomNum(3, 5); i++) {
let center = [MathUtil.getRandomNum(150, 400), MathUtil.getRandomNum(50, 400)];
let sideNum = MathUtil.getRandomNum(3, 8);
let radius = MathUtil.getRandomNum(20, 40);
layer.getSource().add(new Polygon({
"coords": circle2LineRing(center, radius, sideNum),
"style": { "fillColor": "#E5FFF5", "fillStyle": 1, "lineWidth": 1, "color": "#FF9F9F" }
}));
center = [MathUtil.getRandomNum(150, 620), MathUtil.getRandomNum(50, 400)];
layer.getSource().add(new Polygon({
"coords": getStarLineRing(center, radius, null, sideNum >= 6 ? sideNum - 3 : sideNum),
"style": { "fillColor": "#E5FFF5", "fillStyle": 1, "lineWidth": 1, "color": "#FF9F9F" }
}));
}
} else {
layer.getSource().clearTypeData(GGeometryType.POLYGON);
}
graph.render();
});
$("#chkRect").click();
$("#chkPolygon").click();
})