apankrat/nullboard

Touch support

Opened this issue · 1 comments

4jag commented

It seems that touch is not supported, both on mobile screens and on desktop (laptops).

Looking through the scripts, I'm not clear whether you included the code of an existing drag-and-drop framework, or rolled your own. Is it Dragster? (Maybe an older version? I see the word "dragsters" in there, but the latest Dragster supports touch screens).

I was hoping to update the drag/drop code to support touch, but I just thought I ask first so I might find a better starting point.

Thank you!

4jag commented

Without getting too fancy, doubling up on the mouse events with equivalent touch events, a-la below, almost gets there, but when dragging with touch the note snaps to a place outside any droppable containers and then touch looses hold of the note position.

	$('.wrap').on('mousedown touchstart', '.board .note .text', function(ev){
		NB.noteDrag.prime(this.parentNode, ev);
	});

	$('.config').on('mousedown touchstart', 'a.load-board', function(ev){
		if ($('.config a.load-board').length > 1)
			NB.loadDrag.prime(this, ev);
	});

	$('.config').on('mousedown touchstart', '.ui-fs .val', function(ev){
		var org = getFontSize();
		NB.varAdjust.start(ev, function(delta){ setFontSize( org + delta/50. ); }, saveUiPrefs);
	});

	$('.config').on('mousedown touchstart', '.ui-lh .val', function(ev){
		var org = getLineHeight();
		NB.varAdjust.start(ev, function(delta){ setLineHeight( org + delta/50. ); }, saveUiPrefs);
	});

	$('.config').on('mousedown touchstart', '.ui-lw .val', function(ev){
		var org = getListWidth();
		NB.varAdjust.start(ev, function(delta){ setListWidth( org + delta/5. ); }, saveUiPrefs);
	});

	$(document).on('mouseup touchend', function(ev){
		NB.noteDrag.end();
		NB.loadDrag.end();
		NB.varAdjust.end();
	});

	$(document).on('mousemove', function(ev){
		setRevealState(ev);
		NB.noteDrag.onMouseMove(ev);
		NB.loadDrag.onMouseMove(ev);
		NB.varAdjust.onMouseMove(ev);
	});

        // Different function because need touches[] function
	$(document).on('touchmove', function(ev) {
		setRevealState(ev);
		NB.noteDrag.onTouchMove(ev);
		NB.loadDrag.onTouchMove(ev);
		NB.varAdjust.onTouchMove(ev);
	});

	this.onTouchMove = function(ev)
	{
		this.mouseEv = ev;

		if (! this.item)
			return;

		if (this.priming)
		{
			var touch = ev.touches[0];
			var x = touch.clientX;
			var y = touch.clientY;
				if (x*x + y*y > 5*5)
					this.onPrimed();
		}
		else
		{
			this.adjustDrag();
		}
	}

EDIT

I don't have a fix yet, but I read that the x/y coords are different for touchmove, so onTouchMove becomes:

    var touch = ev.touches[0];
    var x = touch.clientX;
    var y = touch.clientY;

But more importantly touchmove events stop after the DOM is modified. So once the drag element is removed from the DOM the touchmove event ends and no touchend fires.

From: Why touchmove event is not fired after DOM changes?:
"The target of this event must be the same Element on which the touch point started when it was first placed on the surface, even if the touch point has since moved outside the interactive area of the target element."

Ref: https://www.w3.org/TR/touch-events/#the-touchmove-event

And...

I think this is what's needed for onTouchMove (I cloned onMouseMove, and changed it to support x/y for touch) is what's described in ZitRo's SO post:
https://stackoverflow.com/a/45760014