UNPKG

plumes

Version:

Flying-fast Metro future vision components

186 lines (145 loc) 4.73 kB
(function() { 'use strict'; window.Ractive.controller('pl-scrolls', function(component, data, el, config, done) { var PAGE_SIZE = 268, _inDrag = false, _mousewheelBinds = ('onwheel' in document || document.documentMode >= 9) ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll']; if (typeof window.Ractive.plScrollsWidth == 'undefined') { var $tester = $('<div/>') .css({ 'overflow-y': 'auto', 'overflow-x': 'hidden', visibility: 'hidden', height: 50, width: 100 }) .html('<div style="height: 200px; width: 100%"></div>'); $('body').append($tester); var width = Math.ceil(100 - $tester.find('div').width()); $tester.remove(); var sheet = window.document.styleSheets[0]; if (sheet.insertRule) { sheet.insertRule('.pl-scrolls { margin-right: -' + width + 'px; }', sheet.cssRules.length); } else { sheet.addRule('.pl-scrolls', 'margin-right: -' + width + 'px;', -1); } window.Ractive.plScrollsWidth = width; } function _update() { var area = _$el.container.prop('scrollHeight'), max = _$el.vertical.outerHeight(), height = max * 100 / area; Scrolls.set('active', area > max); Scrolls.set('height', height); _scroll(); } function _scroll() { var area = _$el.container.prop('scrollHeight'), scrollTop = _$el.container.scrollTop(), top = scrollTop * 100 / area; Scrolls.set('top', top); } function _topPX() { return _$el.verticalTicker.offset().top - _$el.vertical.offset().top; } function _mousedown(event) { _inDrag = { scrollTop: _$el.container.scrollTop(), pageY: event.pageY }; Scrolls.set('inDrag', true); event.preventDefault(); event.stopPropagation(); } function _mousemove(event) { if (!_inDrag) { return; } var area = _$el.container.prop('scrollHeight'), max = _$el.vertical.outerHeight(), scrollTop = _inDrag.scrollTop + ((event.pageY - _inDrag.pageY) * area / max); _$el.container.scrollTop(scrollTop); event.preventDefault(); event.stopPropagation(); } function _mouseup() { _inDrag = false; Scrolls.set('inDrag', false); } function _mouseenter() { _update(); Scrolls.set('enter', true); } function _mouseleave() { Scrolls.set('enter', false); } var Scrolls = component({ plName: 'pl-scrolls', data: $.extend(true, { top: 0, height: 0, active: false, hover: false, inDrag: false, enter: false }, data), update: _update }), _$el = { body: $('body'), scrolls: $(Scrolls.el), vertical: $(Scrolls.el).find('.pl-scrolls-vertical'), verticalTicker: $(Scrolls.el).find('.pl-scrolls-vertical-ticker'), container: $(Scrolls.el).next('.pl-scrolls') }; Scrolls.on('teardown', function() { _$el.container.off('scroll', _scroll); _$el.body.off('mousemove', _mousemove); _$el.body.off('mouseup', _mouseup); _$el.container.off('mouseenter', _mouseenter); _$el.container.off('mouseenter', _mouseleave); _$el = null; Scrolls = null; }); _$el.container.scroll(_scroll); _$el.vertical.mouseenter(function() { Scrolls.set('hover', true); }); _$el.vertical.mouseleave(function() { Scrolls.set('hover', false); }); _$el.vertical.click(function(event) { if (event.target != _$el.vertical[0]) { return; } var top = _topPX(), scrollTop = _$el.container.scrollTop(); _$el.container .stop() .animate({ scrollTop: scrollTop + (top > event.offsetY ? -PAGE_SIZE : PAGE_SIZE) }, 150, data.easing || 'swing'); }); $.each(_mousewheelBinds, function(i, bind) { _$el.vertical.on(bind, function(event) { var cloneEvent = new window.WheelEvent(bind, event.originalEvent); if (document.createEvent) { _$el.container[0].dispatchEvent(cloneEvent); } else { _$el.container[0].fireEvent('on' + cloneEvent.eventType, cloneEvent); } }); }); _$el.verticalTicker.mousedown(_mousedown); _$el.body.mousemove(_mousemove); _$el.body.mouseup(_mouseup); _$el.container.mouseenter(_mouseenter); _$el.container.mouseleave(_mouseleave); _update(); done(); }); })();