API Docs for: 0.1.1
Show:

File: src/components/map/core/baseEventlisteners/baseEventlisteners.js

(function () {
  /*-----------------------
  --------- IMPORT --------
  -----------------------*/
  const { mapEvents, utils, mapStates, eventListeners } = window.flatworld;
  const { Hammer, Hamster } = window.flatworld_libraries;

  /*-----------------------
  ---------- API ----------
  -----------------------*/
  window.flatworld.extensions.baseEventlisteners = baseEventlistenersModule();

  /*-----------------------
  -------- PUBLIC ---------
  -----------------------*/
  /**
   * Core plugin. Houses the default eventlisteners used in the map. When plugins are added to the map this class can be used for the
   * eventlistener management. Creates window.flatworld.setFullScreen function to be used when switching to fullscreen.
   *
   * @namespace flatworld
   * @class extensions.baseEventlisteners
   * @requires Hammer.js                    (for touch events)
   * @requires Hamster.js                   (for good cross-browser mousewheel events)
   * @event                                 mapEvents.publish('mapResized')
   * @param {HTMLElement} canvasElement     The canvas element we listen events from. Will try to search the first canvas in the DOM,
   * if none is provided
   */
  function baseEventlistenersModule() {
    const caches = {};
    var hammer, hamster, mapInstance;

    /*---------------------------
    ----------- API -------------
    ---------------------------*/
    return {
      init,
      toggleFullSize,
      toggleFullscreen,
      toggleZoom,
      toggleDrag,
      toggleSelect,
      toggleOrder,
      toggleMouseTextSelection,

      /**
       * Plugins name
       *
       * @attribute pluginName
       * @type {String}
       */
      pluginName: 'baseEventlisteners',
    };

    /**
     * Initialize plugin
     *
     * @method init
     */
    function init(map) {
      const orderToggle = toggleOrder();
      const selectToggle = toggleSelect();

      mapInstance = map;
      hammer = new Hammer.Manager(map.canvas);
      hamster = new Hamster(map.canvas);

      eventListeners.setDetector('fullSize', toggleFullSize().on, toggleFullSize().off);
      eventListeners.on('fullSize', resizeCanvas);

      eventListeners.setDetector('fullscreen', toggleFullscreen().on, toggleFullscreen().off);
      map.setPrototype('setFullScreen', () => {
        eventListeners.on('fullscreen', _setFullScreen);
      });

      eventListeners.setDetector('zoom', toggleZoom().on, toggleZoom().off);
      eventListeners.setDetector('drag', toggleDrag().on, toggleDrag().off);
      eventListeners.setDetector('select', selectToggle.on, selectToggle.off);
      eventListeners.setDetector('order', orderToggle.on, orderToggle.off);
    }

    /**
     * Sets the canvas to fullsize as in the same size of the window / content area. But not fullscreen. Note that
     *
     * @method toggleFullSize
     */
    function toggleFullSize() {
      var activeCB;

      if (!caches['fullsize']) {
        caches['fullsize'] = {
          on: (cb) => {
            activeCB = cb;

            window.addEventListener('resize', activeCB);
          },
          off: () => {
            window.removeEventListener('resize', activeCB);
          },
        };
      }

      return caches['fullsize'];
    }
    /**
     * Sets the browser in fullscreen mode.
     *
     * @method toggleFullscreen
     * @param {Function} cb     Callback that fires when this event activates
     * @return {Boolean}        Return the state of this event
     */
    function toggleFullscreen() {
      var activeCB;

      if (!caches['fullscreen']) {
        caches['fullscreen'] = {
          on: (cb) => {
            activeCB = cb;

            window.addEventListener('fullscreen', activeCB);
          },
          off: () => {
            window.removeEventListener('fullscreen', activeCB);
          },
        };

        return caches['fullscreen'];
      }

      return caches['fullscreen'];
    }
    /**
     * Zoom the map. Mousewheel (desktop) and pinch (mobile)
     *
     * @method toggleZoom
     * @param {Function} cb         Callback that fires when this event activates
     * @return {Boolean}            Return the state of this event
     */
    function toggleZoom() {
      var activeCB;

      if (!caches['zoom']) {
        caches['zoom'] = {
          on: (cb) => {
            var pinch = new Hammer.Pinch();
            activeCB = cb;

            hammer.add(pinch);
            hammer.on('pinch', activeCB);
            /* Hamster handles wheel events really nicely */
            hamster.wheel(activeCB);
          },
          off: () => {
            hammer.on('pinch', activeCB);
            hamster.unwheel(activeCB);
          },
        };
      }

      return caches['zoom'];
    }
    /**
     * DragListener (normally used for moving the map)
     *
     * @method toggleDrag
     * @param {Function} cb     Callback that fires when this event activates
     * @return {Boolean}        Return the state of this event
     */
    function toggleDrag() {
      var activeCB;

      if (!caches['drag']) {
        caches['drag'] = {
          on: (cb) => {
            var pan = new Hammer.Pan({
              pointers: 1,
              threshold: 5,
              direction: Hammer.DIRECTION_ALL });
            activeCB = cb;

            hammer.add(pan);
            hammer.on('pan', activeCB);
          },
          off: () => {
            hammer.off('pan', activeCB);
          },
        };
      }

      return caches['drag'];
    }
    /**
     * Selecting something from the map
     *
     * @method toggleSelect
     * @param {Function} cb     Callback that fires when this event activates
     * @return {Boolean}        Return the state of this event
     */
    function toggleSelect() {
      var activeCB;

      if (!caches['select']) {
        caches['select'] = {
          on: (cb) => {
            var tap = new Hammer.Tap();
            activeCB = cb;

            hammer.add(tap);
            hammer.on('tap', activeCB);
          },
          off: () => {
            hammer.off('tap', activeCB);
          },
        };
      }

      return caches['select'];
    }
    /**
     * Selecting something from the map. With mouse you can use the default right click and in touch devices you can use continuous press
     * event (keeping the finger pressed on the screen for a preset time).
     *
     * @method toggleOrder
     * @param {Function} cb     Callback that fires when this event activates
     * @return {Boolean}        Return the state of this event
     */
    function toggleOrder() {
      var activeCB;

      if (!caches['order']) {
        caches['order'] = {
          on: (cb) => {
            activeCB = cb;

            var press = new Hammer.Press();

            hammer.add(press);
            hammer.on('press', clickListener);
            /* We are detecting mouse right click here. This should be in utils */
            mapInstance.canvas.addEventListener('mouseup', (e) => {
              if (e.which === 3) {
                clickListener(e);
              }
            }, true);
          },
          off: () => {
            hammer.off('press', clickListener);
            mapInstance.canvas.removeEventListener('mouseup', clickListener, true);
          },
        };
      }

      return caches['order'];

      function clickListener(e) {
        if (!utils.mouse.isRightClick(e) && e.type !== 'press') {
          return;
        }

        /* Check that finite state is correct and that if desktop, the user clicked right button */
        if (! mapStates.can('objectOrder') && (mapInstance.isSupportedTouch || utils.mouse.isRightClick(e))) {
          return false;
        }

        activeCB(e);
      }
    }
    /**
     * Deactivate the selection of text, by dragging
     *
     * @method toggleMouseTextSelection
     */
    function toggleMouseTextSelection() {
      var bodyStyles = document.getElementsByTagName('body')[0].style;

      bodyStyles.webkitTouchCallout = 'none';
      bodyStyles.webkitUserSelect = 'none';
      bodyStyles.khtmlUserSelect = 'none';
      bodyStyles.mozUserSelect = 'none';
      bodyStyles.msUserSelect = 'none';
      bodyStyles.userSelect = 'none';
    }

    /**
     * Activate the browsers fullScreen mode and expand the canvas to fullsize
     *
     * @private
     * @method _setFullScreen
     */
    function _setFullScreen() {
      utils.resize.toggleFullScreen();
      mapEvents.publish('mapResized');
      resizeCanvas();
    }
    /**
     * Resizes the canvas to the current most wide and high element status.
     * Basically canvas size === window size.
     *
     * @private
     * @method _resizeCanvas
     */
    function resizeCanvas() {
      utils.resize.resizePIXIRenderer(
        mapInstance.getRenderer(),
        mapInstance.drawOnNextTick.bind(mapInstance)
      );
      mapEvents.publish('mapResized');
    }
  }
}());