Drag and Drop をマルチタッチ対応に
シングルマウスなDrag and Dropなコードを、マルチタッチ対応にしてみました。
http://jsdo.it/uupaa/MultiTouchDnD
iPhoneでテストしています。
マルチタッチ初挑戦なので、色々と分かってません。
マルチタッチ対応の要点
今回は、シングルマウスのコードを流用し、マルチタッチ対応を行なっています。
// 0.8/src/ui/drag.js // 初期化処理で、mousedown の代わりに touchstart をハンドリング uu.event(grip, uu.ver.touch ? "touchstart" : "mousedown", this)
// 0.8/src/ui/drag.js function dragHandleEvent(evt) { uu.event.stop(evt); uu.ui.dragbase(evt, this.node, this.grip, this.option); var code = evt.code, fn; if (code < 5) { if (code < 3) { // 1: mousedown, touchstart // 2: mouseup, touchend fn = code === 1 ? uu.event : uu.event.unbind; // タッチデバイスなら touchmove と touchend をキャプチャー fn(_ie678 ? this.grip : document, uu.ver.touch ? "touchmove+,touchend+" : "mousemove+,mouseup+", this); } else if (code === 3) { // 3: mousemove } else if (code === 4) { // 4: wheel // this.option.wheel && this.mousewheel(evt); } } }
// 0.8/src/ui/dragbase.js uu.ui.dragbase || (function(uu) { uu.ui.dragbase = uuuidragbase; // drag & drop base handler var _uuuidrag = "data-uuuidrag", // node["data-uuuidrag"] = { dragging: Boolean, x, y } _touch = uu.ver.touch; // uu.ui.dragbase - function uuuidragbase(evt, // @param event: node, // @param Node: move target node grip, // @param Node: grip target node option) { // @param Hash(= {}): { mouseup, mousemove, mousedown, shim } // option.mouseup - Function: mouseup callback // option.mousemove - Function: mousemove callback // option.mousedown - Function: mousedown callback // option.shim - Object: shim object var opt = option || {}, pageX = evt.pageX, pageY = evt.pageY, code = evt.code, dragInfo = grip[_uuuidrag] || {}, // この行を追加 touches, finger, identifier, i, iz; // for iPhone if (code === 1 && !dragInfo.dragging) { // 1: mousedown, touchstart // ここから追加〜 if (_touch) { finger = evt.touches[evt.touches.length - 1]; identifier = finger.identifier; pageX = finger.pageX; pageY = finger.pageY; } // 〜ここまで追加 dragInfo = grip[_uuuidrag] = { x: pageX - (parseInt(node.style.left) || 0), y: pageY - (parseInt(node.style.top) || 0), // この行を追加し、identifier を保存 id: identifier, // touch.identifier dragging: 1 }; opt.mousedown && opt.mousedown(evt, node, option, dragInfo); uu.ui.zindex.beginDrag(node); } else if (code === 2 && dragInfo.dragging) { // 2: mouseup, touchend // このへんはそのまま dragInfo.dragging = 0; opt.mouseup && opt.mouseup(evt, node, option, dragInfo); uu.ui.zindex.endDrag(node); } else if (code === 3 && dragInfo.dragging) { // 3: mousemove, touchmove // ここから追加〜 if (_touch) { touches = evt.touches; // touchmodeイベントが発生したノードと、event.touches[...] の identifier を比較し // 同じなら pageX, pageY を加算する // これで、個々の finger を識別し同時に動かしている for (i = 0, iz = touches.length; i < iz; ++i) { finger = touches[i]; if (dragInfo.id === finger.identifier) { pageX = finger.pageX; pageY = finger.pageY; } } } // 〜ここまで追加 node.style.left = (pageX - dragInfo.x) + "px"; node.style.top = (pageY - dragInfo.y) + "px"; opt.mousemove && opt.mousemove(evt, node, option, dragInfo); } } })(uu);
ということをやっています。identifierの識別方法は、もっとうまい方法があるのかもしれません。