@jxstjh/jhvideo
Version:
HTML5 jhvideo base on MPEG2-TS Stream Player
156 lines (145 loc) • 186 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if (typeof define === 'function' && define.amd)
define("nipplejs", [], factory);
else if (typeof exports === 'object')
exports["nipplejs"] = factory();
else
root["nipplejs"] = factory();
})(window, function () {
return /******/ (function (modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if (installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/
}
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/
};
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/
}
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function (exports, name, getter) {
/******/ if (!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/
}
/******/
};
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function (exports) {
/******/ if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/
}
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/
};
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function (value, mode) {
/******/ if (mode & 1) value = __webpack_require__(value);
/******/ if (mode & 8) return value;
/******/ if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if (mode & 2 && typeof value != 'string') for (var key in value) __webpack_require__.d(ns, key, function (key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/
};
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function (module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/
};
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function (object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./src/index.js");
/******/
})
/************************************************************************/
/******/({
/***/ "./src/collection.js":
/*!***************************!*\
!*** ./src/collection.js ***!
\***************************/
/*! exports provided: default */
/***/ (function (module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _nipple__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./nipple */ \"./src/nipple.js\");\n/* harmony import */ var _super__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./super */ \"./src/super.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ \"./src/utils.js\");\n\n\n ///////////////////////////\n/// THE COLLECTION ///\n///////////////////////////\n\nfunction Collection(manager, options) {\n var self = this;\n self.nipples = [];\n self.idles = [];\n self.actives = [];\n self.ids = [];\n self.pressureIntervals = {};\n self.manager = manager;\n self.id = Collection.id;\n Collection.id += 1; // Defaults\n\n self.defaults = {\n zone: document.body,\n multitouch: false,\n maxNumberOfNipples: 10,\n mode: 'dynamic',\n position: {\n top: 0,\n left: 0\n },\n catchDistance: 200,\n size: 100,\n threshold: 0.1,\n color: 'white',\n fadeTime: 250,\n dataOnly: false,\n restJoystick: true,\n restOpacity: 0.5,\n lockX: false,\n lockY: false,\n shape: 'circle',\n dynamicPage: false,\n follow: false,\n jvideo: false\n };\n self.config(options); // Overwrites\n\n if (self.options.mode === 'static' || self.options.mode === 'semi') {\n self.options.multitouch = false;\n }\n\n if (!self.options.multitouch) {\n self.options.maxNumberOfNipples = 1;\n }\n\n self.updateBox();\n self.prepareNipples();\n self.bindings();\n self.begin();\n return self.nipples;\n}\n\nCollection.prototype = new _super__WEBPACK_IMPORTED_MODULE_1__[\"default\"]();\nCollection.constructor = Collection;\nCollection.id = 0;\n\nCollection.prototype.prepareNipples = function () {\n var self = this;\n var nips = self.nipples; // Public API Preparation.\n\n nips.on = self.on.bind(self);\n nips.off = self.off.bind(self);\n nips.options = self.options;\n nips.destroy = self.destroy.bind(self);\n nips.ids = self.ids;\n nips.id = self.id;\n nips.processOnMove = self.processOnMove.bind(self);\n nips.processOnEnd = self.processOnEnd.bind(self);\n\n nips.get = function (id) {\n if (id === undefined) {\n return nips[0];\n }\n\n for (var i = 0, max = nips.length; i < max; i += 1) {\n if (nips[i].identifier === id) {\n return nips[i];\n }\n }\n\n return false;\n };\n};\n\nCollection.prototype.bindings = function () {\n var self = this; // Touch start event.\n\n self.bindEvt(self.options.zone, 'start'); // Avoid native touch actions (scroll, zoom etc...) on the zone.\n\n self.options.zone.style.touchAction = 'none';\n self.options.zone.style.msTouchAction = 'none';\n};\n\nCollection.prototype.begin = function () {\n var self = this;\n var opts = self.options; // We place our static nipple\n // if needed.\n\n if (opts.mode === 'static') {\n var nipple = self.createNipple(opts.position, self.manager.getIdentifier()); // Add it to the dom.\n\n nipple.add(); // Store it in idles.\n\n self.idles.push(nipple);\n }\n}; // Nipple Factory\n\n\nCollection.prototype.createNipple = function (position, identifier) {\n var self = this;\n var scroll = self.manager.scroll;\n var toPutOn = {};\n var opts = self.options;\n\n if (position.x && position.y) {\n toPutOn = {\n x: position.x - (scroll.x + self.box.left),\n y: position.y - (scroll.y + self.box.top)\n };\n } else if (position.top || position.right || position.bottom || position.left) {\n // We need to compute the position X / Y of the joystick.\n var dumb = document.createElement('DIV');\n dumb.style.display = 'hidden';\n dumb.style.top = position.top;\n dumb.style.right = position.right;\n dumb.style.bottom = position.bottom;\n dumb.style.left = position.left;\n dumb.style.position = 'absolute';\n opts.zone.appendChild(dumb);\n var dumbBox = dumb.getBoundingClientRect();\n opts.zone.removeChild(dumb);\n toPutOn = position;\n position = {\n x: dumbBox.left + scroll.x,\n y: dumbBox.top + scroll.y\n };\n }\n\n var nipple = new _nipple__WEBPACK_IMPORTED_MODULE_0__[\"default\"](self, {\n color: opts.color,\n size: opts.size,\n threshold: opts.threshold,\n fadeTime: opts.fadeTime,\n dataOnly: opts.dataOnly,\n restJoystick: opts.restJoystick,\n restOpacity: opts.restOpacity,\n mode: opts.mode,\n identifier: identifier,\n position: position,\n zone: opts.zone,\n frontPosition: {\n x: 0,\n y: 0\n },\n shape: opts.shape,\n jvideo: opts.jvideo\n });\n\n if (!opts.dataOnly) {\n _utils__WEBPACK_IMPORTED_MODULE_2__[\"applyPosition\"](nipple.ui.el, toPutOn);\n _utils__WEBPACK_IMPORTED_MODULE_2__[\"applyPosition\"](nipple.ui.front, nipple.frontPosition);\n }\n\n self.nipples.push(nipple);\n self.trigger('added ' + nipple.identifier + ':added', nipple);\n self.manager.trigger('added ' + nipple.identifier + ':added', nipple);\n self.bindNipple(nipple);\n return nipple;\n};\n\nCollection.prototype.updateBox = function () {\n var self = this;\n self.box = self.options.zone.getBoundingClientRect();\n};\n\nCollection.prototype.bindNipple = function (nipple) {\n var self = this;\n var type; // Bubble up identified events.\n\n var handler = function handler(evt, data) {\n // Identify the event type with the nipple's id.\n type = evt.type + ' ' + data.id + ':' + evt.type;\n self.trigger(type, data);\n }; // When it gets destroyed.\n\n\n nipple.on('destroyed', self.onDestroyed.bind(self)); // Other events that will get bubbled up.\n\n nipple.on('shown hidden rested dir plain', handler);\n nipple.on('dir:up dir:right dir:down dir:left', handler);\n nipple.on('plain:up plain:right plain:down plain:left', handler);\n};\n\nCollection.prototype.pressureFn = function (touch, nipple, identifier) {\n var self = this;\n var previousPressure = 0;\n clearInterval(self.pressureIntervals[identifier]); // Create an interval that will read the pressure every 100ms\n\n self.pressureIntervals[identifier] = setInterval(function () {\n var pressure = touch.force || touch.pressure || touch.webkitForce || 0;\n\n if (pressure !== previousPressure) {\n nipple.trigger('pressure', pressure);\n self.trigger('pressure ' + nipple.identifier + ':pressure', pressure);\n previousPressure = pressure;\n }\n }.bind(self), 100);\n};\n\nCollection.prototype.onstart = function (evt) {\n var self = this;\n var opts = self.options;\n var origEvt = evt;\n evt = _utils__WEBPACK_IMPORTED_MODULE_2__[\"prepareEvent\"](evt); // Update the box position\n\n self.updateBox();\n\n var process = function process(touch) {\n // If we can create new nipples\n // meaning we don't have more active nipples than we should.\n if (self.actives.length < opts.maxNumberOfNipples) {\n self.processOnStart(touch);\n } else if (origEvt.type.match(/^touch/)) {\n // zombies occur when end event is not received on Safari\n // first touch removed before second touch, we need to catch up...\n // so remove where touches in manager that no longer exist\n Object.keys(self.manager.ids).forEach(function (k) {\n if (Object.values(origEvt.touches).findIndex(function (t) {\n return t.identifier === k;\n }) < 0) {\n // manager has id that doesn't exist in touches\n var e = [evt[0]];\n e.identifier = k;\n self.processOnEnd(e);\n }\n });\n\n if (self.actives.length < opts.maxNumberOfNipples) {\n self.processOnStart(touch);\n }\n }\n };\n\n _utils__WEBPACK_IMPORTED_MODULE_2__[\"map\"](evt, process); // We ask upstream to bind the document\n // on 'move' and 'end'\n\n self.manager.bindDocument();\n return false;\n};\n\nCollection.prototype.processOnStart = function (evt) {\n var self = this;\n var opts = self.options;\n var indexInIdles;\n var identifier = self.manager.getIdentifier(evt);\n var pressure = evt.force || evt.pressure || evt.webkitForce || 0;\n var position = {\n x: evt.pageX,\n y: evt.pageY\n };\n var nipple = self.getOrCreate(identifier, position); // Update its touch identifier\n\n if (nipple.identifier !== identifier) {\n self.manager.removeIdentifier(nipple.identifier);\n }\n\n nipple.identifier = identifier;\n\n var process = function process(nip) {\n // Trigger the start.\n nip.trigger('start', nip);\n self.trigger('start ' + nip.id + ':start', nip);\n nip.show();\n\n if (pressure > 0) {\n self.pressureFn(evt, nip, nip.identifier);\n } // Trigger the first move event.\n\n\n self.processOnMove(evt);\n }; // Transfer it from idles to actives.\n\n\n if ((indexInIdles = self.idles.indexOf(nipple)) >= 0) {\n self.idles.splice(indexInIdles, 1);\n } // Store the nipple in the actives array\n\n\n self.actives.push(nipple);\n self.ids.push(nipple.identifier);\n\n if (opts.mode !== 'semi') {\n process(nipple);\n } else {\n // In semi we check the distance of the touch\n // to decide if we have to reset the nipple\n var distance = _utils__WEBPACK_IMPORTED_MODULE_2__[\"distance\"](position, nipple.position);\n\n if (distance <= opts.catchDistance) {\n process(nipple);\n } else {\n nipple.destroy();\n self.processOnStart(evt);\n return;\n }\n }\n\n return nipple;\n};\n\nCollection.prototype.getOrCreate = function (identifier, position) {\n var self = this;\n var opts = self.options;\n var nipple; // If we're in static or semi, we might already have an active.\n\n if (/(semi|static)/.test(opts.mode)) {\n // Get the active one.\n // TODO: Multi-touche for semi and static will start here.\n // Return the nearest one.\n nipple = self.idles[0];\n\n if (nipple) {\n self.idles.splice(0, 1);\n return nipple;\n }\n\n if (opts.mode === 'semi') {\n // If we're in semi mode, we need to create one.\n return self.createNipple(position, identifier);\n } // eslint-disable-next-line no-console\n\n\n console.warn('Coudln\\'t find the needed nipple.');\n return false;\n } // In dynamic, we create a new one.\n\n\n nipple = self.createNipple(position, identifier);\n return nipple;\n};\n\nCollection.prototype.processOnMove = function (evt) {\n var self = this;\n var opts = self.options;\n var identifier = self.manager.getIdentifier(evt);\n var nipple = self.nipples.get(identifier);\n var scroll = self.manager.scroll;\n var isJvideo = opts.jvideo; // If we're moving without pressing\n // it's that we went out the active zone\n\n if (!_utils__WEBPACK_IMPORTED_MODULE_2__[\"isPressed\"](evt)) {\n this.processOnEnd(evt);\n return;\n }\n\n if (!nipple) {\n // This is here just for safety.\n // It shouldn't happen.\n // eslint-disable-next-line no-console\n console.error('Found zombie joystick with ID ' + identifier);\n self.manager.removeIdentifier(identifier);\n return;\n }\n\n if (opts.dynamicPage) {\n var elBox = nipple.el.getBoundingClientRect();\n nipple.position = {\n x: scroll.x + elBox.left,\n y: scroll.y + elBox.top\n };\n }\n\n nipple.identifier = identifier;\n var size = isJvideo ? nipple.options.size / 5 : nipple.options.size / 2;\n var pos = {\n x: evt.pageX,\n y: evt.pageY\n };\n\n if (opts.lockX) {\n pos.y = nipple.position.y;\n }\n\n if (opts.lockY) {\n pos.x = nipple.position.x;\n }\n\n var dist = _utils__WEBPACK_IMPORTED_MODULE_2__[\"distance\"](pos, nipple.position);\n var angle = _utils__WEBPACK_IMPORTED_MODULE_2__[\"angle\"](pos, nipple.position);\n var rAngle = _utils__WEBPACK_IMPORTED_MODULE_2__[\"radians\"](angle);\n var force = dist / size;\n var raw = {\n distance: dist,\n position: pos\n }; // Clamp the position\n\n var clamped_dist;\n var clamped_pos;\n\n if (nipple.options.shape === 'circle') {\n // Clamp to a circle\n clamped_dist = Math.min(dist, size);\n clamped_pos = _utils__WEBPACK_IMPORTED_MODULE_2__[\"findCoord\"](nipple.position, clamped_dist, angle);\n } else {\n // Clamp to a square\n clamped_pos = _utils__WEBPACK_IMPORTED_MODULE_2__[\"clamp\"](pos, nipple.position, size);\n clamped_dist = _utils__WEBPACK_IMPORTED_MODULE_2__[\"distance\"](clamped_pos, nipple.position);\n }\n\n if (opts.follow) {\n // follow behaviour\n if (dist > size) {\n var delta_x = pos.x - clamped_pos.x;\n var delta_y = pos.y - clamped_pos.y;\n nipple.position.x += delta_x;\n nipple.position.y += delta_y;\n nipple.el.style.top = nipple.position.y - (self.box.top + scroll.y) + 'px';\n nipple.el.style.left = nipple.position.x - (self.box.left + scroll.x) + 'px';\n dist = _utils__WEBPACK_IMPORTED_MODULE_2__[\"distance\"](pos, nipple.position);\n }\n } else {\n // clamp behaviour\n pos = clamped_pos;\n dist = clamped_dist;\n }\n\n var xPosition = pos.x - nipple.position.x;\n var yPosition = pos.y - nipple.position.y;\n nipple.frontPosition = {\n x: xPosition,\n y: yPosition\n };\n\n if (!opts.dataOnly) {\n _utils__WEBPACK_IMPORTED_MODULE_2__[\"applyPosition\"](nipple.ui.front, nipple.frontPosition);\n } // Prepare event's datas.\n\n\n var toSend = {\n identifier: nipple.identifier,\n position: pos,\n force: force,\n pressure: evt.force || evt.pressure || evt.webkitForce || 0,\n distance: dist,\n angle: {\n radian: rAngle,\n degree: angle\n },\n vector: {\n x: xPosition / size,\n y: -yPosition / size\n },\n raw: raw,\n instance: nipple,\n lockX: opts.lockX,\n lockY: opts.lockY\n }; // Compute the direction's datas.\n\n toSend = nipple.computeDirection(toSend); // Offset angles to follow units circle.\n\n toSend.angle = {\n radian: _utils__WEBPACK_IMPORTED_MODULE_2__[\"radians\"](180 - angle),\n degree: 180 - angle\n }; // Send everything to everyone.\n\n nipple.trigger('move', toSend);\n self.trigger('move ' + nipple.id + ':move', toSend);\n};\n\nCollection.prototype.processOnEnd = function (evt) {\n var self = this;\n var opts = self.options;\n var identifier = self.manager.getIdentifier(evt);\n var nipple = self.nipples.get(identifier);\n var removedIdentifier = self.manager.removeIdentifier(nipple.identifier);\n\n if (!nipple) {\n return;\n }\n\n if (!opts.dataOnly) {\n nipple.hide(function () {\n if (opts.mode === 'dynamic') {\n nipple.trigger('removed', nipple);\n self.trigger('removed ' + nipple.id + ':removed', nipple);\n self.manager.trigger('removed ' + nipple.id + ':removed', nipple);\n nipple.destroy();\n }\n });\n } // Clear the pressure interval reader\n\n\n clearInterval(self.pressureIntervals[nipple.identifier]); // Reset the direciton of the nipple, to be able to trigger a new direction\n // on start.\n\n nipple.resetDirection();\n nipple.trigger('end', nipple);\n self.trigger('end ' + nipple.id + ':end', nipple); // Remove identifier from our bank.\n\n if (self.ids.indexOf(nipple.identifier) >= 0) {\n self.ids.splice(self.ids.indexOf(nipple.identifier), 1);\n } // Clean our actives array.\n\n\n if (self.actives.indexOf(nipple) >= 0) {\n self.actives.splice(self.actives.indexOf(nipple), 1);\n }\n\n if (/(semi|static)/.test(opts.mode)) {\n // Transfer nipple from actives to idles\n // if we're in semi or static mode.\n self.idles.push(nipple);\n } else if (self.nipples.indexOf(nipple) >= 0) {\n // Only if we're not in semi or static mode\n // we can remove the instance.\n self.nipples.splice(self.nipples.indexOf(nipple), 1);\n } // We unbind move and end.\n\n\n self.manager.unbindDocument(); // We add back the identifier of the idle nipple;\n\n if (/(semi|static)/.test(opts.mode)) {\n self.manager.ids[removedIdentifier.id] = removedIdentifier.identifier;\n }\n}; // Remove destroyed nipple from the lists\n\n\nCollection.prototype.onDestroyed = function (evt, nipple) {\n var self = this;\n\n if (self.nipples.indexOf(nipple) >= 0) {\n self.nipples.splice(self.nipples.indexOf(nipple), 1);\n }\n\n if (self.actives.indexOf(nipple) >= 0) {\n self.actives.splice(self.actives.indexOf(nipple), 1);\n }\n\n if (self.idles.indexOf(nipple) >= 0) {\n self.idles.splice(self.idles.indexOf(nipple), 1);\n }\n\n if (self.ids.indexOf(nipple.identifier) >= 0) {\n self.ids.splice(self.ids.indexOf(nipple.identifier), 1);\n } // Remove the identifier from our bank\n\n\n self.manager.removeIdentifier(nipple.identifier); // We unbind move and end.\n\n self.manager.unbindDocument();\n}; // Cleanly destroy the manager\n\n\nCollection.prototype.destroy = function () {\n var self = this;\n self.unbindEvt(self.options.zone, 'start'); // Destroy nipples.\n\n self.nipples.forEach(function (nipple) {\n nipple.destroy();\n }); // Clean 3DTouch intervals.\n\n for (var i in self.pressureIntervals) {\n if (self.pressureIntervals.hasOwnProperty(i)) {\n clearInterval(self.pressureIntervals[i]);\n }\n } // Notify the manager passing the instance\n\n\n self.trigger('destroyed', self.nipples); // We unbind move and end.\n\n self.manager.unbindDocument(); // Unbind everything.\n\n self.off();\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Collection);\n\n//# sourceURL=webpack://nipplejs/./src/collection.js?");
/***/
}),
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/*! exports provided: default */
/***/ (function (module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _manager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./manager */ \"./src/manager.js\");\n\nvar factory = new _manager__WEBPACK_IMPORTED_MODULE_0__[\"default\"]();\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n create: function create(options) {\n return factory.create(options);\n },\n factory: factory\n});\n\n//# sourceURL=webpack://nipplejs/./src/index.js?");
/***/
}),
/***/ "./src/manager.js":
/*!************************!*\
!*** ./src/manager.js ***!
\************************/
/*! exports provided: default */
/***/ (function (module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _collection__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./collection */ \"./src/collection.js\");\n/* harmony import */ var _super__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./super */ \"./src/super.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ \"./src/utils.js\");\n\n\n ///////////////////////\n/// MANAGER ///\n///////////////////////\n\nfunction Manager(options) {\n var self = this;\n self.ids = {};\n self.index = 0;\n self.collections = [];\n self.scroll = _utils__WEBPACK_IMPORTED_MODULE_2__[\"getScroll\"]();\n self.config(options);\n self.prepareCollections(); // Listen for resize, to reposition every joysticks\n\n var resizeHandler = function resizeHandler() {\n var pos;\n self.collections.forEach(function (collection) {\n collection.forEach(function (nipple) {\n pos = nipple.el.getBoundingClientRect();\n nipple.position = {\n x: self.scroll.x + pos.left,\n y: self.scroll.y + pos.top\n };\n });\n });\n };\n\n _utils__WEBPACK_IMPORTED_MODULE_2__[\"bindEvt\"](window, 'resize', function () {\n _utils__WEBPACK_IMPORTED_MODULE_2__[\"throttle\"](resizeHandler);\n }); // Listen for scrolls, so we have a global scroll value\n // without having to request it all the time.\n\n var scrollHandler = function scrollHandler() {\n self.scroll = _utils__WEBPACK_IMPORTED_MODULE_2__[\"getScroll\"]();\n };\n\n _utils__WEBPACK_IMPORTED_MODULE_2__[\"bindEvt\"](window, 'scroll', function () {\n _utils__WEBPACK_IMPORTED_MODULE_2__[\"throttle\"](scrollHandler);\n });\n return self.collections;\n}\n\nManager.prototype = new _super__WEBPACK_IMPORTED_MODULE_1__[\"default\"]();\nManager.constructor = Manager;\n\nManager.prototype.prepareCollections = function () {\n var self = this; // Public API Preparation.\n\n self.collections.create = self.create.bind(self); // Listen to anything\n\n self.collections.on = self.on.bind(self); // Unbind general events\n\n self.collections.off = self.off.bind(self); // Destroy everything\n\n self.collections.destroy = self.destroy.bind(self); // Get any nipple\n\n self.collections.get = function (id) {\n var nipple; // Use .every() to break the loop as soon as found.\n\n self.collections.every(function (collection) {\n nipple = collection.get(id);\n return nipple ? false : true;\n });\n return nipple;\n };\n};\n\nManager.prototype.create = function (options) {\n return this.createCollection(options);\n}; // Collection Factory\n\n\nManager.prototype.createCollection = function (options) {\n var self = this;\n var collection = new _collection__WEBPACK_IMPORTED_MODULE_0__[\"default\"](self, options);\n self.bindCollection(collection);\n self.collections.push(collection);\n return collection;\n};\n\nManager.prototype.bindCollection = function (collection) {\n var self = this;\n var type; // Bubble up identified events.\n\n var handler = function handler(evt, data) {\n // Identify the event type with the nipple's identifier.\n type = evt.type + ' ' + data.id + ':' + evt.type;\n self.trigger(type, data);\n }; // When it gets destroyed we clean.\n\n\n collection.on('destroyed', self.onDestroyed.bind(self)); // Other events that will get bubbled up.\n\n collection.on('shown hidden rested dir plain', handler);\n collection.on('dir:up dir:right dir:down dir:left', handler);\n collection.on('plain:up plain:right plain:down plain:left', handler);\n};\n\nManager.prototype.bindDocument = function () {\n var self = this; // Bind only if not already binded\n\n if (!self.binded) {\n self.bindEvt(document, 'move').bindEvt(document, 'end');\n self.binded = true;\n }\n};\n\nManager.prototype.unbindDocument = function (force) {\n var self = this; // If there are no touch left\n // unbind the document.\n\n if (!Object.keys(self.ids).length || force === true) {\n self.unbindEvt(document, 'move').unbindEvt(document, 'end');\n self.binded = false;\n }\n};\n\nManager.prototype.getIdentifier = function (evt) {\n var id; // If no event, simple increment\n\n if (!evt) {\n id = this.index;\n } else {\n // Extract identifier from event object.\n // Unavailable in mouse events so replaced by latest increment.\n id = evt.identifier === undefined ? evt.pointerId : evt.identifier;\n\n if (id === undefined) {\n id = this.latest || 0;\n }\n }\n\n if (this.ids[id] === undefined) {\n this.ids[id] = this.index;\n this.index += 1;\n } // Keep the latest id used in case we're using an unidentified mouseEvent\n\n\n this.latest = id;\n return this.ids[id];\n};\n\nManager.prototype.removeIdentifier = function (identifier) {\n var removed = {};\n\n for (var id in this.ids) {\n if (this.ids[id] === identifier) {\n removed.id = id;\n removed.identifier = this.ids[id];\n delete this.ids[id];\n break;\n }\n }\n\n return removed;\n};\n\nManager.prototype.onmove = function (evt) {\n var self = this;\n self.onAny('move', evt);\n return false;\n};\n\nManager.prototype.onend = function (evt) {\n var self = this;\n self.onAny('end', evt);\n return false;\n};\n\nManager.prototype.oncancel = function (evt) {\n var self = this;\n self.onAny('end', evt);\n return false;\n};\n\nManager.prototype.onAny = function (which, evt) {\n var self = this;\n var id;\n var processFn = 'processOn' + which.charAt(0).toUpperCase() + which.slice(1);\n evt = _utils__WEBPACK_IMPORTED_MODULE_2__[\"prepareEvent\"](evt);\n\n var processColl = function processColl(e, id, coll) {\n if (coll.ids.indexOf(id) >= 0) {\n coll[processFn](e); // Mark the event to avoid cleaning it later.\n\n e._found_ = true;\n }\n };\n\n var processEvt = function processEvt(e) {\n id = self.getIdentifier(e);\n _utils__WEBPACK_IMPORTED_MODULE_2__[\"map\"](self.collections, processColl.bind(null, e, id)); // If the event isn't handled by any collection,\n // we need to clean its identifier.\n\n if (!e._found_) {\n self.removeIdentifier(id);\n }\n };\n\n _utils__WEBPACK_IMPORTED_MODULE_2__[\"map\"](evt, processEvt);\n return false;\n}; // Cleanly destroy the manager\n\n\nManager.prototype.destroy = function () {\n var self = this;\n self.unbindDocument(true);\n self.ids = {};\n self.index = 0;\n self.collections.forEach(function (collection) {\n collection.destroy();\n });\n self.off();\n}; // When a collection gets destroyed\n// we clean behind.\n\n\nManager.prototype.onDestroyed = function (evt, coll) {\n var self = this;\n\n if (self.collections.indexOf(coll) < 0) {\n return false;\n }\n\n self.collections.splice(self.collections.indexOf(coll), 1);\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Manager);\n\n//# sourceURL=webpack://nipplejs/./src/manager.js?");
/***/
}),
/***/ "./src/nipple.js":
/*!***********************!*\
!*** ./src/nipple.js ***!
\***********************/
/*! exports provided: default */
/***/ (function (module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _super__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./super */ \"./src/super.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ \"./src/utils.js\");\n\n ///////////////////////\n/// THE NIPPLE ///\n///////////////////////\n\nfunction Nipple(collection, options) {\n this.identifier = options.identifier;\n this.position = options.position;\n this.frontPosition = options.frontPosition;\n this.collection = collection;\n this.jvideo = options.jvideo; // Defaults\n\n this.defaults = {\n size: 100,\n threshold: 0.1,\n color: 'white',\n fadeTime: 250,\n dataOnly: false,\n restJoystick: true,\n restOpacity: 0.5,\n mode: 'dynamic',\n zone: document.body,\n lockX: false,\n lockY: false,\n shape: 'circle',\n jvideo: false\n };\n this.config(options); // Overwrites\n\n if (this.options.mode === 'dynamic') {\n this.options.restOpacity = 0;\n }\n\n this.id = Nipple.id;\n Nipple.id += 1;\n this.buildEl().stylize(); // Nipple's API.\n\n this.instance = {\n el: this.ui.el,\n on: this.on.bind(this),\n off: this.off.bind(this),\n show: this.show.bind(this),\n hide: this.hide.bind(this),\n add: this.addToDom.bind(this),\n remove: this.removeFromDom.bind(this),\n destroy: this.destroy.bind(this),\n setPosition: this.setPosition.bind(this),\n resetDirection: this.resetDirection.bind(this),\n computeDirection: this.computeDirection.bind(this),\n trigger: this.trigger.bind(this),\n position: this.position,\n frontPosition: this.frontPosition,\n ui: this.ui,\n identifier: this.identifier,\n id: this.id,\n options: this.options\n };\n return this.instance;\n}\n\nNipple.prototype = new _super__WEBPACK_IMPORTED_MODULE_0__[\"default\"]();\nNipple.constructor = Nipple;\nNipple.id = 0; // Build the dom element of the Nipple instance.\n\nNipple.prototype.buildEl = function (options) {\n this.ui = {};\n var isJvideo = this.options.jvideo;\n\n if (this.options.dataOnly) {\n return this;\n }\n\n this.ui.el = document.createElement('div');\n this.ui.back = document.createElement('div');\n this.ui.front = document.createElement('div');\n var icons = [{\n name: 'up',\n icon: _utils__WEBPACK_IMPORTED_MODULE_1__[\"dirUpIcon\"],\n mt: 'calc(-0.75em - 35%)',\n ml: '-0.75em'\n }, {\n name: 'down',\n icon: _utils__WEBPACK_IMPORTED_MODULE_1__[\"dirDownIcon\"],\n mt: 'calc(-0.75em + 35%)',\n ml: '-0.75em'\n }, {\n name: 'left',\n icon: _utils__WEBPACK_IMPORTED_MODULE_1__[\"dirLeftIcon\"],\n mt: '-0.75em',\n ml: 'calc(-0.75em - 35%)'\n }, {\n name: 'right',\n icon: _utils__WEBPACK_IMPORTED_MODULE_1__[\"dirRightIcon\"],\n mt: '-0.75em',\n ml: 'calc(-0.75em + 35%)'\n }];\n\n if (isJvideo) {\n for (var index = 0; index < icons.length; index++) {\n var item = icons[index];\n var div = document.createElement('div');\n div.className = 'dir-box';\n div.innerHTML = item.icon;\n div.setAttribute('data-dir', item.name);\n div.style.position = 'absolute';\n div.style.display = 'flex';\n div.style.justifyContent = 'center';\n div.style.alignItems = 'center';\n div.style.width = '1.5em';\n div.style.height = '1.5em';\n div.style.top = '50%';\n div.style.left = '50%';\n div.style.marginTop = item.mt;\n div.style.marginLeft = item.ml;\n this.ui.front.appendChild(div);\n }\n }\n\n this.ui.el.className = 'nipple collection_' + this.collection.id + (isJvideo ? ' jvideo' : '');\n this.ui.back.className = 'back';\n this.ui.front.className = 'front';\n this.ui.el.setAttribute('id', 'nipple_' + this.collection.id + '_' + this.id);\n this.ui.el.appendChild(this.ui.back);\n this.ui.el.appendChild(this.ui.front);\n return this;\n}; // Apply CSS to the Nipple instance.\n\n\nNipple.prototype.stylize = function () {\n if (this.options.dataOnly) {\n return this;\n }\n\n var isJvideo = this.options.jvideo;\n var animTime = this.options.fadeTime + 'ms';\n var borderStyle = _utils__WEBPACK_IMPORTED_MODULE_1__[\"getVendorStyle\"]('borderRadius', '50%');\n var transitStyle = _utils__WEBPACK_IMPORTED_MODULE_1__[\"getTransitionStyle\"]('transition', 'opacity', animTime);\n var styles = {};\n styles.el = {\n position: 'absolute',\n opacity: this.options.restOpacity,\n display: 'block',\n 'zIndex': 999\n };\n styles.back = {\n position: 'absolute',\n display: 'block',\n width: this.options.size + 'px',\n height: this.options.size + 'px',\n marginLeft: -this.options.size / 2 + 'px',\n marginTop: -this.options.size / 2 + 'px',\n background: isJvideo ? '#dcdcdc' : this.options.color,\n 'opacity': isJvideo ? '1' : '.5'\n };\n styles.front = {\n width: isJvideo ? this.options.size / 1.25 + 'px' : this.options.size / 2 + 'px',\n height: isJvideo ? this.options.size / 1.25 + 'px' : this.options.size / 2 + 'px',\n position: 'absolute',\n display: 'block',\n marginLeft: isJvideo ? -this.options.size / 2.5 + 'px' : -this.options.size / 4 + 'px',\n marginTop: isJvideo ? -this.options.size / 2.5 + 'px' : -this.options.size / 4 + 'px',\n background: !isJvideo ? this.options.color : 'url(data:image/png;base64,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