Skip to content

Commit c767ea4

Browse files
authored
Emscripten mouse / touch event improvement (#7342)
#changelog #emscripten
1 parent d678413 commit c767ea4

File tree

1 file changed

+69
-57
lines changed

1 file changed

+69
-57
lines changed

addons/ofxEmscripten/src/ofxAppEmscriptenWindow.cpp

Lines changed: 69 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -47,29 +47,29 @@ void ofxAppEmscriptenWindow::setup(const ofGLESWindowSettings & settings){
4747
_renderer = make_shared<ofGLProgrammableRenderer>(this);
4848
((ofGLProgrammableRenderer*)_renderer.get())->setup(2,0);
4949

50-
emscripten_set_keydown_callback("#canvas",this,1,&keydown_cb);
51-
emscripten_set_keyup_callback("#canvas",this,1,&keyup_cb);
50+
emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&keydown_cb);
51+
emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&keyup_cb);
5252

53-
emscripten_set_mousedown_callback("#canvas",this,1,&mousedown_cb);
54-
emscripten_set_mouseup_callback("#canvas",this,1,&mouseup_cb);
55-
emscripten_set_mousemove_callback("#canvas",this,1,&mousemoved_cb);
56-
emscripten_set_mouseenter_callback("#canvas",this,1,&mouseenter_cb);
57-
emscripten_set_mouseleave_callback("#canvas",this,1,&mouseleave_cb);
58-
59-
emscripten_set_touchstart_callback("#canvas",this,1,&touch_cb);
60-
emscripten_set_touchend_callback("#canvas",this,1,&touch_cb);
61-
emscripten_set_touchmove_callback("#canvas",this,1,&touch_cb);
62-
emscripten_set_touchcancel_callback("#canvas",this,1,&touch_cb);
53+
emscripten_set_mousedown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&mousedown_cb);
54+
emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&mouseup_cb);
55+
emscripten_set_mousemove_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&mousemoved_cb);
56+
emscripten_set_mouseenter_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&mouseenter_cb);
57+
emscripten_set_mouseleave_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&mouseleave_cb);
58+
59+
emscripten_set_touchstart_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&touch_cb);
60+
emscripten_set_touchend_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&touch_cb);
61+
emscripten_set_touchmove_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&touch_cb);
62+
emscripten_set_touchcancel_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&touch_cb);
6363

64-
emscripten_set_wheel_callback("#canvas",this,1,&mousescrolled_cb);
64+
emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,1,&mousescrolled_cb);
6565
}
6666

6767
void ofxAppEmscriptenWindow::loop(){
6868

6969
instance->events().notifySetup();
7070

7171
// Emulate loop via callbacks
72-
emscripten_set_main_loop( display_cb, -1, 1);
72+
emscripten_set_main_loop(display_cb, -1, 1);
7373
}
7474

7575
void ofxAppEmscriptenWindow::update(){
@@ -279,71 +279,84 @@ int ofxAppEmscriptenWindow::keyup_cb(int eventType, const EmscriptenKeyboardEven
279279
}
280280

281281
int ofxAppEmscriptenWindow::mousedown_cb(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData){
282-
int canvas_width, canvas_height;
283-
emscripten_get_canvas_element_size("#canvas", &canvas_width, &canvas_height);
284-
double css_width, css_height;
285-
emscripten_get_element_css_size("#canvas", &css_width, &css_height);
286-
instance->events().notifyMousePressed(mouseEvent->targetX * (canvas_width / css_width), mouseEvent->targetY * (canvas_height / css_height), mouseEvent->button);
282+
float mouseX = mouseEvent->targetX - EM_ASM_INT(return canvas.getBoundingClientRect().left);
283+
float mouseY = mouseEvent->targetY - EM_ASM_INT(return canvas.getBoundingClientRect().top);
284+
int canvasWidth, canvasHeight;
285+
emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight);
286+
double cssWidth, cssHeight;
287+
emscripten_get_element_css_size("#canvas", &cssWidth, &cssHeight);
288+
if(mouseX * canvasWidth / cssWidth >= 0 && mouseX * canvasWidth / cssWidth < canvasWidth && mouseY * canvasHeight / cssHeight >= 0 && mouseY * canvasHeight / cssHeight < canvasHeight){
289+
instance->events().notifyMousePressed(mouseX * canvasWidth / cssWidth, mouseY * canvasHeight / cssHeight, mouseEvent->button);
290+
}
287291
return 0;
288292
}
289293

290294
int ofxAppEmscriptenWindow::mouseup_cb(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData){
291-
int canvas_width, canvas_height;
292-
emscripten_get_canvas_element_size("#canvas", &canvas_width, &canvas_height);
293-
double css_width, css_height;
294-
emscripten_get_element_css_size("#canvas", &css_width, &css_height);
295-
instance->events().notifyMouseReleased(mouseEvent->targetX * (canvas_width / css_width), mouseEvent->targetY * (canvas_height / css_height), mouseEvent->button);
295+
float mouseX = mouseEvent->targetX - EM_ASM_INT(return canvas.getBoundingClientRect().left);
296+
float mouseY = mouseEvent->targetY - EM_ASM_INT(return canvas.getBoundingClientRect().top);
297+
int canvasWidth, canvasHeight;
298+
emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight);
299+
double cssWidth, cssHeight;
300+
emscripten_get_element_css_size("#canvas", &cssWidth, &cssHeight);
301+
if(ofGetMousePressed()){
302+
instance->events().notifyMouseReleased(mouseX * canvasWidth / cssWidth, mouseY * canvasHeight / cssHeight, mouseEvent->button);
303+
}
296304
return 0;
297305
}
298306

299307
int ofxAppEmscriptenWindow::mousemoved_cb(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData){
300-
int canvas_width, canvas_height;
301-
emscripten_get_canvas_element_size("#canvas", &canvas_width, &canvas_height);
302-
double css_width, css_height;
303-
emscripten_get_element_css_size("#canvas", &css_width, &css_height);
304-
if (ofGetMousePressed(OF_MOUSE_BUTTON_LEFT)){
305-
instance->events().notifyMouseDragged(mouseEvent->targetX * (canvas_width / css_width), mouseEvent->targetY * (canvas_height / css_height), 0);
306-
}else if (ofGetMousePressed(OF_MOUSE_BUTTON_MIDDLE)){
307-
instance->events().notifyMouseDragged(mouseEvent->targetX * (canvas_width / css_width), mouseEvent->targetY * (canvas_height / css_height), 1);
308-
}else if (ofGetMousePressed(OF_MOUSE_BUTTON_RIGHT)){
309-
instance->events().notifyMouseDragged(mouseEvent->targetX * (canvas_width / css_width), mouseEvent->targetY * (canvas_height / css_height), 2);
310-
}else{
311-
instance->events().notifyMouseMoved(mouseEvent->targetX * (canvas_width / css_width), mouseEvent->targetY * (canvas_height / css_height));
308+
float mouseX = mouseEvent->targetX - EM_ASM_INT(return canvas.getBoundingClientRect().left);
309+
float mouseY = mouseEvent->targetY - EM_ASM_INT(return canvas.getBoundingClientRect().top);
310+
int canvasWidth, canvasHeight;
311+
emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight);
312+
double cssWidth, cssHeight;
313+
emscripten_get_element_css_size("#canvas", &cssWidth, &cssHeight);
314+
if(ofGetMousePressed(OF_MOUSE_BUTTON_LEFT)){
315+
instance->events().notifyMouseDragged(mouseX * canvasWidth / cssWidth, mouseY * canvasHeight / cssHeight, 0);
316+
}else if(ofGetMousePressed(OF_MOUSE_BUTTON_MIDDLE)){
317+
instance->events().notifyMouseDragged(mouseX * canvasWidth / cssWidth, mouseY * canvasHeight / cssHeight, 1);
318+
}else if(ofGetMousePressed(OF_MOUSE_BUTTON_RIGHT)){
319+
instance->events().notifyMouseDragged(mouseX * canvasWidth / cssWidth, mouseY * canvasHeight / cssHeight, 2);
320+
}else if(mouseX * canvasWidth / cssWidth >= 0 && mouseX * canvasWidth / cssWidth < canvasWidth && mouseY * canvasHeight / cssHeight >= 0 && mouseY * canvasHeight / cssHeight < canvasHeight){
321+
instance->events().notifyMouseMoved(mouseX * canvasWidth / cssWidth, mouseY * canvasHeight / cssHeight);
312322
}
313323
return 0;
314324
}
315325

316326
int ofxAppEmscriptenWindow::mousescrolled_cb(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData){
317-
instance->events().notifyMouseScrolled(ofGetMouseX(), ofGetMouseY(), wheelEvent->deltaX, wheelEvent->deltaY / 100);
327+
instance->events().notifyMouseScrolled(ofGetMouseX(), ofGetMouseY(), wheelEvent->deltaX / 100, wheelEvent->deltaY / 100);
318328
return 0;
319329
}
320330

321331
int ofxAppEmscriptenWindow::mouseenter_cb(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData){
322-
int canvas_width, canvas_height;
323-
emscripten_get_canvas_element_size("#canvas", &canvas_width, &canvas_height);
324-
double css_width, css_height;
325-
emscripten_get_element_css_size("#canvas", &css_width, &css_height);
326-
instance->events().notifyMouseEntered(mouseEvent->targetX * (canvas_width / css_width), mouseEvent->targetY * (canvas_height / css_height));
327-
if(mouseEvent->buttons == 0){
328-
instance->events().notifyMouseReleased(mouseEvent->targetX * (canvas_width / css_width), mouseEvent->targetY * (canvas_height / css_height), mouseEvent->button);
329-
}
332+
float mouseX = mouseEvent->targetX - EM_ASM_INT(return canvas.getBoundingClientRect().left);
333+
float mouseY = mouseEvent->targetY - EM_ASM_INT(return canvas.getBoundingClientRect().top);
334+
int canvasWidth, canvasHeight;
335+
emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight);
336+
double cssWidth, cssHeight;
337+
emscripten_get_element_css_size("#canvas", &cssWidth, &cssHeight);
338+
instance->events().notifyMouseEntered(mouseX * canvasWidth / cssWidth, mouseY * canvasHeight / cssHeight);
330339
return 0;
331340
}
332341

333342
int ofxAppEmscriptenWindow::mouseleave_cb(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData){
334-
int canvas_width, canvas_height;
335-
emscripten_get_canvas_element_size("#canvas", &canvas_width, &canvas_height);
336-
double css_width, css_height;
337-
emscripten_get_element_css_size("#canvas", &css_width, &css_height);
338-
instance->events().notifyMouseExited(mouseEvent->targetX * (canvas_width / css_width), mouseEvent->targetY * (canvas_height / css_height));
343+
float mouseX = mouseEvent->targetX - EM_ASM_INT(return canvas.getBoundingClientRect().left);
344+
float mouseY = mouseEvent->targetY - EM_ASM_INT(return canvas.getBoundingClientRect().top);
345+
int canvasWidth, canvasHeight;
346+
emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight);
347+
double cssWidth, cssHeight;
348+
emscripten_get_element_css_size("#canvas", &cssWidth, &cssHeight);
349+
instance->events().notifyMouseExited(mouseX * canvasWidth / cssWidth, mouseY * canvasHeight / cssHeight);
339350
return 0;
340351
}
341352

342353
int ofxAppEmscriptenWindow::touch_cb(int eventType, const EmscriptenTouchEvent* e, void* userData) {
343-
int canvas_width, canvas_height;
344-
emscripten_get_canvas_element_size("#canvas", &canvas_width, &canvas_height);
345-
double css_width, css_height;
346-
emscripten_get_element_css_size("#canvas", &css_width, &css_height);
354+
float boundingX = EM_ASM_INT(return canvas.getBoundingClientRect().left);
355+
float boundingY = EM_ASM_INT(return canvas.getBoundingClientRect().top);
356+
int canvasWidth, canvasHeight;
357+
emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight);
358+
double cssWidth, cssHeight;
359+
emscripten_get_element_css_size("#canvas", &cssWidth, &cssHeight);
347360
ofTouchEventArgs::Type touchArgsType;
348361
switch (eventType) {
349362
case EMSCRIPTEN_EVENT_TOUCHSTART:
@@ -366,8 +379,8 @@ int ofxAppEmscriptenWindow::touch_cb(int eventType, const EmscriptenTouchEvent*
366379
ofTouchEventArgs touchArgs;
367380
touchArgs.type = touchArgsType;
368381
touchArgs.id = i;
369-
touchArgs.x = std::ceil(e->touches[i].targetX * (canvas_width / css_width));
370-
touchArgs.y = std::ceil(e->touches[i].targetY* (canvas_height / css_height));
382+
touchArgs.x = (e->touches[i].targetX - boundingX) * canvasWidth / cssWidth;
383+
touchArgs.y = (e->touches[i].targetY - boundingY) * canvasHeight / cssHeight;
371384
instance->events().notifyTouchEvent(touchArgs);
372385
}
373386
return 0;
@@ -466,4 +479,3 @@ void ofxAppEmscriptenWindow::startRender(){
466479
void ofxAppEmscriptenWindow::finishRender(){
467480
renderer()->finishRender();
468481
}
469-

0 commit comments

Comments
 (0)