Skip to content

Commit 6ea51dc

Browse files
deyihufuzhenn
andauthored
fix Geometry cursor Not working properly (#2149)
* fix Geometry cursor Not working properly * spec * delete isGeometryListening * add pickutil for gllayer pick performance * updates --------- Co-authored-by: Fu Zhen <fuzhen@maptalks.org>
1 parent 19e44b9 commit 6ea51dc

File tree

6 files changed

+166
-25
lines changed

6 files changed

+166
-25
lines changed

src/core/util/pick.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/**
2+
*
3+
* layer pick utils
4+
* can use by PointLayer,LineStringLayer,PolygonLayer,VectorTileLayer,Geo3DTilesLayer,GLTFLayer etc
5+
*
6+
* @returns
7+
*/
8+
import Canvas from '../Canvas';
9+
10+
export function isGLRenderLayer(layer) {
11+
if (!layer) {
12+
return false;
13+
}
14+
const renderer = layer.getRenderer && layer.getRenderer();
15+
return !!(renderer && renderer.gl);
16+
}
17+
18+
export function checkCanvasSize(targetCanvas, sourceCanvas) {
19+
if (!targetCanvas || !sourceCanvas) {
20+
return null;
21+
}
22+
const { width, height, style } = sourceCanvas;
23+
if (targetCanvas.width !== width || targetCanvas.height !== height) {
24+
targetCanvas.width = width;
25+
targetCanvas.height = height;
26+
}
27+
if (targetCanvas.style.width !== style.width || targetCanvas.style.height !== style.height) {
28+
targetCanvas.style.width = style.width;
29+
targetCanvas.style.height = style.height;
30+
}
31+
return targetCanvas;
32+
}
33+
34+
export function clearCanvas(canvas) {
35+
if (!canvas) {
36+
return null;
37+
}
38+
const ctx = Canvas.getCanvas2DContext(canvas);
39+
Canvas.clearRect(ctx, 0, 0, canvas.width, canvas.height);
40+
return ctx;
41+
}
42+
43+
let tempCanvas;
44+
export function layerIsBlankInPoint(layer, containerPoint, tolerance = 1) {
45+
if (!layer || !containerPoint) {
46+
return true;
47+
}
48+
const renderer = layer.getRenderer && layer.getRenderer();
49+
if (!renderer || !renderer.canvas) {
50+
return true;
51+
}
52+
const map = layer.getMap();
53+
if (!map) {
54+
return true;
55+
}
56+
if (!tempCanvas) {
57+
tempCanvas = Canvas.createCanvas(1, 1);
58+
// document.body.appendChild(tempCanvas);
59+
}
60+
tempCanvas = checkCanvasSize(tempCanvas, renderer.canvas);
61+
if (!tempCanvas) {
62+
return true;
63+
}
64+
const ctx = clearCanvas(tempCanvas);
65+
if (!ctx) {
66+
return true;
67+
}
68+
tolerance = Math.max(layer.options.geometryEventTolerance || 1, tolerance);
69+
tolerance = Math.abs(Math.round(tolerance));
70+
tolerance = Math.max(1, tolerance);
71+
const r = map.getDevicePixelRatio();
72+
const { x, y } = containerPoint;
73+
let left = x - tolerance, top = y - tolerance;
74+
left = Math.round(left * r);
75+
top = Math.round(top * r);
76+
left = Math.max(0, left);
77+
top = Math.max(0, top);
78+
const size = tolerance * 2;
79+
let imageData;
80+
try {
81+
ctx.drawImage(renderer.canvas, 0, 0);
82+
imageData = ctx.getImageData(left, top, size, size);
83+
} catch (error) {
84+
console.warn('hit detect failed with tainted canvas, some geometries have external resources in another domain:\n', error);
85+
}
86+
if (!imageData) {
87+
return false;
88+
}
89+
const data = imageData.data;
90+
for (let i = 0, len = data.length; i < len; i += 4) {
91+
const A = data[i + 3];
92+
if (A > 0) {
93+
return false;
94+
}
95+
}
96+
return true;
97+
98+
}

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import * as Util from './core/util';
66
import * as DomUtil from './core/util/dom';
77
import * as StringUtil from './core/util/strings';
88
import * as MapboxUtil from './core/mapbox';
9+
910
import * as MicroTask from './core/MicroTask';
1011
export { Util, DomUtil, StringUtil, MapboxUtil, MicroTask };
12+
1113
export { default as LRUCache } from './core/util/LRUCache';
1214
export { default as Ajax } from './core/Ajax';
1315
export { default as Canvas } from './core/Canvas';

src/layer/OverlayLayer.js

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,26 +56,29 @@ class OverlayLayer extends Layer {
5656
}
5757
}
5858

59-
isGeometryListening(types) {
60-
if (!this._geoList) {
61-
return false;
62-
}
63-
if (!Array.isArray(types)) {
64-
types = [types];
65-
}
66-
for (let i = 0, l = this._geoList.length; i < l; i++) {
67-
const geometry = this._geoList[i];
68-
if (!geometry) {
69-
continue;
70-
}
71-
for (let j = 0; j < types.length; j++) {
72-
if (geometry.listens(types[j])) {
73-
return true;
74-
}
75-
}
76-
}
77-
return false;
78-
}
59+
// isGeometryListening(types) {
60+
// if (!this._geoList) {
61+
// return false;
62+
// }
63+
// if (!Array.isArray(types)) {
64+
// types = [types];
65+
// }
66+
// for (let i = 0, l = this._geoList.length; i < l; i++) {
67+
// const geometry = this._geoList[i];
68+
// if (!geometry) {
69+
// continue;
70+
// }
71+
// if (geometry.options.cursor) {
72+
// return true;
73+
// }
74+
// for (let j = 0; j < types.length; j++) {
75+
// if (geometry.listens(types[j])) {
76+
// return true;
77+
// }
78+
// }
79+
// }
80+
// return false;
81+
// }
7982

8083
/**
8184
* Get a geometry by its id
@@ -712,9 +715,16 @@ class OverlayLayer extends Layer {
712715
}
713716
const geos = this.getGeometries() || [];
714717
for (let i = 0, len = geos.length; i < len; i++) {
718+
const geometry = geos[i];
719+
if (!geometry) {
720+
continue;
721+
}
722+
if (geometry.options.cursor) {
723+
return true;
724+
}
715725
for (let j = 0, len1 = eventTypes.length; j < len1; j++) {
716726
const eventType = eventTypes[j];
717-
const listens = geos[i].listens(eventType);
727+
const listens = geometry.listens(eventType);
718728
if (listens > 0) {
719729
return true;
720730
}

src/map/Map.Topo.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { INTERNAL_LAYER_PREFIX } from '../core/Constants';
22
import { isNil, isString, isArrayHasData, pushIn, isFunction } from '../core/util';
3+
import { isGLRenderLayer, layerIsBlankInPoint } from '../core/util/pick';
34
import Coordinate from '../geo/Coordinate';
45
import Point from '../geo/Point';
56
import Map from './Map';
@@ -102,22 +103,29 @@ Map.include(/** @lends Map.prototype */ {
102103
const coordinate = this.containerPointToCoord(containerPoint);
103104
return this._identify(opts, callback, layer => {
104105
let result;
106+
const containerPoint = opts.containerPoint;
105107
if (isMapGeometryEvent && !isNil(layer.options.geometryEventTolerance)) {
106108
opts.tolerance = opts.tolerance || 0;
107109
opts.tolerance += layer.options.geometryEventTolerance;
108110
}
109-
if (layer.isGeometryListening && isMapGeometryEvent && opts.eventTypes.indexOf('mousemove') >= 0) {
110-
if (!layer.isGeometryListening(opts.eventTypes)) {
111+
//only gllayer,exclude canvas layer
112+
const isGLLayer = isGLRenderLayer(layer);
113+
const isBlank = isGLLayer && layerIsBlankInPoint(layer, containerPoint, opts.tolerance);
114+
if (!isBlank && layer._hasGeoListeners && isMapGeometryEvent && opts.eventTypes.indexOf('mousemove') >= 0) {
115+
if (!layer._hasGeoListeners(opts.eventTypes)) {
111116
return [];
112117
}
113118
}
114-
if (layer.identifyAtPoint) {
119+
if (isBlank) {
120+
result = [];
121+
} else if (layer.identifyAtPoint) {
115122
result = layer.identifyAtPoint(containerPoint, opts);
116123
} else if (coordinate && layer.identify) {
117124
result = layer.identify(coordinate, opts);
118125
} else {
119126
result = [];
120127
}
128+
121129
if (isMapGeometryEvent) {
122130
if (isNil(tolerance)) {
123131
delete opts.tolerance;

src/map/handler/Map.GeometryEvents.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ class MapGeometryEventsHandler extends Handler {
269269
}
270270
return false;
271271
});
272-
map._setPriorityCursor(geometryCursorStyle);
272+
// map._setPriorityCursor(geometryCursorStyle);
273273
if (!layers.length) {
274274
return;
275275
}

test/geometry/event/GeometryEventSpec.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,4 +484,27 @@ describe('Geometry.Events', function () {
484484
});
485485
}, 50);
486486
});
487+
488+
it('#2148 geometry cursor when listens is empty', function (done) {
489+
var circle = new maptalks.Circle(map.getCenter(), 10, { cursor: 'zoom-in' });
490+
circle.addTo(layer);
491+
var domPosition = GET_PAGE_POSITION(container);
492+
var point = map.coordinateToContainerPoint(center).add(domPosition);
493+
494+
happen.mousemove(eventContainer, {
495+
'clientX': point.x,
496+
'clientY': point.y
497+
});
498+
setTimeout(() => {
499+
happen.mousemove(eventContainer, {
500+
'clientX': point.x + 2,
501+
'clientY': point.y + 2
502+
});
503+
504+
setTimeout(() => {
505+
expect(map._priorityCursor).to.be.eql('zoom-in');
506+
done();
507+
}, 100);
508+
}, 16);
509+
});
487510
});

0 commit comments

Comments
 (0)