Last active
June 15, 2017 21:14
-
-
Save axelchalon/bb64f2258d0de59e385c to your computer and use it in GitHub Desktop.
Rotate an element with touch events
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @param DOMElement touchElement The element whose center we use for the rotation, and on which the touch events occur; musn't be an svg element | |
* @param function callbacks {move: function, end (optional): function} | |
*/ | |
var TouchRotate = function (touchElement, callbacks) { | |
// Does not work with SVG, hence touchElement mustn't be an SVG | |
function getElementCenterCoordinates(el) { | |
return { | |
centerX: el.offsetLeft + el.offsetWidth / 2, | |
centerY: el.offsetTop + el.offsetHeight / 2 | |
} | |
} | |
// Get radian starting from standard CSS transform axis (vertical top axis: ((0,0),(0,1))) | |
function getRadian(currentX, currentY, centerX, centerY) { | |
var opp = centerY - currentY | |
var adj = currentX - centerX | |
var rad_starting_right = Math.atan2(opp, adj) | |
return Math.PI / 2 - rad_starting_right | |
} | |
// Handle mobile and desktop mouse events for rotation | |
['touchstart', 'mousedown', 'touchmove', 'mousedownmove'].forEach(function (eventName) { | |
touchElement.addEventListener(eventName, function (e) { | |
var currentX = e.touches ? e.touches[0].pageX : (e.pageX ? e.pageX : e.detail.pageX) | |
var currentY = e.touches ? e.touches[0].pageY : (e.pageY ? e.pageY : e.detail.pageY) | |
var {centerX, centerY} = getElementCenterCoordinates(touchElement) | |
var currentRadian = getRadian(currentX, currentY, centerX, centerY) | |
callbacks['move'](currentRadian) | |
event.preventDefault() | |
}) | |
}); // do not remove the semi-colon | |
['touchend', 'mouseup'].forEach(function (eventName) { | |
console.log('up') | |
touchElement.addEventListener(eventName, function () { | |
if (typeof callbacks.end !== 'undefined') | |
callbacks['end']() | |
}) | |
}) | |
// Create custom "mousedownmove" event | |
var mousedown = false | |
touchElement.addEventListener('mousedown', () => { | |
console.log('mousedown') | |
mousedown = true | |
}) | |
touchElement.addEventListener('mouseup', () => { | |
console.log('mouseup') | |
mousedown = false | |
}) | |
touchElement.addEventListener('mousemove', (e) => { | |
if (mousedown) { | |
console.log('mousemove mousedown') | |
function triggerEvent(el, eventName, options) { | |
var event | |
if (window.CustomEvent) { | |
event = new CustomEvent(eventName, options) | |
} else { | |
event = document.createEvent('CustomEvent') | |
event.initCustomEvent(eventName, true, true, options) | |
} | |
el.dispatchEvent(event) | |
} | |
triggerEvent(touchElement, 'mousedownmove', { | |
detail: { | |
pageX: e.pageX, | |
pageY: e.pageY | |
} | |
}) | |
} | |
}) | |
} | |
var index = 0; | |
var TouchRotateCallbacks = function () { | |
var lastNotchRadian = false | |
return { | |
move: function (touchMoveRadian) { // closure isn't functional #todo | |
// Quick fix because touchMoveRadian abruptly switches from (+3/2 * PI) to (-1/2 * PI) | |
var radianDiff = touchMoveRadian - lastNotchRadian | |
if (radianDiff < -Math.PI) | |
radianDiff = touchMoveRadian + Math.PI * 2 - lastNotchRadian | |
else if (radianDiff > Math.PI) | |
radianDiff = lastNotchRadian - (touchMoveRadian + Math.PI * 2) | |
if (lastNotchRadian === false) | |
lastNotchRadian = touchMoveRadian | |
else if (radianDiff > Math.PI / MAX_VISIBLE_NUMBER_OF_NODES) { | |
lastNotchRadian = touchMoveRadian | |
index++ | |
} else if (radianDiff < -Math.PI / MAX_VISIBLE_NUMBER_OF_NODES) { | |
lastNotchRadian = touchMoveRadian | |
index-- | |
} | |
}, | |
end: function () { | |
lastNotchRadian = false | |
} | |
} | |
} | |
var touchRotateCallbacks = TouchRotateCallbacks() | |
new TouchRotate(document.querySelector('#some-dom-element'), touchRotateCallbacks.move, touchRotateCallbacks.end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment