API Docs for: 0.1.1
Show:

File: src/components/map/extensions/minimaps/pixelizedMinimap.js

(function () {
  /*-----------------------
  --------- IMPORT --------
  -----------------------*/
  var mapEvents = window.flatworld.mapEvents;
  var eventListeners = window.flatworld.eventListeners;
  var MapDataManipulator = window.flatworld.MapDataManipulator;
  var utils = window.flatworld.utils;
  var Hammer = window.flatworld_libraries.Hammer;

  /*-----------------------
  ---------- API ----------
  -----------------------*/
  window.flatworld.extensions.minimaps.pixelizedMinimap = setupPixelizedMinimap();

  /*-----------------------
  -------- PUBLIC ---------
  -----------------------*/
  /**
   * Pixelized minimap works in situations, where you map a symmetrical map. E.g. hexagon or square based map.
   * It can only be created in sizes that match pixel squares (not sure what it is called). So basically object area on the minimap can be
   * either 1, 4, 9, 16 etc. pixels in size.
   *
   * After plugin has been initialized by the flatworld, you must still call initMinimap to start showing the minimap.
   *
   * @namespace flatworld.extensions.minimaps
   * @class pixelizedMinimap
   **/
  function setupPixelizedMinimap() {
    var paddingX = 0;
    var paddingY = 0;
    var map, minimap, minimapViewport, hammer, coordinateConverterCB, mapMoveTimestamp, dynamicContainer;

    return {
      init,
      pluginName: 'pixelizedMinimap',
      initMinimap,
      _testObject: {

      },
    };
    /**
     * Ínitialize as a plugin. Done by the Flatworld class.
     *
     * @method init
     * @param  {Map} givenMap     Instance of Map
     */
    function init(givenMap) {
      map = givenMap;
      hammer = new Hammer.Manager(map.minimapCanvas);
      map.initMinimap = initMinimap;
      minimap = map.getMinimapLayer();
    }
    /**
     * initMinimap requires some data, to initialize and show the actual minimap.
     *
     * @param  {PIXI.DisplayObject} UIImage         The canvas image that you want to show around the UI element
     * @param  {Integer} {}.x                       x coordinate for the minimap layer
     * @param  {Integer} {}.y                       y coordinate for the minimap layer
     * @return {PIXI.Container}                     minimap layer
     */
    function initMinimap(UIImage, minimapSize, staticCB, dynamicCB, coordinateConvCB, givenMinimapViewport, {
          xPadding = 10,
          yPadding = 10 } = {}) {
      paddingX = xPadding;
      paddingY = yPadding;
      minimap.minimapSize = minimapSize;
      coordinateConverterCB = coordinateConvCB;
      // utils.mouse.disableContextMenu(map.getRenderer('minimap').view);
      setMinimapUI(UIImage);
      setupBackgroundLayer(staticCB);
      setupDynamicLayer(dynamicCB);
      _setMinimapArea(minimap.minimapSize.x, minimap.minimapSize.y, minimap.minimapSize.width, minimap.minimapSize.height);
      setupMinimapViewportEvents();
      setupMinimapClickEvent();
      minimapViewport = givenMinimapViewport;
      minimap.addChild(minimapViewport);

      mapEvents.publish('minimapInitialized', minimap);

      return minimap;
    }
    function setMinimapUI(UIImage) {
      minimap.addChild(UIImage);
    }
    /**
     * Sets up the layer that doesn't change, normally terrain layer. This layer is supposed to be unchanged during this play session, so
     * is is cached for efficiency.
     *
     * @param  {Function} staticCB   Callback that receives each object that is added to the map individually.
     */
    function setupBackgroundLayer(staticCB) {
      const filters = new MapDataManipulator({
        type: 'filter',
        object: 'layer',
        property: 'staticLayer',
        value: true,
      });
      var backgroundContainer = createMinimapLayer();

      map.getAllObjects({ filters }).forEach((obj) => {
        backgroundContainer.addChild(staticCB(obj));
      });

      backgroundContainer.cacheAsBitmap = true;

      minimap.addChild(backgroundContainer);
    }
    function setupDynamicLayer(updateCB) {
      const filters = new MapDataManipulator({
        type: 'filter',
        object: 'object',
        property: 'static',
        value: false,
      });
      dynamicContainer = createMinimapLayer();

      map.getAllObjects({ filters }).forEach((obj) => {
        dynamicContainer.addChild(updateCB(obj));
      });

      dynamicContainer.cacheAsBitmap = true;

      minimap.addChild(dynamicContainer);
    }
    function setupMinimapViewportEvents() {
      mapEvents.subscribe('mapMoved', reactToMapMovement);
      mapEvents.subscribe('mapZoomed', reactToMapScale);
      mapEvents.subscribe('minimapClicked', moveViewport);
    }
    function reactToMapMovement() {
      if (mapMoveTimestamp - Date.now() > -5) {
        return;
      }

      var minimapCoordinates = coordinateConverterCB(map.getMovableLayer(), true);

      minimapViewport.x = minimapCoordinates.x;
      minimapViewport.y = minimapCoordinates.y;

      map.drawOnNextTick();
    }
    function reactToMapScale() {
      minimapViewport.scale.x += 0.1;
      minimapViewport.scale.y = 0.1;
    }
    function moveViewport(datas) {
      var globalCoordinates = utils.mouse.eventData.getHAMMERPointerCoords(datas);
      var mapCoordinates = new PIXI.Point(datas.srcEvent.layerX, datas.srcEvent.layerY);

      globalCoordinates = utils.mouse.coordinatesFromGlobalToRelative(globalCoordinates, map.minimapCanvas);

      /* We need to keep track when the map was moved, so we don't react to this movement */
      mapMoveTimestamp = Date.now();

      /* Select the center of the viewport rectangle */
      globalCoordinates.x -= Math.round(minimapViewport.width / 2);
      globalCoordinates.y -= Math.round(minimapViewport.height / 2);

      mapCoordinates = coordinateConverterCB(globalCoordinates, true);
      minimapViewport.x = mapCoordinates.x;
      minimapViewport.y = mapCoordinates.y;
      mapCoordinates = coordinateConverterCB(globalCoordinates, false);
      map.moveMap(mapCoordinates, { absolute: true, noEvent: true });

      map.drawOnNextTick();
    }
    function setupMinimapClickEvent() {
      var activeCB;
      var minimapClickDetector = {
        on: (cb) => {
          var tap = new Hammer.Tap();
          activeCB = cb;

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

      eventListeners.setDetector('minimapClicked', minimapClickDetector.on, minimapClickDetector.off);

      eventListeners.on('minimapClicked', moveViewport);
    }
    /*-----------------------
    -------- PRIVATE --------
    -----------------------*/
    /**
     * Sets up the minimap area. Like correct position and renderer auto resizing.
     *
     * @param {Integer} x
     * @param {Integer} y
     * @param {Integer} width
     * @param {Integer} height
     */
    function _setMinimapArea(x, y, width, height) {
      var _minimapRenderer = map.getRenderer('minimap');

      minimap.position = new PIXI.Point(x, y);
      _minimapRenderer.autoResize = true;
      _minimapRenderer.resize(width + (paddingX * 2), height + (paddingY * 2));

      map.drawOnNextTick();
    }
    /**
     * Creates minimap layer with proper starting coordinates
     *
     * @return {PIXI.Container}
     */
    function createMinimapLayer() {
      var container = new PIXI.Container();

      container.x = paddingX;
      container.y = paddingY;

      return container;
    }
    function updateMinimapLayer() {
      dynamicContainer.cacheAsBitmap = false;
      dynamicContainer.cacheAsBitmap = true;
    }
  }
})();