feat: add event

This commit is contained in:
thinkinggis 2020-06-11 16:00:45 +08:00
parent e5fa732002
commit 5ed9b8b5f6
13 changed files with 389 additions and 7 deletions

View File

@ -10,7 +10,12 @@ L7 Layer 接口设计遵循图形语法,所有图层都继承于该基类。
语法示例
```javascript
const layer = new Layer(option).source().color().size().shape().style();
const layer = new Layer(option)
.source()
.color()
.size()
.shape()
.style();
scene.addLayer(layer);
```
@ -78,7 +83,7 @@ layer.source(data, {
transforms: [
{
type: 'map',
callback: function (item) {
callback: function(item) {
const [x, y] = item.coordinates;
item.lat = item.lat * 1;
item.lng = item.lng * 1;

View File

@ -10,7 +10,12 @@ L7 Layer 接口设计遵循图形语法,所有图层都继承于该基类。
语法示例
```javascript
const layer = new Layer(option).source().color().size().shape().style();
const layer = new Layer(option)
.source()
.color()
.size()
.shape()
.style();
scene.addLayer(layer);
```
@ -82,7 +87,7 @@ layer.source(data, {
transforms: [
{
type: 'map',
callback: function (item) {
callback: function(item) {
const [x, y] = item.coordinates;
item.lat = item.lat * 1;
item.lng = item.lng * 1;

View File

@ -0,0 +1,65 @@
import Point from '@mapbox/point-geometry';
import { Map } from '../map';
import { MapMouseEvent, MapTouchEvent, MapWheelEvent } from './events';
export class BlockableMapEventHandler {
private map: Map;
private delayContextMenu: boolean;
private contextMenuEvent: MouseEvent;
constructor(map: Map) {
this.map = map;
}
public reset() {
this.delayContextMenu = false;
delete this.contextMenuEvent;
}
public mousemove(e: MouseEvent) {
// mousemove map events should not be fired when interaction handlers (pan, rotate, etc) are active
this.map.emit(e.type, new MapMouseEvent(e.type, this.map, e));
}
public mousedown() {
this.delayContextMenu = true;
}
public mouseup() {
this.delayContextMenu = false;
if (this.contextMenuEvent) {
this.map.emit(
'contextmenu',
new MapMouseEvent('contextmenu', this.map, this.contextMenuEvent),
);
delete this.contextMenuEvent;
}
}
public contextmenu(e: MouseEvent) {
if (this.delayContextMenu) {
// Mac: contextmenu fired on mousedown; we save it until mouseup for consistency's sake
this.contextMenuEvent = e;
} else {
// Windows: contextmenu fired on mouseup, so fire event now
this.map.emit(new MapMouseEvent(e.type, this.map, e));
}
// prevent browser context menu when necessary
if (this.map.listeners('contextmenu')) {
e.preventDefault();
}
}
public isEnabled() {
return true;
}
public isActive() {
return false;
}
public enable() {
return true;
}
public disable() {
return false;
}
}

View File

@ -0,0 +1,183 @@
// @flow
import Point from '@mapbox/point-geometry';
import DOM from '../utils/dom';
const LEFT_BUTTON = 0;
const RIGHT_BUTTON = 2;
// the values for each button in MouseEvent.buttons
const BUTTONS_FLAGS = {
[LEFT_BUTTON]: 1,
[RIGHT_BUTTON]: 2,
};
function buttonStillPressed(e: MouseEvent, button: number) {
const flag = BUTTONS_FLAGS[button];
return e.buttons === undefined || (e.buttons & flag) !== flag;
}
class MouseHandler {
private enabled: boolean;
private active: boolean;
private lastPoint: Point;
private eventButton: number;
private moved: boolean;
private clickTolerance: number;
constructor(options: { clickTolerance: number }) {
this.reset();
this.clickTolerance = options.clickTolerance || 1;
}
public reset() {
this.active = false;
this.moved = false;
delete this.lastPoint;
delete this.eventButton;
}
public mousedown(e: MouseEvent, point: Point) {
if (this.lastPoint) {
return;
}
const eventButton = DOM.mouseButton(e);
if (!this.correctButton(e, eventButton)) {
return;
}
this.lastPoint = point;
this.eventButton = eventButton;
}
public mousemoveWindow(e: MouseEvent, point: Point) {
const lastPoint = this.lastPoint;
if (!lastPoint) {
return;
}
e.preventDefault();
if (buttonStillPressed(e, this.eventButton)) {
// Some browsers don't fire a `mouseup` when the mouseup occurs outside
// the window or iframe:
// https://github.com/mapbox/mapbox-gl-js/issues/4622
//
// If the button is no longer pressed during this `mousemove` it may have
// been released outside of the window or iframe.
this.reset();
return;
}
if (!this.moved && point.dist(lastPoint) < this.clickTolerance) {
return;
}
this.moved = true;
this.lastPoint = point;
// implemented by child class
return this.move(lastPoint, point);
}
public mouseupWindow(e: MouseEvent) {
if (!this.lastPoint) {
return;
}
const eventButton = DOM.mouseButton(e);
if (eventButton !== this.eventButton) {
return;
}
if (this.moved) {
DOM.suppressClick();
}
this.reset();
}
public enable() {
this.enabled = true;
}
public disable() {
this.enabled = false;
this.reset();
}
public isEnabled() {
return this.enabled;
}
public isActive() {
return this.active;
}
private correctButton(e: MouseEvent, button: number) {
// eslint-disable-line
return false; // implemented by child
}
private move(lastPoint: Point, point: Point) {
// eslint-disable-line
return {}; // implemented by child
}
}
export class MousePanHandler extends MouseHandler {
public mousedown(e: MouseEvent, point: Point) {
super.mousedown(e, point);
if (this.lastPoint) {
this.active = true;
}
}
public _correctButton(e: MouseEvent, button: number) {
return button === LEFT_BUTTON && !e.ctrlKey;
}
public _move(lastPoint: Point, point: Point) {
return {
around: point,
panDelta: point.sub(lastPoint),
};
}
}
export class MouseRotateHandler extends MouseHandler {
public _correctButton(e: MouseEvent, button: number) {
return (button === LEFT_BUTTON && e.ctrlKey) || button === RIGHT_BUTTON;
}
public _move(lastPoint: Point, point: Point) {
const degreesPerPixelMoved = 0.8;
const bearingDelta = (point.x - lastPoint.x) * degreesPerPixelMoved;
if (bearingDelta) {
this.active = true;
return { bearingDelta };
}
}
public contextmenu(e: MouseEvent) {
// prevent browser context menu when necessary; we don't allow it with rotation
// because we can't discern rotation gesture start from contextmenu on Mac
e.preventDefault();
}
}
export class MousePitchHandler extends MouseHandler {
public _correctButton(e: MouseEvent, button: number) {
return (button === LEFT_BUTTON && e.ctrlKey) || button === RIGHT_BUTTON;
}
public _move(lastPoint: Point, point: Point) {
const degreesPerPixelMoved = -0.5;
const pitchDelta = (point.y - lastPoint.y) * degreesPerPixelMoved;
if (pitchDelta) {
this.active = true;
return { pitchDelta };
}
}
public contextmenu(e: MouseEvent) {
// prevent browser context menu when necessary; we don't allow it with rotation
// because we can't discern rotation gesture start from contextmenu on Mac
e.preventDefault();
}
}

View File

@ -0,0 +1,106 @@
import { DOM } from '@antv/l7-utils';
import Point from '@mapbox/point-geometry';
import { buttonStillPressed } from './util';
class MouseHandler {
private enabled: boolean;
private active: boolean;
private lastPoint: Point;
private eventButton: number;
private moved: boolean;
private clickTolerance: number;
constructor(options: { clickTolerance: number }) {
this.reset();
this.clickTolerance = options.clickTolerance || 1;
}
public reset() {
this.active = false;
this.moved = false;
delete this.lastPoint;
delete this.eventButton;
}
public mousedown(e: MouseEvent, point: Point) {
if (this.lastPoint) {
return;
}
const eventButton = DOM.mouseButton(e);
if (!this.correctButton(e, eventButton)) {
return;
}
this.lastPoint = point;
this.eventButton = eventButton;
}
public mousemoveWindow(e: MouseEvent, point: Point) {
const lastPoint = this.lastPoint;
if (!lastPoint) {
return;
}
e.preventDefault();
if (buttonStillPressed(e, this.eventButton)) {
// Some browsers don't fire a `mouseup` when the mouseup occurs outside
// the window or iframe:
// https://github.com/mapbox/mapbox-gl-js/issues/4622
//
// If the button is no longer pressed during this `mousemove` it may have
// been released outside of the window or iframe.
this.reset();
return;
}
if (!this.moved && point.dist(lastPoint) < this.clickTolerance) {
return;
}
this.moved = true;
this.lastPoint = point;
// implemented by child class
return this.move(lastPoint, point);
}
public mouseupWindow(e: MouseEvent) {
if (!this.lastPoint) {
return;
}
const eventButton = DOM.mouseButton(e);
if (eventButton !== this.eventButton) {
return;
}
if (this.moved) {
DOM.suppressClick();
}
this.reset();
}
public enable() {
this.enabled = true;
}
public disable() {
this.enabled = false;
this.reset();
}
public isEnabled() {
return this.enabled;
}
public isActive() {
return this.active;
}
private correctButton(e: MouseEvent, button: number) {
// eslint-disable-line
return false; // implemented by child
}
private move(lastPoint: Point, point: Point) {
// eslint-disable-line
return {}; // implemented by child
}
}

View File

@ -0,0 +1,13 @@
export const LEFT_BUTTON = 0;
export const RIGHT_BUTTON = 2;
// the values for each button in MouseEvent.buttons
export const BUTTONS_FLAGS = {
[LEFT_BUTTON]: 1,
[RIGHT_BUTTON]: 2,
};
export function buttonStillPressed(e: MouseEvent, button: number) {
const flag = BUTTONS_FLAGS[button];
return e.buttons === undefined || (e.buttons & flag) !== flag;
}

View File

@ -30,9 +30,14 @@ export default class ZoomComponent extends React.Component {
this.scene = scene;
const layer = new PolygonLayer({});
layer.source(data).color('#fff').shape('name', 'text').size(16).style({
opacity: 1.0,
});
layer
.source(data)
.color('#fff')
.shape('name', 'text')
.size(16)
.style({
opacity: 1.0,
});
scene.addLayer(layer);
const zoomControl = new Zoom({
position: 'bottomright',