fix(event): fix event x & y, fix tooltip x & y, add capture

This commit is contained in:
Elaine1234 2019-03-21 17:05:12 +08:00
parent 4616fd1c5f
commit c8aa0a5cbb
5 changed files with 106 additions and 12 deletions

View File

@ -55,8 +55,8 @@ module.exports = {
const width = this.width;
const height = this.height;
const container = this.container;
let x = e.x;
let y = e.y;
let x = e.canvasX;
let y = e.canvasY;
const bbox = container.getBoundingClientRect();
if (x > width / 2) {
x -= (bbox.width);

View File

@ -26,6 +26,18 @@ function getItemRoot(shape) {
return shape;
}
const ORIGIN_MATRIX = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ];
const MATRIX_LEN = 9;
function isViewportChanged(matrix) {
for (let i = 0; i < MATRIX_LEN; i++) {
if (matrix[i] !== ORIGIN_MATRIX[i]) {
return true;
}
}
return false;
}
class Event {
constructor(graph) {
this.graph = graph;
@ -57,8 +69,19 @@ class Event {
const pixelRatio = canvas.get('pixelRatio');
const target = e.target;
const eventType = e.type;
e.x /= pixelRatio;
e.y /= pixelRatio;
/**
* (clientX, clientY): 相对于页面的坐标
* (canvasX, canvasY): 相对于 <canvas> 左上角的坐标
* (x, y): 相对于整个画布的坐标, model x, y 是同一维度的
*/
e.canvasX = e.x / pixelRatio;
e.canvasY = e.y / pixelRatio;
let point = { x: e.canvasX, y: e.canvasY };
if (isViewportChanged(graph.get('group').getMatrix())) {
point = graph.getPointByCanvas(e.canvasX, e.canvasY);
}
e.x = point.x;
e.y = point.y;
// 事件currentTarget是graph
e.currentTarget = graph;
if (target === canvas) {

View File

@ -491,6 +491,15 @@ class Item {
this.set('visible', visible);
}
/**
* 是否拾取及出发该元素的交互事件
* @param {Boolean} enable 标识位
*/
enableCapture(enable) {
const group = this.get('group');
group && group.attr('capture', enable);
}
isVisible() {
return this.get('visible');
}

View File

@ -17,7 +17,7 @@ describe('tooltip', () => {
type: 'tooltip'
}, 'default');
const node = graph.addItem('node', { color: '#666', x: 50, y: 50, r: 20, style: { lineWidth: 2, fill: '#666' }, label: 'text' });
graph.emit('node:mouseenter', { x: 52, y: 52, item: node });
graph.emit('node:mouseenter', { canvasX: 52, canvasY: 52, item: node });
const tooltip = div.childNodes[1];
expect(tooltip).not.to.be.null;
const bbox = tooltip.getBoundingClientRect();
@ -29,7 +29,7 @@ describe('tooltip', () => {
expect(style.top).to.equal('64px');
expect(style.visibility).to.equal('visible');
expect(tooltip.innerHTML).to.equal('text');
graph.emit('node:mousemove', { x: 54, y: 54, item: node });
graph.emit('node:mousemove', { canvasX: 54, canvasY: 54, item: node });
expect(style.left).to.equal('66px');
expect(style.top).to.equal('66px');
div.removeChild(tooltip);
@ -42,19 +42,19 @@ describe('tooltip', () => {
const rt = graph.addItem('node', { id: 'rt', color: '#666', x: 400, y: 50, r: 20, style: { lineWidth: 2, fill: '#666' }, label: 'text' });
const lb = graph.addItem('node', { id: 'lb', color: '#666', x: 50, y: 400, r: 20, style: { lineWidth: 2, fill: '#666' }, label: 'text' });
graph.paint();
graph.emit('node:mouseenter', { x: 52, y: 52, item: lt });
graph.emit('node:mouseenter', { canvasX: 52, canvasY: 52, item: lt });
const tooltip = div.childNodes[1];
const style = tooltip.style;
expect(tooltip).not.to.be.null;
expect(style.left).to.equal('64px');
expect(style.top).to.equal('64px');
graph.emit('node:mouseenter', { x: 410, y: 52, item: rt });
graph.emit('node:mouseenter', { canvasX: 410, canvasY: 52, item: rt });
expect(style.left).to.equal('384.203px');
expect(style.top).to.equal('64px');
graph.emit('node:mouseenter', { x: 410, y: 410, item: rb });
graph.emit('node:mouseenter', { canvasX: 410, canvasY: 410, item: rb });
expect(style.left).to.equal('384.203px');
expect(style.top).to.equal('392px');
graph.emit('node:mouseenter', { x: 52, y: 410, item: lb });
graph.emit('node:mouseenter', { canvasX: 52, canvasY: 410, item: lb });
expect(style.left).to.equal('64px');
expect(style.top).to.equal('392px');
graph.removeBehaviors('tooltip', 'default');
@ -70,7 +70,7 @@ describe('tooltip', () => {
return 'custom label';
}
}], 'default');
graph.emit('node:mouseenter', { x: 52, y: 52, item: node });
graph.emit('node:mouseenter', { canvasX: 52, canvasY: 52, item: node });
const tooltip = div.childNodes[1];
expect(tooltip.innerHTML).to.equal('custom label');
});

View File

@ -48,7 +48,7 @@ describe('event', () => {
done();
}, 500);
});
// 报错,暂时注释掉
it('g event on shape', () => {
let target = null;
const canvas = graph.get('canvas');
@ -117,6 +117,68 @@ describe('event', () => {
canvas.emit('mousemove', { type: 'mousemove', taregt: canvas });
expect(leave).to.equal(1);
});
it('modified viewport', () => {
let triggered = false;
graph.removeEvent();
graph.on('mousedown', e => {
if (triggered) {
expect(e.canvasX).to.equal(10);
expect(e.canvasY).to.equal(10);
expect(e.x).to.equal(-90);
expect(e.y).to.equal(-90);
} else {
expect(e.canvasX).to.equal(10);
expect(e.canvasY).to.equal(10);
expect(e.x).to.equal(10);
expect(e.y).to.equal(10);
triggered = true;
}
});
graph.on('mouseup', e => {
expect(e.canvasX).to.equal(10);
expect(e.canvasY).to.equal(10);
expect(e.x).to.equal(-80);
expect(e.y).to.equal(-80);
});
const canvas = graph.get('canvas').get('el');
const bbox = canvas.getBoundingClientRect();
Simulate.simulate(canvas, 'mousedown', {
clientY: bbox.top + 10,
clientX: bbox.left + 10
});
graph.translate(100, 100);
Simulate.simulate(canvas, 'mousedown', {
clientY: bbox.top + 10,
clientX: bbox.left + 10
});
graph.zoom(0.5);
Simulate.simulate(canvas, 'mouseup', {
clientY: bbox.top + 10,
clientX: bbox.left + 10
});
});
it('item capture', () => {
graph.removeEvent();
const node = graph.addItem('node', { x: 100, y: 100, id: 'node' });
const canvas = graph.get('canvas').get('el');
const bbox = canvas.getBoundingClientRect();
let targetItem;
graph.on('node:click', e => {
targetItem = e.item;
});
Simulate.simulate(canvas, 'mousedown', {
clientY: bbox.top + 100,
clientX: bbox.left + 100
});
expect(targetItem === node);
targetItem = null;
node.enableCapture(false);
Simulate.simulate(canvas, 'mousedown', {
clientY: bbox.top + 100,
clientX: bbox.left + 100
});
expect(targetItem === node).to.be.false;
});
it('event object overlap', () => {
let count = 0;
let triggered = false;