Hammer.js drag and drop issue, multitouch - javascript

I've implemented the drag and drop algorithm from this page: https://github.com/EightMedia/hammer.js/blob/master/examples/drag.html
It works fine if the mouse doesn't move too fast on the desktop, otherwise it loses track of the original picked up element and just moves the new one, which is below the current mouse position.
A Video of the problem can be seen here:
http://www.screenr.com/tIO8
I tried to change the code to this, then it works fine, but it is not able to use multiple touches for different objects at the same time.
for(var t=0,len=touches.length; t<len; t++) {
var target = $(this);
target.css({
zIndex: 1337,
left: touches[t].pageX-50,
top: touches[t].pageY-50
});
The code shouldn't lose track of the object and should be able to use multitouch.

Related

gsap draggable auto sliding

I am using Greensock Draggable, to build a draggable slider control. for example, let's say I have a 3 pages slider, when the position is scrolled to 1/3, turns to the second page.
let myDraggable = new Draggable(dragger, {
//trigger:ufo,
type:'x',
bounds:{minX:0, maxX:maxDrag},
throwProps:true,
//cursor:'auto',
/* liveSnap:function(value){
return Math.round(value / step) * step;
}, */
onPress:onPress,
onRelease:onRelease,
onThrowComplete:function(){isDragging = false},
overshootTolerance:0
})
everything works fine so far, by defining onRelease function, I built the functionality completely.
but then I want to build auto-scrolling, not the one mentioned in documentation, but, use setInterval to gradually scroll to 1/3, 2/3... but draggable does not seem to support customise x position dragging, which I failed to look up for a function that takes x position and drag the element there.
is there a draggable api that takes one position and drags the element there? if it doesn't, do I have to build a untrusted drag event? if so how can I do that?
sorry that I did a lot relative research but failed to work out solution. I will be more than glad if you can give me a hand, or just something to read for another direction.

Getting a more precise selection of target from the mousemove event

I'm currently developing a Chrome Extension and a part of that is having items highlighted as the user mouses over them, much like that of the developer DOM selector tools build into the browser.
Currently I've been able to impliment two solutions, one that adds and removes a border to the item thats being selected, this works really well actually but ive been trying to do it with an overlay too. Currently I have a semi working solution for the overlay but it's no where near as accurate or as good as the border. Basically I have this code so far for the border:
The idea with this solution is to grab the mouseover event, find what element the mouse is over and insert a div thats semi transparent inside filling up the same size, and then remove it after
var overlay = $('<div></div>',{id: "8b29f35f-6cc6"});
$(overlay).css(({
position: 'absolute',
display:'block',
width: '100%',
height: '100%',
top: '0',
left: '0',
right: '0',
bottom: '0',
background: 'rgba(55,22,124,0.5)',
zindex: '1000000',
cursor: 'pointer'}));
var CurrentItem;
$('body').mousemove(function(evt){
CurrentItem = evt.target
});
selecting = setInterval(function(){
$("#8b29f35f-6cc6").remove();
currentElement = CurrentItem;
$(currentElement).append(overlay);
}, 100);
However with this approach lots of elements aren't getting the overlay and often with sites like for example stack overflow the overlay is just going straight over most of the content and not smaller indivial DOM elements. as shown below, you cant really see because the mouse isnt shown but basically its always going for much bigger DOM elements over the small ones im actually moused over

HTML5 Drag and Drop events and setDragImage browser support

I'm working on a small jQuery plugin that mimics the jQuery UI draggable/droppable behavior with native HTML5 drag and drop events.
A feature I'd want to add is the ability to specify the node which will serve as the drag proxy.
I did a bit of research, and according to MDN, to do this requires the use of setDragImage(), passing an image or an element.
What is the support for setDragImage in different browsers?
I've noticed there's a plugin named jquery.event.drag which takes a different than I expected to this problem.
Would this feature require me to make some kind of workaround like the above plugin, or should this be possible out-of-the-box in most or all browsers using setDragImage?
EDIT
After playing around a bit with this functionality, it would seem that this function is quite limited.
Besides having no support in quite a few browsers, using an arbitrary DOM element as the helper requires it to be in the DOM tree and visible, and so you have the element itself on the body, and a copy of it as the handler. This is mostly unwanted for this sort of plugin.
Further more, rendering is also problematic even when the right terms are met. When trying to create a helper from <span>TEST</span>, the helper itself only showed a white rectangle with the dimensions of the span.
Are these issues that were to be expected according to the specs? Could they be fixed in code or would they require a workaround?
setDragImage is IMO a vital feature for any non trivial drag and drop use case. e.g consider a multi select list where a drag needs to include all the selected items and not just the row that the drag gesture was made on. it's odd that the thing you want to set needs to be visible in the DOM but even worse is that this method is not implemented at all in IE as of version 11.
However, with a bit of effort I was able to get it working reasonably satisfactorily. The custom drag image node can be removed from the DOM in a timeout 0 function. so add it to the DOM in dragstart then use it in set drag image and then remove it. This works perfectly in FF but in chrome the drag image node will flicker before the timeout fires. One way to prevent this is to position it such that the actual browser generated drag image will appear in exactly the same place, this is not as bad as it sounds since you can control the position of the custom drag image relative to the cursor.
I was playing with this recently and was able to get it working on IE as well. the trick there is to get IE to drag the custom drag image node and not the node that dragstart fired on. you can do this with the IE specific dragDrop() method.
The final thing to be aware of is that on windows there is a 300px limit on the width of the custom drag image node this applies to all draggables not just the custom node actually. so the browser applies a heavy radial gradient if the drag image is too big.
http://jsfiddle.net/stevendwood/akScu/21/
$(function() {
(function($) {
var isIE = (typeof document.createElement("span").dragDrop === "function");
$.fn.customDragImage = function(options) {
var offsetX = options.offsetX || 0,
offsetY = options.offsetY || 0;
var createDragImage = function($node, x, y) {
var $img = $(options.createDragImage($node));
$img.css({
"top": Math.max(0, y-offsetY)+"px",
"left": Math.max(0, x-offsetX)+"px",
"position": "absolute",
"pointerEvents": "none"
}).appendTo(document.body);
setTimeout(function() {
$img.remove();
});
return $img[0];
};
if (isIE) {
$(this).on("mousedown", function(e) {
var originalEvent = e.originalEvent,
node = createDragImage($(this), originalEvent.pageX, originalEvent.pageY);
node.dragDrop();
});
}
$(this).on("dragstart", function(e) {
var originalEvent = e.originalEvent,
dt = originalEvent.dataTransfer;
if (typeof dt.setDragImage === "function") {
node = createDragImage($(this), originalEvent.pageX, originalEvent.pageY);
dt.setDragImage(node, offsetX, offsetY);
}
});
return this;
};
}) (jQuery);
$("[draggable='true']").customDragImage({
offsetX: 50,
offsetY: 50,
createDragImage: function($node) {
return $node.clone().html("I'm a custom DOM node/drag image").css("backgroundColor", "orange");
}
}).on("dragstart", function(e) {
e.originalEvent.dataTransfer.setData("Text", "Foo");
});
});

Iscroll - Jquery - Get position on a list item

The error I'm having is the following:
To the right of my page, I have a list of interesting points (displayed on a map to the left of the page).
Because the list is so long, I am using iScroll 4 (great plugin).
However, what I would like to do is fire an event when the user has scrolled the list, so I can check which items are currently visible to the user. iScroll already has an event set up for that, so I have a function that fires when needed. However, I cannot seem to get the proper coordinates of my list items.
What happens is the following:
When the list loads, I get an .offset() value for the first element. offset.top = 35, because my list starts 35px lower than the top edge of the page. This is good.
When I scroll the list; say I pull it down for 500px; I would expect the new location to be 35px - 500px = -465px. However, it sill says 35. Scrolling though the list does not affect the elemen'ts coordinates even though it has moved.
How can I get the actual coordinates?
Playing with iScroll, I think I found the solution. the offset() function is javascript refering to the #scroller div, which doesn't change. However internally, iScroll uses its own x and y properties.
So you can refer to the iScroll offset like this
var myScroll = new iScroll(...)
alert(myScroll.y) // -- will return your offset (negative number)
add in iscroll.js
getScrollY: function () { var that = this; return that.y; },

How can I react when a user touches an HTML element on an iPhone?

I'm displaying some HTML content in my iPhone app using a UIWebView. I have an image link, and I want it to change when the user touches it - at the moment the user puts a finger on the screen, rather than waiting until they lift their finger back off.
What CSS or JavaScript concept could accomplish this? I've looked at the hover and active states in CSS, but they don't seem to be what I'm after: hover relates to touch-up rather than touch-down, while active seems to have no effect at all.
You could try this.
I think it should be what you are looking for!
http://articles.sitepoint.com/article/iphone-development-12-tips/2
8: Touch Events
Of course, you use your iPhone with a
finger instead of a mouse; rather than
clicking, you tap. What’s more, you
can use several fingers to touch and
tap. On the iPhone, mouse events are
replaced by touch events. They are:
touchstart
touchend
touchmove
touchcancel (when the system cancels the touch)
When you subscribe to any of those
events, your event listener will
receive an event object. The event
object has some important properties,
such as:
touches — a collection of touch objects, one for each finger that
touches the screen. The touch objects
have, for example, pageX and pageY
properties containing the coordinates
of the touch within the page.
targetTouches — works like touches, but only registers touches on
a target element as opposed to the
whole page.
The next example is a simple
implementation of drag and drop. Let’s
put a box on a blank page and drag it
around. All you need to do is
subscribe to the touchmove event and
update the position of the box as the
finger moves around, like so:
window.addEventListener('load', function() {
var b = document.getElementById('box'),
xbox = b.offsetWidth / 2, // half the box width
ybox = b.offsetHeight / 2, // half the box height
bstyle = b.style; // cached access to the style object
b.addEventListener('touchmove', function(event) {
event.preventDefault(); // the default behaviour is scrolling
bstyle.left = event.targetTouches[0].pageX - xbox + 'px';
bstyle.top = event.targetTouches[0].pageY - ybox + 'px';
}, false);
}, false);
The touchmove event listener first cancels the default behavior of the finger move—otherwise Safari will scroll the page. The collection event.targetTouches contains a list of data for each finger currently on the target div element.
We only care about one finger, so we use event.targetTouches[0]. Then pageX gives us the X coordinate of the finger. From this value we subtract half the width of the div so that the finger stays in the center of the box.
Hope it helps!
Try the Javascript "onMouseDown", hopefully the mobile Safari will fire the event.
Link

Categories

Resources