Это относится и к другим браузерам, но основными целями являются Firefox и Chrome.
Я зарегистрировал всех слушателей событий указателя и должен был зарегистрировать мышь вниз и moue up слушателей, чтобы получить изменения состояния кнопки (состояния кнопки всобытия указателя не являются точными или «chorded»)
Но даже если я выполняю event.preventDefault () для всех указателей: события over, enter, down, up, out и, exit (за исключением мыши pointerType длявниз, так как это отключит слушателей mousedown и mouse up) У меня есть остающиеся проблемы:
Мультитач (более одного пальца) будет перенесен и выполнит операцию масштабирования страницы, отрисовывая мультитач в моемприложение бесполезно.
Если на странице есть полосы прокрутки, операция сенсорного панорамирования / прокрутки переходит на одно касание.
Функция protectDefault () неправильно реализована в операционной системе (то есть: окна 10) и указатель вниз над моим элементом также будет генерировать искусственную мышь вниз и синтетически перемещать мышь ккоснулся локации.Я могу игнорировать синтетические события «вниз» и «вверх» с грязным кодом), но он помещает мышь в неожиданные места и предотвращает использование мыши и одновременное касание в качестве отдельных входов при желании.(исправление этого, вероятно, потребует наличия флага для самого элемента DOM, а не для каждого события, поскольку внутренняя очередь событий будет устанавливать задержку между ОС и событиями, отправляемыми браузером - я решил эту проблему в своих собственных приложениях)
Я тестирую с помощью консоли веб-разработчика, чтобы я мог регистрировать состояние - я не знаю, влияет ли это на вещи.
У меня такое же отсутствие управления панорамированием / масштабированием в Chrome.Поведение при наведении / опускании мыши в Chrome и Firefox значительно отличается, что требует отдельного пути к коду.PK
Для любителей кода - обратите внимание, что это интерфейсное устройство "front end" для движка "webasm" (игра или игра в жизнь):)
Цель состоит в том, чтобы получить «чистый необработанный» поток событий для любого указателя, входящего в элемент canvas (который не перехватывается обработчиком другого элемента). Отразите состояние всех кнопок на всех поддерживаемых устройствах с захваченными указателями, пока захват не будет потерян.Кроме того, чтобы иметь возможность использовать мышь и сенсорный экран (и любые другие поддерживаемые устройства) в качестве отдельных устройств, игнорируя все синтетические события и желая отключить все, где одно устройство, которое я слушаю, эмулируется другим устройством, которое я слушаю (поэтому они нене борись).Также, чтобы полностью контролировать, что делается с событиями, пока захват потока событий для указателя не будет потерян.Я хотел бы захватить все касания, которые исчезают после и в то время как «основное» касание отключается на нашем элементе для сенсорного устройства (планшет, панель, экран и т. Д.) И, при желании, позволяет им «проваливаться», если они не используют наш пользовательский интерфейс.
Ниже приведены обработчики событий, которые прикреплены к элементу «canvas».Они ничего не делают, но пересылают данные в приложение webasm.Конечно будет вычищен после того, как все заработает.Это код Firefox.:)
canvas.addEventListener('pointerover', this.onPeOED, false);
canvas.addEventListener('pointerenter', this.onPeOED, false);
canvas.addEventListener('pointerdown', this.onPeOED, false);
canvas.addEventListener('pointermove', this.onPeMove, false);
canvas.addEventListener('pointerup', this.onPeUOCL, false);
canvas.addEventListener('pointerout', this.onPeUOCL, false);
canvas.addEventListener('pointercancel', this.onPeUOCL, false);
canvas.addEventListener('pointerleave', this.onPeUOCL, false);
canvas.addEventListener('mousedown', this.onMouseDown, false);
canvas.addEventListener('mouseup', this.onMouseUp, false);
onPeOED: (function(e) {
var handled = 0;
var code = e.type.charCodeAt(7);
var target = e.currentTarget;
var posX = e.clientX;
var posY = e.clientY;
var flags = (1 << (9 + 16)); // fPointerInside
if(posX < 0 || posY < 0 || posX >= target.width || posY >= target.height) {
flags = 0;
}
// o == over, e == enter, d == down,
if(code == 100) { // 100 == 'd'
flags |= (1 << (10 + 16)); // in contact << 16
}
target._mousePointerId_ = -1;
switch(e.pointerType) {
case 'mouse':
target._mousePointerId_ = e.pointerId;
if(code == 100) { // 100 == 'd' handled by onMouseDown
target.setPointerCapture(e.pointerId);
return;
}
flags |= 0x0100; // UID_MOUSE << 8
break;
case 'pen':
flags |= 0x0200; // UID_STYLUS << 8
break;
case 'touch':
flags |= 0x0300; // UID_FINGER << 8
break;
default:
Module.print("unknown UID");
break;
}
if(code == 100) { // 100 == 'd'
target.setPointerCapture(e.pointerId);
}
// Module.print("ON uid " + e.pointerType + " " + e.type + " buttons " + e.which + " inside " + ((flags & (1 << (9 + 16))) != 0));
if(e.buttons != 0) {
flags |= (e.buttons << 16) | (1 << (10 + 16)); // fPointerInContact
}
handled = ccall('onPointerFlagsOn', 'number', EngineConnector.number_11_Sig,
// target type|flags time id screenX screenY pageX pageY targetX targetY pressure
[ target._CPPHandle_,
(code | flags),
e.timeStamp,
e.pointerId,
e.screenX,
e.screenY,
e.pageX,
e.pageY,
posX,
posY,
e.pressure
]);
e.preventDefault();
}),
onMouseDown: (function(e) {
var target = e.currentTarget;
var posX = e.clientX;
var posY = e.clientY;
// Module.print("mouse ME down " + target._mousePointerId_);
if(target._mousePointerId_ < 0 || posX < 0 || posY < 0 || posX >= target.width || posY >= target.height) {
Module.print("mouse ignored");
e.preventDefault();
return; // ignore downs while outide element
}
var wentDown = (e.buttons & (~(target._mouseButtons_)));
target._mouseButtons_ = e.buttons;
// Module.print("mouse down " + e.buttons + " went down " + wentDown);
handled = ccall('onPointerFlagsOn', 'number', EngineConnector.number_11_Sig,
// target type time id screenX screenY pageX pageY targetX targetY pressure
[ target._CPPHandle_,
// 'd' UID_MOUSE fPointerInside fPointerInContact
(100 | 0x0100 | (1 << (9 + 16)) | (1 << (10 + 16)) | (wentDown << 16)),
e.timeStamp,
e.pointerId,
e.screenX,
e.screenY,
e.pageX,
e.pageY,
posX,
posY,
e.pressure
]);
// e.preventDefault();
}),
fireButtonUp: (function(e, buttons) {
// Module.print("ME fire up true " + buttons );
var ptrId = e.currentTarget._mousePointerId_;
if(ptrId < 0) {
return;
}
ccall('onPointerFlagsOff', 'number', EngineConnector.number_11_Sig,
// target type time id screenX screenY pageX pageY targetX targetY pressure
[e.currentTarget._CPPHandle_,
(117 | 0x0100 | (buttons << 16)), // 117 == 'u' == 'up', 1 == UID_MOUSE
e.timeStamp,
ptrId,
e.screenX,
e.screenY,
e.pageX,
e.pageY,
e.clientX,
e.clientY,
0,
]);
}),
// up/leave
onMouseUp: (function(e) {
var target = e.currentTarget;
var posX = e.clientX;
var posY = e.clientY;
if(posX < 0 || posY < 0 || posX >= target.width || posY >= target.height) {
// we have to kill ALL the buttons
EngineConnector.fireButtonUp(e,target._mouseButtons_ | (1 << 10));
target._mouseButtons_ = 0;
} else {
var released = (target._mouseButtons_ & (~e.buttons)); // will leave the one we released
target._mouseButtons_ = e.buttons;
if(e.buttons == 0) {
released |= (1 << 10); // fPointerInContact
}
EngineConnector.fireButtonUp(e,(released | (1 << 9)));
}
e.preventDefault();
}),
onPeMove: (function(e) {
var target = e.currentTarget;
var posX = e.clientX;
var posY = e.clientY;
var flags = (1 << 9);
if(posX < 0 || posY < 0 || posX >= target.width || posY >= target.height) {
flags = 0;
}
var pType = e.pointerType.charCodeAt(0);
if(pType == 109) { // 'm' == 109
// MOUSE
if(target._mousePointerId_ < 0) {
e.preventDefault();
return;
}
} else {
Module.print("move !!!");
}
flags |= pType; // 'm', 'p', 't'
handled = ccall('onPointerMove', 'number', EngineConnector.number_11_Sig,
// target flags time id screenX screenY pageX pageY targetX targetY pressure
[ target._CPPHandle_,
flags,
e.timeStamp,
e.pointerId,
e.screenX,
e.screenY,
e.pageX,
e.pageY,
posX,
posY,
e.pressure
]);
}),
onPeUOCL: (function(e) {
var code = e.type.charCodeAt(7);
var target = e.currentTarget;
target._poinsePointerId_ = -1;
switch(e.pointerType) {
case 'mouse':
target._poinsePointerId_ = e.pointerId;
if(code == 117) { // 117 == 'u' mouseup handled by mouse event handler
return;
}
code |= 0x0100; // UID_MOUSE << 8
// let leave and cancel get reported
break;
case 'pen':
code |= 0x0200; // UID_STYLUS << 8
if(code == 117) {
code |= ((1 << 16) << e.which);
}
break;
case 'touch':
code |= 0x0300; // UID_FINGER << 8
if(code == 117) {
code |= ((1 << 16) << e.which);
}
break;
default:
Module.print("unknown UID");
break;
}
var posX = e.clientX;
var posY = e.clientY;
if(posX >= 0 && posY >= 0 || posX < target.width || posY < target.height) {
code |= (1 << (9 + 16));
}
// Module.print("off uid " + e.pointerType + " " + e.type + " buttons " + e.which + " inside " + ((code & (1 << (9 + 16))) != 0));
var handled = 0;
handled = ccall('onPointerFlagsOff', 'number', EngineConnector.number_11_Sig,
// target type time id screenX screenY pageX pageY targetX targetY pressure
[e.currentTarget._CPPHandle_,
code,
e.timeStamp,
e.pointerId,
e.screenX,
e.screenY,
e.pageX,
e.pageY,
posX,
posY,
e.pressure,
]);
e.preventDefault();
}),
Цитата от Меня, когда я работал над тем, чтобы заставить Microsoft создавать DirectX почти 30 лет назад - это снова Дежа Воус:)
«Чтобы любая система была по-настоящему гибкой, необходимо иметь возможность внедрить эту систему с нуля с помощью предоставляемых ею средств».