Skip to content

Commit e6d0c45

Browse files
committed
- added touch events
1 parent 94a2265 commit e6d0c45

2 files changed

Lines changed: 120 additions & 0 deletions

File tree

examples/particle_system.html

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@ <h3>4. Time integration</h3>
213213
this.canvas.addEventListener("mousemove", this.mouseMove.bind(this), false);
214214
this.canvas.addEventListener("mouseup", this.mouseUp.bind(this), false);
215215
this.canvas.addEventListener("wheel", this.wheel.bind(this), false);
216+
// register touch event listeners (mobile / tablet)
217+
// passive:false is required so we can call preventDefault() to suppress scrolling
218+
this.canvas.addEventListener("touchstart", this.touchStart.bind(this), { passive: false });
219+
this.canvas.addEventListener("touchmove", this.touchMove.bind(this), { passive: false });
220+
this.canvas.addEventListener("touchend", this.touchEnd.bind(this), { passive: false });
216221
}
217222

218223
// set simulation parameters from GUI and start mainLoop
@@ -371,6 +376,61 @@ <h3>4. Time integration</h3>
371376
if (this.zoom < 1)
372377
this.zoom = 1;
373378
}
379+
380+
// Convert the first touch point to a plain {clientX, clientY} object
381+
// so it can be passed directly to the existing mouse handlers.
382+
getTouchClient(event)
383+
{
384+
const t = event.touches.length > 0 ? event.touches[0] : event.changedTouches[0];
385+
return { clientX: t.clientX, clientY: t.clientY };
386+
}
387+
388+
touchStart(event)
389+
{
390+
event.preventDefault();
391+
if (event.touches.length === 1)
392+
this.mouseDown({ which: 1, ...this.getTouchClient(event) });
393+
else if (event.touches.length === 2)
394+
this.lastPinchDist = this.getPinchDist(event);
395+
}
396+
397+
touchMove(event)
398+
{
399+
event.preventDefault();
400+
if (event.touches.length === 1)
401+
{
402+
this.lastPinchDist = null;
403+
this.mouseMove(this.getTouchClient(event));
404+
}
405+
else if (event.touches.length === 2)
406+
{
407+
// deselect any dragged particle while pinching
408+
this.selectedParticle = -1;
409+
const dist = this.getPinchDist(event);
410+
if (this.lastPinchDist !== null)
411+
{
412+
this.zoom += (dist - this.lastPinchDist) * 0.3;
413+
if (this.zoom < 1) this.zoom = 1;
414+
}
415+
this.lastPinchDist = dist;
416+
}
417+
}
418+
419+
touchEnd(event)
420+
{
421+
event.preventDefault();
422+
if (event.touches.length < 2)
423+
this.lastPinchDist = null;
424+
if (event.touches.length === 0)
425+
this.mouseUp(event);
426+
}
427+
428+
getPinchDist(event)
429+
{
430+
const dx = event.touches[0].clientX - event.touches[1].clientX;
431+
const dy = event.touches[0].clientY - event.touches[1].clientY;
432+
return Math.sqrt(dx*dx + dy*dy);
433+
}
374434
}
375435

376436
gui = new GUI();

examples/particle_system_rb.html

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ <h3>4. Time integration</h3>
225225
this.canvas.addEventListener("mousemove", this.mouseMove.bind(this), false);
226226
this.canvas.addEventListener("mouseup", this.mouseUp.bind(this), false);
227227
this.canvas.addEventListener("wheel", this.wheel.bind(this), false);
228+
// register touch event listeners (mobile / tablet)
229+
// passive:false is required so we can call preventDefault() to suppress scrolling
230+
this.canvas.addEventListener("touchstart", this.touchStart.bind(this), { passive: false });
231+
this.canvas.addEventListener("touchmove", this.touchMove.bind(this), { passive: false });
232+
this.canvas.addEventListener("touchend", this.touchEnd.bind(this), { passive: false });
228233
}
229234

230235
// set simulation parameters from GUI and start mainLoop
@@ -400,6 +405,61 @@ <h3>4. Time integration</h3>
400405
if (this.zoom < 1)
401406
this.zoom = 1;
402407
}
408+
409+
// Convert the first touch point to a plain {clientX, clientY} object
410+
// so it can be passed directly to the existing mouse handlers.
411+
getTouchClient(event)
412+
{
413+
const t = event.touches.length > 0 ? event.touches[0] : event.changedTouches[0];
414+
return { clientX: t.clientX, clientY: t.clientY };
415+
}
416+
417+
touchStart(event)
418+
{
419+
event.preventDefault();
420+
if (event.touches.length === 1)
421+
this.mouseDown({ which: 1, ...this.getTouchClient(event) });
422+
else if (event.touches.length === 2)
423+
this.lastPinchDist = this.getPinchDist(event);
424+
}
425+
426+
touchMove(event)
427+
{
428+
event.preventDefault();
429+
if (event.touches.length === 1)
430+
{
431+
this.lastPinchDist = null;
432+
this.mouseMove(this.getTouchClient(event));
433+
}
434+
else if (event.touches.length === 2)
435+
{
436+
// deselect any dragged particle while pinching
437+
this.selectedParticle = -1;
438+
const dist = this.getPinchDist(event);
439+
if (this.lastPinchDist !== null)
440+
{
441+
this.zoom += (dist - this.lastPinchDist) * 0.3;
442+
if (this.zoom < 1) this.zoom = 1;
443+
}
444+
this.lastPinchDist = dist;
445+
}
446+
}
447+
448+
touchEnd(event)
449+
{
450+
event.preventDefault();
451+
if (event.touches.length < 2)
452+
this.lastPinchDist = null;
453+
if (event.touches.length === 0)
454+
this.mouseUp(event);
455+
}
456+
457+
getPinchDist(event)
458+
{
459+
const dx = event.touches[0].clientX - event.touches[1].clientX;
460+
const dy = event.touches[0].clientY - event.touches[1].clientY;
461+
return Math.sqrt(dx*dx + dy*dy);
462+
}
403463
}
404464

405465
gui = new GUI();

0 commit comments

Comments
 (0)