var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b ||= {})
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __publicField = (obj, key, value) => {
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};

// packages/map/src/map/map.ts
import {
  MOUSE,
  Vector2 as Vector22,
  Vector3 as Vector33,
  Vector4,
  Quaternion,
  Matrix4,
  Spherical,
  Box3,
  Sphere,
  Raycaster as Raycaster2,
  MathUtils as MathUtils2,
  HemisphereLight,
  Clock,
  PerspectiveCamera as PerspectiveCamera2,
  Scene as Scene2,
  WebGLRenderer,
  Object3D as Object3D2
} from "three";
import elementResizeDetectorMaker from "element-resize-detector";
import { debounce } from "lodash-es";

// packages/map/src/map/myCameraControls.ts
import CameraControls from "camera-controls";
import { Vector3, MathUtils } from "three";
var _v3A = new Vector3();
var MyCameraControls = class extends CameraControls {
  constructor() {
    super(...arguments);
    __publicField(this, "truckYDisabled", false);
    __publicField(this, "_truckInternal", (deltaX, deltaY, dragToOffset) => {
      const _this = this;
      const offset = _v3A.copy(_this._camera.position).sub(_this._target);
      const fov = _this._camera.getEffectiveFOV() * MathUtils.DEG2RAD;
      const targetDistance = offset.length() * Math.tan(fov * 0.5);
      const truckX = _this.truckSpeed * deltaX * targetDistance / _this._elementRect.width;
      const pedestalY = _this.truckSpeed * deltaY * targetDistance / _this._elementRect.width;
      if (_this.verticalDragToForward) {
        dragToOffset ? _this.setFocalOffset(
          _this._focalOffsetEnd.x + truckX,
          _this._focalOffsetEnd.y,
          _this._focalOffsetEnd.z,
          true
        ) : _this.truck(truckX, 0, true);
        _this.forward(-pedestalY, true);
      } else {
        dragToOffset ? _this.setFocalOffset(
          _this._focalOffsetEnd.x + truckX,
          _this._focalOffsetEnd.y + pedestalY,
          _this._focalOffsetEnd.z,
          true
        ) : _this.truck(this.truckYDisabled ? 0 : truckX, pedestalY, true);
      }
    });
  }
};

// packages/map/src/utils.ts
import {
  Raycaster,
  Vector2,
  Vector3 as Vector32
} from "three";
function getIntersects({
  event,
  $map,
  scene,
  camera,
  objects
}) {
  const { top, left } = $map.getBoundingClientRect();
  const raycaster = new Raycaster();
  const mouse = new Vector2();
  mouse.x = (event.clientX - left) / $map.clientWidth * 2 - 1;
  mouse.y = -((event.clientY - top) / $map.clientHeight) * 2 + 1;
  raycaster.setFromCamera(mouse, camera);
  const intersects = raycaster.intersectObjects(
    objects || scene.children,
    true
  );
  return intersects;
}
function getWorldPosition({
  event,
  $map,
  scene,
  camera,
  objects
}) {
  const intersects = getIntersects({ event, $map, scene, camera, objects });
  const points = intersects.map((item) => item.point);
  const worldPosition = new Vector32();
  if (points.length > 0) {
    worldPosition.set(points[0].x, points[0].y, points[0].z);
    return { worldPosition, intersects };
  }
  return {};
}
function getObjectsByName(name, parent) {
  const arr = [];
  parent.traverse((item) => {
    if (item.name === name)
      arr.push(item);
  });
  return arr;
}

// packages/map/src/map/createStats.ts
import Stats from "stats.js";
function createStats(container) {
  var _a, _b;
  const stats = new Stats();
  stats.showPanel(0);
  (_a = document.querySelector(`.${container}__stats-wrapper`)) == null ? void 0 : _a.remove();
  (_b = document.getElementById(container)) == null ? void 0 : _b.appendChild(stats.dom);
  stats.dom.className = `.${container}__stats-wrapper`;
  stats.dom.style.cssText = "position: absolute; bottom: 0px; right: 0px; cursor: pointer; opacity: 0.9; z-index: 10000;";
  return stats;
}

// packages/map/src/map/map.ts
import mitt from "mitt";
import { getDollys, getScreenPostion } from "@ktmap/shared";
var subsetOfTHREE = {
  MOUSE,
  Vector2: Vector22,
  Vector3: Vector33,
  Vector4,
  Quaternion,
  Matrix4,
  Spherical,
  Box3,
  Sphere,
  Raycaster: Raycaster2,
  MathUtils: {
    DEG2RAD: MathUtils2.DEG2RAD,
    clamp: MathUtils2.clamp
  }
};
var _Map = class {
  constructor(container, { style = "normal", showStats = false, viewMode = "3D" } = {}) {
    this.container = container;
    __publicField(this, "options");
    __publicField(this, "stats");
    __publicField(this, "scene");
    __publicField(this, "camera");
    __publicField(this, "$map");
    __publicField(this, "renderer");
    __publicField(this, "domElement");
    __publicField(this, "updateSizeMap", /* @__PURE__ */ new Map());
    __publicField(this, "tweenGroupMap", /* @__PURE__ */ new Map());
    __publicField(this, "emitter", mitt());
    __publicField(this, "timer", 0);
    __publicField(this, "viewChanged", false);
    __publicField(this, "cameraControls");
    __publicField(this, "info", {
      fitDistance: 0,
      boundingClientRect: {
        x: 0,
        y: 0,
        left: 0,
        top: 0,
        right: 0,
        bottom: 0,
        width: 0,
        height: 0
      }
    });
    __publicField(this, "reDraw", (time = 3e3) => {
      this.viewChanged = true;
      clearTimeout(this.timer);
      this.timer = setTimeout(() => {
        this.viewChanged = false;
      }, time);
    });
    this.options = { style, showStats, viewMode };
    const { scene, camera, cameraControls, $map, renderer } = this.init();
    this.scene = scene;
    this.camera = camera;
    this.cameraControls = cameraControls;
    this.$map = $map;
    this.renderer = renderer;
    this.domElement = renderer.domElement;
    this.reset();
    this.setShowStats(showStats);
    let isMousedonw = false;
    let time = 0;
    const onMouseDown = (ev) => {
      if (ev.button === 2)
        return;
      isMousedonw = true;
      time = +new Date();
    };
    const onMouseUp = (ev) => {
      if (!isMousedonw)
        return;
      const newTime = +new Date();
      if (newTime - time > 300) {
      } else {
        const { scene: scene2, camera: camera2, $map: $map2 } = this;
        const obj = getWorldPosition({
          event: ev,
          scene: scene2,
          camera: camera2,
          $map: $map2
        });
        let screenPosition;
        if (obj.worldPosition) {
          screenPosition = getScreenPostion({
            worldPosition: obj.worldPosition,
            $map: $map2,
            scene: scene2,
            camera: camera2
          });
        }
        this.emitter.emit("click", __spreadProps(__spreadValues(__spreadValues({}, ev), obj), {
          screenPosition
        }));
      }
      isMousedonw = false;
    };
    const onMouseMove = (ev) => {
      const { scene: scene2, camera: camera2, $map: $map2 } = this;
      const obj = getWorldPosition({
        event: ev,
        scene: scene2,
        camera: camera2,
        $map: $map2
      });
      let screenPosition;
      if (obj.worldPosition) {
        screenPosition = getScreenPostion({
          worldPosition: obj.worldPosition,
          $map: $map2,
          scene: scene2,
          camera: camera2
        });
      }
      this.emitter.emit("mousemove", __spreadProps(__spreadValues(__spreadValues({}, ev), obj), {
        screenPosition
      }));
    };
    this.domElement.removeEventListener("mousedown", onMouseDown);
    this.domElement.removeEventListener("mouseup", onMouseUp);
    this.domElement.ownerDocument.removeEventListener("mousemove", onMouseMove);
    this.domElement.addEventListener("mousedown", onMouseDown);
    this.domElement.addEventListener("mouseup", onMouseUp);
    this.domElement.ownerDocument.addEventListener("mousemove", onMouseMove);
    console.log("map init success");
  }
  generateImage(type = "image/png", quality = 1) {
    const canvas = this.renderer.domElement;
    const img = canvas.toDataURL(type, quality);
    return img;
  }
  getScene() {
    return this.scene;
  }
  add(...objects) {
    const { camera, $map, scene, cameraControls, reDraw } = this;
    for (const item of objects) {
      if (!(item instanceof Object3D2)) {
        item.__inject(this);
        item.__init();
      } else {
        this.scene.add(item);
      }
    }
    this.reDraw();
    return this;
  }
  remove(...object) {
  }
  on(type, handler) {
    this.emitter.on(type, handler);
    return this;
  }
  off(type, handler) {
    this.emitter.off(type, handler);
    return this;
  }
  init() {
    const $map = document.getElementById(this.container);
    const scene = new Scene2();
    const width = $map.clientWidth;
    const height = $map.clientHeight;
    const k = width / height;
    const camera = new PerspectiveCamera2(45, k, 0.01, Math.pow(10, 100));
    camera.up.x = 0;
    camera.up.y = 0;
    camera.up.z = 1;
    camera.lookAt(scene.position);
    const light = new HemisphereLight("#ffffff", "#e7e7e7", 1);
    light.name = "light";
    light.position.set(-100, -100, 0);
    scene.add(light);
    const renderer = new WebGLRenderer({
      preserveDrawingBuffer: true,
      antialias: true,
      alpha: true,
      logarithmicDepthBuffer: true
    });
    renderer.setSize($map.clientWidth, $map.clientHeight);
    renderer.setClearColor("#e7f2fe", 1);
    renderer.setPixelRatio(window.devicePixelRatio);
    $map.appendChild(renderer.domElement);
    renderer.render(scene, camera);
    const onWindowResize = debounce(() => {
      const boundingClientRect = $map.getBoundingClientRect();
      this.info.boundingClientRect = JSON.parse(
        JSON.stringify(boundingClientRect)
      );
      const { width: width2, height: height2 } = this.info.boundingClientRect;
      camera.aspect = width2 / height2;
      camera.updateProjectionMatrix();
      renderer.setSize(width2, height2);
      this.reDraw();
    }, 100);
    const observer = elementResizeDetectorMaker();
    observer.listenTo($map, onWindowResize);
    const cameraControls = this.createCameraControls(
      $map,
      scene,
      camera,
      renderer,
      () => {
        for (const [, value] of this.updateSizeMap) {
          value == null ? void 0 : value();
        }
      },
      this.tweenGroupMap
    );
    return { scene, camera, cameraControls, $map, renderer };
  }
  createCameraControls($map, scene, camera, renderer, updateFn, tweenGroupMap) {
    MyCameraControls.install({ THREE: subsetOfTHREE });
    const clock = new Clock();
    const controls = new MyCameraControls(camera, $map);
    const _this = this;
    (function anim() {
      var _a, _b;
      (_a = _this.stats) == null ? void 0 : _a.begin();
      const delta = clock.getDelta();
      const hasControlsUpdated = controls.update(delta);
      requestAnimationFrame(anim);
      if (hasControlsUpdated || _this.viewChanged) {
        updateFn();
        renderer.render(scene, camera);
      }
      for (const [k] of tweenGroupMap)
        k == null ? void 0 : k.update();
      (_b = _this.stats) == null ? void 0 : _b.end();
    })();
    return controls;
  }
  reset() {
    const { cameraControls, camera } = this;
    cameraControls.dampingFactor = 1;
    cameraControls.draggingDampingFactor = 0.25 * 2;
    cameraControls.dollySpeed = 1 * 1.5;
    cameraControls.verticalDragToForward = true;
    cameraControls.minPolarAngle = 0;
    cameraControls.maxPolarAngle = Math.PI;
    cameraControls.minDistance = 0;
    cameraControls.maxDistance = Infinity;
    cameraControls.minAzimuthAngle = -Infinity;
    cameraControls.maxAzimuthAngle = Infinity;
    camera.fov = 45;
    camera.updateProjectionMatrix();
    return this;
  }
  destroy() {
  }
  addHelper() {
    return this;
  }
  setStyle(style) {
    return this;
  }
  setShowStats(showStats) {
    if (showStats) {
      this.stats = createStats(this.container);
      this.reDraw();
    }
    return this;
  }
  setViewMode(viewMode) {
    this.options.viewMode = viewMode;
    viewMode === "3D" ? this.fitToBox3d() : this.fitToBox2d();
    return this;
  }
  fitToBox2d() {
    const _getTarget = () => {
      const allLevelObjs = getObjectsByName("level", this.scene);
      return allLevelObjs[allLevelObjs.length - 1];
    };
    const target = _getTarget();
    const { fitDistance, dollys } = getDollys(target, this.cameraControls);
    const enableTransition = true;
    this.cameraControls.minPolarAngle = this.cameraControls.maxPolarAngle = this.cameraControls.minAzimuthAngle = this.cameraControls.maxAzimuthAngle = 0;
    this.cameraControls.dollyTo(fitDistance, enableTransition);
    this.cameraControls.rotateTo(0, 0, enableTransition);
    this.cameraControls.moveTo(0, 0, 0, true);
  }
  fitToBox3d() {
    const _getTarget = () => {
      const allLevelObjs = getObjectsByName("level", this.scene);
      return allLevelObjs[allLevelObjs.length - 1];
    };
    const enableTransition = true;
    this.cameraControls.minAzimuthAngle = -Infinity;
    this.cameraControls.maxAzimuthAngle = Infinity;
    const target = _getTarget();
    const { fitDistance, dollys } = getDollys(target, this.cameraControls);
    if (fitDistance) {
      this.cameraControls.dollyTo(fitDistance, enableTransition);
      Object.assign(this.info, {
        fitDistance
      });
    }
    this.cameraControls.rotateTo(0, Math.PI * (60 / 180), enableTransition);
    this.cameraControls.moveTo(0, 0, 0, true);
  }
};

// packages/map/src/base/mitt.ts
import mitt2 from "mitt";
var MyMitt = class {
  constructor() {
    __publicField(this, "emitter", mitt2());
  }
  on(type, handler) {
    this.emitter.on(type, handler);
    return this;
  }
  off(type, handler) {
    this.emitter.off(type, handler);
    return this;
  }
};

// packages/map/src/base/element.ts
var Element = class extends MyMitt {
  constructor() {
    super();
    __publicField(this, "map");
  }
  __inject(map) {
    this.map = map;
    return this;
  }
};

// packages/map/src/base/control.ts
var Control = class extends MyMitt {
  constructor() {
    super();
    __publicField(this, "map");
  }
  __inject(map) {
    this.map = map;
    return this;
  }
};

// packages/map/src/base/service.ts
var Service = class extends MyMitt {
  constructor() {
    super();
  }
};

// packages/map/src/base/infoWindow.ts
var InfoWindow = class extends MyMitt {
  constructor() {
    super();
  }
};

// packages/map/src/base/contextMenu.ts
var ContextMenu = class {
  constructor() {
  }
};

// packages/map/src/index.ts
var KTMap = {
  Map: _Map,
  use(plugins) {
    plugins = Array.isArray(plugins) ? plugins : [plugins];
    for (const item of plugins) {
      this[item.NAME] = item;
    }
    return this;
  }
};
var src_default = KTMap;
export {
  ContextMenu,
  Control,
  Element,
  InfoWindow,
  MyMitt,
  Service,
  src_default as default
};
//# sourceMappingURL=map.esm-bundler.js.map
