first commit
[ratchet] / lib / js / toggles.js
1 /* ----------------------------------
2  * TOGGLE v1.0.0
3  * Licensed under The MIT License
4  * http://opensource.org/licenses/MIT
5  * ---------------------------------- */
6
7 !function () {
8
9   var start     = {};
10   var touchMove = false;
11   var distanceX = false;
12   var toggle    = false;
13
14   var findToggle = function (target) {
15     var i, toggles = document.querySelectorAll('.toggle');
16     for (; target && target !== document; target = target.parentNode) {
17       for (i = toggles.length; i--;) { if (toggles[i] === target) return target; }
18     }
19   }
20
21   window.addEventListener('touchstart', function (e) {
22     e = e.originalEvent || e;
23
24     toggle = findToggle(e.target);
25
26     if (!toggle) return;
27
28     var handle      = toggle.querySelector('.toggle-handle');
29     var toggleWidth = toggle.offsetWidth;
30     var handleWidth = handle.offsetWidth;
31     var offset      = toggle.classList.contains('active') ? toggleWidth - handleWidth : 0;
32
33     start     = { pageX : e.touches[0].pageX - offset, pageY : e.touches[0].pageY };
34     touchMove = false;
35
36     // todo: probably should be moved to the css
37     toggle.style['-webkit-transition-duration'] = 0;
38   });
39
40   window.addEventListener('touchmove', function (e) {
41     e = e.originalEvent || e;
42
43     if (e.touches.length > 1) return; // Exit if a pinch
44
45     if (!toggle) return;
46
47     var handle      = toggle.querySelector('.toggle-handle');
48     var current     = e.touches[0];
49     var toggleWidth = toggle.offsetWidth;
50     var handleWidth = handle.offsetWidth;
51     var offset      = toggleWidth - handleWidth;
52
53     touchMove = true;
54     distanceX = current.pageX - start.pageX;
55
56     if (Math.abs(distanceX) < Math.abs(current.pageY - start.pageY)) return;
57
58     e.preventDefault();
59
60     if (distanceX < 0)      return handle.style.webkitTransform = 'translate3d(0,0,0)';
61     if (distanceX > offset) return handle.style.webkitTransform = 'translate3d(' + offset + 'px,0,0)';
62
63     handle.style.webkitTransform = 'translate3d(' + distanceX + 'px,0,0)';
64
65     toggle.classList[(distanceX > (toggleWidth/2 - handleWidth/2)) ? 'add' : 'remove']('active');
66   });
67
68   window.addEventListener('touchend', function (e) {
69     if (!toggle) return;
70
71     var handle      = toggle.querySelector('.toggle-handle');
72     var toggleWidth = toggle.offsetWidth;
73     var handleWidth = handle.offsetWidth;
74     var offset      = toggleWidth - handleWidth;
75     var slideOn     = (!touchMove && !toggle.classList.contains('active')) || (touchMove && (distanceX > (toggleWidth/2 - handleWidth/2)));
76
77     if (slideOn) handle.style.webkitTransform = 'translate3d(' + offset + 'px,0,0)';
78     else handle.style.webkitTransform = 'translate3d(0,0,0)';
79
80     toggle.classList[slideOn ? 'add' : 'remove']('active');
81
82     e = new CustomEvent('toggle', {
83       detail: { isActive: slideOn },
84       bubbles: true,
85       cancelable: true
86     });
87
88     toggle.dispatchEvent(e);
89
90     touchMove = false;
91     toggle    = false;
92   });
93
94 }();