UNPKG

interactjs

Version:

Drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+)

301 lines (229 loc) 15 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>src/autoStart/base.js - Documentation</title> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"> <link type="text/css" rel="stylesheet" href="styles/prettify.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav> <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Interactable.html">Interactable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#actionChecker">actionChecker</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#context">context</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#deltaSource">deltaSource</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#draggable">draggable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#dropzone">dropzone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#fire">fire</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#gesturable">gesturable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#getRect">getRect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#off">off</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#on">on</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#origin">origin</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#preventDefault">preventDefault</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#rectChecker">rectChecker</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#resizable">resizable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#set">set</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#styleCursor">styleCursor</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interactable.html#unset">unset</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="InteractEvent.html">InteractEvent</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="InteractEvent.html#stopImmediatePropagation">stopImmediatePropagation</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="InteractEvent.html#stopPropagation">stopPropagation</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Interaction.html">Interaction</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interaction.html#doMove">doMove</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interaction.html#end">end</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interaction.html#start">start</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interaction.html#stop">stop</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="module.exports_module.exports.html">exports</a></span></li><li class="nav-heading">Modules</li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-interact.html">interact</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-interact.html#.debug">debug</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-interact.html#.dynamicDrop">dynamicDrop</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-interact.html#.isSet">isSet</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-interact.html#.maxInteractions">maxInteractions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-interact.html#.off">off</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-interact.html#.on">on</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-interact.html#.pointerMoveTolerance">pointerMoveTolerance</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-interact.html#.stop">stop</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-interact.html#.supportsPointerEvent">supportsPointerEvent</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-interact.html#.supportsTouch">supportsTouch</a></span></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#interact">interact</a></span></li> </nav> <div class="code-col-bg"></div> <div id="main"> <h1 class="page-title">src/autoStart/base.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>const interact = require('../interact'); const Interactable = require('../Interactable'); const Interaction = require('../Interaction'); const actions = require('../actions/base'); const defaultOptions = require('../defaultOptions'); const scope = require('../scope'); const utils = require('../utils'); const signals = require('../utils/Signals').new(); require('./InteractableMethods'); const autoStart = { signals, withinInteractionLimit, // Allow this many interactions to happen simultaneously maxInteractions: Infinity, defaults: { perAction: { manualStart: false, max: Infinity, maxPerElement: 1, allowFrom: null, ignoreFrom: null, // only allow left button by default // see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons#Return_value mouseButtons: 1, }, }, setActionDefaults: function (action) { utils.extend(action.defaults, autoStart.defaults.perAction); }, validateAction, }; // set cursor style on mousedown Interaction.signals.on('down', function ({ interaction, pointer, event, eventTarget }) { if (interaction.interacting()) { return; } const actionInfo = getActionInfo(interaction, pointer, event, eventTarget); prepare(interaction, actionInfo); }); // set cursor style on mousemove Interaction.signals.on('move', function ({ interaction, pointer, event, eventTarget }) { if (interaction.pointerType !== 'mouse' || interaction.pointerIsDown || interaction.interacting()) { return; } const actionInfo = getActionInfo(interaction, pointer, event, eventTarget); prepare(interaction, actionInfo); }); Interaction.signals.on('move', function (arg) { const { interaction, event } = arg; if (!interaction.pointerIsDown || interaction.interacting() || !interaction.pointerWasMoved || !interaction.prepared.name) { return; } signals.fire('before-start', arg); const target = interaction.target; if (interaction.prepared.name &amp;&amp; target) { // check manualStart and interaction limit if (target.options[interaction.prepared.name].manualStart || !withinInteractionLimit(target, interaction.element, interaction.prepared)) { interaction.stop(event); } else { interaction.start(interaction.prepared, target, interaction.element); } } }); // Check if the current target supports the action. // If so, return the validated action. Otherwise, return null function validateAction (action, interactable, element, eventTarget) { if (utils.is.object(action) &amp;&amp; interactable.testIgnoreAllow(interactable.options[action.name], element, eventTarget) &amp;&amp; interactable.options[action.name].enabled &amp;&amp; withinInteractionLimit(interactable, element, action)) { return action; } return null; } function validateSelector (interaction, pointer, event, matches, matchElements, eventTarget) { for (let i = 0, len = matches.length; i &lt; len; i++) { const match = matches[i]; const matchElement = matchElements[i]; const action = validateAction(match.getAction(pointer, event, interaction, matchElement), match, matchElement, eventTarget); if (action) { return { action, target: match, element: matchElement, }; } } return {}; } function getActionInfo (interaction, pointer, event, eventTarget) { let matches = []; let matchElements = []; let element = eventTarget; function pushMatches (interactable) { matches.push(interactable); matchElements.push(element); } while (utils.is.element(element)) { matches = []; matchElements = []; scope.interactables.forEachMatch(element, pushMatches); const actionInfo = validateSelector(interaction, pointer, event, matches, matchElements, eventTarget); if (actionInfo.action &amp;&amp; !actionInfo.target.options[actionInfo.action.name].manualStart) { return actionInfo; } element = utils.parentNode(element); } return {}; } function prepare (interaction, { action, target, element }) { action = action || {}; if (interaction.target &amp;&amp; interaction.target.options.styleCursor) { interaction.target._doc.documentElement.style.cursor = ''; } interaction.target = target; interaction.element = element; utils.copyAction(interaction.prepared, action); if (target &amp;&amp; target.options.styleCursor) { const cursor = action? actions[action.name].getCursor(action) : ''; interaction.target._doc.documentElement.style.cursor = cursor; } signals.fire('prepared', { interaction: interaction }); } Interaction.signals.on('stop', function ({ interaction }) { const target = interaction.target; if (target &amp;&amp; target.options.styleCursor) { target._doc.documentElement.style.cursor = ''; } }); function withinInteractionLimit (interactable, element, action) { const options = interactable.options; const maxActions = options[action.name].max; const maxPerElement = options[action.name].maxPerElement; let activeInteractions = 0; let targetCount = 0; let targetElementCount = 0; // no actions if any of these values == 0 if (!(maxActions &amp;&amp; maxPerElement &amp;&amp; autoStart.maxInteractions)) { return; } for (const interaction of scope.interactions) { const otherAction = interaction.prepared.name; if (!interaction.interacting()) { continue; } activeInteractions++; if (activeInteractions >= autoStart.maxInteractions) { return false; } if (interaction.target !== interactable) { continue; } targetCount += (otherAction === action.name)|0; if (targetCount >= maxActions) { return false; } if (interaction.element === element) { targetElementCount++; if (otherAction !== action.name || targetElementCount >= maxPerElement) { return false; } } } return autoStart.maxInteractions > 0; } /** * Returns or sets the maximum number of concurrent interactions allowed. By * default only 1 interaction is allowed at a time (for backwards * compatibility). To allow multiple interactions on the same Interactables and * elements, you need to enable it in the draggable, resizable and gesturable * `'max'` and `'maxPerElement'` options. * * @alias module:interact.maxInteractions * * @param {number} [newValue] Any number. newValue &lt;= 0 means no interactions. */ interact.maxInteractions = function (newValue) { if (utils.is.number(newValue)) { autoStart.maxInteractions = newValue; return interact; } return autoStart.maxInteractions; }; Interactable.settingsMethods.push('styleCursor'); Interactable.settingsMethods.push('actionChecker'); Interactable.settingsMethods.push('ignoreFrom'); Interactable.settingsMethods.push('allowFrom'); defaultOptions.base.actionChecker = null; defaultOptions.base.styleCursor = true; utils.extend(defaultOptions.perAction, autoStart.defaults.perAction); module.exports = autoStart; </code></pre> </article> </section> </div> <script>prettyPrint();</script> <script src="scripts/linenumber.js"></script> </body> </html>