@realsee/dnalogel 2.0.0-alpha.7 → 2.0.0-beta.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -28
- package/components/index.js +1450 -0
- package/dist/CSS3DRenderPlugin/Plugin.d.ts +49 -0
- package/dist/CSS3DRenderPlugin/index.d.ts +4 -0
- package/dist/CSS3DRenderPlugin/index.js +234 -0
- package/dist/CSS3DRenderPlugin/utils/createResizeObserver.d.ts +7 -0
- package/dist/CameraMovementPlugin/CameraMovementPlugin.d.ts +7 -0
- package/dist/CameraMovementPlugin/index.d.ts +5 -0
- package/dist/CameraMovementPlugin/index.js +302 -0
- package/dist/CameraMovementPlugin/typing.d.ts +68 -0
- package/dist/ItemLabelPlugin/Plugin.d.ts +4 -0
- package/dist/ItemLabelPlugin/events.type.d.ts +9 -0
- package/dist/ItemLabelPlugin/index.d.ts +9 -0
- package/dist/ItemLabelPlugin/index.js +941 -0
- package/dist/ItemLabelPlugin/typings.d.ts +59 -0
- package/dist/ItemLabelPlugin/utils/getLabelTransform.d.ts +1 -0
- package/dist/ItemLabelPlugin/utils/getStrokeLength.d.ts +5 -0
- package/dist/ItemLabelPlugin/utils/isImpacted.d.ts +6 -0
- package/dist/ItemLabelPlugin/utils/parseData.d.ts +3 -0
- package/dist/ItemLabelPlugin/utils/transform2RenderData.d.ts +3 -0
- package/dist/ModelChassisCompassPlugin/Plugin.d.ts +19 -0
- package/dist/ModelChassisCompassPlugin/index.d.ts +4 -0
- package/dist/ModelChassisCompassPlugin/index.js +145 -0
- package/dist/ModelEntryDoorGuidePlugin/Plugin.d.ts +26 -0
- package/dist/ModelEntryDoorGuidePlugin/index.d.ts +4 -0
- package/dist/ModelEntryDoorGuidePlugin/index.js +196 -0
- package/dist/ModelItemLabelPlugin/ModelItemLabelPlugin.d.ts +4 -0
- package/dist/ModelItemLabelPlugin/events.type.d.ts +9 -0
- package/dist/ModelItemLabelPlugin/index.d.ts +9 -0
- package/dist/ModelItemLabelPlugin/index.js +674 -0
- package/dist/ModelItemLabelPlugin/typings.d.ts +56 -0
- package/dist/ModelItemLabelPlugin/utils/parseData.d.ts +3 -0
- package/dist/ModelRoomLabelPlugin/Assets/roomLabelBg.d.ts +1 -0
- package/dist/ModelRoomLabelPlugin/Controller.d.ts +36 -0
- package/dist/ModelRoomLabelPlugin/index.d.ts +12 -0
- package/dist/ModelRoomLabelPlugin/index.js +541 -0
- package/dist/ModelRoomLabelPlugin/typings.d.ts +35 -0
- package/dist/ModelRoomLabelPlugin/utils/parseData.d.ts +3 -0
- package/dist/ModelTVVideoPlugin/Plugin.d.ts +4 -0
- package/dist/ModelTVVideoPlugin/index.d.ts +5 -0
- package/dist/ModelTVVideoPlugin/index.js +301 -0
- package/dist/ModelTVVideoPlugin/typings.d.ts +25 -0
- package/dist/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
- package/dist/ModelViewPlugin/Plugin.d.ts +17 -0
- package/dist/ModelViewPlugin/index.d.ts +4 -0
- package/dist/ModelViewPlugin/index.js +187 -0
- package/dist/PanoCompassPlugin/Assets/roomInfoIcon.d.ts +1 -0
- package/dist/PanoCompassPlugin/Plugin.d.ts +47 -0
- package/dist/PanoCompassPlugin/getRoomInfoInstance.d.ts +8 -0
- package/dist/PanoCompassPlugin/index.d.ts +8 -0
- package/dist/PanoCompassPlugin/index.js +636 -0
- package/dist/PanoCursorRaycasterPlugin/index.d.ts +48 -0
- package/dist/PanoCursorRaycasterPlugin/index.js +90 -0
- package/dist/PanoMeasurePlugin/Controller/BaseController.d.ts +39 -0
- package/dist/PanoMeasurePlugin/Controller/EditController.d.ts +52 -0
- package/dist/PanoMeasurePlugin/Controller/MixedController.d.ts +44 -0
- package/dist/PanoMeasurePlugin/Controller/ShortcutKeyController.d.ts +12 -0
- package/dist/PanoMeasurePlugin/Controller/WatchController.d.ts +26 -0
- package/dist/PanoMeasurePlugin/Controller/index.d.ts +70 -0
- package/dist/PanoMeasurePlugin/Model/index.d.ts +38 -0
- package/dist/PanoMeasurePlugin/Model/line.d.ts +30 -0
- package/dist/PanoMeasurePlugin/Model/point.d.ts +16 -0
- package/dist/PanoMeasurePlugin/Model/polyline.d.ts +16 -0
- package/dist/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete.svg.d.ts +2 -0
- package/dist/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete_bg.png.d.ts +2 -0
- package/dist/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete_hover_bg.png.d.ts +2 -0
- package/dist/PanoMeasurePlugin/Modules/DeleteDom/index.d.ts +25 -0
- package/dist/PanoMeasurePlugin/Modules/FiveHelper.d.ts +11 -0
- package/dist/PanoMeasurePlugin/Modules/GuideController.d.ts +18 -0
- package/dist/PanoMeasurePlugin/Modules/Magnifier.d.ts +59 -0
- package/dist/PanoMeasurePlugin/Modules/UIController/HTML.d.ts +6 -0
- package/dist/PanoMeasurePlugin/Modules/UIController/MainBtnController.d.ts +18 -0
- package/dist/PanoMeasurePlugin/Modules/UIController/NewMainBtnController.d.ts +12 -0
- package/dist/PanoMeasurePlugin/Modules/UIController/Revoke/index.d.ts +13 -0
- package/dist/PanoMeasurePlugin/Modules/UIController/index.d.ts +20 -0
- package/dist/PanoMeasurePlugin/Modules/UIController/mobileHTML.d.ts +2 -0
- package/dist/PanoMeasurePlugin/Modules/UIController/style.d.ts +19 -0
- package/dist/PanoMeasurePlugin/Modules/rangePiece/html.d.ts +4 -0
- package/dist/PanoMeasurePlugin/Modules/rangePiece/index.d.ts +42 -0
- package/dist/PanoMeasurePlugin/index.d.ts +10 -0
- package/dist/PanoMeasurePlugin/index.js +3996 -0
- package/dist/PanoMeasurePlugin/typings/data.d.ts +32 -0
- package/dist/PanoMeasurePlugin/typings/event.type.d.ts +37 -0
- package/dist/PanoMeasurePlugin/typings/utils.type.d.ts +1 -0
- package/dist/PanoMeasurePlugin/utils/calculateThreeMouse.d.ts +10 -0
- package/dist/PanoMeasurePlugin/utils/clearGroup.d.ts +2 -0
- package/dist/PanoMeasurePlugin/utils/constants.d.ts +4 -0
- package/dist/PanoMeasurePlugin/utils/distanceDom.d.ts +28 -0
- package/dist/PanoMeasurePlugin/utils/findAssociatedLines.d.ts +2 -0
- package/dist/PanoMeasurePlugin/utils/findClosestPoint.d.ts +10 -0
- package/dist/PanoMeasurePlugin/utils/getIntersectionFromEvent.d.ts +4 -0
- package/dist/PanoMeasurePlugin/utils/getPointFromHammerEvent.d.ts +10 -0
- package/dist/PanoMeasurePlugin/utils/ironbox.d.ts +1 -0
- package/dist/PanoMeasurePlugin/utils/isNDCPointInScreen.d.ts +2 -0
- package/dist/PanoMeasurePlugin/utils/line.d.ts +17 -0
- package/dist/PanoMeasurePlugin/utils/math.d.ts +17 -0
- package/dist/PanoMeasurePlugin/utils/mouseGroup.d.ts +2 -0
- package/dist/PanoMeasurePlugin/utils/ndc2Screen.d.ts +5 -0
- package/dist/PanoRulerPlugin/Plugin.d.ts +31 -0
- package/dist/PanoRulerPlugin/index.d.ts +5 -0
- package/dist/PanoRulerPlugin/index.js +610 -0
- package/dist/PanoRulerPlugin/style.d.ts +2 -0
- package/dist/PanoRulerPlugin/typings.d.ts +21 -0
- package/dist/PanoSpatialTagPlugin/Plugin.d.ts +35 -0
- package/dist/PanoSpatialTagPlugin/index.d.ts +5 -0
- package/dist/PanoSpatialTagPlugin/index.js +1307 -0
- package/dist/PanoSpatialTagPlugin/store.d.ts +1 -0
- package/dist/PanoSpatialTagPlugin/style.d.ts +1 -0
- package/dist/PanoSpatialTagPlugin/typings.d.ts +40 -0
- package/dist/base/BasePlugin.d.ts +100 -0
- package/dist/base/BasePluginWithData.d.ts +34 -0
- package/dist/components/PaintBrush/Controller.d.ts +43 -0
- package/dist/components/PaintBrush/Subscribe.d.ts +76 -0
- package/dist/components/PaintBrush/index.d.ts +27 -0
- package/dist/components/PaintBrush/style.d.ts +2 -0
- package/dist/components/PaintBrush/tween.d.ts +62 -0
- package/dist/components/PaintBrush/typings.d.ts +58 -0
- package/dist/components/PaintBrush/utils.d.ts +26 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/floorplan/Assets/camera.d.ts +1 -0
- package/dist/floorplan/Assets/compass.d.ts +1 -0
- package/dist/floorplan/Assets/floorplanExtraObject.d.ts +1 -0
- package/dist/floorplan/ModelFloorplanPlugin/Controller.d.ts +97 -0
- package/dist/floorplan/ModelFloorplanPlugin/index.d.ts +7 -0
- package/dist/floorplan/ModelFloorplanPlugin/index.js +4526 -0
- package/dist/floorplan/ModelFloorplanPlugin/typing.d.ts +107 -0
- package/dist/floorplan/ModelFloorplanPlugin/typings/events.type.d.ts +23 -0
- package/dist/floorplan/ModelFloorplanPlugin/utils/constant.d.ts +15 -0
- package/dist/floorplan/ModelFloorplanPlugin/utils/correctFiveState.d.ts +14 -0
- package/dist/floorplan/PanoFloorplanRadarPlugin/Controller.d.ts +36 -0
- package/dist/floorplan/PanoFloorplanRadarPlugin/index.d.ts +7 -0
- package/dist/floorplan/PanoFloorplanRadarPlugin/index.js +2008 -0
- package/dist/floorplan/PanoFloorplanRadarPlugin/typing.d.ts +52 -0
- package/dist/floorplan/TopviewFloorplanPlugin/Controller.d.ts +67 -0
- package/dist/floorplan/TopviewFloorplanPlugin/index.d.ts +7 -0
- package/dist/floorplan/TopviewFloorplanPlugin/index.js +4236 -0
- package/dist/floorplan/TopviewFloorplanPlugin/style.d.ts +1 -0
- package/dist/floorplan/TopviewFloorplanPlugin/typing.d.ts +86 -0
- package/dist/floorplan/constant.d.ts +5 -0
- package/dist/floorplan/index.d.ts +6 -0
- package/dist/floorplan/typings/floorplanData.d.ts +137 -0
- package/dist/floorplan/typings/floorplanServerData.d.ts +131 -0
- package/dist/floorplan/typings/utility.d.ts +2 -0
- package/dist/floorplan/utils/constant.d.ts +22 -0
- package/dist/floorplan/utils/correctFiveState.d.ts +15 -0
- package/dist/floorplan/utils/formatData.d.ts +5 -0
- package/dist/floorplan/utils/formatPosition.d.ts +36 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.es.js +15436 -0
- package/dist/index.js +15488 -0
- package/dist/index.umd.js +15480 -0
- package/dist/shared-utils/Preloader.d.ts +6 -0
- package/dist/shared-utils/Subscribe.d.ts +45 -0
- package/dist/shared-utils/animationFrame/BetterTween.d.ts +11 -0
- package/dist/shared-utils/animationFrame/calculateProgress.d.ts +8 -0
- package/dist/shared-utils/animationFrame/formatRad.d.ts +15 -0
- package/dist/shared-utils/animationFrame/index.d.ts +15 -0
- package/dist/shared-utils/animationFrame/tween.d.ts +75 -0
- package/dist/shared-utils/changeModelCanvasOpacity.d.ts +2 -0
- package/dist/shared-utils/createCanvasTextTexture.d.ts +8 -0
- package/dist/shared-utils/createLine/index.d.ts +3 -0
- package/dist/shared-utils/debounce.d.ts +6 -0
- package/dist/shared-utils/equal.d.ts +11 -0
- package/dist/shared-utils/filter.d.ts +27 -0
- package/dist/shared-utils/five/changeMode.d.ts +5 -0
- package/dist/shared-utils/formatRad.d.ts +7 -0
- package/dist/shared-utils/getPxmm.d.ts +19 -0
- package/dist/shared-utils/getRandomColor.d.ts +1 -0
- package/dist/shared-utils/index.d.ts +1 -0
- package/dist/shared-utils/isNil.d.ts +10 -0
- package/dist/shared-utils/isTruelyObject.d.ts +18 -0
- package/dist/shared-utils/math/Interval.d.ts +13 -0
- package/dist/shared-utils/math/Rectangle.d.ts +27 -0
- package/dist/shared-utils/math/evenNumber.d.ts +3 -0
- package/dist/shared-utils/math/index.d.ts +2 -0
- package/dist/shared-utils/math/planimetry.d.ts +116 -0
- package/dist/shared-utils/math/rad2Deg.d.ts +1 -0
- package/dist/shared-utils/nearlyEqual.d.ts +7 -0
- package/dist/shared-utils/nextFrame.d.ts +1 -0
- package/dist/shared-utils/noop.d.ts +5 -0
- package/dist/shared-utils/object3d2LocalMatrix.d.ts +12 -0
- package/dist/shared-utils/px2rem.d.ts +1 -0
- package/dist/shared-utils/removeArrayItem.d.ts +7 -0
- package/dist/shared-utils/tap.d.ts +8 -0
- package/dist/shared-utils/three/centerPoint.d.ts +2 -0
- package/dist/shared-utils/three/getExtraModelLoader.d.ts +6 -0
- package/dist/shared-utils/three/getNormal.d.ts +2 -0
- package/dist/shared-utils/three/getTextureLoader.d.ts +6 -0
- package/dist/shared-utils/three/loadFbxObj.d.ts +2 -0
- package/dist/shared-utils/three/loadTexture.d.ts +2 -0
- package/dist/shared-utils/three/transformPositionToVector3.d.ts +7 -0
- package/dist/shared-utils/three/transfromToMeshBasicMaterial.d.ts +2 -0
- package/dist/shared-utils/throttle.d.ts +7 -0
- package/dist/shared-utils/tinyEJSrender.d.ts +5 -0
- package/dist/shared-utils/to.d.ts +8 -0
- package/dist/shared-utils/uuid.d.ts +5 -0
- package/dist/shared-utils/vectorTocoordinates.d.ts +7 -0
- package/dist/typings/math.type.d.ts +44 -0
- package/dist/typings/utils.type.d.ts +2 -0
- package/docs/.nojekyll +1 -0
- package/docs/assets/highlight.css +78 -0
- package/docs/assets/icons.css +1043 -0
- package/docs/assets/icons.png +0 -0
- package/docs/assets/icons@2x.png +0 -0
- package/docs/assets/main.js +52 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1413 -0
- package/docs/assets/widgets.png +0 -0
- package/docs/assets/widgets@2x.png +0 -0
- package/docs/classes/Magnifier.html +9 -0
- package/docs/classes/ModelRoomLabelController.html +17 -0
- package/docs/enums/CameraMovementEffect.html +3 -0
- package/docs/enums/DIRECTION.html +1 -0
- package/docs/enums/DISPLAY_STRATEGY_TYPE.html +1 -0
- package/docs/enums/FLOOR_PLAN_ATTACHED_TO.html +1 -0
- package/docs/enums/ITEM_LABEL_PLUGIN_DISPLAY_STRATEGY_TYPE.html +1 -0
- package/docs/enums/Rotation.html +3 -0
- package/docs/index.html +88 -0
- package/docs/interfaces/CSS3DRenderPluginExportType.html +4 -0
- package/docs/interfaces/CameraMovementPluginExportType.html +17 -0
- package/docs/interfaces/FloorplanBounding.html +10 -0
- package/docs/interfaces/FloorplanData.html +3 -0
- package/docs/interfaces/FloorplanEntrance.html +15 -0
- package/docs/interfaces/FloorplanExtraObject.html +7 -0
- package/docs/interfaces/FloorplanExtraObject3D.html +3 -0
- package/docs/interfaces/FloorplanFloorData.html +3 -0
- package/docs/interfaces/FloorplanImagePosition.html +3 -0
- package/docs/interfaces/FloorplanObserver.html +5 -0
- package/docs/interfaces/FloorplanOutlineItem.html +3 -0
- package/docs/interfaces/FloorplanPosition.html +3 -0
- package/docs/interfaces/FloorplanRoomItem.html +17 -0
- package/docs/interfaces/FloorplanRoomLabelItem.html +7 -0
- package/docs/interfaces/FloorplanServerBounding.html +10 -0
- package/docs/interfaces/FloorplanServerComputedData.html +1 -0
- package/docs/interfaces/FloorplanServerData.html +3 -0
- package/docs/interfaces/FloorplanServerEntrance.html +15 -0
- package/docs/interfaces/FloorplanServerFloorData.html +3 -0
- package/docs/interfaces/FloorplanServerImagePosition.html +3 -0
- package/docs/interfaces/FloorplanServerObserver.html +5 -0
- package/docs/interfaces/FloorplanServerOutlineItem.html +3 -0
- package/docs/interfaces/FloorplanServerPosition.html +3 -0
- package/docs/interfaces/FloorplanServerRoomItem.html +20 -0
- package/docs/interfaces/FloorplanServerRoomLabelItem.html +7 -0
- package/docs/interfaces/ItemLabelPluginData.html +1 -0
- package/docs/interfaces/ItemLabelPluginExportReturnsType.html +1 -0
- package/docs/interfaces/ItemLabelPluginParametersType.html +1 -0
- package/docs/interfaces/LineJson.html +1 -0
- package/docs/interfaces/ModelChassisCompassPluginData.html +1 -0
- package/docs/interfaces/ModelChassisCompassPluginExportType.html +1 -0
- package/docs/interfaces/ModelChassisCompassPluginParameterType.html +1 -0
- package/docs/interfaces/ModelEntryDoorGuidePluginData.html +1 -0
- package/docs/interfaces/ModelEntryDoorGuidePluginExportType.html +1 -0
- package/docs/interfaces/ModelItemLabelPluginData.html +1 -0
- package/docs/interfaces/ModelItemLabelPluginExportReturnsType.html +1 -0
- package/docs/interfaces/ModelItemLabelPluginParametersType.html +1 -0
- package/docs/interfaces/ModelRoomLabelPluginData.html +1 -0
- package/docs/interfaces/ModelTVVideoPluginData.html +1 -0
- package/docs/interfaces/ModelTVVideoPluginExportType.html +1 -0
- package/docs/interfaces/ModelTVVideoPluginParameterType.html +1 -0
- package/docs/interfaces/ModelViewPluginExportType.html +1 -0
- package/docs/interfaces/OpenParameter.html +3 -0
- package/docs/interfaces/PanoCompassPluginData.html +1 -0
- package/docs/interfaces/PanoCompassPluginParameterType.html +1 -0
- package/docs/interfaces/PanoCursorRaycasterPluginExportType.html +11 -0
- package/docs/interfaces/PanoCursorRaycasterPluginParameterType.html +1 -0
- package/docs/interfaces/PanoMeasureParameterType.html +1 -0
- package/docs/interfaces/PanoRulerPluginExportType.html +1 -0
- package/docs/interfaces/PanoRulerPluginOptions.html +1 -0
- package/docs/interfaces/PanoRulerPluginParameterType.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginContentEvent.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginContentReplacement.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginData.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginDataElement.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginExportType.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginOriginElement.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginParameterType.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginPointElement.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginTagElement.html +1 -0
- package/docs/interfaces/Point.html +1 -0
- package/docs/interfaces/PointJson.html +1 -0
- package/docs/interfaces/Room.html +1 -0
- package/docs/interfaces/RoomInfo.html +1 -0
- package/docs/interfaces/RoomLabel.html +13 -0
- package/docs/interfaces/RoomRules.html +1 -0
- package/docs/interfaces/Rooms.html +1 -0
- package/docs/modules.html +34 -0
- package/libs/CSS3DRenderPlugin/Plugin.d.ts +49 -0
- package/libs/CSS3DRenderPlugin/Plugin.js +182 -0
- package/libs/CSS3DRenderPlugin/index.d.ts +3 -48
- package/libs/CSS3DRenderPlugin/index.js +2 -180
- package/libs/CameraMovementPlugin/CameraMovementPlugin.d.ts +7 -0
- package/libs/CameraMovementPlugin/CameraMovementPlugin.js +159 -0
- package/libs/CameraMovementPlugin/index.d.ts +4 -6
- package/libs/CameraMovementPlugin/index.js +3 -158
- package/libs/CameraMovementPlugin/typing.d.ts +1 -1
- package/libs/ItemLabelPlugin/ItemLabelComponent.js +577 -0
- package/libs/ItemLabelPlugin/ItemLabelItem.js +227 -0
- package/libs/ItemLabelPlugin/Plugin.d.ts +4 -0
- package/libs/ItemLabelPlugin/Plugin.js +120 -0
- package/libs/ItemLabelPlugin/events.type.d.ts +9 -0
- package/libs/ItemLabelPlugin/events.type.js +1 -0
- package/libs/ItemLabelPlugin/index.d.ts +9 -0
- package/libs/ItemLabelPlugin/index.js +8 -0
- package/libs/ItemLabelPlugin/typings.d.ts +59 -0
- package/libs/ItemLabelPlugin/typings.js +7 -0
- package/libs/ItemLabelPlugin/utils/getLabelTransform.d.ts +1 -0
- package/libs/ItemLabelPlugin/utils/getLabelTransform.js +3 -0
- package/libs/ItemLabelPlugin/utils/getStrokeLength.d.ts +5 -0
- package/libs/ItemLabelPlugin/utils/getStrokeLength.js +16 -0
- package/libs/ItemLabelPlugin/utils/isImpacted.d.ts +6 -0
- package/libs/ItemLabelPlugin/utils/isImpacted.js +13 -0
- package/libs/ItemLabelPlugin/utils/parseData.d.ts +3 -0
- package/libs/ItemLabelPlugin/utils/parseData.js +4 -0
- package/libs/ItemLabelPlugin/utils/transform2RenderData.d.ts +3 -0
- package/libs/ItemLabelPlugin/utils/transform2RenderData.js +4 -0
- package/libs/ModelChassisCompassPlugin/Plugin.d.ts +19 -0
- package/libs/ModelChassisCompassPlugin/Plugin.js +77 -0
- package/libs/ModelChassisCompassPlugin/index.d.ts +3 -18
- package/libs/ModelChassisCompassPlugin/index.js +2 -74
- package/libs/ModelEntryDoorGuidePlugin/Plugin.d.ts +26 -0
- package/libs/ModelEntryDoorGuidePlugin/Plugin.js +140 -0
- package/libs/ModelEntryDoorGuidePlugin/index.d.ts +3 -25
- package/libs/ModelEntryDoorGuidePlugin/index.js +2 -135
- package/libs/ModelItemLabelPlugin/ItemLabelComponent.js +409 -0
- package/libs/ModelItemLabelPlugin/ItemLabelItem.js +133 -0
- package/libs/ModelItemLabelPlugin/ModelItemLabelPlugin.d.ts +4 -0
- package/libs/ModelItemLabelPlugin/ModelItemLabelPlugin.js +120 -0
- package/libs/ModelItemLabelPlugin/events.type.d.ts +9 -0
- package/libs/ModelItemLabelPlugin/events.type.js +1 -0
- package/libs/ModelItemLabelPlugin/index.d.ts +9 -0
- package/libs/ModelItemLabelPlugin/index.js +8 -0
- package/libs/ModelItemLabelPlugin/typings.d.ts +56 -0
- package/libs/ModelItemLabelPlugin/typings.js +7 -0
- package/libs/ModelItemLabelPlugin/utils/parseData.d.ts +3 -0
- package/libs/ModelItemLabelPlugin/utils/parseData.js +4 -0
- package/libs/ModelRoomLabelPlugin/Controller.js +67 -25
- package/libs/ModelRoomLabelPlugin/RoomLabelItem.js +121 -0
- package/libs/ModelRoomLabelPlugin/RoomLabelItems.js +291 -0
- package/libs/ModelRoomLabelPlugin/utils/parseData.d.ts +1 -1
- package/libs/ModelSimulationPlugin/index.d.ts +33 -0
- package/libs/ModelSimulationPlugin/index.js +166 -0
- package/libs/ModelSimulationPlugin/shaders/fragment.d.ts +2 -0
- package/libs/ModelSimulationPlugin/shaders/fragment.js +96 -0
- package/libs/ModelSimulationPlugin/shaders/vertex.d.ts +2 -0
- package/libs/ModelSimulationPlugin/shaders/vertex.js +23 -0
- package/libs/ModelTVVideoPlugin/Plugin.d.ts +4 -0
- package/libs/ModelTVVideoPlugin/Plugin.js +254 -0
- package/libs/ModelTVVideoPlugin/index.d.ts +5 -0
- package/libs/ModelTVVideoPlugin/index.js +4 -0
- package/libs/ModelTVVideoPlugin/typings.d.ts +25 -0
- package/libs/ModelTVVideoPlugin/typings.js +8 -0
- package/libs/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
- package/libs/ModelTVVideoPlugin/utils/parseData.js +13 -0
- package/libs/ModelViewPlugin/Plugin.d.ts +17 -0
- package/libs/ModelViewPlugin/Plugin.js +160 -0
- package/libs/ModelViewPlugin/index.d.ts +3 -16
- package/libs/ModelViewPlugin/index.js +2 -159
- package/libs/PanoCompassPlugin/Plugin.d.ts +47 -0
- package/libs/PanoCompassPlugin/Plugin.js +249 -0
- package/libs/PanoCompassPlugin/index.d.ts +4 -47
- package/libs/PanoCompassPlugin/index.js +3 -167
- package/libs/PanoCursorRaycasterPlugin/index.d.ts +1 -1
- package/libs/PanoCursorRaycasterPlugin/index.js +5 -3
- package/libs/PanoMeasurePlugin/Controller/BaseController.d.ts +12 -9
- package/libs/PanoMeasurePlugin/Controller/BaseController.js +77 -14
- package/libs/PanoMeasurePlugin/Controller/EditController.d.ts +1 -1
- package/libs/PanoMeasurePlugin/Controller/EditController.js +267 -154
- package/libs/PanoMeasurePlugin/Controller/MixedController.d.ts +44 -0
- package/libs/PanoMeasurePlugin/Controller/MixedController.js +337 -0
- package/libs/PanoMeasurePlugin/Controller/ShortcutKeyController.d.ts +2 -2
- package/libs/PanoMeasurePlugin/Controller/ShortcutKeyController.js +40 -20
- package/libs/PanoMeasurePlugin/Controller/WatchController.d.ts +2 -1
- package/libs/PanoMeasurePlugin/Controller/WatchController.js +246 -153
- package/libs/PanoMeasurePlugin/Controller/index.d.ts +18 -9
- package/libs/PanoMeasurePlugin/Controller/index.js +182 -54
- package/libs/PanoMeasurePlugin/Model/index.d.ts +2 -2
- package/libs/PanoMeasurePlugin/Model/index.js +30 -5
- package/libs/PanoMeasurePlugin/Model/line.d.ts +5 -5
- package/libs/PanoMeasurePlugin/Model/line.js +61 -11
- package/libs/PanoMeasurePlugin/Model/point.d.ts +2 -2
- package/libs/PanoMeasurePlugin/Model/point.js +24 -4
- package/libs/PanoMeasurePlugin/Model/polyline.d.ts +3 -3
- package/libs/PanoMeasurePlugin/Model/polyline.js +20 -3
- package/libs/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete.svg.d.ts +1 -1
- package/libs/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete.svg.js +11 -14
- package/libs/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete_bg.png.d.ts +1 -1
- package/libs/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete_bg.png.js +1 -1
- package/libs/PanoMeasurePlugin/Modules/DeleteDom/index.d.ts +5 -2
- package/libs/PanoMeasurePlugin/Modules/DeleteDom/index.js +107 -25
- package/libs/PanoMeasurePlugin/Modules/FiveHelper.d.ts +1 -1
- package/libs/PanoMeasurePlugin/Modules/FiveHelper.js +23 -8
- package/libs/PanoMeasurePlugin/Modules/GuideController.d.ts +1 -1
- package/libs/PanoMeasurePlugin/Modules/GuideController.js +61 -26
- package/libs/PanoMeasurePlugin/Modules/Magnifier.d.ts +50 -15
- package/libs/PanoMeasurePlugin/Modules/Magnifier.js +234 -59
- package/libs/PanoMeasurePlugin/Modules/UIController/MainBtnController.d.ts +1 -1
- package/libs/PanoMeasurePlugin/Modules/UIController/MainBtnController.js +84 -38
- package/libs/PanoMeasurePlugin/Modules/UIController/NewMainBtnController.d.ts +12 -0
- package/libs/PanoMeasurePlugin/Modules/UIController/NewMainBtnController.js +98 -0
- package/libs/PanoMeasurePlugin/Modules/UIController/Revoke/index.d.ts +2 -1
- package/libs/PanoMeasurePlugin/Modules/UIController/Revoke/index.js +52 -17
- package/libs/PanoMeasurePlugin/Modules/UIController/index.d.ts +5 -1
- package/libs/PanoMeasurePlugin/Modules/UIController/index.js +84 -34
- package/libs/PanoMeasurePlugin/Modules/UIController/mobileHTML.d.ts +2 -0
- package/libs/PanoMeasurePlugin/Modules/UIController/mobileHTML.js +80 -0
- package/libs/PanoMeasurePlugin/Modules/UIController/style.d.ts +2 -0
- package/libs/PanoMeasurePlugin/Modules/UIController/style.js +11 -1
- package/libs/PanoMeasurePlugin/Modules/rangePiece/html.d.ts +4 -0
- package/libs/PanoMeasurePlugin/Modules/rangePiece/html.js +64 -0
- package/libs/PanoMeasurePlugin/Modules/rangePiece/index.d.ts +42 -0
- package/libs/PanoMeasurePlugin/Modules/rangePiece/index.js +265 -0
- package/libs/PanoMeasurePlugin/index.d.ts +9 -6
- package/libs/PanoMeasurePlugin/index.js +3 -1
- package/libs/PanoMeasurePlugin/typings/data.d.ts +4 -0
- package/libs/PanoMeasurePlugin/typings/event.type.d.ts +14 -5
- package/libs/PanoMeasurePlugin/utils/calculateThreeMouse.d.ts +10 -0
- package/libs/PanoMeasurePlugin/utils/calculateThreeMouse.js +15 -0
- package/libs/PanoMeasurePlugin/utils/clearGroup.d.ts +1 -1
- package/libs/PanoMeasurePlugin/utils/constants.d.ts +1 -1
- package/libs/PanoMeasurePlugin/utils/constants.js +7 -7
- package/libs/PanoMeasurePlugin/utils/distanceDom.d.ts +3 -3
- package/libs/PanoMeasurePlugin/utils/distanceDom.js +22 -16
- package/libs/PanoMeasurePlugin/utils/findAssociatedLines.d.ts +1 -1
- package/libs/PanoMeasurePlugin/utils/findClosestPoint.d.ts +3 -3
- package/libs/PanoMeasurePlugin/utils/getIntersectionFromEvent.d.ts +2 -2
- package/libs/PanoMeasurePlugin/utils/getPointFromHammerEvent.d.ts +1 -1
- package/libs/PanoMeasurePlugin/utils/isNDCPointInScreen.d.ts +1 -1
- package/libs/PanoMeasurePlugin/utils/line.d.ts +1 -1
- package/libs/PanoMeasurePlugin/utils/line.js +8 -7
- package/libs/PanoMeasurePlugin/utils/mouseGroup.d.ts +2 -2
- package/libs/PanoMeasurePlugin/utils/mouseGroup.js +5 -5
- package/libs/PanoRulerPlugin/Plugin.d.ts +31 -0
- package/libs/PanoRulerPlugin/Plugin.js +403 -0
- package/libs/PanoRulerPlugin/index.d.ts +4 -30
- package/libs/PanoRulerPlugin/index.js +2 -397
- package/libs/PanoSpatialTagPlugin/Components/origins.js +168 -0
- package/libs/PanoSpatialTagPlugin/Components/tag.js +302 -0
- package/libs/PanoSpatialTagPlugin/Plugin.d.ts +35 -0
- package/libs/PanoSpatialTagPlugin/Plugin.js +426 -0
- package/libs/PanoSpatialTagPlugin/index.d.ts +5 -0
- package/libs/PanoSpatialTagPlugin/index.js +5 -0
- package/libs/PanoSpatialTagPlugin/store.d.ts +1 -0
- package/libs/PanoSpatialTagPlugin/store.js +2 -0
- package/libs/PanoSpatialTagPlugin/style.d.ts +1 -0
- package/libs/PanoSpatialTagPlugin/style.js +8 -0
- package/libs/PanoSpatialTagPlugin/typings.d.ts +40 -0
- package/libs/PanoSpatialTagPlugin/typings.js +1 -0
- package/libs/base/BasePlugin.d.ts +100 -0
- package/libs/base/BasePlugin.js +31 -0
- package/libs/base/BasePluginWithData.d.ts +34 -0
- package/libs/base/BasePluginWithData.js +4 -0
- package/libs/components/PaintBrush/Controller.d.ts +43 -0
- package/libs/components/PaintBrush/Controller.js +575 -0
- package/libs/components/PaintBrush/Subscribe.d.ts +76 -0
- package/libs/components/PaintBrush/Subscribe.js +121 -0
- package/libs/components/PaintBrush/index.d.ts +27 -0
- package/libs/components/PaintBrush/index.js +57 -0
- package/libs/components/PaintBrush/style.d.ts +2 -0
- package/libs/components/PaintBrush/style.js +102 -0
- package/libs/components/PaintBrush/tween.d.ts +62 -0
- package/libs/components/PaintBrush/tween.js +15 -0
- package/libs/components/PaintBrush/typings.d.ts +58 -0
- package/libs/components/PaintBrush/typings.js +6 -0
- package/libs/components/PaintBrush/utils.d.ts +26 -0
- package/libs/components/PaintBrush/utils.js +51 -0
- package/libs/components/index.d.ts +2 -0
- package/libs/components/index.js +3 -0
- package/libs/floorplan/Assets/compass.d.ts +1 -0
- package/libs/floorplan/Assets/compass.js +1 -0
- package/libs/floorplan/Components/BaseImage.js +222 -0
- package/libs/floorplan/Components/Camera.js +120 -0
- package/libs/floorplan/Components/Compass.js +120 -0
- package/libs/floorplan/Components/CurrentFloor.js +469 -0
- package/libs/floorplan/Components/Main.js +470 -0
- package/libs/floorplan/Components/Normalmage.js +63 -0
- package/libs/floorplan/Components/RoomHighlight/Room.js +107 -0
- package/libs/floorplan/Components/RoomHighlight/RoomHighlight.js +216 -0
- package/libs/floorplan/Components/RoomLabels/RoomLabel.js +322 -0
- package/libs/floorplan/Components/RoomLabels/RoomLabels.js +309 -0
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial.js +331 -0
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial_0.js +64 -0
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial_1.js +104 -0
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial_2.js +142 -0
- package/libs/floorplan/Components/RuleLabels/RuleItem.js +284 -0
- package/libs/floorplan/Components/RuleLabels/RuleLabels.js +269 -0
- package/libs/floorplan/Components/SvgImage.js +83 -0
- package/libs/floorplan/ModelFloorplanPlugin/Components/Camera.js +120 -0
- package/libs/floorplan/ModelFloorplanPlugin/Components/Compass.js +106 -0
- package/libs/floorplan/ModelFloorplanPlugin/Components/CurrentFloor/CurrentFloor.js +463 -0
- package/libs/floorplan/ModelFloorplanPlugin/Components/Main.js +375 -0
- package/libs/floorplan/ModelFloorplanPlugin/Components/RoomLabels/RoomLabel.js +171 -0
- package/libs/floorplan/ModelFloorplanPlugin/Components/RoomLabels/RoomLabels.js +265 -0
- package/libs/floorplan/ModelFloorplanPlugin/Components/RuleLabels/RuleItem.js +301 -0
- package/libs/floorplan/ModelFloorplanPlugin/Components/RuleLabels/RuleLabels.js +219 -0
- package/libs/floorplan/ModelFloorplanPlugin/Controller.d.ts +70 -77
- package/libs/floorplan/ModelFloorplanPlugin/Controller.js +661 -326
- package/libs/floorplan/ModelFloorplanPlugin/index.d.ts +5 -7
- package/libs/floorplan/ModelFloorplanPlugin/index.js +2 -2
- package/libs/floorplan/ModelFloorplanPlugin/typing.d.ts +107 -0
- package/libs/floorplan/ModelFloorplanPlugin/typing.js +1 -0
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/Camera.js +168 -0
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/CurrentFloor/CurrentFloor.js +250 -0
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/CurrentFloor/ExtraObjects.js +154 -0
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/Main.js +373 -0
- package/libs/floorplan/PanoFloorplanRadarPlugin/Controller.d.ts +24 -16
- package/libs/floorplan/PanoFloorplanRadarPlugin/Controller.js +195 -43
- package/libs/floorplan/PanoFloorplanRadarPlugin/index.d.ts +5 -6
- package/libs/floorplan/PanoFloorplanRadarPlugin/index.js +2 -2
- package/libs/floorplan/PanoFloorplanRadarPlugin/typing.d.ts +52 -0
- package/libs/floorplan/PanoFloorplanRadarPlugin/typing.js +1 -0
- package/libs/floorplan/TopviewFloorplanPlugin/Controller.d.ts +53 -47
- package/libs/floorplan/TopviewFloorplanPlugin/Controller.js +450 -154
- package/libs/floorplan/TopviewFloorplanPlugin/index.d.ts +6 -4
- package/libs/floorplan/TopviewFloorplanPlugin/index.js +2 -2
- package/libs/floorplan/TopviewFloorplanPlugin/style.js +1 -1
- package/libs/floorplan/TopviewFloorplanPlugin/typing.d.ts +86 -0
- package/libs/floorplan/TopviewFloorplanPlugin/typing.js +1 -0
- package/libs/floorplan/index.d.ts +6 -0
- package/libs/floorplan/index.js +7 -0
- package/libs/floorplan/utils/constant.d.ts +22 -0
- package/libs/floorplan/utils/constant.js +23 -0
- package/libs/floorplan/utils/correctFiveState.d.ts +15 -0
- package/libs/floorplan/utils/correctFiveState.js +46 -0
- package/libs/floorplan/utils/formatPosition.d.ts +1 -1
- package/libs/floorplan/utils/formatPosition.js +3 -3
- package/libs/index.d.ts +15 -24
- package/libs/index.js +25 -14
- package/libs/shared-utils/Subscribe.js +8 -1
- package/libs/shared-utils/animationFrame/BetterTween.js +47 -18
- package/libs/shared-utils/createCanvasTextTexture.js +6 -5
- package/libs/shared-utils/five/changeMode.d.ts +4 -1
- package/libs/shared-utils/five/changeMode.js +34 -13
- package/libs/shared-utils/getPxmm.d.ts +8 -0
- package/libs/shared-utils/getPxmm.js +25 -20
- package/libs/shared-utils/index.d.ts +1 -0
- package/libs/shared-utils/index.js +1 -0
- package/libs/shared-utils/math/Interval.d.ts +13 -0
- package/libs/shared-utils/math/Interval.js +40 -0
- package/libs/shared-utils/math/Rectangle.d.ts +27 -0
- package/libs/shared-utils/math/Rectangle.js +50 -0
- package/libs/shared-utils/math/evenNumber.js +1 -1
- package/libs/shared-utils/math/index.d.ts +2 -0
- package/libs/shared-utils/math/index.js +2 -0
- package/libs/shared-utils/three/getExtraModelLoader.d.ts +1 -1
- package/libs/shared-utils/three/getNormal.d.ts +1 -1
- package/libs/shared-utils/three/getTextureLoader.d.ts +1 -1
- package/libs/shared-utils/three/loadFbxObj.d.ts +1 -1
- package/libs/shared-utils/three/transfromToMeshBasicMaterial.js +2 -1
- package/libs/shared-utils/tinyEJSrender.d.ts +5 -0
- package/libs/shared-utils/tinyEJSrender.js +210 -0
- package/libs/shared-utils/uuid.d.ts +1 -0
- package/libs/shared-utils/uuid.js +1 -0
- package/libs/shared-utils/vectorTocoordinates.d.ts +1 -1
- package/package.json +29 -14
- package/CHANGELOG.md +0 -21
- package/dist/dnalogel.cjs.js +0 -7
- package/dist/dnalogel.es.js +0 -41280
- package/dist/dnalogel.umd.js +0 -7
- package/dist/style.css +0 -1
- package/libs/ModelRoomLabelPlugin/RoomLabelItem.svelte +0 -63
- package/libs/ModelRoomLabelPlugin/RoomLabelItem.svelte.map +0 -1
- package/libs/ModelRoomLabelPlugin/RoomLabelItems.svelte +0 -80
- package/libs/ModelRoomLabelPlugin/RoomLabelItems.svelte.map +0 -1
- package/libs/floorplan/Components/BaseImage.svelte +0 -25
- package/libs/floorplan/Components/BaseImage.svelte.map +0 -1
- package/libs/floorplan/Components/Normalmage.svelte +0 -11
- package/libs/floorplan/Components/Normalmage.svelte.map +0 -1
- package/libs/floorplan/Components/RoomHighlight/Room.svelte +0 -21
- package/libs/floorplan/Components/RoomHighlight/Room.svelte.map +0 -1
- package/libs/floorplan/Components/RoomHighlight/RoomHighlight.svelte +0 -60
- package/libs/floorplan/Components/RoomHighlight/RoomHighlight.svelte.map +0 -1
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial.svelte +0 -35
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial.svelte.map +0 -1
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial_0.svelte +0 -7
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial_0.svelte.map +0 -1
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial_1.svelte +0 -16
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial_1.svelte.map +0 -1
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial_2.svelte +0 -17
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial_2.svelte.map +0 -1
- package/libs/floorplan/Components/SvgImage.svelte +0 -25
- package/libs/floorplan/Components/SvgImage.svelte.map +0 -1
- package/libs/floorplan/ModelFloorplanPlugin/Components/Camera.svelte +0 -46
- package/libs/floorplan/ModelFloorplanPlugin/Components/Camera.svelte.map +0 -1
- package/libs/floorplan/ModelFloorplanPlugin/Components/Compass.svelte +0 -48
- package/libs/floorplan/ModelFloorplanPlugin/Components/Compass.svelte.map +0 -1
- package/libs/floorplan/ModelFloorplanPlugin/Components/CurrentFloor/CurrentFloor.svelte +0 -37
- package/libs/floorplan/ModelFloorplanPlugin/Components/CurrentFloor/CurrentFloor.svelte.map +0 -1
- package/libs/floorplan/ModelFloorplanPlugin/Components/Main.svelte +0 -50
- package/libs/floorplan/ModelFloorplanPlugin/Components/Main.svelte.map +0 -1
- package/libs/floorplan/ModelFloorplanPlugin/Components/RoomLabels/RoomLabel.svelte +0 -41
- package/libs/floorplan/ModelFloorplanPlugin/Components/RoomLabels/RoomLabel.svelte.map +0 -1
- package/libs/floorplan/ModelFloorplanPlugin/Components/RoomLabels/RoomLabels.svelte +0 -25
- package/libs/floorplan/ModelFloorplanPlugin/Components/RoomLabels/RoomLabels.svelte.map +0 -1
- package/libs/floorplan/ModelFloorplanPlugin/Components/RuleLabels/RuleItem.svelte +0 -148
- package/libs/floorplan/ModelFloorplanPlugin/Components/RuleLabels/RuleItem.svelte.map +0 -1
- package/libs/floorplan/ModelFloorplanPlugin/Components/RuleLabels/RuleLabels.svelte +0 -15
- package/libs/floorplan/ModelFloorplanPlugin/Components/RuleLabels/RuleLabels.svelte.map +0 -1
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/Camera.svelte +0 -84
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/Camera.svelte.map +0 -1
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/CurrentFloor/CurrentFloor.svelte +0 -18
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/CurrentFloor/CurrentFloor.svelte.map +0 -1
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/CurrentFloor/ExtraObjects.svelte +0 -40
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/CurrentFloor/ExtraObjects.svelte.map +0 -1
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/Main.svelte +0 -61
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/Main.svelte.map +0 -1
|
@@ -0,0 +1,3996 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var Hammer = require('hammerjs');
|
|
6
|
+
var THREE = require('three');
|
|
7
|
+
var five = require('@realsee/five');
|
|
8
|
+
var line = require('@realsee/five/line');
|
|
9
|
+
var TWEEN = require('@tweenjs/tween.js');
|
|
10
|
+
|
|
11
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
12
|
+
|
|
13
|
+
function _interopNamespace(e) {
|
|
14
|
+
if (e && e.__esModule) return e;
|
|
15
|
+
var n = Object.create(null);
|
|
16
|
+
if (e) {
|
|
17
|
+
Object.keys(e).forEach(function (k) {
|
|
18
|
+
if (k !== 'default') {
|
|
19
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
20
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return e[k]; }
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
n["default"] = e;
|
|
28
|
+
return Object.freeze(n);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
var Hammer__default = /*#__PURE__*/_interopDefaultLegacy(Hammer);
|
|
32
|
+
var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
33
|
+
var TWEEN__default = /*#__PURE__*/_interopDefaultLegacy(TWEEN);
|
|
34
|
+
|
|
35
|
+
/** 交换数组元素 */
|
|
36
|
+
function exchange(array, index1, index2) {
|
|
37
|
+
const value = array[index1];
|
|
38
|
+
array[index1] = array[index2];
|
|
39
|
+
array[index2] = value;
|
|
40
|
+
}
|
|
41
|
+
/** 翻转 ArrayBuffer(RGBA像素) 的 Y 轴 */
|
|
42
|
+
function flipPixelsY(pixels, width, height) {
|
|
43
|
+
const flipYLength = height / 2;
|
|
44
|
+
for (let currentHeight = 1; currentHeight <= flipYLength; currentHeight++) {
|
|
45
|
+
const targetHeight = height - (currentHeight - 1);
|
|
46
|
+
for (let currentWidth = 1; currentWidth <= width; currentWidth++) {
|
|
47
|
+
const pixelIndex = (currentHeight - 1) * width + currentWidth - 1;
|
|
48
|
+
const targetPixelIndex = (targetHeight - 1) * width + currentWidth - 1;
|
|
49
|
+
exchange(pixels, pixelIndex * 4 + 0, targetPixelIndex * 4 + 0);
|
|
50
|
+
exchange(pixels, pixelIndex * 4 + 1, targetPixelIndex * 4 + 1);
|
|
51
|
+
exchange(pixels, pixelIndex * 4 + 2, targetPixelIndex * 4 + 2);
|
|
52
|
+
exchange(pixels, pixelIndex * 4 + 3, targetPixelIndex * 4 + 3);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
class Magnifier {
|
|
57
|
+
constructor(five$1, options) {
|
|
58
|
+
var _a, _b, _c;
|
|
59
|
+
Object.defineProperty(this, "width", {
|
|
60
|
+
enumerable: true,
|
|
61
|
+
configurable: true,
|
|
62
|
+
writable: true,
|
|
63
|
+
value: void 0
|
|
64
|
+
});
|
|
65
|
+
Object.defineProperty(this, "height", {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
configurable: true,
|
|
68
|
+
writable: true,
|
|
69
|
+
value: void 0
|
|
70
|
+
});
|
|
71
|
+
Object.defineProperty(this, "visible", {
|
|
72
|
+
enumerable: true,
|
|
73
|
+
configurable: true,
|
|
74
|
+
writable: true,
|
|
75
|
+
value: false
|
|
76
|
+
});
|
|
77
|
+
Object.defineProperty(this, "hooks", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
configurable: true,
|
|
80
|
+
writable: true,
|
|
81
|
+
value: new five.Subscribe()
|
|
82
|
+
});
|
|
83
|
+
Object.defineProperty(this, "contentDom", {
|
|
84
|
+
enumerable: true,
|
|
85
|
+
configurable: true,
|
|
86
|
+
writable: true,
|
|
87
|
+
value: document.createElement('canvas')
|
|
88
|
+
});
|
|
89
|
+
Object.defineProperty(this, "five", {
|
|
90
|
+
enumerable: true,
|
|
91
|
+
configurable: true,
|
|
92
|
+
writable: true,
|
|
93
|
+
value: void 0
|
|
94
|
+
});
|
|
95
|
+
Object.defineProperty(this, "scale", {
|
|
96
|
+
enumerable: true,
|
|
97
|
+
configurable: true,
|
|
98
|
+
writable: true,
|
|
99
|
+
value: void 0
|
|
100
|
+
});
|
|
101
|
+
Object.defineProperty(this, "wrapper", {
|
|
102
|
+
enumerable: true,
|
|
103
|
+
configurable: true,
|
|
104
|
+
writable: true,
|
|
105
|
+
value: void 0
|
|
106
|
+
});
|
|
107
|
+
Object.defineProperty(this, "config", {
|
|
108
|
+
enumerable: true,
|
|
109
|
+
configurable: true,
|
|
110
|
+
writable: true,
|
|
111
|
+
value: void 0
|
|
112
|
+
});
|
|
113
|
+
Object.defineProperty(this, "offset", {
|
|
114
|
+
enumerable: true,
|
|
115
|
+
configurable: true,
|
|
116
|
+
writable: true,
|
|
117
|
+
value: { x: 0, y: 0 }
|
|
118
|
+
});
|
|
119
|
+
Object.defineProperty(this, "canvas", {
|
|
120
|
+
enumerable: true,
|
|
121
|
+
configurable: true,
|
|
122
|
+
writable: true,
|
|
123
|
+
value: this.contentDom
|
|
124
|
+
});
|
|
125
|
+
Object.defineProperty(this, "context", {
|
|
126
|
+
enumerable: true,
|
|
127
|
+
configurable: true,
|
|
128
|
+
writable: true,
|
|
129
|
+
value: void 0
|
|
130
|
+
});
|
|
131
|
+
Object.defineProperty(this, "renderCenter", {
|
|
132
|
+
enumerable: true,
|
|
133
|
+
configurable: true,
|
|
134
|
+
writable: true,
|
|
135
|
+
value: new THREE__namespace.Vector3()
|
|
136
|
+
});
|
|
137
|
+
Object.defineProperty(this, "lastPanEvent", {
|
|
138
|
+
enumerable: true,
|
|
139
|
+
configurable: true,
|
|
140
|
+
writable: true,
|
|
141
|
+
value: void 0
|
|
142
|
+
});
|
|
143
|
+
Object.defineProperty(this, "hammer", {
|
|
144
|
+
enumerable: true,
|
|
145
|
+
configurable: true,
|
|
146
|
+
writable: true,
|
|
147
|
+
value: void 0
|
|
148
|
+
});
|
|
149
|
+
Object.defineProperty(this, "onPan", {
|
|
150
|
+
enumerable: true,
|
|
151
|
+
configurable: true,
|
|
152
|
+
writable: true,
|
|
153
|
+
value: (event) => {
|
|
154
|
+
var _a, _b, _c, _d;
|
|
155
|
+
if (!this.wrapper)
|
|
156
|
+
return;
|
|
157
|
+
const lastDeltaX = (_b = (_a = this.lastPanEvent) === null || _a === void 0 ? void 0 : _a.deltaX) !== null && _b !== void 0 ? _b : 0;
|
|
158
|
+
const lastDeltaY = (_d = (_c = this.lastPanEvent) === null || _c === void 0 ? void 0 : _c.deltaY) !== null && _d !== void 0 ? _d : 0;
|
|
159
|
+
const deltaX = event.deltaX - lastDeltaX;
|
|
160
|
+
const deltaY = event.deltaY - lastDeltaY;
|
|
161
|
+
this.lastPanEvent = event;
|
|
162
|
+
const prevented = this.hooks.emit('wantsPanGesture', { srcEvent: event, deltaX, deltaY });
|
|
163
|
+
if (prevented)
|
|
164
|
+
return;
|
|
165
|
+
const translateX = this.offset.x + deltaX;
|
|
166
|
+
const translateY = this.offset.y + deltaY;
|
|
167
|
+
this.contentDom.style.boxShadow = '0 2px 30px 0 rgba(0,0,0,0.20)';
|
|
168
|
+
this.canvas.style.transform = `translate3d(${translateX}px, ${translateY}px, 100px)`;
|
|
169
|
+
this.offset = { x: translateX, y: translateY };
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
Object.defineProperty(this, "onPanEnd", {
|
|
173
|
+
enumerable: true,
|
|
174
|
+
configurable: true,
|
|
175
|
+
writable: true,
|
|
176
|
+
value: (event) => {
|
|
177
|
+
this.lastPanEvent = undefined;
|
|
178
|
+
this.contentDom.style.boxShadow = 'none';
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
if (!five$1.renderer)
|
|
182
|
+
throw new Error('Five Render 未初始化');
|
|
183
|
+
this.five = five$1;
|
|
184
|
+
this.scale = (_a = options === null || options === void 0 ? void 0 : options.scale) !== null && _a !== void 0 ? _a : 2;
|
|
185
|
+
this.width = (_b = options === null || options === void 0 ? void 0 : options.width) !== null && _b !== void 0 ? _b : 190;
|
|
186
|
+
this.height = (_c = options === null || options === void 0 ? void 0 : options.height) !== null && _c !== void 0 ? _c : 190;
|
|
187
|
+
this.config = {
|
|
188
|
+
dragEnabled: (options === null || options === void 0 ? void 0 : options.dragEnabled) || false,
|
|
189
|
+
autoFixPCPosition: (options === null || options === void 0 ? void 0 : options.autoFixPCPosition) || false,
|
|
190
|
+
initialPosition: (options === null || options === void 0 ? void 0 : options.initialPosition) || { left: '0', top: '0' },
|
|
191
|
+
};
|
|
192
|
+
const context = this.canvas.getContext('2d');
|
|
193
|
+
if (!context)
|
|
194
|
+
throw new Error('CANNOT CREATE CONTEXT2D');
|
|
195
|
+
this.context = context;
|
|
196
|
+
if (this.config.dragEnabled) {
|
|
197
|
+
this.hammer = new Hammer__default["default"](this.canvas);
|
|
198
|
+
this.hammer.on('pan', this.onPan);
|
|
199
|
+
this.hammer.on('panend', this.onPanEnd);
|
|
200
|
+
// this.hooks.on('wantsPanGesture', this.onMagnifierWantsPanGesture)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
dispose() {
|
|
204
|
+
var _a;
|
|
205
|
+
this.clear();
|
|
206
|
+
this.remove();
|
|
207
|
+
(_a = this.hammer) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
208
|
+
}
|
|
209
|
+
/** 移除放大镜 DOM */
|
|
210
|
+
remove() {
|
|
211
|
+
this.canvas.remove();
|
|
212
|
+
this.visible = false;
|
|
213
|
+
}
|
|
214
|
+
/** 清除放大镜渲染内容 */
|
|
215
|
+
clear() {
|
|
216
|
+
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
217
|
+
}
|
|
218
|
+
/** 把放大镜放到某一个容器中 */
|
|
219
|
+
appendTo(element) {
|
|
220
|
+
this.wrapper = element;
|
|
221
|
+
this.initStyle();
|
|
222
|
+
element.append(this.canvas);
|
|
223
|
+
this.visible = true;
|
|
224
|
+
}
|
|
225
|
+
/** 放大传入点位周围的内容 */
|
|
226
|
+
renderWithPoint(point) {
|
|
227
|
+
if (!this.wrapper)
|
|
228
|
+
return;
|
|
229
|
+
this.renderCenter = point;
|
|
230
|
+
this.render();
|
|
231
|
+
if (this.config.autoFixPCPosition)
|
|
232
|
+
this.autoFixPCPosition();
|
|
233
|
+
}
|
|
234
|
+
autoFixPCPosition() {
|
|
235
|
+
if (!this.wrapper)
|
|
236
|
+
return;
|
|
237
|
+
const { width, height } = this;
|
|
238
|
+
const position2d = this.renderCenter.clone().project(this.five.camera);
|
|
239
|
+
const left = ((position2d.x + 1) / 2) * this.wrapper.clientWidth;
|
|
240
|
+
const right = (-(position2d.x - 1) / 2) * this.wrapper.clientWidth;
|
|
241
|
+
const top = (-(position2d.y - 1) / 2) * this.wrapper.clientHeight;
|
|
242
|
+
if (left < 183) {
|
|
243
|
+
this.canvas.style.top = -height / 2 + 'px';
|
|
244
|
+
this.canvas.style.left = 90 + 'px';
|
|
245
|
+
}
|
|
246
|
+
else if (top < 183) {
|
|
247
|
+
this.canvas.style.top = 90 + 'px';
|
|
248
|
+
this.canvas.style.left = -width / 2 + 'px';
|
|
249
|
+
}
|
|
250
|
+
else if (right < 183) {
|
|
251
|
+
this.canvas.style.top = -height / 2 + 'px';
|
|
252
|
+
this.canvas.style.left = -width - 90 + 'px';
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this.canvas.style.left = -width / 2 + 'px';
|
|
256
|
+
this.canvas.style.top = -height - 90 + 'px';
|
|
257
|
+
}
|
|
258
|
+
this.canvas.style.transform = `translate3d(${left}px, ${top}px, 10px)`;
|
|
259
|
+
this.offset = { x: left, y: top };
|
|
260
|
+
}
|
|
261
|
+
render() {
|
|
262
|
+
if (!this.five.renderer || !this.wrapper)
|
|
263
|
+
return;
|
|
264
|
+
const { scale, context, width, height } = this;
|
|
265
|
+
const position2d = this.renderCenter.clone().project(this.five.camera);
|
|
266
|
+
const renderSize = this.five.renderer.getSize(new THREE__namespace.Vector2());
|
|
267
|
+
// const pixelRatio = this.five.renderer.getPixelRatio()
|
|
268
|
+
// 安卓机型和ios部分机型在app里读不到像素,固定为1降低清晰度可以读到
|
|
269
|
+
const pixelRatio = 1;
|
|
270
|
+
// 从 renderTarget 读取区域的大小
|
|
271
|
+
const readPixelsWidth = width / scale;
|
|
272
|
+
const readPixelsHeight = height / scale;
|
|
273
|
+
// 一个像素重复多少倍,pixelRatio 是兼容屏幕像素比,scale 是真实重复倍数
|
|
274
|
+
const readPixelsRadio = pixelRatio * scale;
|
|
275
|
+
const x = ((position2d.x + 1) / 2) * renderSize.x;
|
|
276
|
+
const y = ((position2d.y + 1) / 2) * renderSize.y;
|
|
277
|
+
const pixels = this.five.getPixels(x - readPixelsWidth / 2, y - readPixelsWidth / 2, readPixelsWidth, readPixelsHeight, readPixelsRadio);
|
|
278
|
+
// 最后生成的图像大小是 [width * pixelRatio, height * pixelRatio]
|
|
279
|
+
// 绘制在[width, height]的区域上
|
|
280
|
+
const imageWidth = Math.floor(width * pixelRatio);
|
|
281
|
+
const imageHeight = Math.floor(height * pixelRatio);
|
|
282
|
+
// 因为 Canvas 与 THREE Renderer Y 坐标相反,所以需要 Y 轴翻转
|
|
283
|
+
flipPixelsY(pixels, imageWidth, imageHeight);
|
|
284
|
+
const imageData = new ImageData(imageWidth, imageHeight);
|
|
285
|
+
imageData.data.set(pixels);
|
|
286
|
+
context.putImageData(imageData, 0, 0);
|
|
287
|
+
}
|
|
288
|
+
initStyle() {
|
|
289
|
+
const canvas = this.canvas;
|
|
290
|
+
canvas.classList.add('five-plugin__magnifier');
|
|
291
|
+
canvas.style.position = 'absolute';
|
|
292
|
+
canvas.style.pointerEvents = 'all';
|
|
293
|
+
canvas.style.borderRadius = '50%';
|
|
294
|
+
canvas.style.zIndex = '99';
|
|
295
|
+
const pixelRatio = 1;
|
|
296
|
+
canvas.setAttribute('width', (this.width * pixelRatio).toString());
|
|
297
|
+
canvas.setAttribute('height', (this.height * pixelRatio).toString());
|
|
298
|
+
canvas.style.border = '2px solid rgba(255,255,255,0.20)';
|
|
299
|
+
canvas.style.width = this.width + 'px';
|
|
300
|
+
canvas.style.height = this.height + 'px';
|
|
301
|
+
canvas.style.top = this.config.initialPosition.top;
|
|
302
|
+
canvas.style.left = this.config.initialPosition.left;
|
|
303
|
+
canvas.style.transform = 'translate(0,0,100px)';
|
|
304
|
+
if (this.config.dragEnabled) {
|
|
305
|
+
this.canvas.style.cursor = 'pointer';
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
class FiveHelper {
|
|
311
|
+
constructor(five) {
|
|
312
|
+
Object.defineProperty(this, "edges", {
|
|
313
|
+
enumerable: true,
|
|
314
|
+
configurable: true,
|
|
315
|
+
writable: true,
|
|
316
|
+
value: []
|
|
317
|
+
});
|
|
318
|
+
Object.defineProperty(this, "five", {
|
|
319
|
+
enumerable: true,
|
|
320
|
+
configurable: true,
|
|
321
|
+
writable: true,
|
|
322
|
+
value: void 0
|
|
323
|
+
});
|
|
324
|
+
/** 模型加载后获取折线 */
|
|
325
|
+
Object.defineProperty(this, "onModelLoaded", {
|
|
326
|
+
enumerable: true,
|
|
327
|
+
configurable: true,
|
|
328
|
+
writable: true,
|
|
329
|
+
value: () => {
|
|
330
|
+
if (!this.five.model)
|
|
331
|
+
return;
|
|
332
|
+
this.edges = this.five.model.getEdges();
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
this.five = five;
|
|
336
|
+
this.five.model.loaded ? this.onModelLoaded() : this.five.on('modelLoaded', this.onModelLoaded);
|
|
337
|
+
}
|
|
338
|
+
dispose() { }
|
|
339
|
+
getAdsorbentPoint(intersection) {
|
|
340
|
+
if (this.edges.length === 0)
|
|
341
|
+
return null;
|
|
342
|
+
let distance = Infinity;
|
|
343
|
+
let closestPoint;
|
|
344
|
+
this.edges.forEach((line) => {
|
|
345
|
+
const _closestPoint = line.closestPointToPoint(intersection.point, true, new THREE.Vector3());
|
|
346
|
+
const _distance = _closestPoint.distanceTo(intersection.point);
|
|
347
|
+
if (_distance < distance) {
|
|
348
|
+
closestPoint = _closestPoint;
|
|
349
|
+
distance = _distance;
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
if (distance > 0.1)
|
|
353
|
+
return null;
|
|
354
|
+
return closestPoint || null;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// uuid
|
|
359
|
+
function S4() {
|
|
360
|
+
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* 随机生成一个uuid值
|
|
364
|
+
*/
|
|
365
|
+
function uuid() {
|
|
366
|
+
// then to call it, plus stitch in '4' in the third group
|
|
367
|
+
return (S4() + S4() + '-' + S4() + '-4' + S4().substr(0, 3) + '-' + S4() + '-' + S4() + S4() + S4()).toLowerCase();
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
class Polyline {
|
|
371
|
+
constructor() {
|
|
372
|
+
Object.defineProperty(this, "id", {
|
|
373
|
+
enumerable: true,
|
|
374
|
+
configurable: true,
|
|
375
|
+
writable: true,
|
|
376
|
+
value: uuid()
|
|
377
|
+
});
|
|
378
|
+
Object.defineProperty(this, "points", {
|
|
379
|
+
enumerable: true,
|
|
380
|
+
configurable: true,
|
|
381
|
+
writable: true,
|
|
382
|
+
value: []
|
|
383
|
+
});
|
|
384
|
+
Object.defineProperty(this, "lines", {
|
|
385
|
+
enumerable: true,
|
|
386
|
+
configurable: true,
|
|
387
|
+
writable: true,
|
|
388
|
+
value: []
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
push(line) {
|
|
392
|
+
const next = this.getNext(line);
|
|
393
|
+
if (!next)
|
|
394
|
+
throw new Error('当前线段于上一条线段无法构成折线');
|
|
395
|
+
this.lines.push(next.line);
|
|
396
|
+
this.points.push(...next.points);
|
|
397
|
+
return this.lines.length;
|
|
398
|
+
}
|
|
399
|
+
pop() {
|
|
400
|
+
const lastPoint = this.lines.pop();
|
|
401
|
+
const polylineLength = this.lines.length;
|
|
402
|
+
if (polylineLength === 0)
|
|
403
|
+
this.points.slice(0, this.points.length);
|
|
404
|
+
else
|
|
405
|
+
this.points.pop();
|
|
406
|
+
return lastPoint;
|
|
407
|
+
}
|
|
408
|
+
getNext(line) {
|
|
409
|
+
const lastPoint = this.points.slice(-1)[0];
|
|
410
|
+
if (!lastPoint)
|
|
411
|
+
return { line: line, points: line.points };
|
|
412
|
+
if (!line.points.includes(lastPoint))
|
|
413
|
+
return null;
|
|
414
|
+
const nextPoint = line.points.find((point) => point !== lastPoint);
|
|
415
|
+
if (!nextPoint)
|
|
416
|
+
return null;
|
|
417
|
+
return { line: line, points: [nextPoint] };
|
|
418
|
+
}
|
|
419
|
+
toJson() {
|
|
420
|
+
return {
|
|
421
|
+
id: this.id,
|
|
422
|
+
lines: this.lines.map((line) => line.id),
|
|
423
|
+
points: this.points.map((point) => point.id),
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
toCompletelyJson() {
|
|
427
|
+
return {
|
|
428
|
+
id: this.id,
|
|
429
|
+
points: this.points.map((point) => point.toJson()),
|
|
430
|
+
lines: this.lines.map((line) => line.toCompletelyJson()),
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const lineWidth = 1;
|
|
436
|
+
const lightLineWidth = 3;
|
|
437
|
+
const lineColor = new THREE.Color(0xffffff);
|
|
438
|
+
const lightLineColor = new THREE.Color(0x6386ff);
|
|
439
|
+
const pointColor = new THREE.Color(0xffffff);
|
|
440
|
+
const lightPointColor = new THREE.Color(0x6386ff);
|
|
441
|
+
const pointSize = 6;
|
|
442
|
+
const lightPointSize = 8;
|
|
443
|
+
const pointImage = 'data:image/png;base64,' +
|
|
444
|
+
'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAIVBMVEUAAAD////////////////////////////////////////PIev5AAAACnRSTlMAG/Py2baba05un7UgfgAAAHJJREFUKM9joBpgLHVSCRdA4metAoJlCJHmVWBgAeNzroKCCVCBLpjACqgJVjCBxRBT2FbBQQJYQAohsBAsUIUQWA4WiEIILAULeCEEloAFtBACizAEMLRgGIphLabDMJ2O6TlM72MGECIIMQIZIxqoBQCPvpJ/e9FaAAAAAABJRU5ErkJggg==';
|
|
445
|
+
const pointTexture = new THREE.TextureLoader().load(pointImage);
|
|
446
|
+
const normalLineOpts = {
|
|
447
|
+
pointTexture,
|
|
448
|
+
pointSize,
|
|
449
|
+
lineWidth,
|
|
450
|
+
lineColor,
|
|
451
|
+
pointColor,
|
|
452
|
+
lineRenderOrder: 20,
|
|
453
|
+
pointsRenderOrder: 20,
|
|
454
|
+
};
|
|
455
|
+
Object.assign(Object.assign({}, normalLineOpts), { dashed: true });
|
|
456
|
+
const lightLineOpts = {
|
|
457
|
+
pointTexture,
|
|
458
|
+
pointSize: lightPointSize,
|
|
459
|
+
lineWidth: lightLineWidth,
|
|
460
|
+
lineColor: lightLineColor,
|
|
461
|
+
pointColor: lightPointColor,
|
|
462
|
+
lineRenderOrder: 10,
|
|
463
|
+
pointsRenderOrder: 10,
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
function creatLine(start, end, opts) {
|
|
467
|
+
var _a, _b, _c, _d, _e;
|
|
468
|
+
const lineWidth = (_a = opts === null || opts === void 0 ? void 0 : opts.lineWidth) !== null && _a !== void 0 ? _a : 2;
|
|
469
|
+
const lineColor = (_b = opts === null || opts === void 0 ? void 0 : opts.lineColor) !== null && _b !== void 0 ? _b : new THREE.Color(0xffffff);
|
|
470
|
+
const pointSize = (_c = opts === null || opts === void 0 ? void 0 : opts.pointSize) !== null && _c !== void 0 ? _c : 5;
|
|
471
|
+
const lineRenderOrder = (_d = opts === null || opts === void 0 ? void 0 : opts.lineRenderOrder) !== null && _d !== void 0 ? _d : 10;
|
|
472
|
+
const pointsRenderOrder = (_e = opts === null || opts === void 0 ? void 0 : opts.lineRenderOrder) !== null && _e !== void 0 ? _e : 20;
|
|
473
|
+
const line$1 = new line.Line(start, end);
|
|
474
|
+
// set line
|
|
475
|
+
line$1.setMaterial({ linewidth: lineWidth, color: lineColor });
|
|
476
|
+
line$1.line.material.depthTest = false;
|
|
477
|
+
line$1.line.material.transparent = true;
|
|
478
|
+
line$1.line.renderOrder = lineRenderOrder;
|
|
479
|
+
// set point
|
|
480
|
+
line$1.points.renderOrder = pointsRenderOrder;
|
|
481
|
+
const pointMaterial = line$1.points.material;
|
|
482
|
+
pointMaterial.depthTest = false;
|
|
483
|
+
pointMaterial.size = pointSize;
|
|
484
|
+
(opts === null || opts === void 0 ? void 0 : opts.pointColor) && pointMaterial.color.set(opts.pointColor).convertSRGBToLinear();
|
|
485
|
+
if (opts === null || opts === void 0 ? void 0 : opts.pointTexture)
|
|
486
|
+
pointMaterial.map = opts.pointTexture;
|
|
487
|
+
return line$1;
|
|
488
|
+
}
|
|
489
|
+
function creatLineMesh(line, type) {
|
|
490
|
+
const [point, anotherPoint] = line.points;
|
|
491
|
+
const opts = type === 'light' ? lightLineOpts : normalLineOpts;
|
|
492
|
+
const fiveLine = creatLine(point.position, anotherPoint.position, opts);
|
|
493
|
+
fiveLine.name = 'normalLine_' + line.id;
|
|
494
|
+
return fiveLine;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
function isNDCPointInScreen(ndcPoint) {
|
|
498
|
+
const { x, y, z } = ndcPoint;
|
|
499
|
+
if (Math.abs(x) > 1 || Math.abs(y) > 1 || Math.abs(z) > 1)
|
|
500
|
+
return false;
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function creatContentDom() {
|
|
505
|
+
const contentDom = document.createElement('div');
|
|
506
|
+
contentDom.setAttribute('style', `backdrop-filter: blur(4px);-webkit-backdrop-filter: blur(4px);`);
|
|
507
|
+
contentDom.style.padding = '3px 6px';
|
|
508
|
+
contentDom.style.lineHeight = '1';
|
|
509
|
+
contentDom.style.textAlign = 'center';
|
|
510
|
+
contentDom.style.transform = 'translate(-50%, -50%)';
|
|
511
|
+
contentDom.style.borderRadius = '100px';
|
|
512
|
+
contentDom.style.fontSize = '14px';
|
|
513
|
+
contentDom.style.color = '#fff';
|
|
514
|
+
contentDom.style.background = 'rgba(195,195,195,0.70)';
|
|
515
|
+
contentDom.style.border = '0.5px solid rgba(255,255,255,0.6)';
|
|
516
|
+
contentDom.style.pointerEvents = 'all';
|
|
517
|
+
contentDom.style.cursor = 'pointer';
|
|
518
|
+
return contentDom;
|
|
519
|
+
}
|
|
520
|
+
function createContainerDom(line) {
|
|
521
|
+
const containerDom = document.createElement('div');
|
|
522
|
+
containerDom.id = 'distance_' + line.id;
|
|
523
|
+
containerDom.classList.add('five-plugin-measure__distance');
|
|
524
|
+
containerDom.style.opacity = '0';
|
|
525
|
+
containerDom.style.position = 'absolute';
|
|
526
|
+
containerDom.style.left = '0';
|
|
527
|
+
containerDom.style.top = '0';
|
|
528
|
+
containerDom.style.transform = 'translate3d(0, 0, 0)';
|
|
529
|
+
containerDom.style.transformOrigin = 'left top';
|
|
530
|
+
return containerDom;
|
|
531
|
+
}
|
|
532
|
+
function creatDistanceItem(props) {
|
|
533
|
+
function handleClick() {
|
|
534
|
+
var _a;
|
|
535
|
+
// 线被选中时才高亮,外部手动触发高亮
|
|
536
|
+
// highlight()
|
|
537
|
+
(_a = props.clickCallback) === null || _a === void 0 ? void 0 : _a.call(props, distanceItem);
|
|
538
|
+
}
|
|
539
|
+
function highlight() {
|
|
540
|
+
if (userDistanceItem)
|
|
541
|
+
return userDistanceItem.highlight();
|
|
542
|
+
contentDom.style.border = '0.5px solid #95AEFF';
|
|
543
|
+
contentDom.style.background = 'linear-gradient(90deg, #95AEFF 0%, #6386FF 100%)';
|
|
544
|
+
}
|
|
545
|
+
function unHighlight() {
|
|
546
|
+
if (userDistanceItem)
|
|
547
|
+
return userDistanceItem.unHighlight();
|
|
548
|
+
contentDom.style.border = '0.5px solid rgba(255,255,255,0.6)';
|
|
549
|
+
contentDom.style.background = 'rgba(195,195,195,0.70)';
|
|
550
|
+
}
|
|
551
|
+
function update(five) {
|
|
552
|
+
const fiveElement = five.getElement();
|
|
553
|
+
if (!fiveElement)
|
|
554
|
+
return;
|
|
555
|
+
const screenWidth = fiveElement.clientWidth;
|
|
556
|
+
const screenHeight = fiveElement.clientHeight;
|
|
557
|
+
if (line.points.length < 2)
|
|
558
|
+
return;
|
|
559
|
+
const [startPoint, endPoint] = line.points;
|
|
560
|
+
const ndcStartPosition = startPoint.position.clone().project(five.camera);
|
|
561
|
+
const ndcEndPosition = endPoint.position.clone().project(five.camera);
|
|
562
|
+
const ndcDomPosition = ndcStartPosition.clone().lerp(ndcEndPosition, 0.5);
|
|
563
|
+
const screenStartPosition = new THREE.Vector2(ndcStartPosition.x * screenWidth, ndcStartPosition.y * screenHeight);
|
|
564
|
+
const screenEndPosition = new THREE.Vector2(ndcEndPosition.x * screenWidth, ndcEndPosition.y * screenHeight);
|
|
565
|
+
const visible = (() => {
|
|
566
|
+
// 对于超过近平面和远平面的点,计算会有问题
|
|
567
|
+
if (Math.abs(ndcStartPosition.z) > 1 || Math.abs(ndcEndPosition.z) > 1)
|
|
568
|
+
return false;
|
|
569
|
+
if (!isNDCPointInScreen(ndcStartPosition) && !isNDCPointInScreen(ndcEndPosition))
|
|
570
|
+
return false;
|
|
571
|
+
if (!isNDCPointInScreen(ndcDomPosition))
|
|
572
|
+
return false;
|
|
573
|
+
if (screenStartPosition.distanceTo(screenEndPosition) < 20)
|
|
574
|
+
return false;
|
|
575
|
+
return true;
|
|
576
|
+
})();
|
|
577
|
+
if (visible === false) {
|
|
578
|
+
containerDom.style.opacity = '0';
|
|
579
|
+
containerDom.style.pointerEvents = 'none';
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
// 更新 UI
|
|
583
|
+
const left = ((ndcDomPosition.x + 1) / 2) * screenWidth;
|
|
584
|
+
const top = (-(ndcDomPosition.y - 1) / 2) * screenHeight;
|
|
585
|
+
const rad = Math.atan((screenStartPosition.y - screenEndPosition.y) / (screenStartPosition.x - screenEndPosition.x));
|
|
586
|
+
const deg = -(rad * 180) / Math.PI;
|
|
587
|
+
containerDom.style.transform = `translate(${left}px, ${top}px) rotate(${deg}deg)`;
|
|
588
|
+
containerDom.style.opacity = '1';
|
|
589
|
+
containerDom.style.pointerEvents = 'all';
|
|
590
|
+
if (userDistanceItem) {
|
|
591
|
+
userDistanceItem.update({ line: line.toCompletelyJson(), polyline: line.getPolyline().toCompletelyJson() });
|
|
592
|
+
}
|
|
593
|
+
const distanceString = startPoint.position.clone().distanceTo(endPoint.position).toFixed(2) + 'm';
|
|
594
|
+
contentDom.innerText !== distanceString && (contentDom.innerText = distanceString);
|
|
595
|
+
}
|
|
596
|
+
function appendTo(container) {
|
|
597
|
+
container.appendChild(containerDom);
|
|
598
|
+
containerDom.addEventListener('click', handleClick);
|
|
599
|
+
}
|
|
600
|
+
function remove() {
|
|
601
|
+
contentDom.removeEventListener('click', handleClick);
|
|
602
|
+
containerDom.remove();
|
|
603
|
+
}
|
|
604
|
+
const { line } = props;
|
|
605
|
+
const lineID = line.id;
|
|
606
|
+
const contentDom = creatContentDom();
|
|
607
|
+
const containerDom = createContainerDom(line);
|
|
608
|
+
const userDistanceItem = props.userDistanceItem;
|
|
609
|
+
const ndcPosition = new THREE.Vector3(0, 0, 0);
|
|
610
|
+
const distanceItem = {
|
|
611
|
+
lineID,
|
|
612
|
+
ndcPosition,
|
|
613
|
+
update,
|
|
614
|
+
appendTo,
|
|
615
|
+
remove,
|
|
616
|
+
highlight: highlight,
|
|
617
|
+
unHighlight: unHighlight,
|
|
618
|
+
};
|
|
619
|
+
(userDistanceItem === null || userDistanceItem === void 0 ? void 0 : userDistanceItem.element) ? containerDom.appendChild(userDistanceItem.element) : containerDom.appendChild(contentDom);
|
|
620
|
+
return distanceItem;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
class Line {
|
|
624
|
+
constructor(point, anotherPoint, model) {
|
|
625
|
+
Object.defineProperty(this, "id", {
|
|
626
|
+
enumerable: true,
|
|
627
|
+
configurable: true,
|
|
628
|
+
writable: true,
|
|
629
|
+
value: void 0
|
|
630
|
+
});
|
|
631
|
+
Object.defineProperty(this, "selected", {
|
|
632
|
+
enumerable: true,
|
|
633
|
+
configurable: true,
|
|
634
|
+
writable: true,
|
|
635
|
+
value: false
|
|
636
|
+
});
|
|
637
|
+
Object.defineProperty(this, "type", {
|
|
638
|
+
enumerable: true,
|
|
639
|
+
configurable: true,
|
|
640
|
+
writable: true,
|
|
641
|
+
value: 'line'
|
|
642
|
+
});
|
|
643
|
+
Object.defineProperty(this, "model", {
|
|
644
|
+
enumerable: true,
|
|
645
|
+
configurable: true,
|
|
646
|
+
writable: true,
|
|
647
|
+
value: void 0
|
|
648
|
+
});
|
|
649
|
+
Object.defineProperty(this, "mesh", {
|
|
650
|
+
enumerable: true,
|
|
651
|
+
configurable: true,
|
|
652
|
+
writable: true,
|
|
653
|
+
value: void 0
|
|
654
|
+
});
|
|
655
|
+
Object.defineProperty(this, "points", {
|
|
656
|
+
enumerable: true,
|
|
657
|
+
configurable: true,
|
|
658
|
+
writable: true,
|
|
659
|
+
value: void 0
|
|
660
|
+
});
|
|
661
|
+
Object.defineProperty(this, "lightMesh", {
|
|
662
|
+
enumerable: true,
|
|
663
|
+
configurable: true,
|
|
664
|
+
writable: true,
|
|
665
|
+
value: void 0
|
|
666
|
+
});
|
|
667
|
+
Object.defineProperty(this, "hook", {
|
|
668
|
+
enumerable: true,
|
|
669
|
+
configurable: true,
|
|
670
|
+
writable: true,
|
|
671
|
+
value: void 0
|
|
672
|
+
});
|
|
673
|
+
Object.defineProperty(this, "distanceItem", {
|
|
674
|
+
enumerable: true,
|
|
675
|
+
configurable: true,
|
|
676
|
+
writable: true,
|
|
677
|
+
value: void 0
|
|
678
|
+
});
|
|
679
|
+
Object.defineProperty(this, "polyline", {
|
|
680
|
+
enumerable: true,
|
|
681
|
+
configurable: true,
|
|
682
|
+
writable: true,
|
|
683
|
+
value: void 0
|
|
684
|
+
});
|
|
685
|
+
this.id = uuid();
|
|
686
|
+
this.model = model;
|
|
687
|
+
if (point.id === anotherPoint.id)
|
|
688
|
+
throw new Error('无效的线段, 一个点无法构成线段');
|
|
689
|
+
this.hook = new five.Subscribe();
|
|
690
|
+
this.points = [point, anotherPoint];
|
|
691
|
+
this.mesh = creatLineMesh(this, 'normal');
|
|
692
|
+
this.lightMesh = creatLineMesh(this, 'light');
|
|
693
|
+
this.distanceItem = creatDistanceItem({
|
|
694
|
+
line: this,
|
|
695
|
+
clickCallback: () => this.hook.emit('selected', this),
|
|
696
|
+
userDistanceItem: this.model.params.userDistanceItemCreator
|
|
697
|
+
? this.model.params.userDistanceItemCreator()
|
|
698
|
+
: undefined,
|
|
699
|
+
});
|
|
700
|
+
point.lines.push(this);
|
|
701
|
+
anotherPoint.lines.push(this);
|
|
702
|
+
}
|
|
703
|
+
clear() {
|
|
704
|
+
this.selected = false;
|
|
705
|
+
this.polyline = undefined;
|
|
706
|
+
}
|
|
707
|
+
getPolyline() {
|
|
708
|
+
if (this.polyline)
|
|
709
|
+
return this.polyline;
|
|
710
|
+
const modelPolyline = this.model.polylines.find((polyline) => polyline.lines.includes(this));
|
|
711
|
+
this.polyline = modelPolyline;
|
|
712
|
+
if (modelPolyline)
|
|
713
|
+
return modelPolyline;
|
|
714
|
+
const polyline = new Polyline();
|
|
715
|
+
polyline.push(this);
|
|
716
|
+
return polyline;
|
|
717
|
+
}
|
|
718
|
+
findAnotherPoint(point) {
|
|
719
|
+
return this.points.find(({ id }) => id !== point.id);
|
|
720
|
+
}
|
|
721
|
+
toJson() {
|
|
722
|
+
return { id: this.id, points: this.points.map(({ id }) => id) };
|
|
723
|
+
}
|
|
724
|
+
toCompletelyJson() {
|
|
725
|
+
return { id: this.id, points: this.points.map((point) => point.toJson()) };
|
|
726
|
+
}
|
|
727
|
+
clone() {
|
|
728
|
+
const line = new Line(this.points[0].clone(), this.points[1].clone(), this.model);
|
|
729
|
+
return line;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* 从数组中删除
|
|
735
|
+
* @param item
|
|
736
|
+
* @param array
|
|
737
|
+
* @return 如果删除返回 item
|
|
738
|
+
*/
|
|
739
|
+
function removeArrayItem(item, array) {
|
|
740
|
+
for (let index = 0, len = array.length; index < len; index++) {
|
|
741
|
+
if (item === array[index])
|
|
742
|
+
return array.splice(index, 1)[0];
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
class Point {
|
|
747
|
+
constructor(position) {
|
|
748
|
+
Object.defineProperty(this, "id", {
|
|
749
|
+
enumerable: true,
|
|
750
|
+
configurable: true,
|
|
751
|
+
writable: true,
|
|
752
|
+
value: void 0
|
|
753
|
+
});
|
|
754
|
+
Object.defineProperty(this, "lines", {
|
|
755
|
+
enumerable: true,
|
|
756
|
+
configurable: true,
|
|
757
|
+
writable: true,
|
|
758
|
+
value: void 0
|
|
759
|
+
});
|
|
760
|
+
Object.defineProperty(this, "position", {
|
|
761
|
+
enumerable: true,
|
|
762
|
+
configurable: true,
|
|
763
|
+
writable: true,
|
|
764
|
+
value: void 0
|
|
765
|
+
});
|
|
766
|
+
Object.defineProperty(this, "type", {
|
|
767
|
+
enumerable: true,
|
|
768
|
+
configurable: true,
|
|
769
|
+
writable: true,
|
|
770
|
+
value: 'point'
|
|
771
|
+
});
|
|
772
|
+
this.id = uuid();
|
|
773
|
+
this.lines = [];
|
|
774
|
+
this.position = new THREE.Vector3();
|
|
775
|
+
position instanceof THREE.Vector3 ? this.position.copy(position) : this.position.fromArray(position);
|
|
776
|
+
}
|
|
777
|
+
toJson() {
|
|
778
|
+
return { id: this.id, lines: this.lines.map(({ id }) => id), position: this.position.toArray() };
|
|
779
|
+
}
|
|
780
|
+
addLine(line) {
|
|
781
|
+
this.lines.push(line);
|
|
782
|
+
}
|
|
783
|
+
removeLine(line) {
|
|
784
|
+
removeArrayItem(line, this.lines);
|
|
785
|
+
}
|
|
786
|
+
clone() {
|
|
787
|
+
const point = new Point(this.position);
|
|
788
|
+
return point;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
class Model {
|
|
793
|
+
constructor(params) {
|
|
794
|
+
Object.defineProperty(this, "lines", {
|
|
795
|
+
enumerable: true,
|
|
796
|
+
configurable: true,
|
|
797
|
+
writable: true,
|
|
798
|
+
value: []
|
|
799
|
+
});
|
|
800
|
+
Object.defineProperty(this, "points", {
|
|
801
|
+
enumerable: true,
|
|
802
|
+
configurable: true,
|
|
803
|
+
writable: true,
|
|
804
|
+
value: []
|
|
805
|
+
});
|
|
806
|
+
Object.defineProperty(this, "params", {
|
|
807
|
+
enumerable: true,
|
|
808
|
+
configurable: true,
|
|
809
|
+
writable: true,
|
|
810
|
+
value: void 0
|
|
811
|
+
});
|
|
812
|
+
Object.defineProperty(this, "polylines", {
|
|
813
|
+
enumerable: true,
|
|
814
|
+
configurable: true,
|
|
815
|
+
writable: true,
|
|
816
|
+
value: []
|
|
817
|
+
});
|
|
818
|
+
Object.defineProperty(this, "hook", {
|
|
819
|
+
enumerable: true,
|
|
820
|
+
configurable: true,
|
|
821
|
+
writable: true,
|
|
822
|
+
value: new five.Subscribe()
|
|
823
|
+
});
|
|
824
|
+
this.params = params;
|
|
825
|
+
}
|
|
826
|
+
addLine(line) {
|
|
827
|
+
const [startPoint, endPoint] = line.points;
|
|
828
|
+
if (!startPoint || !endPoint)
|
|
829
|
+
return this;
|
|
830
|
+
if (!this.includes(startPoint))
|
|
831
|
+
this.points.push(startPoint);
|
|
832
|
+
if (!this.includes(endPoint))
|
|
833
|
+
this.points.push(endPoint);
|
|
834
|
+
this.lines.push(line);
|
|
835
|
+
const lastPolyline = this.polylines.find((polyline) => !!polyline.getNext(line));
|
|
836
|
+
if (lastPolyline) {
|
|
837
|
+
lastPolyline.push(line);
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
const polyline = new Polyline();
|
|
841
|
+
polyline.push(line);
|
|
842
|
+
this.polylines.push(polyline);
|
|
843
|
+
}
|
|
844
|
+
this.hook.emit('lineAdded', line);
|
|
845
|
+
}
|
|
846
|
+
removeLineByID(lineID) {
|
|
847
|
+
const line = this.getLineByID(lineID);
|
|
848
|
+
if (line)
|
|
849
|
+
this.removeLine(line);
|
|
850
|
+
}
|
|
851
|
+
removeLine(line) {
|
|
852
|
+
// handle polyline
|
|
853
|
+
const polyline = this.polylines.find((polyline) => polyline.lines.includes(line));
|
|
854
|
+
if (polyline) {
|
|
855
|
+
if (polyline.lines.slice(-1)[0] !== line)
|
|
856
|
+
throw new Error('不能从中间删除线段');
|
|
857
|
+
polyline.pop();
|
|
858
|
+
if (polyline.lines.length === 0)
|
|
859
|
+
removeArrayItem(polyline, this.polylines);
|
|
860
|
+
}
|
|
861
|
+
const [point, anotherPoint] = line.points;
|
|
862
|
+
if (point.lines.length === 0)
|
|
863
|
+
removeArrayItem(point, this.points);
|
|
864
|
+
if (anotherPoint.lines.length === 0)
|
|
865
|
+
removeArrayItem(anotherPoint, this.points);
|
|
866
|
+
removeArrayItem(line, this.lines);
|
|
867
|
+
line.clear();
|
|
868
|
+
this.hook.emit('lineRemoved', line);
|
|
869
|
+
return this;
|
|
870
|
+
}
|
|
871
|
+
mergeModel(model) {
|
|
872
|
+
model.lines.forEach((line) => this.addLine(line));
|
|
873
|
+
}
|
|
874
|
+
includes(item) {
|
|
875
|
+
if (item.type === 'point') {
|
|
876
|
+
return this.points.find(({ id }) => id === item.id) !== undefined;
|
|
877
|
+
}
|
|
878
|
+
else if (item.type === 'line') {
|
|
879
|
+
return this.lines.find(({ id }) => id === item.id) !== undefined;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
getPointByID(id) {
|
|
883
|
+
return this.points.find(({ id: _id }) => _id === id);
|
|
884
|
+
}
|
|
885
|
+
getLineByID(id) {
|
|
886
|
+
return this.lines.find(({ id: _id }) => _id === id);
|
|
887
|
+
}
|
|
888
|
+
getClosestPoint() { }
|
|
889
|
+
parse(data) {
|
|
890
|
+
const points = data.points.map(({ id, position }) => {
|
|
891
|
+
const point = new Point(position);
|
|
892
|
+
point.id = id;
|
|
893
|
+
return point;
|
|
894
|
+
});
|
|
895
|
+
const lines = data.lines.map((data) => {
|
|
896
|
+
const [pointID, anotherPointID] = data.points;
|
|
897
|
+
const point = this.getPointByID.call({ points }, pointID);
|
|
898
|
+
const anotherPoint = this.getPointByID.call({ points }, anotherPointID);
|
|
899
|
+
if (!point || !anotherPoint)
|
|
900
|
+
throw new Error('线上的点不存在');
|
|
901
|
+
const line = new Line(point, anotherPoint, this);
|
|
902
|
+
line.id = data.id;
|
|
903
|
+
return line;
|
|
904
|
+
});
|
|
905
|
+
const polylines = data.polylines.map((polylineJson) => {
|
|
906
|
+
const polyline = new Polyline();
|
|
907
|
+
polylineJson.lines.forEach((lineID) => {
|
|
908
|
+
const line = lines.find(({ id }) => id === lineID);
|
|
909
|
+
line && polyline.push(line);
|
|
910
|
+
});
|
|
911
|
+
return polyline;
|
|
912
|
+
});
|
|
913
|
+
this.points.splice(0, this.points.length, ...points);
|
|
914
|
+
this.lines.splice(0, this.lines.length, ...lines);
|
|
915
|
+
this.polylines.splice(0, this.polylines.length, ...polylines);
|
|
916
|
+
return this;
|
|
917
|
+
}
|
|
918
|
+
toJson() {
|
|
919
|
+
return {
|
|
920
|
+
points: this.points.map((point) => point.toJson()),
|
|
921
|
+
lines: this.lines.map((line) => line.toJson()),
|
|
922
|
+
polylines: this.polylines.map((polyline) => polyline.toJson()).filter((polylines) => polylines.lines.length > 0),
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* 创建一个防抖动函数,该函数在高频调用时会每隔 wait 毫秒后调用 func 方法
|
|
929
|
+
* `throttle` 会在第一次调用时立刻调用一次
|
|
930
|
+
* @param func - 要防抖动的函数
|
|
931
|
+
* @param wait - 需要延迟的毫秒数
|
|
932
|
+
*/
|
|
933
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
934
|
+
function throttle(func, wait = 200) {
|
|
935
|
+
let last;
|
|
936
|
+
return function (...args) {
|
|
937
|
+
if (last)
|
|
938
|
+
return;
|
|
939
|
+
func(...args);
|
|
940
|
+
last = setTimeout(function () {
|
|
941
|
+
last = null;
|
|
942
|
+
}, wait);
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
const preventDefault = (e) => e.preventDefault();
|
|
947
|
+
|
|
948
|
+
class BaseController {
|
|
949
|
+
constructor(params) {
|
|
950
|
+
var _a, _b;
|
|
951
|
+
Object.defineProperty(this, "five", {
|
|
952
|
+
enumerable: true,
|
|
953
|
+
configurable: true,
|
|
954
|
+
writable: true,
|
|
955
|
+
value: void 0
|
|
956
|
+
});
|
|
957
|
+
Object.defineProperty(this, "group", {
|
|
958
|
+
enumerable: true,
|
|
959
|
+
configurable: true,
|
|
960
|
+
writable: true,
|
|
961
|
+
value: void 0
|
|
962
|
+
});
|
|
963
|
+
Object.defineProperty(this, "model", {
|
|
964
|
+
enumerable: true,
|
|
965
|
+
configurable: true,
|
|
966
|
+
writable: true,
|
|
967
|
+
value: void 0
|
|
968
|
+
});
|
|
969
|
+
Object.defineProperty(this, "disposed", {
|
|
970
|
+
enumerable: true,
|
|
971
|
+
configurable: true,
|
|
972
|
+
writable: true,
|
|
973
|
+
value: false
|
|
974
|
+
});
|
|
975
|
+
Object.defineProperty(this, "isMobile", {
|
|
976
|
+
enumerable: true,
|
|
977
|
+
configurable: true,
|
|
978
|
+
writable: true,
|
|
979
|
+
value: void 0
|
|
980
|
+
});
|
|
981
|
+
Object.defineProperty(this, "mouseGroup", {
|
|
982
|
+
enumerable: true,
|
|
983
|
+
configurable: true,
|
|
984
|
+
writable: true,
|
|
985
|
+
value: void 0
|
|
986
|
+
});
|
|
987
|
+
Object.defineProperty(this, "container", {
|
|
988
|
+
enumerable: true,
|
|
989
|
+
configurable: true,
|
|
990
|
+
writable: true,
|
|
991
|
+
value: void 0
|
|
992
|
+
});
|
|
993
|
+
Object.defineProperty(this, "fiveHelper", {
|
|
994
|
+
enumerable: true,
|
|
995
|
+
configurable: true,
|
|
996
|
+
writable: true,
|
|
997
|
+
value: void 0
|
|
998
|
+
});
|
|
999
|
+
Object.defineProperty(this, "hook", {
|
|
1000
|
+
enumerable: true,
|
|
1001
|
+
configurable: true,
|
|
1002
|
+
writable: true,
|
|
1003
|
+
value: void 0
|
|
1004
|
+
});
|
|
1005
|
+
Object.defineProperty(this, "magnifier", {
|
|
1006
|
+
enumerable: true,
|
|
1007
|
+
configurable: true,
|
|
1008
|
+
writable: true,
|
|
1009
|
+
value: void 0
|
|
1010
|
+
});
|
|
1011
|
+
Object.defineProperty(this, "userDistanceItemCreator", {
|
|
1012
|
+
enumerable: true,
|
|
1013
|
+
configurable: true,
|
|
1014
|
+
writable: true,
|
|
1015
|
+
value: void 0
|
|
1016
|
+
});
|
|
1017
|
+
Object.defineProperty(this, "updateDistanceUI", {
|
|
1018
|
+
enumerable: true,
|
|
1019
|
+
configurable: true,
|
|
1020
|
+
writable: true,
|
|
1021
|
+
value: () => {
|
|
1022
|
+
this.model.lines.forEach((line) => line.distanceItem.update(this.five));
|
|
1023
|
+
}
|
|
1024
|
+
});
|
|
1025
|
+
// ==================== Params ====================
|
|
1026
|
+
this.five = params.five;
|
|
1027
|
+
this.hook = params.hook;
|
|
1028
|
+
this.model = params.model;
|
|
1029
|
+
this.magnifier = params.magnifier;
|
|
1030
|
+
this.container = params.container;
|
|
1031
|
+
this.fiveHelper = params.fiveHelper;
|
|
1032
|
+
this.isMobile = (_b = (_a = params.openParams) === null || _a === void 0 ? void 0 : _a.isMobile) !== null && _b !== void 0 ? _b : false;
|
|
1033
|
+
this.userDistanceItemCreator = params.userDistanceItemCreator;
|
|
1034
|
+
// ==================== Groups ====================
|
|
1035
|
+
this.group = params.group;
|
|
1036
|
+
this.mouseGroup = params.mouseGroup;
|
|
1037
|
+
const fiveElement = this.five.getElement();
|
|
1038
|
+
if (fiveElement) {
|
|
1039
|
+
fiveElement.addEventListener('touchstart', preventDefault);
|
|
1040
|
+
fiveElement.addEventListener('contextmenu', preventDefault);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
removeLine(line) {
|
|
1044
|
+
this.group.remove(line.mesh, line.lightMesh);
|
|
1045
|
+
line.distanceItem.remove();
|
|
1046
|
+
this.five.needsRender = true;
|
|
1047
|
+
}
|
|
1048
|
+
updateMouseGroup(intersection, mesh) {
|
|
1049
|
+
if (!intersection)
|
|
1050
|
+
return this.mouseGroup;
|
|
1051
|
+
// ============ update mouseGroup position ============
|
|
1052
|
+
const adsorbentPoint = this.fiveHelper.getAdsorbentPoint(intersection);
|
|
1053
|
+
const viewPosition = adsorbentPoint ? adsorbentPoint : intersection.point;
|
|
1054
|
+
this.mouseGroup.position.copy(viewPosition);
|
|
1055
|
+
// ============ update mouseGroup quaternion ============
|
|
1056
|
+
if (mesh) {
|
|
1057
|
+
this.mouseGroup.quaternion.copy(mesh.quaternion);
|
|
1058
|
+
}
|
|
1059
|
+
else if (intersection.face) {
|
|
1060
|
+
const normal = intersection.face.normal;
|
|
1061
|
+
const positionVector = normal.clone().multiplyScalar(0.05);
|
|
1062
|
+
const position = intersection.point.clone().add(positionVector);
|
|
1063
|
+
const lookAtVector = position.clone().add(positionVector);
|
|
1064
|
+
this.mouseGroup.lookAt(lookAtVector);
|
|
1065
|
+
}
|
|
1066
|
+
return this.mouseGroup;
|
|
1067
|
+
}
|
|
1068
|
+
dispose() {
|
|
1069
|
+
this.disposed = true;
|
|
1070
|
+
this.magnifier.remove();
|
|
1071
|
+
this.model.lines.forEach((line) => this.removeLine(line));
|
|
1072
|
+
const fiveElement = this.five.getElement();
|
|
1073
|
+
if (fiveElement) {
|
|
1074
|
+
fiveElement.removeEventListener('touchstart', preventDefault);
|
|
1075
|
+
fiveElement.removeEventListener('contextmenu', preventDefault);
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* 从 Hammer 事件中获取操作的点在交互 DOM 中的位置
|
|
1082
|
+
* @ignore TODO: make a suitable name
|
|
1083
|
+
*/
|
|
1084
|
+
function getPointFromHammerEvent(event) {
|
|
1085
|
+
// clientX 与 clientY 是相对 document 的,需要转换成相对于 target 的坐标
|
|
1086
|
+
const { x: clientX, y: clientY } = event.center;
|
|
1087
|
+
const { clientWidth, clientHeight } = event.target;
|
|
1088
|
+
const clientRect = event.target.getBoundingClientRect();
|
|
1089
|
+
const position = new THREE.Vector2(clientX, clientY).sub(new THREE.Vector2(clientRect.left, clientRect.top));
|
|
1090
|
+
const mouse = new THREE.Vector2((position.x / clientWidth) * 2 - 1, -(position.y / clientHeight) * 2 + 1);
|
|
1091
|
+
return { point: position, ndcPoint: mouse };
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
/** 通过鼠标事件或者触摸事件,获取当前点击屏幕关联的射线与模型的交点 */
|
|
1095
|
+
function getIntersectionFromEvent(five, event) {
|
|
1096
|
+
const mouse = getPointFromHammerEvent(event).ndcPoint;
|
|
1097
|
+
const raycaster = new THREE.Raycaster();
|
|
1098
|
+
raycaster.setFromCamera(mouse, five.camera);
|
|
1099
|
+
return five.model.intersectRaycaster(raycaster);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
class EditController extends BaseController {
|
|
1103
|
+
constructor(params) {
|
|
1104
|
+
var _a;
|
|
1105
|
+
super(params);
|
|
1106
|
+
Object.defineProperty(this, "type", {
|
|
1107
|
+
enumerable: true,
|
|
1108
|
+
configurable: true,
|
|
1109
|
+
writable: true,
|
|
1110
|
+
value: 'edit'
|
|
1111
|
+
});
|
|
1112
|
+
Object.defineProperty(this, "model", {
|
|
1113
|
+
enumerable: true,
|
|
1114
|
+
configurable: true,
|
|
1115
|
+
writable: true,
|
|
1116
|
+
value: new Model({ userDistanceItemCreator: this.userDistanceItemCreator })
|
|
1117
|
+
});
|
|
1118
|
+
Object.defineProperty(this, "pressPoint", {
|
|
1119
|
+
enumerable: true,
|
|
1120
|
+
configurable: true,
|
|
1121
|
+
writable: true,
|
|
1122
|
+
value: void 0
|
|
1123
|
+
});
|
|
1124
|
+
Object.defineProperty(this, "hasAppendDashed", {
|
|
1125
|
+
enumerable: true,
|
|
1126
|
+
configurable: true,
|
|
1127
|
+
writable: true,
|
|
1128
|
+
value: false
|
|
1129
|
+
});
|
|
1130
|
+
Object.defineProperty(this, "hasAppendMouseGroup", {
|
|
1131
|
+
enumerable: true,
|
|
1132
|
+
configurable: true,
|
|
1133
|
+
writable: true,
|
|
1134
|
+
value: false
|
|
1135
|
+
});
|
|
1136
|
+
Object.defineProperty(this, "fiveElement", {
|
|
1137
|
+
enumerable: true,
|
|
1138
|
+
configurable: true,
|
|
1139
|
+
writable: true,
|
|
1140
|
+
value: void 0
|
|
1141
|
+
});
|
|
1142
|
+
/** 上一个端点位置 */
|
|
1143
|
+
Object.defineProperty(this, "lastPoint", {
|
|
1144
|
+
enumerable: true,
|
|
1145
|
+
configurable: true,
|
|
1146
|
+
writable: true,
|
|
1147
|
+
value: null
|
|
1148
|
+
});
|
|
1149
|
+
/** 鼠标点到上一个端点连接的虚线 */
|
|
1150
|
+
Object.defineProperty(this, "dashed", {
|
|
1151
|
+
enumerable: true,
|
|
1152
|
+
configurable: true,
|
|
1153
|
+
writable: true,
|
|
1154
|
+
value: void 0
|
|
1155
|
+
});
|
|
1156
|
+
Object.defineProperty(this, "hammer", {
|
|
1157
|
+
enumerable: true,
|
|
1158
|
+
configurable: true,
|
|
1159
|
+
writable: true,
|
|
1160
|
+
value: void 0
|
|
1161
|
+
});
|
|
1162
|
+
/** 根据 intersection 更新放大镜和吸附点 */
|
|
1163
|
+
Object.defineProperty(this, "onIntersectionUpdate", {
|
|
1164
|
+
enumerable: true,
|
|
1165
|
+
configurable: true,
|
|
1166
|
+
writable: true,
|
|
1167
|
+
value: throttle((intersection, mesh) => {
|
|
1168
|
+
var _a;
|
|
1169
|
+
if (this.hasAppendMouseGroup === false) {
|
|
1170
|
+
this.group.add(this.mouseGroup);
|
|
1171
|
+
this.magnifier.appendTo(this.container);
|
|
1172
|
+
this.hasAppendMouseGroup = true;
|
|
1173
|
+
}
|
|
1174
|
+
const position = this.updateMouseGroup(intersection, mesh).position;
|
|
1175
|
+
(_a = this.pressPoint) === null || _a === void 0 ? void 0 : _a.position.copy(position);
|
|
1176
|
+
this.updateDashed();
|
|
1177
|
+
requestAnimationFrame(() => this.magnifier.renderWithPoint(this.mouseGroup.position));
|
|
1178
|
+
this.five.needsRender = true;
|
|
1179
|
+
}, 20)
|
|
1180
|
+
});
|
|
1181
|
+
/** 撤销编辑 */
|
|
1182
|
+
Object.defineProperty(this, "revoke", {
|
|
1183
|
+
enumerable: true,
|
|
1184
|
+
configurable: true,
|
|
1185
|
+
writable: true,
|
|
1186
|
+
value: () => {
|
|
1187
|
+
// ============ revoke points ============
|
|
1188
|
+
// 如果当前没有虚线,只有起始点,需要删除起始点,重置起始状态。并删除虚线实例
|
|
1189
|
+
if (this.model.lines.length === 0 && this.lastPoint) {
|
|
1190
|
+
this.lastPoint = null;
|
|
1191
|
+
this.hasAppendDashed = false;
|
|
1192
|
+
this.dashed.distanceItem.remove();
|
|
1193
|
+
this.group.remove(this.dashed.mesh);
|
|
1194
|
+
this.hook.emit('anchorChange', null);
|
|
1195
|
+
this.five.needsRender = true;
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
if (this.model.lines.length === 0 && !this.lastPoint)
|
|
1199
|
+
return;
|
|
1200
|
+
if (!this.lastPoint)
|
|
1201
|
+
return;
|
|
1202
|
+
const revokedLine = this.model.lines[this.model.lines.length - 1];
|
|
1203
|
+
const lastPoint = revokedLine.findAnotherPoint(this.lastPoint);
|
|
1204
|
+
if (!lastPoint)
|
|
1205
|
+
return;
|
|
1206
|
+
this.lastPoint = lastPoint;
|
|
1207
|
+
this.hook.emit('anchorChange', lastPoint.position);
|
|
1208
|
+
// ============ revoke lines ============
|
|
1209
|
+
this.group.remove(revokedLine.mesh);
|
|
1210
|
+
this.model.removeLine(revokedLine);
|
|
1211
|
+
// ============ revoke mouse group ============
|
|
1212
|
+
this.hasAppendMouseGroup = false;
|
|
1213
|
+
this.mouseGroup.position.copy(this.lastPoint.position);
|
|
1214
|
+
this.group.remove(this.mouseGroup);
|
|
1215
|
+
// ============ revoke lineDistance ============
|
|
1216
|
+
revokedLine.distanceItem.remove();
|
|
1217
|
+
// ============ revoke dashed ============
|
|
1218
|
+
this.updateDashed();
|
|
1219
|
+
// ============ revoke magnifier ============
|
|
1220
|
+
this.magnifier.remove();
|
|
1221
|
+
this.five.needsRender = true;
|
|
1222
|
+
}
|
|
1223
|
+
});
|
|
1224
|
+
Object.defineProperty(this, "onMouseLeave", {
|
|
1225
|
+
enumerable: true,
|
|
1226
|
+
configurable: true,
|
|
1227
|
+
writable: true,
|
|
1228
|
+
value: () => {
|
|
1229
|
+
this.magnifier.remove();
|
|
1230
|
+
this.group.remove(this.mouseGroup);
|
|
1231
|
+
this.hasAppendMouseGroup = false;
|
|
1232
|
+
if (this.lastPoint) {
|
|
1233
|
+
this.mouseGroup.position.copy(this.lastPoint.position);
|
|
1234
|
+
this.updateDashed();
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
});
|
|
1238
|
+
/** 编辑线条发生改变时通知外部 */
|
|
1239
|
+
Object.defineProperty(this, "onLineChanged", {
|
|
1240
|
+
enumerable: true,
|
|
1241
|
+
configurable: true,
|
|
1242
|
+
writable: true,
|
|
1243
|
+
value: () => {
|
|
1244
|
+
this.hook.emit('editedLineChange', this.model.lines.map((line) => line.toCompletelyJson()));
|
|
1245
|
+
}
|
|
1246
|
+
});
|
|
1247
|
+
Object.defineProperty(this, "onPress", {
|
|
1248
|
+
enumerable: true,
|
|
1249
|
+
configurable: true,
|
|
1250
|
+
writable: true,
|
|
1251
|
+
value: (e) => {
|
|
1252
|
+
const [intersection] = getIntersectionFromEvent(this.five, e);
|
|
1253
|
+
if (!intersection || !intersection.face)
|
|
1254
|
+
return;
|
|
1255
|
+
const nowPoint = new Point(intersection.point);
|
|
1256
|
+
this.pressPoint = nowPoint;
|
|
1257
|
+
this.onIntersectionUpdate(intersection);
|
|
1258
|
+
}
|
|
1259
|
+
});
|
|
1260
|
+
/**
|
|
1261
|
+
* 1. 如果之前没有长按行为「即没有长按点时」-> 滑动全景
|
|
1262
|
+
* 2. 如果有长按点,把长按点位置更新为当前位置
|
|
1263
|
+
*/
|
|
1264
|
+
Object.defineProperty(this, "onPan", {
|
|
1265
|
+
enumerable: true,
|
|
1266
|
+
configurable: true,
|
|
1267
|
+
writable: true,
|
|
1268
|
+
value: (e) => {
|
|
1269
|
+
if (!this.pressPoint)
|
|
1270
|
+
return;
|
|
1271
|
+
const [intersection] = getIntersectionFromEvent(this.five, e);
|
|
1272
|
+
if (!intersection || !intersection.face)
|
|
1273
|
+
return;
|
|
1274
|
+
this.onIntersectionUpdate(intersection);
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
Object.defineProperty(this, "onPanEnd", {
|
|
1278
|
+
enumerable: true,
|
|
1279
|
+
configurable: true,
|
|
1280
|
+
writable: true,
|
|
1281
|
+
value: (e) => {
|
|
1282
|
+
if (!this.pressPoint)
|
|
1283
|
+
return;
|
|
1284
|
+
this.onTap(e);
|
|
1285
|
+
}
|
|
1286
|
+
});
|
|
1287
|
+
/**
|
|
1288
|
+
* 1. 如果存在上一个点,需要绘制当前点到上一个点的连线
|
|
1289
|
+
* 2. 把上一个点的位置更新为当前点的位置
|
|
1290
|
+
* 3. 清除 mouseGroup 和 magnifier
|
|
1291
|
+
*/
|
|
1292
|
+
Object.defineProperty(this, "onTap", {
|
|
1293
|
+
enumerable: true,
|
|
1294
|
+
configurable: true,
|
|
1295
|
+
writable: true,
|
|
1296
|
+
value: (e) => {
|
|
1297
|
+
if (!this.hasAppendDashed) {
|
|
1298
|
+
this.dashed.distanceItem.appendTo(this.container);
|
|
1299
|
+
this.group.add(this.dashed.mesh);
|
|
1300
|
+
}
|
|
1301
|
+
this.hasAppendDashed = true;
|
|
1302
|
+
const [intersection] = getIntersectionFromEvent(this.five, e);
|
|
1303
|
+
this.updateMouseGroup(intersection);
|
|
1304
|
+
const nowPoint = new Point(this.mouseGroup.position);
|
|
1305
|
+
const lastPoint = this.lastPoint;
|
|
1306
|
+
if (nowPoint)
|
|
1307
|
+
this.lastPoint = nowPoint;
|
|
1308
|
+
if (nowPoint && lastPoint) {
|
|
1309
|
+
const line = new Line(lastPoint, nowPoint, this.model);
|
|
1310
|
+
line.distanceItem.appendTo(this.container);
|
|
1311
|
+
this.model.addLine(line);
|
|
1312
|
+
this.group.add(line.mesh);
|
|
1313
|
+
line.distanceItem.update(this.five);
|
|
1314
|
+
}
|
|
1315
|
+
this.pressPoint = undefined;
|
|
1316
|
+
this.hasAppendMouseGroup = false;
|
|
1317
|
+
this.magnifier.remove();
|
|
1318
|
+
this.group.remove(this.mouseGroup);
|
|
1319
|
+
this.updateDashed();
|
|
1320
|
+
this.five.needsRender = true;
|
|
1321
|
+
this.hook.emit('anchorChange', nowPoint.position);
|
|
1322
|
+
}
|
|
1323
|
+
});
|
|
1324
|
+
Object.defineProperty(this, "onWantsTapGesture", {
|
|
1325
|
+
enumerable: true,
|
|
1326
|
+
configurable: true,
|
|
1327
|
+
writable: true,
|
|
1328
|
+
value: () => false
|
|
1329
|
+
});
|
|
1330
|
+
/** 编辑时取消走点 */
|
|
1331
|
+
Object.defineProperty(this, "onWantsToMoveToPano", {
|
|
1332
|
+
enumerable: true,
|
|
1333
|
+
configurable: true,
|
|
1334
|
+
writable: true,
|
|
1335
|
+
value: () => false
|
|
1336
|
+
});
|
|
1337
|
+
/** 存在长按点时不能移动全景 */
|
|
1338
|
+
Object.defineProperty(this, "onWantsPanGesture", {
|
|
1339
|
+
enumerable: true,
|
|
1340
|
+
configurable: true,
|
|
1341
|
+
writable: true,
|
|
1342
|
+
value: () => (this.pressPoint ? false : undefined)
|
|
1343
|
+
});
|
|
1344
|
+
/** 移动全景时更新 distanceItem 在屏幕上的位置 */
|
|
1345
|
+
Object.defineProperty(this, "onCameraUpdate", {
|
|
1346
|
+
enumerable: true,
|
|
1347
|
+
configurable: true,
|
|
1348
|
+
writable: true,
|
|
1349
|
+
value: () => {
|
|
1350
|
+
this.updateDistanceUI();
|
|
1351
|
+
this.dashed.distanceItem.update(this.five);
|
|
1352
|
+
}
|
|
1353
|
+
});
|
|
1354
|
+
/** 更新虚线 */
|
|
1355
|
+
Object.defineProperty(this, "updateDashed", {
|
|
1356
|
+
enumerable: true,
|
|
1357
|
+
configurable: true,
|
|
1358
|
+
writable: true,
|
|
1359
|
+
value: () => {
|
|
1360
|
+
if (!this.lastPoint)
|
|
1361
|
+
return;
|
|
1362
|
+
this.dashed.points[0].position.copy(this.lastPoint.position);
|
|
1363
|
+
this.dashed.points[1].position.copy(this.mouseGroup.position);
|
|
1364
|
+
this.dashed.mesh.setPoints(this.lastPoint.position, this.mouseGroup.position);
|
|
1365
|
+
this.dashed.distanceItem.update(this.five);
|
|
1366
|
+
}
|
|
1367
|
+
});
|
|
1368
|
+
// ==================== 虚线 ====================
|
|
1369
|
+
this.dashed = new Line(new Point([0, 0, 0]), new Point([0, 0, 0]), this.model);
|
|
1370
|
+
this.dashed.mesh.setMaterial({ dashed: true, dashScale: 100 });
|
|
1371
|
+
// ==================== 事件监听 ====================
|
|
1372
|
+
// five
|
|
1373
|
+
this.five.on('cameraUpdate', this.onCameraUpdate);
|
|
1374
|
+
this.five.on('wantsPanGesture', this.onWantsPanGesture);
|
|
1375
|
+
this.five.on('wantsTapGesture', this.onWantsTapGesture);
|
|
1376
|
+
this.five.on('wantsToMoveToPano', this.onWantsToMoveToPano);
|
|
1377
|
+
this.five.on('intersectionOnModelUpdate', this.onIntersectionUpdate);
|
|
1378
|
+
// model
|
|
1379
|
+
this.model.hook.on('lineAdded', this.onLineChanged);
|
|
1380
|
+
this.model.hook.on('lineRemoved', this.onLineChanged);
|
|
1381
|
+
// hammer
|
|
1382
|
+
const fiveElement = this.five.getElement();
|
|
1383
|
+
if (fiveElement) {
|
|
1384
|
+
this.fiveElement = fiveElement;
|
|
1385
|
+
const hammer = new Hammer__default["default"](fiveElement);
|
|
1386
|
+
this.hammer = hammer;
|
|
1387
|
+
hammer.on('tap', this.onTap);
|
|
1388
|
+
hammer.on('pan', this.onPan);
|
|
1389
|
+
hammer.on('press', this.onPress);
|
|
1390
|
+
hammer.on('panend', this.onPanEnd);
|
|
1391
|
+
}
|
|
1392
|
+
// fiveElement
|
|
1393
|
+
(_a = this.fiveElement) === null || _a === void 0 ? void 0 : _a.addEventListener('mouseleave', this.onMouseLeave);
|
|
1394
|
+
// ==================== 其他 ====================
|
|
1395
|
+
this.hook.emit('anchorChange', null);
|
|
1396
|
+
this.five.refresh();
|
|
1397
|
+
}
|
|
1398
|
+
dispose() {
|
|
1399
|
+
var _a, _b;
|
|
1400
|
+
super.dispose();
|
|
1401
|
+
this.group.remove(this.mouseGroup, this.dashed.mesh);
|
|
1402
|
+
// ==================== 解除事件监听 ====================
|
|
1403
|
+
// five
|
|
1404
|
+
this.five.off('cameraUpdate', this.onCameraUpdate);
|
|
1405
|
+
this.five.off('wantsPanGesture', this.onWantsPanGesture);
|
|
1406
|
+
this.five.off('wantsTapGesture', this.onWantsTapGesture);
|
|
1407
|
+
this.five.off('wantsToMoveToPano', this.onWantsToMoveToPano);
|
|
1408
|
+
this.five.off('intersectionOnModelUpdate', this.onIntersectionUpdate);
|
|
1409
|
+
// model
|
|
1410
|
+
this.model.hook.off('lineAdded', this.onLineChanged);
|
|
1411
|
+
this.model.hook.off('lineRemoved', this.onLineChanged);
|
|
1412
|
+
// hammer
|
|
1413
|
+
(_a = this.hammer) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
1414
|
+
// fiveElement
|
|
1415
|
+
(_b = this.fiveElement) === null || _b === void 0 ? void 0 : _b.removeEventListener('mouseleave', this.onMouseLeave);
|
|
1416
|
+
this.magnifier.dispose();
|
|
1417
|
+
this.dashed.distanceItem.remove();
|
|
1418
|
+
this.five.needsRender = true;
|
|
1419
|
+
}
|
|
1420
|
+
getEditingLines() {
|
|
1421
|
+
return this.model.lines;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
const svg = `
|
|
1426
|
+
<svg class="fpm__delete-icon" width="16px" height="17px" viewBox="0 0 16 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
1427
|
+
<defs>
|
|
1428
|
+
<linearGradient x1="22.185491%" y1="100%" x2="66.8316686%" y2="6.67239121%" id="linearGradient-1">
|
|
1429
|
+
<stop stop-color="#FFFCFC" stop-opacity="0.6" offset="0%"></stop>
|
|
1430
|
+
<stop stop-color="#FFFFFF" offset="100%"></stop>
|
|
1431
|
+
</linearGradient>
|
|
1432
|
+
</defs>
|
|
1433
|
+
<path fill="url(#linearGradient-1)" fill-rule="nonzero" transform="translate(2.16 2.16)" d="M11.2979686,2.71818182 C11.611378,2.71818182 11.8654465,2.97561809 11.8654465,3.29318182 C11.8654465,3.58428191 11.6519584,3.82485822 11.374972,3.86293275 L11.2979686,3.86818182 L10.464,3.868 L9.7236795,10.6246222 C9.64153248,11.3737453 9.04854423,11.9512142 8.32013277,12.0165596 L8.18206028,12.0227273 L3.68338622,12.0227273 C2.89302127,12.0227273 2.22904821,11.4205655 2.141767,10.6246222 L2.141767,10.6246222 L1.4,3.868 L0.567477876,3.86818182 C0.254068499,3.86818182 0,3.61074555 0,3.29318182 C0,3.00208173 0.213488114,2.76150541 0.49047449,2.72343089 L0.567477876,2.71818182 L11.2979686,2.71818182 Z M9.322,3.868 L2.542,3.868 L3.26978106,10.4976259 C3.28762252,10.6603274 3.39528004,10.7928487 3.53932022,10.8467307 L3.61412483,10.866894 L3.68338622,10.8727273 L8.18206028,10.8727273 C8.39410941,10.8727273 8.57224853,10.7111717 8.59566544,10.4976259 L8.59566544,10.4976259 L9.322,3.868 Z M8.16824216,0 C8.48165153,0 8.73572003,0.257436269 8.73572003,0.575 C8.73572003,0.866100087 8.52223192,1.1066764 8.24524554,1.14475093 L8.16824216,1.15 L3.69720434,1.15 C3.38379497,1.15 3.12972647,0.892563731 3.12972647,0.575 C3.12972647,0.283899913 3.34321458,0.0433235966 3.62020096,0.00524907226 L3.69720434,0 L8.16824216,0 Z"></path>
|
|
1434
|
+
</svg>
|
|
1435
|
+
`;
|
|
1436
|
+
|
|
1437
|
+
const image$1 = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTciIGhlaWdodD0iMjUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IHgxPSIxMC43MDYlIiB5MT0iNDIuNzQ0JSIgeDI9Ijg5LjA2NCUiIHkyPSI1Ny4yMDglIiBpZD0icHJlZml4X19hIj48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9Ii4zMDgiIG9mZnNldD0iNDkuNTY5JSIvPjxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iMCIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iLS4yNSIgeT0iLS4yNSIgd2lkdGg9IjU3LjUiIGhlaWdodD0iMjMuNSIgcng9IjExLjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIiBmaWxsPSIjMkMyQzJDIiBzdHJva2U9InVybCgjcHJlZml4X19hKSIgc3Ryb2tlLXdpZHRoPSIuNSIgZmlsbC1ydWxlPSJldmVub2RkIiBmaWxsLW9wYWNpdHk9Ii4zMDMiLz48L3N2Zz4=`;
|
|
1438
|
+
|
|
1439
|
+
const image = `data:image/png;base64,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`;
|
|
1440
|
+
|
|
1441
|
+
class DeleteDom {
|
|
1442
|
+
constructor(five, opts) {
|
|
1443
|
+
Object.defineProperty(this, "visible", {
|
|
1444
|
+
enumerable: true,
|
|
1445
|
+
configurable: true,
|
|
1446
|
+
writable: true,
|
|
1447
|
+
value: false
|
|
1448
|
+
});
|
|
1449
|
+
Object.defineProperty(this, "five", {
|
|
1450
|
+
enumerable: true,
|
|
1451
|
+
configurable: true,
|
|
1452
|
+
writable: true,
|
|
1453
|
+
value: void 0
|
|
1454
|
+
});
|
|
1455
|
+
Object.defineProperty(this, "lines", {
|
|
1456
|
+
enumerable: true,
|
|
1457
|
+
configurable: true,
|
|
1458
|
+
writable: true,
|
|
1459
|
+
value: []
|
|
1460
|
+
});
|
|
1461
|
+
Object.defineProperty(this, "points", {
|
|
1462
|
+
enumerable: true,
|
|
1463
|
+
configurable: true,
|
|
1464
|
+
writable: true,
|
|
1465
|
+
value: []
|
|
1466
|
+
});
|
|
1467
|
+
Object.defineProperty(this, "onClick", {
|
|
1468
|
+
enumerable: true,
|
|
1469
|
+
configurable: true,
|
|
1470
|
+
writable: true,
|
|
1471
|
+
value: void 0
|
|
1472
|
+
});
|
|
1473
|
+
Object.defineProperty(this, "cancelDelete", {
|
|
1474
|
+
enumerable: true,
|
|
1475
|
+
configurable: true,
|
|
1476
|
+
writable: true,
|
|
1477
|
+
value: void 0
|
|
1478
|
+
});
|
|
1479
|
+
Object.defineProperty(this, "content", {
|
|
1480
|
+
enumerable: true,
|
|
1481
|
+
configurable: true,
|
|
1482
|
+
writable: true,
|
|
1483
|
+
value: document.createElement('div')
|
|
1484
|
+
});
|
|
1485
|
+
Object.defineProperty(this, "container", {
|
|
1486
|
+
enumerable: true,
|
|
1487
|
+
configurable: true,
|
|
1488
|
+
writable: true,
|
|
1489
|
+
value: document.createElement('div')
|
|
1490
|
+
});
|
|
1491
|
+
Object.defineProperty(this, "masking", {
|
|
1492
|
+
enumerable: true,
|
|
1493
|
+
configurable: true,
|
|
1494
|
+
writable: true,
|
|
1495
|
+
value: document.createElement('div')
|
|
1496
|
+
});
|
|
1497
|
+
Object.defineProperty(this, "onMouseEnter", {
|
|
1498
|
+
enumerable: true,
|
|
1499
|
+
configurable: true,
|
|
1500
|
+
writable: true,
|
|
1501
|
+
value: () => {
|
|
1502
|
+
this.content.style.backgroundImage = `url(${image})`;
|
|
1503
|
+
}
|
|
1504
|
+
});
|
|
1505
|
+
Object.defineProperty(this, "onMouseLeave", {
|
|
1506
|
+
enumerable: true,
|
|
1507
|
+
configurable: true,
|
|
1508
|
+
writable: true,
|
|
1509
|
+
value: () => {
|
|
1510
|
+
this.content.style.backgroundImage = `url(${image$1})`;
|
|
1511
|
+
}
|
|
1512
|
+
});
|
|
1513
|
+
this.five = five;
|
|
1514
|
+
this.onClick = (opts === null || opts === void 0 ? void 0 : opts.onClick) || (() => void 0);
|
|
1515
|
+
this.cancelDelete = (opts === null || opts === void 0 ? void 0 : opts.cancelDelete) || (() => void 0);
|
|
1516
|
+
// container
|
|
1517
|
+
this.container.classList.add('fpm__delete');
|
|
1518
|
+
this.container.style.opacity = '0';
|
|
1519
|
+
this.container.style.position = 'absolute';
|
|
1520
|
+
this.container.style.left = '0';
|
|
1521
|
+
this.container.style.top = '10px';
|
|
1522
|
+
this.container.style.transform = `translate3d(0, 0, 10px)`;
|
|
1523
|
+
this.container.style.pointerEvents = `none`;
|
|
1524
|
+
this.container.style.transition = 'top 200ms ease, opacity 200ms ease';
|
|
1525
|
+
this.container.style.zIndex = '99';
|
|
1526
|
+
// content
|
|
1527
|
+
this.content.classList.add('fpm__delete-content');
|
|
1528
|
+
this.content.style.width = '62px';
|
|
1529
|
+
this.content.style.height = '26px';
|
|
1530
|
+
this.content.style.display = 'flex';
|
|
1531
|
+
this.content.style.alignItems = 'center';
|
|
1532
|
+
this.content.style.justifyContent = 'center';
|
|
1533
|
+
this.content.style.transform = 'translate(-50%, -50%)';
|
|
1534
|
+
this.content.style.color = '#fff';
|
|
1535
|
+
this.content.style.fontSize = '12px';
|
|
1536
|
+
this.content.style.lineHeight = '17px';
|
|
1537
|
+
this.content.style.borderRadius = '11px';
|
|
1538
|
+
this.content.style.backgroundSize = '100% 100%';
|
|
1539
|
+
this.content.style.cursor = 'pointer';
|
|
1540
|
+
this.content.style.userSelect = 'none';
|
|
1541
|
+
this.content.style.backgroundImage = `url(${image$1})`;
|
|
1542
|
+
this.content.innerHTML = `
|
|
1543
|
+
${svg}
|
|
1544
|
+
<span>删除</span>
|
|
1545
|
+
`;
|
|
1546
|
+
this.container.append(this.content);
|
|
1547
|
+
const deleteSvgDom = this.content.querySelector('.fpm__delete-icon');
|
|
1548
|
+
if (deleteSvgDom) {
|
|
1549
|
+
deleteSvgDom.style.width = '16px';
|
|
1550
|
+
deleteSvgDom.style.height = '17px';
|
|
1551
|
+
deleteSvgDom.style.marginRight = '1px';
|
|
1552
|
+
}
|
|
1553
|
+
this.content.addEventListener('click', this.onClick);
|
|
1554
|
+
this.content.addEventListener('mouseenter', this.onMouseEnter);
|
|
1555
|
+
this.content.addEventListener('mouseleave', this.onMouseLeave);
|
|
1556
|
+
// masking
|
|
1557
|
+
this.masking.setAttribute('style', 'position: absolute;top: 0;left: 0;bottom: 0;right: 0;pointer-events: none;');
|
|
1558
|
+
this.masking.addEventListener('click', this.cancelDelete);
|
|
1559
|
+
this.masking.addEventListener('touchstart', this.cancelDelete);
|
|
1560
|
+
}
|
|
1561
|
+
dispose() {
|
|
1562
|
+
this.content.removeEventListener('click', this.onClick);
|
|
1563
|
+
this.content.removeEventListener('mouseenter', this.onMouseEnter);
|
|
1564
|
+
this.content.removeEventListener('mouseleave', this.onMouseLeave);
|
|
1565
|
+
this.container.remove();
|
|
1566
|
+
this.masking.removeEventListener('click', this.cancelDelete);
|
|
1567
|
+
this.masking.removeEventListener('touchstart', this.cancelDelete);
|
|
1568
|
+
this.masking.remove();
|
|
1569
|
+
}
|
|
1570
|
+
appendTo(element) {
|
|
1571
|
+
element.append(this.container);
|
|
1572
|
+
element.append(this.masking);
|
|
1573
|
+
return this;
|
|
1574
|
+
}
|
|
1575
|
+
setLines(lines) {
|
|
1576
|
+
this.lines = lines;
|
|
1577
|
+
this.points = Array.from(new Set(this.lines.map((line) => [line.points[0], line.points[1]]).flat(1)));
|
|
1578
|
+
return this;
|
|
1579
|
+
}
|
|
1580
|
+
updatePosition() {
|
|
1581
|
+
if (this.lines.length === 0)
|
|
1582
|
+
return this;
|
|
1583
|
+
const points = this.points.map((point) => point.position);
|
|
1584
|
+
const ndcPoints = points.map((point) => point.clone().project(this.five.camera));
|
|
1585
|
+
if (ndcPoints.some((ndcPoint) => Math.abs(ndcPoint.z) > 1))
|
|
1586
|
+
return this.hide();
|
|
1587
|
+
const xArray = ndcPoints.map((point) => point.x);
|
|
1588
|
+
const yArray = ndcPoints.map((point) => point.y);
|
|
1589
|
+
const centerX = (Math.min(...xArray) + Math.max(...xArray)) / 2;
|
|
1590
|
+
const maxY = Math.max(...yArray);
|
|
1591
|
+
const wrapper = this.container.parentElement;
|
|
1592
|
+
if (!wrapper)
|
|
1593
|
+
return this;
|
|
1594
|
+
const centerScreenX = ((centerX + 1) / 2) * wrapper.clientWidth;
|
|
1595
|
+
const maxScreenY = (-(maxY - 1) / 2) * wrapper.clientHeight;
|
|
1596
|
+
let x = centerScreenX;
|
|
1597
|
+
let y = maxScreenY - 34;
|
|
1598
|
+
// 只有一条线时且斜率大时删除按钮位于右侧
|
|
1599
|
+
if (this.lines.length === 1 && points.length === 2) {
|
|
1600
|
+
const k = (yArray[1] - yArray[0]) / (xArray[1] - xArray[0]);
|
|
1601
|
+
const centerY = (yArray[1] + yArray[0]) / 2;
|
|
1602
|
+
const centerScreenY = (-(centerY - 1) / 2) * wrapper.clientHeight;
|
|
1603
|
+
if (Math.abs(k) > 0.4) {
|
|
1604
|
+
x = centerScreenX + 57;
|
|
1605
|
+
y = centerScreenY;
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
this.container.style.transform = `translate3d(${x}px, ${y}px, 10px)`;
|
|
1609
|
+
return this.show();
|
|
1610
|
+
}
|
|
1611
|
+
hide() {
|
|
1612
|
+
this.visible = false;
|
|
1613
|
+
this.masking.style.pointerEvents = 'none';
|
|
1614
|
+
this.container.style.opacity = '0';
|
|
1615
|
+
this.container.style.top = '10px';
|
|
1616
|
+
this.container.style.pointerEvents = 'none';
|
|
1617
|
+
return this;
|
|
1618
|
+
}
|
|
1619
|
+
show() {
|
|
1620
|
+
this.visible = true;
|
|
1621
|
+
this.masking.style.pointerEvents = 'auto';
|
|
1622
|
+
this.container.style.opacity = '1';
|
|
1623
|
+
this.container.style.top = '0';
|
|
1624
|
+
this.container.style.pointerEvents = 'auto';
|
|
1625
|
+
return this;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
/**
|
|
1630
|
+
* 获取一点对于线段上最近的一点,
|
|
1631
|
+
* 如果可以是过直线垂线的垂足,不行的话取线段的两端
|
|
1632
|
+
* @param point
|
|
1633
|
+
* @param linePoints
|
|
1634
|
+
* @return
|
|
1635
|
+
*/
|
|
1636
|
+
function closestPointOnLine(point, linePoints) {
|
|
1637
|
+
const tA = point.x - linePoints[0].x;
|
|
1638
|
+
const tB = point.y - linePoints[0].y;
|
|
1639
|
+
const tC = linePoints[1].x - linePoints[0].x;
|
|
1640
|
+
const tD = linePoints[1].y - linePoints[0].y;
|
|
1641
|
+
// 设线段为 AB 线段,线段外一点为 P
|
|
1642
|
+
// tDot = AP 向量与 AB 向量乘积,tLenSq 为 |AB|平方。
|
|
1643
|
+
// tParam 是 AP 向量在 AB 向量投影向量 AC 与 AB 向量的比。
|
|
1644
|
+
const tDot = tA * tC + tB * tD;
|
|
1645
|
+
const tLenSq = tC * tC + tD * tD;
|
|
1646
|
+
const tParam = tDot / tLenSq;
|
|
1647
|
+
let tXx, tYy;
|
|
1648
|
+
if (tParam < 0 || samePointAt(linePoints[0], linePoints[1])) {
|
|
1649
|
+
tXx = linePoints[0].x;
|
|
1650
|
+
tYy = linePoints[0].y;
|
|
1651
|
+
}
|
|
1652
|
+
else if (tParam > 1) {
|
|
1653
|
+
tXx = linePoints[1].x;
|
|
1654
|
+
tYy = linePoints[1].y;
|
|
1655
|
+
}
|
|
1656
|
+
else {
|
|
1657
|
+
tXx = linePoints[0].x + tParam * tC;
|
|
1658
|
+
tYy = linePoints[0].y + tParam * tD;
|
|
1659
|
+
}
|
|
1660
|
+
return new THREE.Vector2(tXx, tYy);
|
|
1661
|
+
}
|
|
1662
|
+
/**
|
|
1663
|
+
* 检查两个点是否位置相同
|
|
1664
|
+
* point: { x: number, y: number }
|
|
1665
|
+
* @param point1
|
|
1666
|
+
* @param point2
|
|
1667
|
+
* @return
|
|
1668
|
+
*/
|
|
1669
|
+
function samePointAt(point1, point2) {
|
|
1670
|
+
return point1.x === point2.x && point1.y === point2.y;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
function ndc2Screen(ndcPosition, containerSize) {
|
|
1674
|
+
const left = ((ndcPosition.x + 1) / 2) * containerSize.width;
|
|
1675
|
+
const top = (-(ndcPosition.y - 1) / 2) * containerSize.height;
|
|
1676
|
+
return new THREE.Vector2(left, top);
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
/**
|
|
1680
|
+
* @param tapPoint 注意这里的坐标是相对于 FiveElement 的
|
|
1681
|
+
*/
|
|
1682
|
+
// eslint-disable-next-line max-params
|
|
1683
|
+
function findClosestPoint(five, points, tapPoint, maxDistance) {
|
|
1684
|
+
const container = five.getElement();
|
|
1685
|
+
if (!container)
|
|
1686
|
+
return null;
|
|
1687
|
+
if (points.length === 0)
|
|
1688
|
+
return null;
|
|
1689
|
+
const containerSize = { width: container.clientWidth, height: container.clientHeight };
|
|
1690
|
+
const ndcPoints = points
|
|
1691
|
+
.map((point) => {
|
|
1692
|
+
const ndcPosition = point.position.clone().project(five.camera);
|
|
1693
|
+
if (!isNDCPointInScreen(ndcPosition))
|
|
1694
|
+
return { distance: Infinity, point };
|
|
1695
|
+
const screenPosition = ndc2Screen(ndcPosition, containerSize);
|
|
1696
|
+
const distance = screenPosition.distanceTo(tapPoint);
|
|
1697
|
+
return { distance, point };
|
|
1698
|
+
})
|
|
1699
|
+
.sort((a, b) => a.distance - b.distance);
|
|
1700
|
+
if (typeof maxDistance === 'number' && ndcPoints[0].distance > maxDistance)
|
|
1701
|
+
return null;
|
|
1702
|
+
return ndcPoints[0];
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
function findAssociatedLines(line) {
|
|
1706
|
+
// 找跟这个线段相邻的线
|
|
1707
|
+
const mergeNextLine = (point, nextIndex, target) => {
|
|
1708
|
+
const nextLine = point.lines.find((line) => {
|
|
1709
|
+
const pointIndex = line.points.findIndex(({ id }) => id === point.id);
|
|
1710
|
+
if (pointIndex === nextIndex)
|
|
1711
|
+
return false;
|
|
1712
|
+
return true;
|
|
1713
|
+
});
|
|
1714
|
+
if (!nextLine)
|
|
1715
|
+
return target;
|
|
1716
|
+
const nextPoint = nextLine.points[nextIndex];
|
|
1717
|
+
if (!nextPoint)
|
|
1718
|
+
return target;
|
|
1719
|
+
return mergeNextLine(nextPoint, nextIndex, target.concat(nextLine));
|
|
1720
|
+
};
|
|
1721
|
+
const rightLines = mergeNextLine(line.points[0], 1, []);
|
|
1722
|
+
const leftLines = mergeNextLine(line.points[0], 0, []);
|
|
1723
|
+
const lines = rightLines.concat(leftLines);
|
|
1724
|
+
return lines;
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
class WatchController extends BaseController {
|
|
1728
|
+
constructor(params) {
|
|
1729
|
+
super(params);
|
|
1730
|
+
Object.defineProperty(this, "type", {
|
|
1731
|
+
enumerable: true,
|
|
1732
|
+
configurable: true,
|
|
1733
|
+
writable: true,
|
|
1734
|
+
value: 'watch'
|
|
1735
|
+
});
|
|
1736
|
+
Object.defineProperty(this, "deleteDom", {
|
|
1737
|
+
enumerable: true,
|
|
1738
|
+
configurable: true,
|
|
1739
|
+
writable: true,
|
|
1740
|
+
value: void 0
|
|
1741
|
+
});
|
|
1742
|
+
Object.defineProperty(this, "highlightedLines", {
|
|
1743
|
+
enumerable: true,
|
|
1744
|
+
configurable: true,
|
|
1745
|
+
writable: true,
|
|
1746
|
+
value: []
|
|
1747
|
+
});
|
|
1748
|
+
Object.defineProperty(this, "fiveElement", {
|
|
1749
|
+
enumerable: true,
|
|
1750
|
+
configurable: true,
|
|
1751
|
+
writable: true,
|
|
1752
|
+
value: void 0
|
|
1753
|
+
});
|
|
1754
|
+
Object.defineProperty(this, "editPointState", {
|
|
1755
|
+
enumerable: true,
|
|
1756
|
+
configurable: true,
|
|
1757
|
+
writable: true,
|
|
1758
|
+
value: void 0
|
|
1759
|
+
});
|
|
1760
|
+
Object.defineProperty(this, "hammer", {
|
|
1761
|
+
enumerable: true,
|
|
1762
|
+
configurable: true,
|
|
1763
|
+
writable: true,
|
|
1764
|
+
value: void 0
|
|
1765
|
+
});
|
|
1766
|
+
Object.defineProperty(this, "onPanStart", {
|
|
1767
|
+
enumerable: true,
|
|
1768
|
+
configurable: true,
|
|
1769
|
+
writable: true,
|
|
1770
|
+
value: (e) => {
|
|
1771
|
+
var _a;
|
|
1772
|
+
if (this.model.points.length === 0 || !this.fiveElement)
|
|
1773
|
+
return;
|
|
1774
|
+
const mouse = getPointFromHammerEvent(e).point;
|
|
1775
|
+
const closestPoint = (_a = findClosestPoint(this.five, this.model.points, mouse, 20)) === null || _a === void 0 ? void 0 : _a.point;
|
|
1776
|
+
if (!closestPoint) {
|
|
1777
|
+
this.editPointState = undefined;
|
|
1778
|
+
return;
|
|
1779
|
+
}
|
|
1780
|
+
const editPointState = {
|
|
1781
|
+
point: closestPoint,
|
|
1782
|
+
associatedLines: findAssociatedLines(closestPoint.lines[0]),
|
|
1783
|
+
};
|
|
1784
|
+
const cancelDragLine = this.hook.emit('wantsDragLine', {
|
|
1785
|
+
point: closestPoint.id,
|
|
1786
|
+
lines: editPointState.associatedLines.map(({ id }) => id),
|
|
1787
|
+
});
|
|
1788
|
+
if (cancelDragLine)
|
|
1789
|
+
return;
|
|
1790
|
+
this.editPointState = editPointState;
|
|
1791
|
+
this.magnifier.appendTo(this.container);
|
|
1792
|
+
this.group.add(this.mouseGroup);
|
|
1793
|
+
}
|
|
1794
|
+
});
|
|
1795
|
+
Object.defineProperty(this, "onPanEnd", {
|
|
1796
|
+
enumerable: true,
|
|
1797
|
+
configurable: true,
|
|
1798
|
+
writable: true,
|
|
1799
|
+
value: () => {
|
|
1800
|
+
if (!this.editPointState)
|
|
1801
|
+
return;
|
|
1802
|
+
// 把拖动的线从虚线转换为实线
|
|
1803
|
+
this.editPointState.point.lines.forEach((line) => line.mesh.setMaterial({ dashed: false }));
|
|
1804
|
+
// 还原选中态
|
|
1805
|
+
this.highlightLines(this.editPointState.associatedLines);
|
|
1806
|
+
this.editPointState = undefined;
|
|
1807
|
+
this.magnifier.remove();
|
|
1808
|
+
this.group.remove(this.mouseGroup);
|
|
1809
|
+
}
|
|
1810
|
+
});
|
|
1811
|
+
Object.defineProperty(this, "onPan", {
|
|
1812
|
+
enumerable: true,
|
|
1813
|
+
configurable: true,
|
|
1814
|
+
writable: true,
|
|
1815
|
+
value: (e) => {
|
|
1816
|
+
if (!this.editPointState || !this.fiveElement)
|
|
1817
|
+
return;
|
|
1818
|
+
const mouse = getPointFromHammerEvent(e).ndcPoint;
|
|
1819
|
+
const raycaster = new THREE.Raycaster();
|
|
1820
|
+
raycaster.setFromCamera(mouse, this.five.camera);
|
|
1821
|
+
const [intersection] = this.five.model.intersectRaycaster(raycaster);
|
|
1822
|
+
if (!intersection)
|
|
1823
|
+
return;
|
|
1824
|
+
this.onIntersectionUpdate(intersection);
|
|
1825
|
+
}
|
|
1826
|
+
});
|
|
1827
|
+
Object.defineProperty(this, "onIntersectionUpdate", {
|
|
1828
|
+
enumerable: true,
|
|
1829
|
+
configurable: true,
|
|
1830
|
+
writable: true,
|
|
1831
|
+
value: (intersection, mesh) => {
|
|
1832
|
+
if (!this.editPointState)
|
|
1833
|
+
return;
|
|
1834
|
+
// 拖动过程中清除选中态
|
|
1835
|
+
this.clearHighlightLines();
|
|
1836
|
+
// 把拖动点相关的线变成虚线 & 改变相关线的位置
|
|
1837
|
+
this.editPointState.point.position.copy(intersection.point);
|
|
1838
|
+
this.editPointState.point.lines.forEach((line) => {
|
|
1839
|
+
line.mesh.setPoints(line.points[0].position.clone(), line.points[1].position.clone());
|
|
1840
|
+
line.lightMesh.setPoints(line.points[0].position.clone(), line.points[1].position.clone());
|
|
1841
|
+
line.mesh.setMaterial({ dashed: true });
|
|
1842
|
+
});
|
|
1843
|
+
this.updateDistanceUI();
|
|
1844
|
+
this.magnifier.renderWithPoint(intersection.point);
|
|
1845
|
+
this.mouseGroup.position.copy(intersection.point);
|
|
1846
|
+
if (mesh) {
|
|
1847
|
+
this.mouseGroup.quaternion.copy(mesh.quaternion);
|
|
1848
|
+
}
|
|
1849
|
+
else if (intersection.face) {
|
|
1850
|
+
const face = intersection.face.normal;
|
|
1851
|
+
const positionVector = face.clone().multiplyScalar(0.05);
|
|
1852
|
+
const position = intersection.point.clone().add(positionVector);
|
|
1853
|
+
const lookAtVector = position.clone().add(positionVector);
|
|
1854
|
+
this.mouseGroup.lookAt(lookAtVector);
|
|
1855
|
+
}
|
|
1856
|
+
this.five.needsRender = true;
|
|
1857
|
+
this.hook.emit('selectedChange', this.editPointState.associatedLines.map((line) => line.toCompletelyJson()));
|
|
1858
|
+
}
|
|
1859
|
+
});
|
|
1860
|
+
Object.defineProperty(this, "wantsPanGesture", {
|
|
1861
|
+
enumerable: true,
|
|
1862
|
+
configurable: true,
|
|
1863
|
+
writable: true,
|
|
1864
|
+
value: () => {
|
|
1865
|
+
if (this.editPointState)
|
|
1866
|
+
return false;
|
|
1867
|
+
}
|
|
1868
|
+
});
|
|
1869
|
+
Object.defineProperty(this, "wantsTapGesture", {
|
|
1870
|
+
enumerable: true,
|
|
1871
|
+
configurable: true,
|
|
1872
|
+
writable: true,
|
|
1873
|
+
value: (raycaster) => {
|
|
1874
|
+
const [target] = this.five.model.intersectRaycaster(raycaster);
|
|
1875
|
+
if (!target)
|
|
1876
|
+
return;
|
|
1877
|
+
const camera = this.five.camera;
|
|
1878
|
+
const ndcTarget = target.point.clone().project(camera);
|
|
1879
|
+
const screenWidth = this.container.clientWidth;
|
|
1880
|
+
const screenHeight = this.container.clientHeight;
|
|
1881
|
+
const targetScreenPosition = new THREE.Vector2(ndcTarget.x * screenWidth, ndcTarget.y * screenHeight);
|
|
1882
|
+
// 把线的端点全部映射到屏幕上,过滤掉不在视野内的线,同时乘以屏幕宽 & 高
|
|
1883
|
+
const screenLines = this.model.lines
|
|
1884
|
+
.map((line) => {
|
|
1885
|
+
const [startPoint, endPoint] = line.points;
|
|
1886
|
+
const ndcStartPoint = startPoint.position.clone().project(camera);
|
|
1887
|
+
const ndcEndPoint = endPoint.position.clone().project(camera);
|
|
1888
|
+
if (!isNDCPointInScreen(ndcStartPoint) && !isNDCPointInScreen(ndcEndPoint))
|
|
1889
|
+
return null;
|
|
1890
|
+
const startScreenPosition = new THREE.Vector2(ndcStartPoint.x * screenWidth, ndcStartPoint.y * screenHeight);
|
|
1891
|
+
const endScreenPosition = new THREE.Vector2(ndcEndPoint.x * screenWidth, ndcEndPoint.y * screenHeight);
|
|
1892
|
+
return { id: line.id, points: [startScreenPosition, endScreenPosition] };
|
|
1893
|
+
})
|
|
1894
|
+
.filter((line) => !!line);
|
|
1895
|
+
if (screenLines.length === 0)
|
|
1896
|
+
return;
|
|
1897
|
+
// 找这些线距离鼠标点击位置最近的线
|
|
1898
|
+
const distanceLines = screenLines
|
|
1899
|
+
.map((line) => {
|
|
1900
|
+
const closestPoint = closestPointOnLine(targetScreenPosition, line.points);
|
|
1901
|
+
return { id: line.id, distance: closestPoint.distanceTo(targetScreenPosition) };
|
|
1902
|
+
})
|
|
1903
|
+
.sort((a, b) => a.distance - b.distance);
|
|
1904
|
+
const closestScreenLine = distanceLines[0];
|
|
1905
|
+
if (closestScreenLine.distance > 20)
|
|
1906
|
+
return;
|
|
1907
|
+
const closestLine = this.model.lines.find(({ id }) => id === closestScreenLine.id);
|
|
1908
|
+
if (!closestLine)
|
|
1909
|
+
return;
|
|
1910
|
+
this.chooseLine(closestLine);
|
|
1911
|
+
return false;
|
|
1912
|
+
}
|
|
1913
|
+
});
|
|
1914
|
+
Object.defineProperty(this, "chooseLine", {
|
|
1915
|
+
enumerable: true,
|
|
1916
|
+
configurable: true,
|
|
1917
|
+
writable: true,
|
|
1918
|
+
value: (line) => {
|
|
1919
|
+
const highlightLines = findAssociatedLines(line);
|
|
1920
|
+
this.highlightLines(highlightLines);
|
|
1921
|
+
this.five.needsRender = true;
|
|
1922
|
+
this.hook.emit('selectedChange', highlightLines.map((line) => line.toCompletelyJson()));
|
|
1923
|
+
}
|
|
1924
|
+
});
|
|
1925
|
+
Object.defineProperty(this, "lineRemoved", {
|
|
1926
|
+
enumerable: true,
|
|
1927
|
+
configurable: true,
|
|
1928
|
+
writable: true,
|
|
1929
|
+
value: (line) => {
|
|
1930
|
+
this.removeLine(line);
|
|
1931
|
+
// TODO: 这个逻辑不太好,改进一下
|
|
1932
|
+
this.hook.emit('selectedChange', this.model.lines.filter((line) => line.selected).map((line) => line.toCompletelyJson()));
|
|
1933
|
+
}
|
|
1934
|
+
});
|
|
1935
|
+
Object.defineProperty(this, "onCameraUpdate", {
|
|
1936
|
+
enumerable: true,
|
|
1937
|
+
configurable: true,
|
|
1938
|
+
writable: true,
|
|
1939
|
+
value: () => {
|
|
1940
|
+
this.updateDistanceUI();
|
|
1941
|
+
this.highlightedLines.length > 0 && this.deleteDom.updatePosition();
|
|
1942
|
+
}
|
|
1943
|
+
});
|
|
1944
|
+
Object.defineProperty(this, "deleteDomClickCallback", {
|
|
1945
|
+
enumerable: true,
|
|
1946
|
+
configurable: true,
|
|
1947
|
+
writable: true,
|
|
1948
|
+
value: () => {
|
|
1949
|
+
const firstLine = this.highlightedLines[0];
|
|
1950
|
+
// TODO: 优化折线的删除逻辑
|
|
1951
|
+
firstLine
|
|
1952
|
+
.getPolyline()
|
|
1953
|
+
.lines.slice()
|
|
1954
|
+
.reverse()
|
|
1955
|
+
.forEach((line) => this.model.removeLine(line));
|
|
1956
|
+
this.highlightedLines = [];
|
|
1957
|
+
// this.clearHighlightLines()
|
|
1958
|
+
// this.highlightedLines.forEach((line) => this.model.removeLine(line))
|
|
1959
|
+
this.deleteDom.setLines([]).hide();
|
|
1960
|
+
}
|
|
1961
|
+
});
|
|
1962
|
+
Object.defineProperty(this, "cancelDeleteClickCallback", {
|
|
1963
|
+
enumerable: true,
|
|
1964
|
+
configurable: true,
|
|
1965
|
+
writable: true,
|
|
1966
|
+
value: () => {
|
|
1967
|
+
this.clearHighlightLines();
|
|
1968
|
+
}
|
|
1969
|
+
});
|
|
1970
|
+
this.deleteDom = new DeleteDom(this.five, {
|
|
1971
|
+
onClick: this.deleteDomClickCallback,
|
|
1972
|
+
cancelDelete: this.cancelDeleteClickCallback,
|
|
1973
|
+
}).appendTo(this.container);
|
|
1974
|
+
this.model.lines.forEach((line) => {
|
|
1975
|
+
line.distanceItem.appendTo(this.container);
|
|
1976
|
+
line.distanceItem.update(this.five);
|
|
1977
|
+
line.hook.on('selected', this.chooseLine);
|
|
1978
|
+
this.group.add(line.mesh);
|
|
1979
|
+
});
|
|
1980
|
+
const fiveElement = this.five.getElement();
|
|
1981
|
+
if (fiveElement) {
|
|
1982
|
+
this.fiveElement = fiveElement;
|
|
1983
|
+
const hammer = new Hammer__default["default"](fiveElement);
|
|
1984
|
+
this.hammer = hammer;
|
|
1985
|
+
hammer.on('pan', this.onPan);
|
|
1986
|
+
hammer.on('panstart', this.onPanStart);
|
|
1987
|
+
hammer.on('panend', this.onPanEnd);
|
|
1988
|
+
}
|
|
1989
|
+
this.model.hook.on('lineRemoved', this.lineRemoved);
|
|
1990
|
+
this.five.on('cameraUpdate', this.onCameraUpdate);
|
|
1991
|
+
this.five.on('wantsTapGesture', this.wantsTapGesture);
|
|
1992
|
+
this.five.on('wantsPanGesture', this.wantsPanGesture);
|
|
1993
|
+
this.five.needsRender = true;
|
|
1994
|
+
}
|
|
1995
|
+
dispose() {
|
|
1996
|
+
var _a;
|
|
1997
|
+
super.dispose();
|
|
1998
|
+
this.deleteDom.dispose();
|
|
1999
|
+
this.model.hook.off('lineRemoved', this.lineRemoved);
|
|
2000
|
+
this.five.off('cameraUpdate', this.onCameraUpdate);
|
|
2001
|
+
this.five.off('wantsPanGesture', this.wantsPanGesture);
|
|
2002
|
+
this.five.off('wantsTapGesture', this.wantsTapGesture);
|
|
2003
|
+
this.five.needsRender = true;
|
|
2004
|
+
this.hook.emit('selectedChange', []);
|
|
2005
|
+
(_a = this.hammer) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
2006
|
+
}
|
|
2007
|
+
highlightLine(line) {
|
|
2008
|
+
if (line.selected)
|
|
2009
|
+
return;
|
|
2010
|
+
line.selected = true;
|
|
2011
|
+
this.group.add(line.lightMesh);
|
|
2012
|
+
line.distanceItem.highlight();
|
|
2013
|
+
this.five.needsRender = true;
|
|
2014
|
+
}
|
|
2015
|
+
clearHighlightLines() {
|
|
2016
|
+
if (this.group.children.length === 0)
|
|
2017
|
+
return;
|
|
2018
|
+
this.deleteDom.setLines([]).hide();
|
|
2019
|
+
this.model.lines.forEach((line) => {
|
|
2020
|
+
line.selected = false;
|
|
2021
|
+
line.distanceItem.unHighlight();
|
|
2022
|
+
this.group.remove(line.lightMesh);
|
|
2023
|
+
});
|
|
2024
|
+
this.highlightedLines = [];
|
|
2025
|
+
this.five.needsRender = true;
|
|
2026
|
+
}
|
|
2027
|
+
highlightLines(lines) {
|
|
2028
|
+
this.clearHighlightLines();
|
|
2029
|
+
this.highlightedLines = lines;
|
|
2030
|
+
this.deleteDom.setLines(lines).updatePosition().show();
|
|
2031
|
+
lines.forEach((line) => this.highlightLine(line));
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
class MixedController extends BaseController {
|
|
2036
|
+
constructor(params) {
|
|
2037
|
+
super(params);
|
|
2038
|
+
Object.defineProperty(this, "state", {
|
|
2039
|
+
enumerable: true,
|
|
2040
|
+
configurable: true,
|
|
2041
|
+
writable: true,
|
|
2042
|
+
value: 'watching'
|
|
2043
|
+
});
|
|
2044
|
+
Object.defineProperty(this, "model", {
|
|
2045
|
+
enumerable: true,
|
|
2046
|
+
configurable: true,
|
|
2047
|
+
writable: true,
|
|
2048
|
+
value: new Model({ userDistanceItemCreator: this.userDistanceItemCreator })
|
|
2049
|
+
});
|
|
2050
|
+
Object.defineProperty(this, "hasAppendDashed", {
|
|
2051
|
+
enumerable: true,
|
|
2052
|
+
configurable: true,
|
|
2053
|
+
writable: true,
|
|
2054
|
+
value: false
|
|
2055
|
+
});
|
|
2056
|
+
Object.defineProperty(this, "fiveElement", {
|
|
2057
|
+
enumerable: true,
|
|
2058
|
+
configurable: true,
|
|
2059
|
+
writable: true,
|
|
2060
|
+
value: void 0
|
|
2061
|
+
});
|
|
2062
|
+
Object.defineProperty(this, "mobileStartPoint", {
|
|
2063
|
+
enumerable: true,
|
|
2064
|
+
configurable: true,
|
|
2065
|
+
writable: true,
|
|
2066
|
+
value: null
|
|
2067
|
+
});
|
|
2068
|
+
Object.defineProperty(this, "mobileNowPoint", {
|
|
2069
|
+
enumerable: true,
|
|
2070
|
+
configurable: true,
|
|
2071
|
+
writable: true,
|
|
2072
|
+
value: null
|
|
2073
|
+
});
|
|
2074
|
+
Object.defineProperty(this, "highlightedLines", {
|
|
2075
|
+
enumerable: true,
|
|
2076
|
+
configurable: true,
|
|
2077
|
+
writable: true,
|
|
2078
|
+
value: []
|
|
2079
|
+
});
|
|
2080
|
+
Object.defineProperty(this, "deleteDom", {
|
|
2081
|
+
enumerable: true,
|
|
2082
|
+
configurable: true,
|
|
2083
|
+
writable: true,
|
|
2084
|
+
value: void 0
|
|
2085
|
+
});
|
|
2086
|
+
/** 圆环点到上一个端点连接的虚线 */
|
|
2087
|
+
Object.defineProperty(this, "dashed", {
|
|
2088
|
+
enumerable: true,
|
|
2089
|
+
configurable: true,
|
|
2090
|
+
writable: true,
|
|
2091
|
+
value: void 0
|
|
2092
|
+
});
|
|
2093
|
+
/** 编辑线条发生改变时通知外部 */
|
|
2094
|
+
Object.defineProperty(this, "onLineChanged", {
|
|
2095
|
+
enumerable: true,
|
|
2096
|
+
configurable: true,
|
|
2097
|
+
writable: true,
|
|
2098
|
+
value: () => {
|
|
2099
|
+
this.hook.emit('editedLineChange', this.model.lines.map((line) => line.toCompletelyJson()));
|
|
2100
|
+
}
|
|
2101
|
+
});
|
|
2102
|
+
Object.defineProperty(this, "onWantsTapGesture", {
|
|
2103
|
+
enumerable: true,
|
|
2104
|
+
configurable: true,
|
|
2105
|
+
writable: true,
|
|
2106
|
+
value: (raycaster) => {
|
|
2107
|
+
if (this.state === 'editing')
|
|
2108
|
+
return false;
|
|
2109
|
+
const [target] = this.five.model.intersectRaycaster(raycaster);
|
|
2110
|
+
if (!target)
|
|
2111
|
+
return;
|
|
2112
|
+
const camera = this.five.camera;
|
|
2113
|
+
const ndcTarget = target.point.clone().project(camera);
|
|
2114
|
+
const screenWidth = this.container.clientWidth;
|
|
2115
|
+
const screenHeight = this.container.clientHeight;
|
|
2116
|
+
const targetScreenPosition = new THREE.Vector2(ndcTarget.x * screenWidth, ndcTarget.y * screenHeight);
|
|
2117
|
+
// 把线的端点全部映射到屏幕上,过滤掉不在视野内的线,同时乘以屏幕宽 & 高
|
|
2118
|
+
const screenLines = this.model.lines
|
|
2119
|
+
.map((line) => {
|
|
2120
|
+
const [startPoint, endPoint] = line.points;
|
|
2121
|
+
const ndcStartPoint = startPoint.position.clone().project(camera);
|
|
2122
|
+
const ndcEndPoint = endPoint.position.clone().project(camera);
|
|
2123
|
+
if (!isNDCPointInScreen(ndcStartPoint) && !isNDCPointInScreen(ndcEndPoint))
|
|
2124
|
+
return null;
|
|
2125
|
+
const startScreenPosition = new THREE.Vector2(ndcStartPoint.x * screenWidth, ndcStartPoint.y * screenHeight);
|
|
2126
|
+
const endScreenPosition = new THREE.Vector2(ndcEndPoint.x * screenWidth, ndcEndPoint.y * screenHeight);
|
|
2127
|
+
return { id: line.id, points: [startScreenPosition, endScreenPosition] };
|
|
2128
|
+
})
|
|
2129
|
+
.filter((line) => !!line);
|
|
2130
|
+
if (screenLines.length === 0)
|
|
2131
|
+
return;
|
|
2132
|
+
// 找这些线距离鼠标点击位置最近的线
|
|
2133
|
+
const distanceLines = screenLines
|
|
2134
|
+
.map((line) => {
|
|
2135
|
+
const closestPoint = closestPointOnLine(targetScreenPosition, line.points);
|
|
2136
|
+
return { id: line.id, distance: closestPoint.distanceTo(targetScreenPosition) };
|
|
2137
|
+
})
|
|
2138
|
+
.sort((a, b) => a.distance - b.distance);
|
|
2139
|
+
const closestScreenLine = distanceLines[0];
|
|
2140
|
+
if (closestScreenLine.distance > 20)
|
|
2141
|
+
return;
|
|
2142
|
+
const closestLine = this.model.lines.find(({ id }) => id === closestScreenLine.id);
|
|
2143
|
+
if (!closestLine)
|
|
2144
|
+
return;
|
|
2145
|
+
this.chooseLine(closestLine);
|
|
2146
|
+
return false;
|
|
2147
|
+
}
|
|
2148
|
+
});
|
|
2149
|
+
/** 编辑时取消走点,watch时可以走 */
|
|
2150
|
+
Object.defineProperty(this, "onWantsToMoveToPano", {
|
|
2151
|
+
enumerable: true,
|
|
2152
|
+
configurable: true,
|
|
2153
|
+
writable: true,
|
|
2154
|
+
value: () => this.state === 'watching'
|
|
2155
|
+
});
|
|
2156
|
+
/** 移动全景时更新 distanceItem 在屏幕上的位置 */
|
|
2157
|
+
Object.defineProperty(this, "onCameraUpdate", {
|
|
2158
|
+
enumerable: true,
|
|
2159
|
+
configurable: true,
|
|
2160
|
+
writable: true,
|
|
2161
|
+
value: () => {
|
|
2162
|
+
this.updateDistanceUI();
|
|
2163
|
+
this.dashed.distanceItem.update(this.five);
|
|
2164
|
+
}
|
|
2165
|
+
});
|
|
2166
|
+
/** mobile态时更新虚线 */
|
|
2167
|
+
Object.defineProperty(this, "updateMobileDashed", {
|
|
2168
|
+
enumerable: true,
|
|
2169
|
+
configurable: true,
|
|
2170
|
+
writable: true,
|
|
2171
|
+
value: () => {
|
|
2172
|
+
if (!this.mobileStartPoint || !this.mobileNowPoint)
|
|
2173
|
+
return;
|
|
2174
|
+
this.dashed.points[0].position.copy(this.mobileStartPoint.position);
|
|
2175
|
+
this.dashed.points[1].position.copy(this.mobileNowPoint.position);
|
|
2176
|
+
this.dashed.mesh.setPoints(this.mobileStartPoint.position, this.mobileNowPoint.position);
|
|
2177
|
+
this.dashed.distanceItem.update(this.five);
|
|
2178
|
+
}
|
|
2179
|
+
});
|
|
2180
|
+
/** mobile态时更新放大镜 */
|
|
2181
|
+
Object.defineProperty(this, "updateMagnifier", {
|
|
2182
|
+
enumerable: true,
|
|
2183
|
+
configurable: true,
|
|
2184
|
+
writable: true,
|
|
2185
|
+
value: (point) => {
|
|
2186
|
+
if (this.magnifier.visible === false) {
|
|
2187
|
+
this.magnifier.appendTo(this.container);
|
|
2188
|
+
}
|
|
2189
|
+
requestAnimationFrame(() => this.magnifier.renderWithPoint(point.position));
|
|
2190
|
+
this.five.needsRender = true;
|
|
2191
|
+
}
|
|
2192
|
+
});
|
|
2193
|
+
Object.defineProperty(this, "onGetStartPoint", {
|
|
2194
|
+
enumerable: true,
|
|
2195
|
+
configurable: true,
|
|
2196
|
+
writable: true,
|
|
2197
|
+
value: (point) => {
|
|
2198
|
+
this.mobileStartPoint = point;
|
|
2199
|
+
}
|
|
2200
|
+
});
|
|
2201
|
+
Object.defineProperty(this, "onGetEndPoint", {
|
|
2202
|
+
enumerable: true,
|
|
2203
|
+
configurable: true,
|
|
2204
|
+
writable: true,
|
|
2205
|
+
value: (point) => {
|
|
2206
|
+
const endPoint = this.mobileNowPoint;
|
|
2207
|
+
this.removeLine(this.dashed);
|
|
2208
|
+
this.hasAppendDashed = false;
|
|
2209
|
+
if (this.mobileStartPoint && endPoint) {
|
|
2210
|
+
const line = new Line(this.mobileStartPoint, endPoint, this.model);
|
|
2211
|
+
line.distanceItem.appendTo(this.container);
|
|
2212
|
+
line.distanceItem.update(this.five);
|
|
2213
|
+
line.hook.on('selected', this.chooseLine);
|
|
2214
|
+
this.group.add(line.mesh);
|
|
2215
|
+
this.model.addLine(line);
|
|
2216
|
+
}
|
|
2217
|
+
this.mobileStartPoint = null;
|
|
2218
|
+
this.mobileNowPoint = null;
|
|
2219
|
+
this.five.needsRender = true;
|
|
2220
|
+
}
|
|
2221
|
+
});
|
|
2222
|
+
Object.defineProperty(this, "onNowPointChange", {
|
|
2223
|
+
enumerable: true,
|
|
2224
|
+
configurable: true,
|
|
2225
|
+
writable: true,
|
|
2226
|
+
value: (point) => {
|
|
2227
|
+
if (this.state === 'watching') {
|
|
2228
|
+
this.mobileNowPoint = point;
|
|
2229
|
+
this.updateMagnifier(point);
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2232
|
+
if (!this.hasAppendDashed) {
|
|
2233
|
+
this.dashed.distanceItem.appendTo(this.container);
|
|
2234
|
+
this.group.add(this.dashed.mesh);
|
|
2235
|
+
this.hasAppendDashed = true;
|
|
2236
|
+
}
|
|
2237
|
+
this.five.needsRender = true;
|
|
2238
|
+
this.mobileNowPoint = point;
|
|
2239
|
+
this.updateMobileDashed();
|
|
2240
|
+
this.updateMagnifier(point);
|
|
2241
|
+
this.five.needsRender = true;
|
|
2242
|
+
}
|
|
2243
|
+
});
|
|
2244
|
+
Object.defineProperty(this, "onWillChangeState", {
|
|
2245
|
+
enumerable: true,
|
|
2246
|
+
configurable: true,
|
|
2247
|
+
writable: true,
|
|
2248
|
+
value: (state, newState) => {
|
|
2249
|
+
this.state = newState;
|
|
2250
|
+
if (this.state === 'watching') {
|
|
2251
|
+
this.five.helperVisible = true;
|
|
2252
|
+
}
|
|
2253
|
+
else {
|
|
2254
|
+
// 隐藏点位和鼠标聚焦环
|
|
2255
|
+
this.five.helperVisible = false;
|
|
2256
|
+
}
|
|
2257
|
+
}
|
|
2258
|
+
});
|
|
2259
|
+
Object.defineProperty(this, "chooseLine", {
|
|
2260
|
+
enumerable: true,
|
|
2261
|
+
configurable: true,
|
|
2262
|
+
writable: true,
|
|
2263
|
+
value: (line) => {
|
|
2264
|
+
const highlightLines = findAssociatedLines(line);
|
|
2265
|
+
this.highlightLines(highlightLines);
|
|
2266
|
+
this.five.needsRender = true;
|
|
2267
|
+
this.hook.emit('selectedChange', highlightLines.map((line) => line.toCompletelyJson()));
|
|
2268
|
+
}
|
|
2269
|
+
});
|
|
2270
|
+
Object.defineProperty(this, "deleteDomClickCallback", {
|
|
2271
|
+
enumerable: true,
|
|
2272
|
+
configurable: true,
|
|
2273
|
+
writable: true,
|
|
2274
|
+
value: () => {
|
|
2275
|
+
this.highlightedLines.forEach((line) => {
|
|
2276
|
+
this.removeLine(line);
|
|
2277
|
+
this.model.removeLine(line);
|
|
2278
|
+
});
|
|
2279
|
+
this.highlightedLines = [];
|
|
2280
|
+
this.deleteDom.setLines([]).hide();
|
|
2281
|
+
}
|
|
2282
|
+
});
|
|
2283
|
+
Object.defineProperty(this, "cancelDeleteClickCallback", {
|
|
2284
|
+
enumerable: true,
|
|
2285
|
+
configurable: true,
|
|
2286
|
+
writable: true,
|
|
2287
|
+
value: () => {
|
|
2288
|
+
this.clearHighlightLines();
|
|
2289
|
+
}
|
|
2290
|
+
});
|
|
2291
|
+
this.deleteDom = new DeleteDom(this.five, {
|
|
2292
|
+
onClick: this.deleteDomClickCallback,
|
|
2293
|
+
cancelDelete: this.cancelDeleteClickCallback,
|
|
2294
|
+
}).appendTo(this.container);
|
|
2295
|
+
// ==================== 虚线 ====================
|
|
2296
|
+
this.dashed = new Line(new Point([0, 0, 0]), new Point([0, 0, 0]), this.model);
|
|
2297
|
+
this.dashed.mesh.setMaterial({ dashed: true, dashScale: 100 });
|
|
2298
|
+
this.dashed.mesh.name = 'dashLine';
|
|
2299
|
+
// ==================== 事件监听 ====================
|
|
2300
|
+
// five
|
|
2301
|
+
this.five.on('cameraUpdate', this.onCameraUpdate);
|
|
2302
|
+
this.five.on('wantsTapGesture', this.onWantsTapGesture);
|
|
2303
|
+
this.five.on('wantsToMoveToPano', this.onWantsToMoveToPano);
|
|
2304
|
+
// model
|
|
2305
|
+
this.model.hook.on('lineAdded', this.onLineChanged);
|
|
2306
|
+
this.model.hook.on('lineRemoved', this.onLineChanged);
|
|
2307
|
+
// ==================== 其他 ====================
|
|
2308
|
+
this.hook.on('getStartPoint', this.onGetStartPoint);
|
|
2309
|
+
this.hook.on('getEndPoint', this.onGetEndPoint);
|
|
2310
|
+
this.hook.on('nowPointChange', this.onNowPointChange);
|
|
2311
|
+
this.hook.on('willChangeState', this.onWillChangeState);
|
|
2312
|
+
this.five.refresh();
|
|
2313
|
+
}
|
|
2314
|
+
dispose() {
|
|
2315
|
+
super.dispose();
|
|
2316
|
+
this.group.remove(this.mouseGroup, this.dashed.mesh);
|
|
2317
|
+
// ==================== 解除事件监听 ====================
|
|
2318
|
+
// five
|
|
2319
|
+
this.five.off('cameraUpdate', this.onCameraUpdate);
|
|
2320
|
+
this.five.off('wantsTapGesture', this.onWantsTapGesture);
|
|
2321
|
+
this.five.off('wantsToMoveToPano', this.onWantsToMoveToPano);
|
|
2322
|
+
// model
|
|
2323
|
+
this.model.hook.off('lineAdded', this.onLineChanged);
|
|
2324
|
+
this.model.hook.off('lineRemoved', this.onLineChanged);
|
|
2325
|
+
this.hook.off('getStartPoint', this.onGetStartPoint);
|
|
2326
|
+
this.hook.off('getEndPoint', this.onGetEndPoint);
|
|
2327
|
+
this.hook.off('nowPointChange', this.onNowPointChange);
|
|
2328
|
+
this.hook.off('willChangeState', this.onWillChangeState);
|
|
2329
|
+
this.hook.emit('selectedChange', []);
|
|
2330
|
+
this.dashed.distanceItem.remove();
|
|
2331
|
+
this.five.needsRender = true;
|
|
2332
|
+
}
|
|
2333
|
+
highlightLine(line) {
|
|
2334
|
+
if (line.selected)
|
|
2335
|
+
return;
|
|
2336
|
+
line.selected = true;
|
|
2337
|
+
this.group.add(line.lightMesh);
|
|
2338
|
+
line.distanceItem.highlight();
|
|
2339
|
+
this.five.needsRender = true;
|
|
2340
|
+
}
|
|
2341
|
+
clearHighlightLines() {
|
|
2342
|
+
if (this.group.children.length === 0)
|
|
2343
|
+
return;
|
|
2344
|
+
this.deleteDom.setLines([]).hide();
|
|
2345
|
+
this.model.lines.forEach((line) => {
|
|
2346
|
+
line.selected = false;
|
|
2347
|
+
line.distanceItem.unHighlight();
|
|
2348
|
+
this.group.remove(line.lightMesh);
|
|
2349
|
+
});
|
|
2350
|
+
this.highlightedLines = [];
|
|
2351
|
+
this.five.needsRender = true;
|
|
2352
|
+
}
|
|
2353
|
+
getEditingLines() {
|
|
2354
|
+
return this.model.lines;
|
|
2355
|
+
}
|
|
2356
|
+
highlightLines(lines) {
|
|
2357
|
+
this.clearHighlightLines();
|
|
2358
|
+
this.highlightedLines = lines;
|
|
2359
|
+
this.deleteDom.setLines(lines).updatePosition().show();
|
|
2360
|
+
lines.forEach((line) => this.highlightLine(line));
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
const planTextureUrl = `data:image/png;base64,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`;
|
|
2365
|
+
function getMouseGroup() {
|
|
2366
|
+
const group = new THREE.Group();
|
|
2367
|
+
const planGeometry = new THREE.PlaneGeometry(0.3, 0.3);
|
|
2368
|
+
const planTexture = new THREE.TextureLoader().load(planTextureUrl);
|
|
2369
|
+
planTexture.encoding = THREE.sRGBEncoding;
|
|
2370
|
+
const planMaterial = new THREE.MeshBasicMaterial({ map: planTexture, transparent: true, depthTest: false });
|
|
2371
|
+
const planMesh = new THREE.Mesh(planGeometry, planMaterial);
|
|
2372
|
+
const zPath = new THREE.CurvePath();
|
|
2373
|
+
zPath.add(new THREE.LineCurve3(new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, 0.1)));
|
|
2374
|
+
const zGeometry = new THREE.TubeGeometry(zPath, 8, 0.004);
|
|
2375
|
+
const zMaterial = new THREE.MeshBasicMaterial({ color: 0x33f1ef, depthTest: false, transparent: true, side: THREE.DoubleSide });
|
|
2376
|
+
new THREE.Mesh(zGeometry, zMaterial);
|
|
2377
|
+
const ballGeometry = new THREE.SphereGeometry(0.01, 20, 20);
|
|
2378
|
+
const ballMesh = new THREE.Mesh(ballGeometry, zMaterial);
|
|
2379
|
+
ballMesh.position.set(0, 0, 0.1);
|
|
2380
|
+
group.name = 'mouse-current';
|
|
2381
|
+
group.add(planMesh);
|
|
2382
|
+
return group;
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2385
|
+
const MAIN_NORMAL_PATH = 'M31.379 15.466a1.045 1.045 0 0 1-.92 1.076l-11.276.607a1.6 1.6 0 0 0-1.512 1.511l-.599 11.113a1.045 1.045 0 0 1-.92 1.075l-.164.008a1.183 1.183 0 0 1-1.123-.975l-.016-.164-.221-10.768a1.6 1.6 0 0 0-1.567-1.567l-11.3-.231-.165-.016a1.187 1.187 0 0 1-.964-.996l-.01-.127.007-.164c.061-.496.455-.876.958-.917l.118-.003 11.112-.599a1.6 1.6 0 0 0 1.498-1.37l.014-.142.607-11.276a1.045 1.045 0 0 1 1.076-.92c.573.015 1.055.46 1.13 1.019l.009.121.221 10.766a1.6 1.6 0 0 0 1.567 1.566l11.3.234a1.181 1.181 0 0 1 1.14 1.139z';
|
|
2386
|
+
const MAIN_DONE_PATH = 'M27.1772552,8.15828895 C27.8664561,7.48070421 28.5574369,7.81156875 28.8336646,8.04968716 C29.1098924,8.28780557 29.3990219,9.110014 28.8256559,9.79263351 L28.7110903,9.9165024 L13.9697229,25.1399531 C13.3288458,25.7700285 12.3239388,25.8070917 11.6402346,25.2511429 L11.5159715,25.1399531 L3.7056151,18.0063788 C3.01641417,17.3287941 3.00699739,16.2207954 3.68458213,15.5315945 C4.32230894,14.8829348 5.3413021,14.8364368 6.03356826,15.3981178 L6.15936649,15.5105615 L12.6856594,21.9049888 L27.1772552,8.15828895 Z';
|
|
2387
|
+
const MAIN_MOUSE_ENTER_FILL = 'url(#fpm__main-b)';
|
|
2388
|
+
const MAIN_MOUSE_LEAVE_FILL = 'url(#fpm__main-c)';
|
|
2389
|
+
const revokeSvg = `
|
|
2390
|
+
<svg class="fpm__revoke-icon" width="40" height="40" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
|
|
2391
|
+
<defs>
|
|
2392
|
+
<linearGradient x1="47.631%" y1="55.183%" x2="2.967%" y2="86.323%" id="fpm__revoke-a">
|
|
2393
|
+
<stop stop-color="#FFF" offset="0%" />
|
|
2394
|
+
<stop stop-color="#FFF" stop-opacity=".5" offset="100%" />
|
|
2395
|
+
</linearGradient>
|
|
2396
|
+
<linearGradient x1="5.297%" y1="43.016%" x2="38.238%" y2="79.932%" id="fpm__revoke-b">
|
|
2397
|
+
<stop stop-color="#FFF" offset="0%" />
|
|
2398
|
+
<stop stop-color="#FFF" stop-opacity="0" offset="100%" />
|
|
2399
|
+
</linearGradient>
|
|
2400
|
+
</defs>
|
|
2401
|
+
<path
|
|
2402
|
+
d="M13.388 7.108c.552 0 1.005.42 1.06.957l.006.11v1.224c0 .921.745 1.667 1.666 1.667h7.184c5.804 0 10.509 4.616 10.509 10.309 0 5.595-4.544 10.15-10.21 10.305l-.3.004H8.924c-.917 0-1.66-.729-1.66-1.628 0-.846.658-1.541 1.5-1.62l.16-.008h14.38c3.972 0 7.191-3.158 7.191-7.053 0-3.81-3.08-6.916-6.933-7.049l-.257-.004H10.029l-.109-.005H8.212c-.245 0-.482-.085-.67-.237l-.09-.082a1.066 1.066 0 0 1-.065-1.422l.079-.086 5.175-5.077c.2-.195.468-.305.747-.305z"
|
|
2403
|
+
fill="url(#fpm__revoke-a)"
|
|
2404
|
+
fill-rule="nonzero"
|
|
2405
|
+
stroke="url(#fpm__revoke-b)"
|
|
2406
|
+
stroke-width=".5"
|
|
2407
|
+
/>
|
|
2408
|
+
</svg>
|
|
2409
|
+
`;
|
|
2410
|
+
const exitSvg = `
|
|
2411
|
+
<svg class="fpm__exit-icon width="40" height="40" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
|
|
2412
|
+
<defs>
|
|
2413
|
+
<linearGradient x1="36.288%" y1="73.736%" x2="54.242%" y2="97.166%" id="fpm__exit-a">
|
|
2414
|
+
<stop stop-color="#FFF" offset="0%" />
|
|
2415
|
+
<stop stop-color="#FFF" stop-opacity=".5" offset="100%" />
|
|
2416
|
+
</linearGradient>
|
|
2417
|
+
<linearGradient x1="100%" y1="47.234%" x2="24.047%" y2="47.234%" id="fpm__exit-b">
|
|
2418
|
+
<stop stop-color="#FFF" offset="0%" />
|
|
2419
|
+
<stop stop-color="#FFF" stop-opacity=".005" offset="99.535%" />
|
|
2420
|
+
<stop stop-color="#FFF" stop-opacity="0" offset="100%" />
|
|
2421
|
+
</linearGradient>
|
|
2422
|
+
</defs>
|
|
2423
|
+
<path
|
|
2424
|
+
d="M22 7a1.5 1.5 0 0 1 .144 2.993L22 10h-9a1.5 1.5 0 0 0-1.493 1.356l-.007.144v17a1.5 1.5 0 0 0 1.356 1.493L13 30h9a1.5 1.5 0 0 1 .144 2.993L22 33h-9a4.5 4.5 0 0 1-4.495-4.288L8.5 28.5v-17a4.5 4.5 0 0 1 4.288-4.495L13 7h9zm6.317 7.755a1 1 0 0 1 .7.286l4.856 4.764a1 1 0 0 1-.7 1.713h-5.856V21.5h-8.032a1.5 1.5 0 1 1 0-3h6.365c.92 0 1.666-.746 1.667-1.667v-1.078a1 1 0 0 1 1-1z"
|
|
2425
|
+
fill="url(#fpm__exit-a)"
|
|
2426
|
+
fill-rule="nonzero"
|
|
2427
|
+
stroke="url(#fpm__exit-b)"
|
|
2428
|
+
stroke-width=".5"
|
|
2429
|
+
/>
|
|
2430
|
+
</svg>
|
|
2431
|
+
`;
|
|
2432
|
+
const mainSvg = `
|
|
2433
|
+
<svg class="fpm__main-icon" width="60" height="60" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg">
|
|
2434
|
+
<defs>
|
|
2435
|
+
<mask id="fpm__main-icon-mask">
|
|
2436
|
+
<rect id="fpm__main-icon-mask-black" x="0" y="0" width="30" height="30" fill="black"></rect>
|
|
2437
|
+
<rect id="fpm__main-icon-mask-white" x="0" y="0" width="0" height="30" fill="white"></rect>
|
|
2438
|
+
</mask>
|
|
2439
|
+
<linearGradient id="fpm__main-a" x1="25.371%" y1="0%" x2="109.587%" y2="172.268%">
|
|
2440
|
+
<stop stop-color="#FFF" offset="0%" />
|
|
2441
|
+
<stop stop-color="#FFF" stop-opacity=".77" offset="44.051%" />
|
|
2442
|
+
<stop stop-color="#FFF" stop-opacity=".201" offset="100%" />
|
|
2443
|
+
</linearGradient>
|
|
2444
|
+
<radialGradient id="fpm__main-b" fx="50%" fy="50%" r="50.864%" gradientTransform="matrix(-.98302 0 0 -1 .992 1)">
|
|
2445
|
+
<stop stop-color="#2D7CFF" offset="0%" />
|
|
2446
|
+
<stop stop-color="#2D7CFF" stop-opacity=".3" offset="100%" />
|
|
2447
|
+
</radialGradient>
|
|
2448
|
+
<radialGradient id="fpm__main-c" fx="50%" fy="50%" r="50.864%" gradientTransform="matrix(-.98302 0 0 -1 .992 1)">
|
|
2449
|
+
<stop stop-opacity=".4" offset="0%" />
|
|
2450
|
+
<stop stop-opacity=".12" offset="100%" />
|
|
2451
|
+
</radialGradient>
|
|
2452
|
+
</defs>
|
|
2453
|
+
<g fill="none" fill-rule="evenodd">
|
|
2454
|
+
<circle fill="url(#fpm__main-a)" cx="30" cy="30" r="30" />
|
|
2455
|
+
<path
|
|
2456
|
+
class="fpm__main-icon-path"
|
|
2457
|
+
d="${MAIN_NORMAL_PATH}"
|
|
2458
|
+
fill="${MAIN_MOUSE_LEAVE_FILL}"
|
|
2459
|
+
fill-rule="nonzero"
|
|
2460
|
+
transform="translate(14 14)"
|
|
2461
|
+
/>
|
|
2462
|
+
</g>
|
|
2463
|
+
</svg>
|
|
2464
|
+
`;
|
|
2465
|
+
var htmlString$1 = `
|
|
2466
|
+
<style>
|
|
2467
|
+
.fpm__revoke {
|
|
2468
|
+
opacity: 0.3;
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
.fpm__revoke.enabled {
|
|
2472
|
+
opacity: 0.7;
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
.fpm__revoke.enabled:hover {
|
|
2476
|
+
opacity: 1;
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
.fpm__revoke-icon {
|
|
2480
|
+
width: 40px;
|
|
2481
|
+
height: 40px;
|
|
2482
|
+
margin-top: 10px;
|
|
2483
|
+
cursor: pointer;
|
|
2484
|
+
}
|
|
2485
|
+
</style>
|
|
2486
|
+
<div class="fpm_ui-bg"></div>
|
|
2487
|
+
<div class="fpm_operating-space">
|
|
2488
|
+
<div class="fpm__ui-item fpm__revoke">
|
|
2489
|
+
${revokeSvg}
|
|
2490
|
+
<span class="fpm__text fpm__revoke-text">撤销</span>
|
|
2491
|
+
</div>
|
|
2492
|
+
<div class="fpm__ui-item fpm__main">
|
|
2493
|
+
${mainSvg}
|
|
2494
|
+
<span class="fpm__text fpm__main-text">添加</span>
|
|
2495
|
+
</div>
|
|
2496
|
+
<div class="fpm__ui-item fpm__exit">
|
|
2497
|
+
${exitSvg}
|
|
2498
|
+
<span class="fpm__text fpm__exit-text">退出</span>
|
|
2499
|
+
</div>
|
|
2500
|
+
</div>
|
|
2501
|
+
`;
|
|
2502
|
+
|
|
2503
|
+
const startIconImage = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzIiIGhlaWdodD0iNzIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxmaWx0ZXIgeD0iLTUuMyUiIHk9Ii01LjMlIiB3aWR0aD0iMTEwLjUlIiBoZWlnaHQ9IjExMC41JSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0icHJlZml4X19hIj48ZmVPZmZzZXQgaW49IlNvdXJjZUFscGhhIiByZXN1bHQ9InNoYWRvd09mZnNldE91dGVyMSIvPjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEiIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSIvPjxmZUNvbXBvc2l0ZSBpbj0ic2hhZG93Qmx1ck91dGVyMSIgaW4yPSJTb3VyY2VBbHBoYSIgb3BlcmF0b3I9Im91dCIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggdmFsdWVzPSIwIDAgMCAwIDEgMCAwIDAgMCAxIDAgMCAwIDAgMSAwIDAgMCAwLjUgMCIgaW49InNoYWRvd0JsdXJPdXRlcjEiLz48L2ZpbHRlcj48ZmlsdGVyIHg9Ii0xMS40JSIgeT0iLTExLjQlIiB3aWR0aD0iMTIyLjklIiBoZWlnaHQ9IjEyMi45JSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0icHJlZml4X19jIj48ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSI0LjUiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dCbHVySW5uZXIxIi8+PGZlT2Zmc2V0IGluPSJzaGFkb3dCbHVySW5uZXIxIiByZXN1bHQ9InNoYWRvd09mZnNldElubmVyMSIvPjxmZUNvbXBvc2l0ZSBpbj0ic2hhZG93T2Zmc2V0SW5uZXIxIiBpbjI9IlNvdXJjZUFscGhhIiBvcGVyYXRvcj0iYXJpdGhtZXRpYyIgazI9Ii0xIiBrMz0iMSIgcmVzdWx0PSJzaGFkb3dJbm5lcklubmVyMSIvPjxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAxIDAgMCAwIDAgMSAwIDAgMCAwIDEgMCAwIDAgMC4zIDAiIGluPSJzaGFkb3dJbm5lcklubmVyMSIvPjwvZmlsdGVyPjxmaWx0ZXIgeD0iLTEyNi42JSIgeT0iLTMzNy41JSIgd2lkdGg9IjM1My4xJSIgaGVpZ2h0PSI3NzUlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJwcmVmaXhfX2UiPjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjE2IiBpbj0iU291cmNlR3JhcGhpYyIvPjwvZmlsdGVyPjxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMTAwJSIgeDI9IjUwJSIgeTI9IjAlIiBpZD0icHJlZml4X19kIj48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9Ii43IiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0ZGRiIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjI2LjQzMiUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iODIuMzA1JSIvPjxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iLjQiIG9mZnNldD0iMTAwJSIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IHgxPSI1MCUiIHkxPSIwJSIgeDI9IjUwJSIgeTI9IjEwMCUiIGlkPSJwcmVmaXhfX2YiPjxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iLjA1IiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0ZGRiIgc3RvcC1vcGFjaXR5PSIuMiIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48Y2lyY2xlIGlkPSJwcmVmaXhfX2IiIGN4PSIzNiIgY3k9IjM2IiByPSIyOC40NDQiLz48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNwcmVmaXhfX2EpIiB4bGluazpocmVmPSIjcHJlZml4X19iIi8+PHVzZSBmaWxsPSIjMDAwIiBmaWx0ZXI9InVybCgjcHJlZml4X19jKSIgeGxpbms6aHJlZj0iI3ByZWZpeF9fYiIvPjxjaXJjbGUgc3Ryb2tlPSJ1cmwoI3ByZWZpeF9fZCkiIHN0cm9rZS13aWR0aD0iLjQiIGZpbGwtb3BhY2l0eT0iLjI0MSIgZmlsbD0iI0ZGRiIgc3Ryb2tlLWxpbmVqb2luPSJzcXVhcmUiIGN4PSIzNiIgY3k9IjM2IiByPSIyOC4yNDQiLz48ZWxsaXBzZSBmaWxsPSIjRkZGIiBvcGFjaXR5PSIuNTk2IiBmaWx0ZXI9InVybCgjcHJlZml4X19lKSIgY3g9IjM2IiBjeT0iMzYiIHJ4PSIxOC45NjMiIHJ5PSI3LjExMSIvPjxwYXRoIGQ9Ik0zNiAwQzE2LjExOCAwIDAgMTYuMTE4IDAgMzZzMTYuMTE4IDM2IDM2IDM2IDM2LTE2LjExOCAzNi0zNlM1NS44ODIgMCAzNiAwem0wIDQuNDQ0YzE3LjQyOCAwIDMxLjU1NiAxNC4xMjggMzEuNTU2IDMxLjU1NlM1My40MjggNjcuNTU2IDM2IDY3LjU1NiA0LjQ0NCA1My40MjggNC40NDQgMzYgMTguNTcyIDQuNDQ0IDM2IDQuNDQ0eiIgZmlsbD0idXJsKCNwcmVmaXhfX2YpIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48L2c+PC9zdmc+`;
|
|
2504
|
+
const endIconImage = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzIiIGhlaWdodD0iNzIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IHgxPSIxNS41MSUiIHkxPSIxMi40OTclIiB4Mj0iODUuMjY1JSIgeTI9Ijg2LjE0MyUiIGlkPSJwcmVmaXhfX2IiPjxzdG9wIHN0b3AtY29sb3I9IiM5NUFFRkYiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjNjM4NkZGIiBvZmZzZXQ9IjEwMCUiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMTAwJSIgeDI9IjUwJSIgeTI9IjAlIiBpZD0icHJlZml4X19hIj48c3RvcCBzdG9wLWNvbG9yPSIjOTlBRUZGIiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0ZGRiIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjI2LjQzMiUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iODIuMzA1JSIvPjxzdG9wIHN0b3AtY29sb3I9IiM5OUFFRkYiIHN0b3Atb3BhY2l0eT0iLjQiIG9mZnNldD0iMTAwJSIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IHgxPSI1MCUiIHkxPSIwJSIgeDI9IjUwJSIgeTI9IjEwMCUiIGlkPSJwcmVmaXhfX2QiPjxzdG9wIHN0b3AtY29sb3I9IiM4Nzk3RDIiIHN0b3Atb3BhY2l0eT0iLjA1IiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iIzYyNzdDNyIgc3RvcC1vcGFjaXR5PSIuMiIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48ZmlsdGVyIHg9Ii02My4zJSIgeT0iLTE2OC44JSIgd2lkdGg9IjIyNi42JSIgaGVpZ2h0PSI0MzcuNSUiIGZpbHRlclVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgaWQ9InByZWZpeF9fYyI+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iOCIgaW49IlNvdXJjZUdyYXBoaWMiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48Y2lyY2xlIHN0cm9rZT0idXJsKCNwcmVmaXhfX2EpIiBzdHJva2Utd2lkdGg9Ii40IiBmaWxsPSJ1cmwoI3ByZWZpeF9fYikiIG9wYWNpdHk9Ii43IiBjeD0iMzYiIGN5PSIzNiIgcj0iMjguMjQ0Ii8+PGVsbGlwc2UgZmlsbD0iIzdDOTBEQSIgb3BhY2l0eT0iLjU5NiIgZmlsdGVyPSJ1cmwoI3ByZWZpeF9fYykiIGN4PSIzNiIgY3k9IjM2IiByeD0iMTguOTYzIiByeT0iNy4xMTEiLz48cGF0aCBkPSJNMzYgMEMxNi4xMTggMCAwIDE2LjExOCAwIDM2czE2LjExOCAzNiAzNiAzNiAzNi0xNi4xMTggMzYtMzZTNTUuODgyIDAgMzYgMHptMCA0LjQ0NGMxNy40MjggMCAzMS41NTYgMTQuMTI4IDMxLjU1NiAzMS41NTZTNTMuNDI4IDY3LjU1NiAzNiA2Ny41NTYgNC40NDQgNTMuNDI4IDQuNDQ0IDM2IDE4LjU3MiA0LjQ0NCAzNiA0LjQ0NHoiIGZpbGw9InVybCgjcHJlZml4X19kKSIgZmlsbC1ydWxlPSJub256ZXJvIi8+PC9nPjwvc3ZnPg==`;
|
|
2505
|
+
const exitIconSvg = `
|
|
2506
|
+
<svg class="fpm__exit-icon width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
2507
|
+
<defs>
|
|
2508
|
+
<radialGradient cx="50%" cy="50%" fx="50%" fy="50%" r="86.3016741%" id="radialGradient-1">
|
|
2509
|
+
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
|
2510
|
+
<stop stop-color="#FFFFFF" stop-opacity="0.3" offset="100%"></stop>
|
|
2511
|
+
</radialGradient>
|
|
2512
|
+
<radialGradient cx="50%" cy="50%" fx="50%" fy="50%" r="70.7106781%" id="radialGradient-2">
|
|
2513
|
+
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
|
2514
|
+
<stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
|
|
2515
|
+
</radialGradient>
|
|
2516
|
+
</defs>
|
|
2517
|
+
<g fill="url(#radialGradient-1)" fill-rule="nonzero" stroke="url(#radialGradient-2)" stroke-width="0.2">
|
|
2518
|
+
<path d="M19.1859205,4.10000004 C19.3691554,4.09993923 19.5526088,4.16602323 19.6925352,4.29904206 C19.8171021,4.41745965 19.8858582,4.56899486 19.8980316,4.7239943 C19.9103475,4.88080848 19.8647874,5.04088037 19.7661957,5.16777131 L19.7661957,5.16777131 L14.3769795,11.1697063 C14.1649599,11.4058657 14.0589501,11.7029328 14.0589501,12 C14.0589501,12.2970672 14.1649599,12.5941343 14.3769795,12.8302937 L14.3769795,12.8302937 L19.6928862,18.7509889 C19.8173649,18.8694879 19.8860087,19.0210672 19.8980683,19.1760728 C19.9102693,19.3328965 19.8645908,19.4929392 19.7701664,19.6153111 C19.6099275,19.772809 19.4324896,19.8610254 19.2586274,19.8856752 C19.0810547,19.910851 18.9081905,19.8692156 18.765363,19.7704965 L18.765363,19.7704965 L11.9999322,13.2904645 L5.32508998,19.6962598 C5.16077108,19.8156635 4.99335965,19.8785989 4.83451361,19.8898888 C4.67442082,19.9012674 4.52389835,19.8596921 4.3968979,19.7731206 C4.23619359,19.588506 4.14871527,19.4164558 4.12392544,19.2589757 C4.09801173,19.094356 4.14341261,18.9485987 4.23380428,18.8322287 L4.23380428,18.8322287 L9.62302046,12.8302937 C9.81773049,12.6134147 9.92302682,12.3451662 9.93892926,12.0727274 C9.95499717,11.7974536 9.87975312,11.5179151 9.70614397,11.2737767 L9.70614397,11.2737767 L4.31595492,5.25860214 C4.17860663,5.08857057 4.11166276,4.9104714 4.11172409,4.7432513 C4.11178577,4.57506821 4.18051603,4.41972395 4.30746483,4.29904206 C4.43371817,4.17902131 4.59543385,4.11349344 4.76041858,4.10187732 L4.76041858,4.10187732 L12.0000677,10.7085251 L18.6794563,4.29937602 C18.8192839,4.16626546 19.0026873,4.10006086 19.1859205,4.10000004 Z" id="形状结合"></path>
|
|
2519
|
+
</g>
|
|
2520
|
+
</svg>
|
|
2521
|
+
`;
|
|
2522
|
+
var mobileHTMLString = `
|
|
2523
|
+
<style>
|
|
2524
|
+
.mobile .fpm__exit {
|
|
2525
|
+
position: absolute;
|
|
2526
|
+
top: 53px;
|
|
2527
|
+
left: 16px;
|
|
2528
|
+
width: 24px;
|
|
2529
|
+
height: 24px;
|
|
2530
|
+
z-index: 10;
|
|
2531
|
+
pointer-events: all;
|
|
2532
|
+
}
|
|
2533
|
+
.mobile .fpm__exit-icon {
|
|
2534
|
+
width: 100%;
|
|
2535
|
+
height: 100%;
|
|
2536
|
+
cursor: pointer;
|
|
2537
|
+
}
|
|
2538
|
+
.fpm_operating--mobile {
|
|
2539
|
+
padding-bottom: 23px;
|
|
2540
|
+
}
|
|
2541
|
+
.fpm__main-btn {
|
|
2542
|
+
display: flex;
|
|
2543
|
+
justify-content: center;
|
|
2544
|
+
align-items: center;
|
|
2545
|
+
margin: 0 !important;
|
|
2546
|
+
}
|
|
2547
|
+
.fpm__main-btn-text {
|
|
2548
|
+
position: absolute;
|
|
2549
|
+
font-weight: 500;
|
|
2550
|
+
font-size: 14px;
|
|
2551
|
+
color: #FFFFFF;
|
|
2552
|
+
text-align: center;
|
|
2553
|
+
text-shadow: 0 2px 8px rgba(0,0,0,0.50);
|
|
2554
|
+
transition: all 200ms ease-in-out;
|
|
2555
|
+
}
|
|
2556
|
+
.fpm__main-text__hide {
|
|
2557
|
+
transform: scale(0.8) translateY(4px);
|
|
2558
|
+
opacity: 0;
|
|
2559
|
+
}
|
|
2560
|
+
.fpm__main-text__show {
|
|
2561
|
+
transform: scale(1) translateY(0);
|
|
2562
|
+
opacity: 1;
|
|
2563
|
+
}
|
|
2564
|
+
.fpm__main__start {
|
|
2565
|
+
background-image: url(${startIconImage});
|
|
2566
|
+
}
|
|
2567
|
+
.fpm__main__end {
|
|
2568
|
+
background-image: url(${endIconImage});
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
</style>
|
|
2572
|
+
<div class="fpm__exit">
|
|
2573
|
+
${exitIconSvg}
|
|
2574
|
+
</div>
|
|
2575
|
+
<div class="fpm_ui-bg"></div>
|
|
2576
|
+
<div class="fpm_operating-space fpm_operating--mobile">
|
|
2577
|
+
<div class="fpm__main fpm__main-btn">
|
|
2578
|
+
<div class="fpm__main-icon fpm__main__start"></div>
|
|
2579
|
+
<div class="fpm__main-text fpm__main-btn-text">开始</div>
|
|
2580
|
+
</div>
|
|
2581
|
+
</div>
|
|
2582
|
+
`;
|
|
2583
|
+
|
|
2584
|
+
const uiWrapperStyle = {
|
|
2585
|
+
display: 'none',
|
|
2586
|
+
position: 'absolute',
|
|
2587
|
+
top: '0',
|
|
2588
|
+
left: '0',
|
|
2589
|
+
width: '100%',
|
|
2590
|
+
height: '100%',
|
|
2591
|
+
opacity: '0',
|
|
2592
|
+
transform: 'translate(0, 10px)',
|
|
2593
|
+
transition: 'opacity 500ms ease-in-out, transform 500ms ease-in-out',
|
|
2594
|
+
};
|
|
2595
|
+
const operatingSpaceStyle = {
|
|
2596
|
+
position: 'absolute',
|
|
2597
|
+
left: '50%',
|
|
2598
|
+
bottom: '32px',
|
|
2599
|
+
transform: 'translateX(-50%)',
|
|
2600
|
+
height: '89px',
|
|
2601
|
+
display: 'flex',
|
|
2602
|
+
justifyContent: 'space-between',
|
|
2603
|
+
fontSize: '16px',
|
|
2604
|
+
pointerEvents: 'all',
|
|
2605
|
+
color: '#fff',
|
|
2606
|
+
zIndex: '10',
|
|
2607
|
+
};
|
|
2608
|
+
const buttonGroupStyle = {
|
|
2609
|
+
height: '100%',
|
|
2610
|
+
width: 'max-content',
|
|
2611
|
+
display: 'flex',
|
|
2612
|
+
flexDirection: 'column',
|
|
2613
|
+
justifyContent: 'space-between',
|
|
2614
|
+
alignItems: 'center',
|
|
2615
|
+
};
|
|
2616
|
+
// 操作区下方的背景
|
|
2617
|
+
const controllerBackgroundStyle = {
|
|
2618
|
+
position: 'absolute',
|
|
2619
|
+
bottom: '0',
|
|
2620
|
+
left: '0',
|
|
2621
|
+
opacity: '0.5',
|
|
2622
|
+
width: '100%',
|
|
2623
|
+
height: '184px',
|
|
2624
|
+
background: `linear-gradient(180deg, rgba(0,0,0,0.00) 0%, #000000 100%)`,
|
|
2625
|
+
zIndex: '0',
|
|
2626
|
+
};
|
|
2627
|
+
// item
|
|
2628
|
+
const mainItemStyle = {
|
|
2629
|
+
margin: '0 80px',
|
|
2630
|
+
opacity: '0.7',
|
|
2631
|
+
};
|
|
2632
|
+
const newMainItemStyle = {
|
|
2633
|
+
margin: '0 80px',
|
|
2634
|
+
};
|
|
2635
|
+
const exitItemStyle = {
|
|
2636
|
+
opacity: '0.7',
|
|
2637
|
+
};
|
|
2638
|
+
// icon
|
|
2639
|
+
const mainIconStyle = {
|
|
2640
|
+
width: '60px',
|
|
2641
|
+
height: '60px',
|
|
2642
|
+
backgroundSize: '100%',
|
|
2643
|
+
cursor: 'pointer',
|
|
2644
|
+
};
|
|
2645
|
+
const newMainIconStyle = {
|
|
2646
|
+
width: '72px',
|
|
2647
|
+
height: '72px',
|
|
2648
|
+
backgroundSize: '100%',
|
|
2649
|
+
cursor: 'pointer',
|
|
2650
|
+
transition: 'all 200ms ease-in-out',
|
|
2651
|
+
};
|
|
2652
|
+
const exitIconStyle = {
|
|
2653
|
+
width: '40px',
|
|
2654
|
+
height: '40px',
|
|
2655
|
+
marginTop: '10px',
|
|
2656
|
+
backgroundSize: '100%',
|
|
2657
|
+
cursor: 'pointer',
|
|
2658
|
+
};
|
|
2659
|
+
// text
|
|
2660
|
+
const textStyle = {
|
|
2661
|
+
cursor: 'default',
|
|
2662
|
+
userSelect: 'none',
|
|
2663
|
+
};
|
|
2664
|
+
|
|
2665
|
+
const _requestAnimationFrame = window.requestAnimationFrame || ((fn) => setTimeout(fn, 16));
|
|
2666
|
+
const _cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
|
|
2667
|
+
/**
|
|
2668
|
+
* 在每个 AnimationFrame 中调用传入的函数
|
|
2669
|
+
* @param callback 每次 AnimationFrame 中调用的函数
|
|
2670
|
+
* @param frame 每秒运行多少次
|
|
2671
|
+
* @returns 返回一个函数,调用可以停止 AnimationFrameLoop
|
|
2672
|
+
*/
|
|
2673
|
+
function requestAnimationFrameInterval(callback, frame = 60) {
|
|
2674
|
+
let index = -1;
|
|
2675
|
+
let oldTime = 0;
|
|
2676
|
+
let startTime = -1;
|
|
2677
|
+
const minDeltaTime = 1000 / frame;
|
|
2678
|
+
function loop(time) {
|
|
2679
|
+
startTime === -1 && (startTime = time);
|
|
2680
|
+
index = _requestAnimationFrame(loop);
|
|
2681
|
+
const deltaTime = time - oldTime;
|
|
2682
|
+
if (deltaTime < minDeltaTime)
|
|
2683
|
+
return;
|
|
2684
|
+
oldTime = time;
|
|
2685
|
+
callback && callback(time - startTime);
|
|
2686
|
+
}
|
|
2687
|
+
index = _requestAnimationFrame(loop);
|
|
2688
|
+
return function stop() {
|
|
2689
|
+
_cancelAnimationFrame(index);
|
|
2690
|
+
};
|
|
2691
|
+
}
|
|
2692
|
+
// export { Easing } from './tween'
|
|
2693
|
+
// export { default as tween } from './tween'
|
|
2694
|
+
|
|
2695
|
+
class BetterTween extends TWEEN__default["default"].Tween {
|
|
2696
|
+
constructor() {
|
|
2697
|
+
super(...arguments);
|
|
2698
|
+
Object.defineProperty(this, "disposeMethods", {
|
|
2699
|
+
enumerable: true,
|
|
2700
|
+
configurable: true,
|
|
2701
|
+
writable: true,
|
|
2702
|
+
value: []
|
|
2703
|
+
});
|
|
2704
|
+
Object.defineProperty(this, "animationFrameDisposer", {
|
|
2705
|
+
enumerable: true,
|
|
2706
|
+
configurable: true,
|
|
2707
|
+
writable: true,
|
|
2708
|
+
value: void 0
|
|
2709
|
+
});
|
|
2710
|
+
Object.defineProperty(this, "onDispose", {
|
|
2711
|
+
enumerable: true,
|
|
2712
|
+
configurable: true,
|
|
2713
|
+
writable: true,
|
|
2714
|
+
value: (callback) => {
|
|
2715
|
+
this.disposeMethods.push(callback);
|
|
2716
|
+
return this;
|
|
2717
|
+
}
|
|
2718
|
+
});
|
|
2719
|
+
Object.defineProperty(this, "play", {
|
|
2720
|
+
enumerable: true,
|
|
2721
|
+
configurable: true,
|
|
2722
|
+
writable: true,
|
|
2723
|
+
value: () => {
|
|
2724
|
+
this.start(0);
|
|
2725
|
+
this.animationFrameDisposer = requestAnimationFrameInterval((time) => this.update(time));
|
|
2726
|
+
return this;
|
|
2727
|
+
}
|
|
2728
|
+
});
|
|
2729
|
+
Object.defineProperty(this, "dispose", {
|
|
2730
|
+
enumerable: true,
|
|
2731
|
+
configurable: true,
|
|
2732
|
+
writable: true,
|
|
2733
|
+
value: () => {
|
|
2734
|
+
var _a;
|
|
2735
|
+
this.stop();
|
|
2736
|
+
(_a = this.animationFrameDisposer) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
2737
|
+
this.disposeMethods.forEach((fn) => fn());
|
|
2738
|
+
this.disposeMethods = [];
|
|
2739
|
+
TWEEN__default["default"].remove(this);
|
|
2740
|
+
}
|
|
2741
|
+
});
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
function tweenProgress(duration, easing = TWEEN__default["default"].Easing.Linear.None) {
|
|
2745
|
+
const tween = new BetterTween({ progress: 0 }).to({ progress: 1 });
|
|
2746
|
+
if (duration !== undefined)
|
|
2747
|
+
tween.duration(duration);
|
|
2748
|
+
if (easing !== undefined)
|
|
2749
|
+
tween.easing(easing);
|
|
2750
|
+
return tween;
|
|
2751
|
+
}
|
|
2752
|
+
|
|
2753
|
+
class MainBtnController {
|
|
2754
|
+
constructor(measureController, container) {
|
|
2755
|
+
Object.defineProperty(this, "container", {
|
|
2756
|
+
enumerable: true,
|
|
2757
|
+
configurable: true,
|
|
2758
|
+
writable: true,
|
|
2759
|
+
value: void 0
|
|
2760
|
+
});
|
|
2761
|
+
Object.defineProperty(this, "measureController", {
|
|
2762
|
+
enumerable: true,
|
|
2763
|
+
configurable: true,
|
|
2764
|
+
writable: true,
|
|
2765
|
+
value: void 0
|
|
2766
|
+
});
|
|
2767
|
+
Object.defineProperty(this, "mainIconMaskTween", {
|
|
2768
|
+
enumerable: true,
|
|
2769
|
+
configurable: true,
|
|
2770
|
+
writable: true,
|
|
2771
|
+
value: void 0
|
|
2772
|
+
});
|
|
2773
|
+
Object.defineProperty(this, "mainElement", {
|
|
2774
|
+
enumerable: true,
|
|
2775
|
+
configurable: true,
|
|
2776
|
+
writable: true,
|
|
2777
|
+
value: void 0
|
|
2778
|
+
});
|
|
2779
|
+
/* 鼠标移入时变成蓝色 */
|
|
2780
|
+
Object.defineProperty(this, "onMouseEnter", {
|
|
2781
|
+
enumerable: true,
|
|
2782
|
+
configurable: true,
|
|
2783
|
+
writable: true,
|
|
2784
|
+
value: () => {
|
|
2785
|
+
const { mainItem, pathDom } = this.mainElement;
|
|
2786
|
+
mainItem.style.opacity = '1';
|
|
2787
|
+
pathDom.setAttribute('fill', MAIN_MOUSE_ENTER_FILL);
|
|
2788
|
+
}
|
|
2789
|
+
});
|
|
2790
|
+
/* 鼠标移出时变成灰色 */
|
|
2791
|
+
Object.defineProperty(this, "onMouseLeave", {
|
|
2792
|
+
enumerable: true,
|
|
2793
|
+
configurable: true,
|
|
2794
|
+
writable: true,
|
|
2795
|
+
value: () => {
|
|
2796
|
+
const { mainItem, pathDom } = this.mainElement;
|
|
2797
|
+
mainItem.style.opacity = '0.7';
|
|
2798
|
+
pathDom.setAttribute('fill', MAIN_MOUSE_LEAVE_FILL);
|
|
2799
|
+
}
|
|
2800
|
+
});
|
|
2801
|
+
Object.defineProperty(this, "onClick", {
|
|
2802
|
+
enumerable: true,
|
|
2803
|
+
configurable: true,
|
|
2804
|
+
writable: true,
|
|
2805
|
+
value: () => {
|
|
2806
|
+
const mode = this.measureController.getCurrentMode();
|
|
2807
|
+
mode === 'Watch' ? this.measureController.changeMode('Edit') : this.measureController.save().changeMode('Watch');
|
|
2808
|
+
}
|
|
2809
|
+
});
|
|
2810
|
+
Object.defineProperty(this, "editedLineChangeHandler", {
|
|
2811
|
+
enumerable: true,
|
|
2812
|
+
configurable: true,
|
|
2813
|
+
writable: true,
|
|
2814
|
+
value: (lines) => {
|
|
2815
|
+
// 线的数量大于 1 时,没有状态的变化
|
|
2816
|
+
if (lines.length > 1)
|
|
2817
|
+
return;
|
|
2818
|
+
// 因为撤销导致的状态变更 -> 取消
|
|
2819
|
+
if (lines.length === 0)
|
|
2820
|
+
return this.change2Cancel(false);
|
|
2821
|
+
this.change2Done();
|
|
2822
|
+
}
|
|
2823
|
+
});
|
|
2824
|
+
Object.defineProperty(this, "modeChangeHandler", {
|
|
2825
|
+
enumerable: true,
|
|
2826
|
+
configurable: true,
|
|
2827
|
+
writable: true,
|
|
2828
|
+
value: (mode) => {
|
|
2829
|
+
mode === 'Watch' ? this.change2Add() : this.change2Cancel();
|
|
2830
|
+
}
|
|
2831
|
+
});
|
|
2832
|
+
this.measureController = measureController;
|
|
2833
|
+
this.container = container;
|
|
2834
|
+
this.mainElement = this.getMainElement();
|
|
2835
|
+
Object.assign(this.mainElement.mainIcon.style, mainIconStyle);
|
|
2836
|
+
Object.assign(this.mainElement.mainItem.style, mainItemStyle);
|
|
2837
|
+
this.change2Add();
|
|
2838
|
+
this.measureController.hook.on('modeChange', this.modeChangeHandler);
|
|
2839
|
+
this.mainElement.mainIcon.addEventListener('click', this.onClick);
|
|
2840
|
+
this.mainElement.mainIcon.addEventListener('mouseenter', this.onMouseEnter);
|
|
2841
|
+
this.mainElement.mainIcon.addEventListener('mouseleave', this.onMouseLeave);
|
|
2842
|
+
}
|
|
2843
|
+
dispose() {
|
|
2844
|
+
this.measureController.hook.off('modeChange', this.modeChangeHandler);
|
|
2845
|
+
this.measureController.hook.off('editedLineChange', this.editedLineChangeHandler);
|
|
2846
|
+
this.mainElement.mainIcon.removeEventListener('click', this.onClick);
|
|
2847
|
+
this.mainElement.mainIcon.removeEventListener('mouseenter', this.onMouseEnter);
|
|
2848
|
+
this.mainElement.mainIcon.removeEventListener('mouseleave', this.onMouseLeave);
|
|
2849
|
+
}
|
|
2850
|
+
getMainElement() {
|
|
2851
|
+
const mainTextDom = this.container.querySelector('.fpm__main-text');
|
|
2852
|
+
const mainItem = this.container.querySelector('.fpm__main');
|
|
2853
|
+
const mainIcon = this.container.querySelector('.fpm__main-icon');
|
|
2854
|
+
const pathDom = mainItem === null || mainItem === void 0 ? void 0 : mainItem.querySelector('.fpm__main-icon-path');
|
|
2855
|
+
const maskWhiteRect = mainIcon === null || mainIcon === void 0 ? void 0 : mainIcon.querySelector('#fpm__main-icon-mask-white');
|
|
2856
|
+
if (!mainItem || !mainTextDom || !mainIcon || !pathDom || !maskWhiteRect)
|
|
2857
|
+
throw new Error('cannot find dom');
|
|
2858
|
+
return { mainTextDom, mainItem, mainIcon, pathDom, maskWhiteRect };
|
|
2859
|
+
}
|
|
2860
|
+
change2Add() {
|
|
2861
|
+
this.measureController.hook.off('editedLineChange', this.editedLineChangeHandler);
|
|
2862
|
+
const { mainIcon, mainTextDom, pathDom } = this.mainElement;
|
|
2863
|
+
mainIcon.style.transition = mainTextDom.innerText === '完成' ? 'none' : 'transform 300ms ease-in-out';
|
|
2864
|
+
mainIcon.style.transform = 'rotate(0deg)';
|
|
2865
|
+
mainTextDom.innerText = '添加';
|
|
2866
|
+
pathDom === null || pathDom === void 0 ? void 0 : pathDom.setAttribute('d', MAIN_NORMAL_PATH);
|
|
2867
|
+
}
|
|
2868
|
+
change2Cancel(withAnime = true) {
|
|
2869
|
+
const { mainIcon, mainTextDom, pathDom } = this.mainElement;
|
|
2870
|
+
pathDom.setAttribute('d', MAIN_NORMAL_PATH);
|
|
2871
|
+
pathDom.setAttribute('mask', '');
|
|
2872
|
+
mainIcon.style.transition = withAnime ? 'transform 300ms ease-in-out' : 'none';
|
|
2873
|
+
mainIcon.style.transform = 'rotate(45deg)';
|
|
2874
|
+
mainTextDom && (mainTextDom.innerText = '取消');
|
|
2875
|
+
this.measureController.hook.on('editedLineChange', this.editedLineChangeHandler);
|
|
2876
|
+
}
|
|
2877
|
+
change2Done() {
|
|
2878
|
+
var _a;
|
|
2879
|
+
const { mainTextDom, mainIcon, pathDom, maskWhiteRect } = this.getMainElement();
|
|
2880
|
+
if (mainTextDom.innerText === '完成')
|
|
2881
|
+
return;
|
|
2882
|
+
mainIcon.style.transition = 'none';
|
|
2883
|
+
mainIcon.style.transform = 'rotate(0deg)';
|
|
2884
|
+
mainTextDom.innerText = '完成';
|
|
2885
|
+
pathDom.setAttribute('d', MAIN_DONE_PATH);
|
|
2886
|
+
pathDom.setAttribute('mask', `url(#fpm__main-icon-mask)`);
|
|
2887
|
+
(_a = this.mainIconMaskTween) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
2888
|
+
this.mainIconMaskTween = tweenProgress()
|
|
2889
|
+
.easing(TWEEN__default["default"].Easing.Quartic.InOut)
|
|
2890
|
+
.onUpdate(({ progress }) => {
|
|
2891
|
+
maskWhiteRect.setAttribute('width', (progress * 30).toString());
|
|
2892
|
+
})
|
|
2893
|
+
.onComplete(() => { var _a; return (_a = this.mainIconMaskTween) === null || _a === void 0 ? void 0 : _a.dispose(); })
|
|
2894
|
+
.play();
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
|
|
2898
|
+
class NewMainBtnController {
|
|
2899
|
+
constructor(measureController, container) {
|
|
2900
|
+
Object.defineProperty(this, "container", {
|
|
2901
|
+
enumerable: true,
|
|
2902
|
+
configurable: true,
|
|
2903
|
+
writable: true,
|
|
2904
|
+
value: void 0
|
|
2905
|
+
});
|
|
2906
|
+
Object.defineProperty(this, "measureController", {
|
|
2907
|
+
enumerable: true,
|
|
2908
|
+
configurable: true,
|
|
2909
|
+
writable: true,
|
|
2910
|
+
value: void 0
|
|
2911
|
+
});
|
|
2912
|
+
Object.defineProperty(this, "mainElement", {
|
|
2913
|
+
enumerable: true,
|
|
2914
|
+
configurable: true,
|
|
2915
|
+
writable: true,
|
|
2916
|
+
value: void 0
|
|
2917
|
+
});
|
|
2918
|
+
Object.defineProperty(this, "onClick", {
|
|
2919
|
+
enumerable: true,
|
|
2920
|
+
configurable: true,
|
|
2921
|
+
writable: true,
|
|
2922
|
+
value: () => {
|
|
2923
|
+
if (this.mainElement.mainTextDom.innerText === '开始') {
|
|
2924
|
+
this.measureController.hook.emit('willChangeState', 'watching', 'editing');
|
|
2925
|
+
this.change2Done();
|
|
2926
|
+
}
|
|
2927
|
+
else {
|
|
2928
|
+
this.measureController.hook.emit('willChangeState', 'editing', 'watching');
|
|
2929
|
+
this.change2Add();
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
});
|
|
2933
|
+
this.measureController = measureController;
|
|
2934
|
+
this.container = container;
|
|
2935
|
+
this.mainElement = this.getMainElement();
|
|
2936
|
+
Object.assign(this.mainElement.mainIcon.style, newMainIconStyle);
|
|
2937
|
+
Object.assign(this.mainElement.mainItem.style, newMainItemStyle);
|
|
2938
|
+
this.change2Add();
|
|
2939
|
+
this.mainElement.mainItem.addEventListener('click', this.onClick);
|
|
2940
|
+
}
|
|
2941
|
+
dispose() {
|
|
2942
|
+
this.mainElement.mainItem.removeEventListener('click', this.onClick);
|
|
2943
|
+
}
|
|
2944
|
+
getMainElement() {
|
|
2945
|
+
const mainTextDom = this.container.querySelector('.fpm__main-text');
|
|
2946
|
+
const mainItem = this.container.querySelector('.fpm__main');
|
|
2947
|
+
const mainIcon = this.container.querySelector('.fpm__main-icon');
|
|
2948
|
+
if (!mainItem || !mainTextDom || !mainIcon)
|
|
2949
|
+
throw new Error('cannot find dom');
|
|
2950
|
+
return { mainTextDom, mainItem, mainIcon };
|
|
2951
|
+
}
|
|
2952
|
+
change2Add() {
|
|
2953
|
+
const { mainIcon, mainTextDom } = this.mainElement;
|
|
2954
|
+
if (mainIcon.className.includes('fpm__main__start'))
|
|
2955
|
+
return;
|
|
2956
|
+
if (mainIcon.className.includes('fpm__main__end')) {
|
|
2957
|
+
mainIcon.style.transform = `scale(0.8)`;
|
|
2958
|
+
if (mainTextDom.className.includes('fpm__main-text__show')) {
|
|
2959
|
+
mainTextDom.classList.replace('fpm__main-text__show', 'fpm__main-text__hide');
|
|
2960
|
+
}
|
|
2961
|
+
else {
|
|
2962
|
+
mainTextDom.classList.add('fpm__main-text__hide');
|
|
2963
|
+
}
|
|
2964
|
+
setTimeout(() => {
|
|
2965
|
+
mainIcon.classList.replace('fpm__main__end', 'fpm__main__start');
|
|
2966
|
+
mainIcon.style.transform = 'scale(1)';
|
|
2967
|
+
mainTextDom.innerText = '开始';
|
|
2968
|
+
mainTextDom.classList.replace('fpm__main-text__hide', 'fpm__main-text__show');
|
|
2969
|
+
}, 200);
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2972
|
+
change2Done() {
|
|
2973
|
+
const { mainTextDom, mainIcon } = this.mainElement;
|
|
2974
|
+
if (mainTextDom.innerText === '结束')
|
|
2975
|
+
return;
|
|
2976
|
+
if (mainIcon.className.includes('fpm__main__end'))
|
|
2977
|
+
return;
|
|
2978
|
+
if (mainIcon.className.includes('fpm__main__start')) {
|
|
2979
|
+
mainIcon.style.transform = `scale(0.8)`;
|
|
2980
|
+
if (mainTextDom.className.includes('fpm__main-text__show')) {
|
|
2981
|
+
mainTextDom.classList.replace('fpm__main-text__show', 'fpm__main-text__hide');
|
|
2982
|
+
}
|
|
2983
|
+
else {
|
|
2984
|
+
mainTextDom.classList.add('fpm__main-text__hide');
|
|
2985
|
+
}
|
|
2986
|
+
setTimeout(() => {
|
|
2987
|
+
mainIcon.classList.replace('fpm__main__start', 'fpm__main__end');
|
|
2988
|
+
mainIcon.style.transform = 'scale(1)';
|
|
2989
|
+
mainTextDom.innerText = '结束';
|
|
2990
|
+
mainTextDom.classList.replace('fpm__main-text__hide', 'fpm__main-text__show');
|
|
2991
|
+
}, 200);
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
|
|
2996
|
+
class Revoke {
|
|
2997
|
+
constructor(measureController, container) {
|
|
2998
|
+
Object.defineProperty(this, "container", {
|
|
2999
|
+
enumerable: true,
|
|
3000
|
+
configurable: true,
|
|
3001
|
+
writable: true,
|
|
3002
|
+
value: void 0
|
|
3003
|
+
});
|
|
3004
|
+
Object.defineProperty(this, "revokeIcon", {
|
|
3005
|
+
enumerable: true,
|
|
3006
|
+
configurable: true,
|
|
3007
|
+
writable: true,
|
|
3008
|
+
value: void 0
|
|
3009
|
+
});
|
|
3010
|
+
Object.defineProperty(this, "revokeItem", {
|
|
3011
|
+
enumerable: true,
|
|
3012
|
+
configurable: true,
|
|
3013
|
+
writable: true,
|
|
3014
|
+
value: void 0
|
|
3015
|
+
});
|
|
3016
|
+
Object.defineProperty(this, "measureController", {
|
|
3017
|
+
enumerable: true,
|
|
3018
|
+
configurable: true,
|
|
3019
|
+
writable: true,
|
|
3020
|
+
value: void 0
|
|
3021
|
+
});
|
|
3022
|
+
Object.defineProperty(this, "onClick", {
|
|
3023
|
+
enumerable: true,
|
|
3024
|
+
configurable: true,
|
|
3025
|
+
writable: true,
|
|
3026
|
+
value: () => {
|
|
3027
|
+
this.measureController.revoke();
|
|
3028
|
+
}
|
|
3029
|
+
});
|
|
3030
|
+
Object.defineProperty(this, "onModeChange", {
|
|
3031
|
+
enumerable: true,
|
|
3032
|
+
configurable: true,
|
|
3033
|
+
writable: true,
|
|
3034
|
+
value: (mode) => {
|
|
3035
|
+
if (mode !== 'Edit') {
|
|
3036
|
+
this.revokeItem.classList.remove('enabled');
|
|
3037
|
+
return;
|
|
3038
|
+
}
|
|
3039
|
+
this.revokeItem.classList.add('enabled');
|
|
3040
|
+
}
|
|
3041
|
+
});
|
|
3042
|
+
Object.defineProperty(this, "handleRevoke", {
|
|
3043
|
+
enumerable: true,
|
|
3044
|
+
configurable: true,
|
|
3045
|
+
writable: true,
|
|
3046
|
+
value: () => {
|
|
3047
|
+
return () => { };
|
|
3048
|
+
}
|
|
3049
|
+
});
|
|
3050
|
+
this.measureController = measureController;
|
|
3051
|
+
this.container = container;
|
|
3052
|
+
const revokeIcon = this.container.querySelector('.fpm__revoke-icon');
|
|
3053
|
+
const revokeItem = this.container.querySelector('.fpm__revoke');
|
|
3054
|
+
if (!revokeIcon || !revokeItem)
|
|
3055
|
+
throw new Error('不正确的选择器');
|
|
3056
|
+
this.revokeIcon = revokeIcon;
|
|
3057
|
+
this.revokeItem = revokeItem;
|
|
3058
|
+
this.revokeIcon.addEventListener('click', this.onClick);
|
|
3059
|
+
measureController.hook.on('modeChange', this.onModeChange);
|
|
3060
|
+
}
|
|
3061
|
+
dispose() {
|
|
3062
|
+
this.revokeIcon.removeEventListener('click', this.onClick);
|
|
3063
|
+
this.measureController.hook.off('modeChange', this.onModeChange);
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
|
|
3067
|
+
class UIController {
|
|
3068
|
+
constructor(measureController, params) {
|
|
3069
|
+
var _a, _b;
|
|
3070
|
+
Object.defineProperty(this, "revoke", {
|
|
3071
|
+
enumerable: true,
|
|
3072
|
+
configurable: true,
|
|
3073
|
+
writable: true,
|
|
3074
|
+
value: void 0
|
|
3075
|
+
});
|
|
3076
|
+
Object.defineProperty(this, "container", {
|
|
3077
|
+
enumerable: true,
|
|
3078
|
+
configurable: true,
|
|
3079
|
+
writable: true,
|
|
3080
|
+
value: void 0
|
|
3081
|
+
});
|
|
3082
|
+
Object.defineProperty(this, "mainController", {
|
|
3083
|
+
enumerable: true,
|
|
3084
|
+
configurable: true,
|
|
3085
|
+
writable: true,
|
|
3086
|
+
value: void 0
|
|
3087
|
+
});
|
|
3088
|
+
Object.defineProperty(this, "disposers", {
|
|
3089
|
+
enumerable: true,
|
|
3090
|
+
configurable: true,
|
|
3091
|
+
writable: true,
|
|
3092
|
+
value: []
|
|
3093
|
+
});
|
|
3094
|
+
Object.defineProperty(this, "measureController", {
|
|
3095
|
+
enumerable: true,
|
|
3096
|
+
configurable: true,
|
|
3097
|
+
writable: true,
|
|
3098
|
+
value: void 0
|
|
3099
|
+
});
|
|
3100
|
+
Object.defineProperty(this, "mode", {
|
|
3101
|
+
enumerable: true,
|
|
3102
|
+
configurable: true,
|
|
3103
|
+
writable: true,
|
|
3104
|
+
value: void 0
|
|
3105
|
+
});
|
|
3106
|
+
Object.defineProperty(this, "handleExit", {
|
|
3107
|
+
enumerable: true,
|
|
3108
|
+
configurable: true,
|
|
3109
|
+
writable: true,
|
|
3110
|
+
value: () => {
|
|
3111
|
+
const exitIcon = this.container.querySelector('.fpm__exit-icon');
|
|
3112
|
+
const exitItem = this.container.querySelector('.fpm__exit');
|
|
3113
|
+
if (!exitItem || !exitIcon)
|
|
3114
|
+
throw new Error('cannot find dom');
|
|
3115
|
+
if (this.mode === 'pc') {
|
|
3116
|
+
Object.assign(exitItem.style, exitItemStyle);
|
|
3117
|
+
Object.assign(exitIcon === null || exitIcon === void 0 ? void 0 : exitIcon.style, exitIconStyle);
|
|
3118
|
+
}
|
|
3119
|
+
const onMouseEnter = () => (exitItem.style.opacity = '1');
|
|
3120
|
+
const onMouseLeave = () => (exitItem.style.opacity = '0.7');
|
|
3121
|
+
const handleClick = () => {
|
|
3122
|
+
this.measureController.disable();
|
|
3123
|
+
};
|
|
3124
|
+
exitIcon.addEventListener('click', handleClick);
|
|
3125
|
+
exitIcon.addEventListener('mouseenter', onMouseEnter);
|
|
3126
|
+
exitIcon.addEventListener('mouseleave', onMouseLeave);
|
|
3127
|
+
return () => {
|
|
3128
|
+
exitIcon.removeEventListener('click', handleClick);
|
|
3129
|
+
exitIcon.removeEventListener('mouseenter', onMouseEnter);
|
|
3130
|
+
exitIcon.removeEventListener('mouseleave', onMouseLeave);
|
|
3131
|
+
};
|
|
3132
|
+
}
|
|
3133
|
+
});
|
|
3134
|
+
this.measureController = measureController;
|
|
3135
|
+
this.mode = ((_a = params.openParams) === null || _a === void 0 ? void 0 : _a.isMobile) ? 'mobile' : 'pc';
|
|
3136
|
+
this.container = document.createElement('div');
|
|
3137
|
+
this.container.innerHTML = ((_b = params.openParams) === null || _b === void 0 ? void 0 : _b.isMobile) ? mobileHTMLString : htmlString$1;
|
|
3138
|
+
this.container.classList.add('fpm__ui-controller', this.mode);
|
|
3139
|
+
params.container.appendChild(this.container);
|
|
3140
|
+
const textDoms = this.container.querySelectorAll('.fpm__text');
|
|
3141
|
+
const UIItems = this.container.querySelectorAll('.fpm__ui-item');
|
|
3142
|
+
const bgDom = this.container.querySelector('.fpm_ui-bg');
|
|
3143
|
+
const operatingSpaceDom = this.container.querySelector('.fpm_operating-space');
|
|
3144
|
+
Object.assign(bgDom === null || bgDom === void 0 ? void 0 : bgDom.style, controllerBackgroundStyle);
|
|
3145
|
+
Object.assign(operatingSpaceDom === null || operatingSpaceDom === void 0 ? void 0 : operatingSpaceDom.style, operatingSpaceStyle);
|
|
3146
|
+
Object.assign(this.container.style, uiWrapperStyle);
|
|
3147
|
+
UIItems.forEach((item) => Object.assign(item.style, buttonGroupStyle));
|
|
3148
|
+
textDoms.forEach((item) => Object.assign(item.style, textStyle));
|
|
3149
|
+
}
|
|
3150
|
+
dispose() {
|
|
3151
|
+
this.hide();
|
|
3152
|
+
this.container.remove();
|
|
3153
|
+
}
|
|
3154
|
+
show() {
|
|
3155
|
+
this.container.style.display = 'block';
|
|
3156
|
+
this.container.style.opacity = '1';
|
|
3157
|
+
this.container.style.transform = 'translate(0, 0)';
|
|
3158
|
+
if (this.mode === 'pc') {
|
|
3159
|
+
this.revoke = new Revoke(this.measureController, this.container);
|
|
3160
|
+
this.mainController = new MainBtnController(this.measureController, this.container);
|
|
3161
|
+
}
|
|
3162
|
+
else {
|
|
3163
|
+
this.mainController = new NewMainBtnController(this.measureController, this.container);
|
|
3164
|
+
}
|
|
3165
|
+
this.disposers.push(this.handleExit());
|
|
3166
|
+
return this;
|
|
3167
|
+
}
|
|
3168
|
+
hide() {
|
|
3169
|
+
var _a, _b;
|
|
3170
|
+
this.container.style.display = 'none';
|
|
3171
|
+
this.container.style.opacity = '0';
|
|
3172
|
+
this.container.style.transform = 'translate(0, 10px)';
|
|
3173
|
+
this.mode === 'pc' && ((_a = this.revoke) === null || _a === void 0 ? void 0 : _a.dispose());
|
|
3174
|
+
(_b = this.mainController) === null || _b === void 0 ? void 0 : _b.dispose();
|
|
3175
|
+
this.disposers.forEach((disposer) => disposer());
|
|
3176
|
+
this.disposers = [];
|
|
3177
|
+
return this;
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3181
|
+
class GuideController {
|
|
3182
|
+
constructor(measureController, params) {
|
|
3183
|
+
Object.defineProperty(this, "measureController", {
|
|
3184
|
+
enumerable: true,
|
|
3185
|
+
configurable: true,
|
|
3186
|
+
writable: true,
|
|
3187
|
+
value: void 0
|
|
3188
|
+
});
|
|
3189
|
+
Object.defineProperty(this, "textDom", {
|
|
3190
|
+
enumerable: true,
|
|
3191
|
+
configurable: true,
|
|
3192
|
+
writable: true,
|
|
3193
|
+
value: document.createElement('span')
|
|
3194
|
+
});
|
|
3195
|
+
Object.defineProperty(this, "container", {
|
|
3196
|
+
enumerable: true,
|
|
3197
|
+
configurable: true,
|
|
3198
|
+
writable: true,
|
|
3199
|
+
value: document.createElement('div')
|
|
3200
|
+
});
|
|
3201
|
+
Object.defineProperty(this, "hasAnchor", {
|
|
3202
|
+
enumerable: true,
|
|
3203
|
+
configurable: true,
|
|
3204
|
+
writable: true,
|
|
3205
|
+
value: false
|
|
3206
|
+
});
|
|
3207
|
+
Object.defineProperty(this, "onModelChange", {
|
|
3208
|
+
enumerable: true,
|
|
3209
|
+
configurable: true,
|
|
3210
|
+
writable: true,
|
|
3211
|
+
value: (mode) => {
|
|
3212
|
+
if (mode === 'Watch') {
|
|
3213
|
+
this.textDom.innerText = ``;
|
|
3214
|
+
return;
|
|
3215
|
+
}
|
|
3216
|
+
this.textDom.innerText = `请选择第一个测量点,Esc或单击鼠标右键可取消选择`;
|
|
3217
|
+
}
|
|
3218
|
+
});
|
|
3219
|
+
Object.defineProperty(this, "anchorChange", {
|
|
3220
|
+
enumerable: true,
|
|
3221
|
+
configurable: true,
|
|
3222
|
+
writable: true,
|
|
3223
|
+
value: (anchor) => {
|
|
3224
|
+
if (!this.hasAnchor && !!anchor) {
|
|
3225
|
+
this.hasAnchor = true;
|
|
3226
|
+
this.textDom.innerText = `选择下一个测量点,Esc或单击鼠标右键取消选择`;
|
|
3227
|
+
}
|
|
3228
|
+
else if (!anchor) {
|
|
3229
|
+
this.hasAnchor = false;
|
|
3230
|
+
this.textDom.innerText = `请选择第一个测量点,Esc或单击鼠标右键可取消选择`;
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
});
|
|
3234
|
+
Object.defineProperty(this, "onEditedLineChange", {
|
|
3235
|
+
enumerable: true,
|
|
3236
|
+
configurable: true,
|
|
3237
|
+
writable: true,
|
|
3238
|
+
value: (lines) => {
|
|
3239
|
+
if (lines.length === 1) {
|
|
3240
|
+
this.textDom.innerText = `可以连续选择测量点,或点击下方“完成”结束测量(Esc取消,Command+S保存)`;
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
});
|
|
3244
|
+
this.initDom();
|
|
3245
|
+
params.container.append(this.container);
|
|
3246
|
+
this.measureController = measureController;
|
|
3247
|
+
measureController.hook.on('modeChange', this.onModelChange);
|
|
3248
|
+
measureController.hook.on('anchorChange', this.anchorChange);
|
|
3249
|
+
measureController.hook.on('editedLineChange', this.onEditedLineChange);
|
|
3250
|
+
}
|
|
3251
|
+
dispose() {
|
|
3252
|
+
this.hide();
|
|
3253
|
+
this.container.remove();
|
|
3254
|
+
}
|
|
3255
|
+
show() {
|
|
3256
|
+
this.container.style.opacity = '1';
|
|
3257
|
+
this.container.style.transform = 'translate(0, 0)';
|
|
3258
|
+
return this;
|
|
3259
|
+
}
|
|
3260
|
+
hide() {
|
|
3261
|
+
this.container.style.opacity = '0';
|
|
3262
|
+
this.container.style.transform = 'translate(0, -10px)';
|
|
3263
|
+
this.measureController.hook.off('modeChange', this.onModelChange);
|
|
3264
|
+
this.measureController.hook.off('anchorChange', this.anchorChange);
|
|
3265
|
+
this.measureController.hook.off('editedLineChange', this.onEditedLineChange);
|
|
3266
|
+
return this;
|
|
3267
|
+
}
|
|
3268
|
+
initDom() {
|
|
3269
|
+
const container = this.container;
|
|
3270
|
+
const textDom = this.textDom;
|
|
3271
|
+
container.classList.add('fpm__guide-container');
|
|
3272
|
+
container.style.position = 'absolute';
|
|
3273
|
+
container.style.top = '0px';
|
|
3274
|
+
container.style.left = '0px';
|
|
3275
|
+
container.style.width = '100%';
|
|
3276
|
+
container.style.height = '110px';
|
|
3277
|
+
container.style.display = 'flex';
|
|
3278
|
+
container.style.alignItems = 'center';
|
|
3279
|
+
container.style.justifyContent = 'center';
|
|
3280
|
+
container.style.transform = 'translate(0, -10px)';
|
|
3281
|
+
container.style.background = `linear-gradient(180deg, rgba(0,0,0,0.40) 0%, rgba(0,0,0,0.00) 100%)`;
|
|
3282
|
+
container.style.transition = 'opacity 500ms ease-in-out, transform 500ms ease-in-out';
|
|
3283
|
+
container.style.opacity = '0';
|
|
3284
|
+
textDom.classList.add('fpm__guide-text');
|
|
3285
|
+
textDom.style.color = '#fff';
|
|
3286
|
+
textDom.style.fontSize = '20px';
|
|
3287
|
+
textDom.innerText = `点击下方“添加”开始测距`;
|
|
3288
|
+
container.appendChild(textDom);
|
|
3289
|
+
}
|
|
3290
|
+
}
|
|
3291
|
+
|
|
3292
|
+
/** 快捷键控制器 */
|
|
3293
|
+
class ShortcutKeyController {
|
|
3294
|
+
constructor(measureController, five) {
|
|
3295
|
+
Object.defineProperty(this, "five", {
|
|
3296
|
+
enumerable: true,
|
|
3297
|
+
configurable: true,
|
|
3298
|
+
writable: true,
|
|
3299
|
+
value: void 0
|
|
3300
|
+
});
|
|
3301
|
+
Object.defineProperty(this, "measureController", {
|
|
3302
|
+
enumerable: true,
|
|
3303
|
+
configurable: true,
|
|
3304
|
+
writable: true,
|
|
3305
|
+
value: void 0
|
|
3306
|
+
});
|
|
3307
|
+
Object.defineProperty(this, "onKeyDown", {
|
|
3308
|
+
enumerable: true,
|
|
3309
|
+
configurable: true,
|
|
3310
|
+
writable: true,
|
|
3311
|
+
value: (e) => {
|
|
3312
|
+
// Command + S -> 保存 & 更改场景
|
|
3313
|
+
if (e.metaKey && e.code === 'KeyS') {
|
|
3314
|
+
this.measureController.save().changeMode('Watch');
|
|
3315
|
+
e.preventDefault();
|
|
3316
|
+
return;
|
|
3317
|
+
}
|
|
3318
|
+
// Escape -> 切换到观察模式 / 如果已经在观察模式,退出功能
|
|
3319
|
+
if (e.code === 'Escape')
|
|
3320
|
+
return this.escape();
|
|
3321
|
+
}
|
|
3322
|
+
});
|
|
3323
|
+
Object.defineProperty(this, "onMouseDown", {
|
|
3324
|
+
enumerable: true,
|
|
3325
|
+
configurable: true,
|
|
3326
|
+
writable: true,
|
|
3327
|
+
value: (e) => {
|
|
3328
|
+
// 鼠标右键取消
|
|
3329
|
+
if (e.button !== 2)
|
|
3330
|
+
return;
|
|
3331
|
+
e.preventDefault();
|
|
3332
|
+
this.escape();
|
|
3333
|
+
}
|
|
3334
|
+
});
|
|
3335
|
+
this.five = five;
|
|
3336
|
+
this.measureController = measureController;
|
|
3337
|
+
const fiveElement = this.five.getElement();
|
|
3338
|
+
if (!fiveElement)
|
|
3339
|
+
return;
|
|
3340
|
+
document.body.addEventListener('keydown', this.onKeyDown);
|
|
3341
|
+
fiveElement.addEventListener('mousedown', this.onMouseDown);
|
|
3342
|
+
}
|
|
3343
|
+
dispose() {
|
|
3344
|
+
const fiveElement = this.five.getElement();
|
|
3345
|
+
if (!fiveElement)
|
|
3346
|
+
return;
|
|
3347
|
+
document.body.removeEventListener('keydown', this.onKeyDown);
|
|
3348
|
+
fiveElement.removeEventListener('mousedown', this.onMouseDown);
|
|
3349
|
+
}
|
|
3350
|
+
escape() {
|
|
3351
|
+
if (this.measureController.getCurrentMode() === 'Watch')
|
|
3352
|
+
return this.measureController.disable();
|
|
3353
|
+
return this.measureController.changeMode('Watch');
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
|
|
3357
|
+
const rangePieceImg = 'data:image/png;base64,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';
|
|
3358
|
+
const rangePieceIntersectImg = 'data:image/png;base64,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';
|
|
3359
|
+
var htmlString = `
|
|
3360
|
+
<style>
|
|
3361
|
+
.range-piece__container {
|
|
3362
|
+
position: absolute;
|
|
3363
|
+
top: 39%;
|
|
3364
|
+
left: 50%;
|
|
3365
|
+
margin-left: -54px;
|
|
3366
|
+
width: 108px;
|
|
3367
|
+
height: 108px;
|
|
3368
|
+
display: flex;
|
|
3369
|
+
align-items: center;
|
|
3370
|
+
justify-content: center;
|
|
3371
|
+
animation: pieceContainer 0.3s ease-in-out;
|
|
3372
|
+
animation-fill-mode: forwards;
|
|
3373
|
+
}
|
|
3374
|
+
.range-piece__content {
|
|
3375
|
+
width: 100%;
|
|
3376
|
+
height: 100%;
|
|
3377
|
+
background-image: url(${rangePieceImg});
|
|
3378
|
+
opacity: 0.4;
|
|
3379
|
+
background-size: 100%;
|
|
3380
|
+
background-repeat: no-repeat;
|
|
3381
|
+
transition: linear transform 0.1s;
|
|
3382
|
+
}
|
|
3383
|
+
.range-piece__content--active {
|
|
3384
|
+
animation: dotting ease-in-out 0.5s;
|
|
3385
|
+
}
|
|
3386
|
+
.range-piece__aim {
|
|
3387
|
+
width: 100%;
|
|
3388
|
+
height: 100%;
|
|
3389
|
+
opacity: 1;
|
|
3390
|
+
position: absolute;
|
|
3391
|
+
background: url(${rangePieceIntersectImg}) center / contain no-repeat;
|
|
3392
|
+
}
|
|
3393
|
+
@keyframes dotting {
|
|
3394
|
+
0% {
|
|
3395
|
+
opacity: 0.4;
|
|
3396
|
+
transform: scale(1);
|
|
3397
|
+
}
|
|
3398
|
+
50% {
|
|
3399
|
+
opacity: 1;
|
|
3400
|
+
transform: scale(0.8);
|
|
3401
|
+
}
|
|
3402
|
+
100% {
|
|
3403
|
+
opacity: 0.4;
|
|
3404
|
+
transform: scale(1);
|
|
3405
|
+
}
|
|
3406
|
+
}
|
|
3407
|
+
@keyframes pieceContainer {
|
|
3408
|
+
from {
|
|
3409
|
+
top: 49%;
|
|
3410
|
+
}
|
|
3411
|
+
to {
|
|
3412
|
+
top: 39%;
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
</style>
|
|
3416
|
+
<div class="range-piece__container">
|
|
3417
|
+
<div class='range-piece__content'></div>
|
|
3418
|
+
<div class="range-piece__aim"></div>
|
|
3419
|
+
</div>
|
|
3420
|
+
`;
|
|
3421
|
+
|
|
3422
|
+
function noop() {
|
|
3423
|
+
return void 0;
|
|
3424
|
+
}
|
|
3425
|
+
|
|
3426
|
+
const { Vector2 } = THREE__namespace;
|
|
3427
|
+
/**
|
|
3428
|
+
* 计算 three 中的 mouse 的值
|
|
3429
|
+
* @param {{x:Number, y:Number}} mouseXY 鼠标相对屏幕位置
|
|
3430
|
+
* @param {Element} element canvas元素(three的展示元素)
|
|
3431
|
+
*/
|
|
3432
|
+
function calculateThreeMouse(mouseXY, element) {
|
|
3433
|
+
const { offsetWidth: width, offsetHeight: height } = element;
|
|
3434
|
+
const { top, left } = element.getBoundingClientRect();
|
|
3435
|
+
return Object.assign(new Vector2(), {
|
|
3436
|
+
x: ((mouseXY.x - left) / width) * 2 - 1,
|
|
3437
|
+
y: (-(mouseXY.y - top) / height) * 2 + 1,
|
|
3438
|
+
});
|
|
3439
|
+
}
|
|
3440
|
+
|
|
3441
|
+
class RangePieceController {
|
|
3442
|
+
// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility
|
|
3443
|
+
constructor(params) {
|
|
3444
|
+
Object.defineProperty(this, "container", {
|
|
3445
|
+
enumerable: true,
|
|
3446
|
+
configurable: true,
|
|
3447
|
+
writable: true,
|
|
3448
|
+
value: document.createElement('div')
|
|
3449
|
+
});
|
|
3450
|
+
Object.defineProperty(this, "five", {
|
|
3451
|
+
enumerable: true,
|
|
3452
|
+
configurable: true,
|
|
3453
|
+
writable: true,
|
|
3454
|
+
value: void 0
|
|
3455
|
+
});
|
|
3456
|
+
Object.defineProperty(this, "group", {
|
|
3457
|
+
enumerable: true,
|
|
3458
|
+
configurable: true,
|
|
3459
|
+
writable: true,
|
|
3460
|
+
value: void 0
|
|
3461
|
+
});
|
|
3462
|
+
Object.defineProperty(this, "mouseGroup", {
|
|
3463
|
+
enumerable: true,
|
|
3464
|
+
configurable: true,
|
|
3465
|
+
writable: true,
|
|
3466
|
+
value: void 0
|
|
3467
|
+
});
|
|
3468
|
+
Object.defineProperty(this, "hasAppendMouseGroup", {
|
|
3469
|
+
enumerable: true,
|
|
3470
|
+
configurable: true,
|
|
3471
|
+
writable: true,
|
|
3472
|
+
value: false
|
|
3473
|
+
});
|
|
3474
|
+
Object.defineProperty(this, "fiveHelper", {
|
|
3475
|
+
enumerable: true,
|
|
3476
|
+
configurable: true,
|
|
3477
|
+
writable: true,
|
|
3478
|
+
value: void 0
|
|
3479
|
+
});
|
|
3480
|
+
Object.defineProperty(this, "hook", {
|
|
3481
|
+
enumerable: true,
|
|
3482
|
+
configurable: true,
|
|
3483
|
+
writable: true,
|
|
3484
|
+
value: void 0
|
|
3485
|
+
});
|
|
3486
|
+
Object.defineProperty(this, "content", {
|
|
3487
|
+
enumerable: true,
|
|
3488
|
+
configurable: true,
|
|
3489
|
+
writable: true,
|
|
3490
|
+
value: void 0
|
|
3491
|
+
});
|
|
3492
|
+
Object.defineProperty(this, "intersectMesh", {
|
|
3493
|
+
enumerable: true,
|
|
3494
|
+
configurable: true,
|
|
3495
|
+
writable: true,
|
|
3496
|
+
value: void 0
|
|
3497
|
+
});
|
|
3498
|
+
Object.defineProperty(this, "centerMouseXY", {
|
|
3499
|
+
enumerable: true,
|
|
3500
|
+
configurable: true,
|
|
3501
|
+
writable: true,
|
|
3502
|
+
value: void 0
|
|
3503
|
+
});
|
|
3504
|
+
Object.defineProperty(this, "raycaster", {
|
|
3505
|
+
enumerable: true,
|
|
3506
|
+
configurable: true,
|
|
3507
|
+
writable: true,
|
|
3508
|
+
value: new THREE.Raycaster()
|
|
3509
|
+
});
|
|
3510
|
+
Object.defineProperty(this, "pieceStyl", {
|
|
3511
|
+
enumerable: true,
|
|
3512
|
+
configurable: true,
|
|
3513
|
+
writable: true,
|
|
3514
|
+
value: {
|
|
3515
|
+
matrix3d: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
|
|
3516
|
+
scale: 1,
|
|
3517
|
+
opacity: 0.4,
|
|
3518
|
+
}
|
|
3519
|
+
});
|
|
3520
|
+
Object.defineProperty(this, "onCameraDirectionUpdate", {
|
|
3521
|
+
enumerable: true,
|
|
3522
|
+
configurable: true,
|
|
3523
|
+
writable: true,
|
|
3524
|
+
value: () => {
|
|
3525
|
+
const intersection = this.getIntersection();
|
|
3526
|
+
if (intersection) {
|
|
3527
|
+
this.pieceChange(intersection);
|
|
3528
|
+
this.updateMouseGroup(intersection);
|
|
3529
|
+
const nowPoint = new Point(this.mouseGroup.position);
|
|
3530
|
+
this.hook.emit('nowPointChange', nowPoint);
|
|
3531
|
+
}
|
|
3532
|
+
}
|
|
3533
|
+
});
|
|
3534
|
+
Object.defineProperty(this, "onWillChangeState", {
|
|
3535
|
+
enumerable: true,
|
|
3536
|
+
configurable: true,
|
|
3537
|
+
writable: true,
|
|
3538
|
+
value: (state, newState) => {
|
|
3539
|
+
var _a;
|
|
3540
|
+
this.dotAnimation();
|
|
3541
|
+
const point = (_a = this.getIntersection()) === null || _a === void 0 ? void 0 : _a.point;
|
|
3542
|
+
if (!point)
|
|
3543
|
+
return;
|
|
3544
|
+
if (newState === 'editing') {
|
|
3545
|
+
this.hook.emit('getStartPoint', new Point(point));
|
|
3546
|
+
}
|
|
3547
|
+
else {
|
|
3548
|
+
this.hook.emit('getEndPoint', new Point(point));
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
});
|
|
3552
|
+
/** 计算目标中心点经纬度 */
|
|
3553
|
+
Object.defineProperty(this, "computedCenterMouseXY", {
|
|
3554
|
+
enumerable: true,
|
|
3555
|
+
configurable: true,
|
|
3556
|
+
writable: true,
|
|
3557
|
+
value: () => {
|
|
3558
|
+
const aimRef = this.container.querySelector('.range-piece__aim');
|
|
3559
|
+
if (!aimRef)
|
|
3560
|
+
return null;
|
|
3561
|
+
const { left, top, width, height } = aimRef.getBoundingClientRect();
|
|
3562
|
+
const mouseX = Math.round(left + width / 2);
|
|
3563
|
+
const mouseY = Math.round(top + height / 2);
|
|
3564
|
+
const mouse = { x: mouseX, y: mouseY };
|
|
3565
|
+
const mouseXY = calculateThreeMouse(mouse, this.five.getElement()); // 经纬度
|
|
3566
|
+
this.centerMouseXY = mouseXY;
|
|
3567
|
+
}
|
|
3568
|
+
});
|
|
3569
|
+
/** 计算目标中心点intersection */
|
|
3570
|
+
Object.defineProperty(this, "getIntersection", {
|
|
3571
|
+
enumerable: true,
|
|
3572
|
+
configurable: true,
|
|
3573
|
+
writable: true,
|
|
3574
|
+
value: () => {
|
|
3575
|
+
if (!this.centerMouseXY)
|
|
3576
|
+
return null;
|
|
3577
|
+
this.raycaster.setFromCamera(this.centerMouseXY, this.five.camera);
|
|
3578
|
+
const intersection = this.five.model.intersectRaycaster(this.raycaster)[0];
|
|
3579
|
+
if (intersection)
|
|
3580
|
+
return intersection;
|
|
3581
|
+
else
|
|
3582
|
+
return null;
|
|
3583
|
+
}
|
|
3584
|
+
});
|
|
3585
|
+
this.five = params.five;
|
|
3586
|
+
this.hook = params.hook;
|
|
3587
|
+
this.group = params.group;
|
|
3588
|
+
this.mouseGroup = getMouseGroup();
|
|
3589
|
+
this.fiveHelper = params.fiveHelper;
|
|
3590
|
+
this.container.innerHTML = htmlString;
|
|
3591
|
+
this.container.classList.add('range-piece-controller');
|
|
3592
|
+
this.content = this.container.querySelector('.range-piece__content');
|
|
3593
|
+
if (this.content) {
|
|
3594
|
+
this.content.style.transform = `matrix3d(${this.pieceStyl.matrix3d.toString()}) scale(${this.pieceStyl.scale})`;
|
|
3595
|
+
this.content.style.opacity = `${this.pieceStyl.opacity}`;
|
|
3596
|
+
}
|
|
3597
|
+
params.container.append(this.container);
|
|
3598
|
+
this.intersectMesh = new THREE.Mesh(new THREE.RingGeometry(0.04, 0.08, 32), new THREE.MeshBasicMaterial({ color: 0x12fffb, opacity: 0, side: THREE.DoubleSide, transparent: true }));
|
|
3599
|
+
this.container.addEventListener('animationend', this.computedCenterMouseXY);
|
|
3600
|
+
this.five.on('cameraUpdate', this.onCameraDirectionUpdate);
|
|
3601
|
+
this.hook.on('willChangeState', this.onWillChangeState);
|
|
3602
|
+
}
|
|
3603
|
+
dispose() {
|
|
3604
|
+
this.container.removeEventListener('animationend', this.computedCenterMouseXY);
|
|
3605
|
+
this.five.off('cameraUpdate', this.onCameraDirectionUpdate);
|
|
3606
|
+
this.hook.off('willChangeState', this.onWillChangeState);
|
|
3607
|
+
this.container.remove();
|
|
3608
|
+
this.group.remove(this.mouseGroup);
|
|
3609
|
+
this.mouseGroup.remove();
|
|
3610
|
+
this.hasAppendMouseGroup = false;
|
|
3611
|
+
this.five.scene.remove(this.intersectMesh);
|
|
3612
|
+
}
|
|
3613
|
+
pieceChange(intersection) {
|
|
3614
|
+
const face = intersection.face;
|
|
3615
|
+
const point = intersection.point;
|
|
3616
|
+
if (face && point) {
|
|
3617
|
+
const normal = face.normal.clone();
|
|
3618
|
+
const positionVector = normal.clone().multiplyScalar(0.05);
|
|
3619
|
+
const position = point.clone().add(positionVector);
|
|
3620
|
+
this.intersectMesh.position.copy(position);
|
|
3621
|
+
const lookAtVector = position.clone().add(positionVector);
|
|
3622
|
+
this.intersectMesh.lookAt(lookAtVector);
|
|
3623
|
+
this.five.scene.add(this.intersectMesh);
|
|
3624
|
+
const matrix = this.intersectMesh.modelViewMatrix.clone().toArray();
|
|
3625
|
+
this.changePieceStyl('matrix3d', matrix);
|
|
3626
|
+
const scale = this.calculateSize(point);
|
|
3627
|
+
this.changePieceStyl('scale', scale);
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
calculateSize(vector) {
|
|
3631
|
+
if (!vector)
|
|
3632
|
+
return;
|
|
3633
|
+
const cameraPos = this.five.camera.position;
|
|
3634
|
+
let distance = vector.distanceTo(cameraPos);
|
|
3635
|
+
const maxDis = 4;
|
|
3636
|
+
const minDis = 1;
|
|
3637
|
+
if (distance > maxDis)
|
|
3638
|
+
distance = maxDis;
|
|
3639
|
+
if (distance < minDis)
|
|
3640
|
+
distance = minDis;
|
|
3641
|
+
const scale = (-0.51 / (maxDis - minDis)) * distance + 1;
|
|
3642
|
+
return scale;
|
|
3643
|
+
}
|
|
3644
|
+
/** 点击按钮时圆片动画 */
|
|
3645
|
+
dotAnimation() {
|
|
3646
|
+
const firstEasing = TWEEN__default["default"].Easing.Quadratic.InOut;
|
|
3647
|
+
const from = { opacity: 0.4, scale: this.pieceStyl.scale };
|
|
3648
|
+
const to = { opacity: [1, 0.4], scale: [this.pieceStyl.scale * 0.8, this.pieceStyl.scale] };
|
|
3649
|
+
let stop = noop;
|
|
3650
|
+
const firstTween = new TWEEN__default["default"].Tween(from)
|
|
3651
|
+
.to(to, 500)
|
|
3652
|
+
.easing(firstEasing)
|
|
3653
|
+
.start(0)
|
|
3654
|
+
.onUpdate(({ opacity, scale }) => {
|
|
3655
|
+
this.changePieceStyl('scale', scale);
|
|
3656
|
+
this.changePieceStyl('opacity', opacity);
|
|
3657
|
+
})
|
|
3658
|
+
.onComplete(() => {
|
|
3659
|
+
stop();
|
|
3660
|
+
});
|
|
3661
|
+
stop = requestAnimationFrameInterval((time) => {
|
|
3662
|
+
firstTween.update(time);
|
|
3663
|
+
});
|
|
3664
|
+
}
|
|
3665
|
+
changePieceStyl(key, value) {
|
|
3666
|
+
if (!this.content)
|
|
3667
|
+
return;
|
|
3668
|
+
this.pieceStyl[key] = value;
|
|
3669
|
+
this.content.style.transform = `matrix3d(${this.pieceStyl.matrix3d.toString()}) scale(${this.pieceStyl.scale})`;
|
|
3670
|
+
this.content.style.opacity = `${this.pieceStyl.opacity}`;
|
|
3671
|
+
}
|
|
3672
|
+
updateMouseGroup(intersection, mesh) {
|
|
3673
|
+
if (!this.hasAppendMouseGroup) {
|
|
3674
|
+
this.group.add(this.mouseGroup);
|
|
3675
|
+
this.hasAppendMouseGroup = true;
|
|
3676
|
+
const aimRef = this.container.querySelector('.range-piece__aim');
|
|
3677
|
+
if (aimRef)
|
|
3678
|
+
aimRef.style.opacity = '0';
|
|
3679
|
+
}
|
|
3680
|
+
if (!intersection)
|
|
3681
|
+
return this.mouseGroup;
|
|
3682
|
+
this.mouseGroup.position.copy(intersection.point);
|
|
3683
|
+
// ============ update mouseGroup quaternion ============
|
|
3684
|
+
if (mesh) {
|
|
3685
|
+
this.mouseGroup.quaternion.copy(mesh.quaternion);
|
|
3686
|
+
}
|
|
3687
|
+
else if (intersection.face) {
|
|
3688
|
+
const normal = intersection.face.normal;
|
|
3689
|
+
const positionVector = normal.clone().multiplyScalar(0.05);
|
|
3690
|
+
const position = intersection.point.clone().add(positionVector);
|
|
3691
|
+
const lookAtVector = position.clone().add(positionVector);
|
|
3692
|
+
this.mouseGroup.lookAt(lookAtVector);
|
|
3693
|
+
}
|
|
3694
|
+
return this.mouseGroup;
|
|
3695
|
+
}
|
|
3696
|
+
}
|
|
3697
|
+
|
|
3698
|
+
class MeasureController {
|
|
3699
|
+
constructor(five$1, params) {
|
|
3700
|
+
var _a, _b;
|
|
3701
|
+
Object.defineProperty(this, "hasOpen", {
|
|
3702
|
+
enumerable: true,
|
|
3703
|
+
configurable: true,
|
|
3704
|
+
writable: true,
|
|
3705
|
+
value: false
|
|
3706
|
+
});
|
|
3707
|
+
Object.defineProperty(this, "hook", {
|
|
3708
|
+
enumerable: true,
|
|
3709
|
+
configurable: true,
|
|
3710
|
+
writable: true,
|
|
3711
|
+
value: new five.Subscribe()
|
|
3712
|
+
});
|
|
3713
|
+
Object.defineProperty(this, "magnifier", {
|
|
3714
|
+
enumerable: true,
|
|
3715
|
+
configurable: true,
|
|
3716
|
+
writable: true,
|
|
3717
|
+
value: void 0
|
|
3718
|
+
});
|
|
3719
|
+
Object.defineProperty(this, "five", {
|
|
3720
|
+
enumerable: true,
|
|
3721
|
+
configurable: true,
|
|
3722
|
+
writable: true,
|
|
3723
|
+
value: void 0
|
|
3724
|
+
});
|
|
3725
|
+
Object.defineProperty(this, "model", {
|
|
3726
|
+
enumerable: true,
|
|
3727
|
+
configurable: true,
|
|
3728
|
+
writable: true,
|
|
3729
|
+
value: void 0
|
|
3730
|
+
});
|
|
3731
|
+
Object.defineProperty(this, "group", {
|
|
3732
|
+
enumerable: true,
|
|
3733
|
+
configurable: true,
|
|
3734
|
+
writable: true,
|
|
3735
|
+
value: void 0
|
|
3736
|
+
});
|
|
3737
|
+
Object.defineProperty(this, "fiveHelper", {
|
|
3738
|
+
enumerable: true,
|
|
3739
|
+
configurable: true,
|
|
3740
|
+
writable: true,
|
|
3741
|
+
value: void 0
|
|
3742
|
+
});
|
|
3743
|
+
Object.defineProperty(this, "useUIController", {
|
|
3744
|
+
enumerable: true,
|
|
3745
|
+
configurable: true,
|
|
3746
|
+
writable: true,
|
|
3747
|
+
value: void 0
|
|
3748
|
+
});
|
|
3749
|
+
Object.defineProperty(this, "params", {
|
|
3750
|
+
enumerable: true,
|
|
3751
|
+
configurable: true,
|
|
3752
|
+
writable: true,
|
|
3753
|
+
value: void 0
|
|
3754
|
+
});
|
|
3755
|
+
Object.defineProperty(this, "useGuideController", {
|
|
3756
|
+
enumerable: true,
|
|
3757
|
+
configurable: true,
|
|
3758
|
+
writable: true,
|
|
3759
|
+
value: void 0
|
|
3760
|
+
});
|
|
3761
|
+
Object.defineProperty(this, "rangePieceController", {
|
|
3762
|
+
enumerable: true,
|
|
3763
|
+
configurable: true,
|
|
3764
|
+
writable: true,
|
|
3765
|
+
value: void 0
|
|
3766
|
+
});
|
|
3767
|
+
Object.defineProperty(this, "container", {
|
|
3768
|
+
enumerable: true,
|
|
3769
|
+
configurable: true,
|
|
3770
|
+
writable: true,
|
|
3771
|
+
value: document.createElement('div')
|
|
3772
|
+
});
|
|
3773
|
+
Object.defineProperty(this, "shortcutKeyController", {
|
|
3774
|
+
enumerable: true,
|
|
3775
|
+
configurable: true,
|
|
3776
|
+
writable: true,
|
|
3777
|
+
value: void 0
|
|
3778
|
+
});
|
|
3779
|
+
Object.defineProperty(this, "controller", {
|
|
3780
|
+
enumerable: true,
|
|
3781
|
+
configurable: true,
|
|
3782
|
+
writable: true,
|
|
3783
|
+
value: null
|
|
3784
|
+
});
|
|
3785
|
+
Object.defineProperty(this, "controllerParams", {
|
|
3786
|
+
enumerable: true,
|
|
3787
|
+
configurable: true,
|
|
3788
|
+
writable: true,
|
|
3789
|
+
value: void 0
|
|
3790
|
+
});
|
|
3791
|
+
Object.defineProperty(this, "getCurrentMode", {
|
|
3792
|
+
enumerable: true,
|
|
3793
|
+
configurable: true,
|
|
3794
|
+
writable: true,
|
|
3795
|
+
value: () => {
|
|
3796
|
+
if (this.controller instanceof EditController)
|
|
3797
|
+
return 'Edit';
|
|
3798
|
+
if (this.controller instanceof WatchController)
|
|
3799
|
+
return 'Watch';
|
|
3800
|
+
if (this.controller instanceof MixedController)
|
|
3801
|
+
return 'Mixed';
|
|
3802
|
+
return null;
|
|
3803
|
+
}
|
|
3804
|
+
});
|
|
3805
|
+
/** 变更场景
|
|
3806
|
+
* @description 如果从编辑场景改变到观看场景,不会自动保存,默认丢弃所有改动
|
|
3807
|
+
*/
|
|
3808
|
+
Object.defineProperty(this, "changeMode", {
|
|
3809
|
+
enumerable: true,
|
|
3810
|
+
configurable: true,
|
|
3811
|
+
writable: true,
|
|
3812
|
+
value: (mode) => {
|
|
3813
|
+
var _a;
|
|
3814
|
+
if (!this.hasOpen)
|
|
3815
|
+
return;
|
|
3816
|
+
if (this.getCurrentMode() === mode)
|
|
3817
|
+
return;
|
|
3818
|
+
// 不支持Mixed模式与其他模式切换
|
|
3819
|
+
if (this.getCurrentMode() === 'Mixed' || mode === 'Mixed')
|
|
3820
|
+
return new Error('不支持切换的Mode');
|
|
3821
|
+
(_a = this.controller) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
3822
|
+
const controllerMap = {
|
|
3823
|
+
Watch: WatchController,
|
|
3824
|
+
Edit: EditController,
|
|
3825
|
+
};
|
|
3826
|
+
if (!controllerMap[mode])
|
|
3827
|
+
throw new Error('不存在的 Mode');
|
|
3828
|
+
this.controller = new controllerMap[mode](this.controllerParams);
|
|
3829
|
+
this.hook.emit('modeChange', mode);
|
|
3830
|
+
}
|
|
3831
|
+
});
|
|
3832
|
+
this.five = five$1;
|
|
3833
|
+
this.params = params;
|
|
3834
|
+
this.model = new Model({ userDistanceItemCreator: this.params.userDistanceItemCreator });
|
|
3835
|
+
this.fiveHelper = new FiveHelper(five$1);
|
|
3836
|
+
// magnifier
|
|
3837
|
+
this.magnifier = new Magnifier(five$1, (_a = params.magnifierParams) !== null && _a !== void 0 ? _a : { width: 190, height: 190, scale: 2 });
|
|
3838
|
+
// ==================== Group ====================
|
|
3839
|
+
this.group = new THREE.Group();
|
|
3840
|
+
this.group.name = 'plugin-measure-group';
|
|
3841
|
+
this.container.classList.add('five-plugin-measure-container');
|
|
3842
|
+
this.container.style.position = 'relative';
|
|
3843
|
+
this.container.style.pointerEvents = 'none';
|
|
3844
|
+
this.container.style.width = '100%';
|
|
3845
|
+
this.container.style.height = '100%';
|
|
3846
|
+
this.container.style.opacity = '0';
|
|
3847
|
+
this.container.style.background = 'rgba(0, 0, 0, 0.15)';
|
|
3848
|
+
const openParams = (_b = this.params.openParams) !== null && _b !== void 0 ? _b : {};
|
|
3849
|
+
this.controllerParams = {
|
|
3850
|
+
five: this.five,
|
|
3851
|
+
hook: this.hook,
|
|
3852
|
+
group: this.group,
|
|
3853
|
+
model: this.model,
|
|
3854
|
+
magnifier: this.magnifier,
|
|
3855
|
+
container: this.container,
|
|
3856
|
+
fiveHelper: this.fiveHelper,
|
|
3857
|
+
openParams,
|
|
3858
|
+
mouseGroup: getMouseGroup(),
|
|
3859
|
+
userDistanceItemCreator: this.params.userDistanceItemCreator,
|
|
3860
|
+
};
|
|
3861
|
+
if (this.params.useUIController !== false)
|
|
3862
|
+
this.useUIController = new UIController(this, this.controllerParams);
|
|
3863
|
+
if (this.params.useGuideController !== false)
|
|
3864
|
+
this.useGuideController = new GuideController(this, this.controllerParams);
|
|
3865
|
+
}
|
|
3866
|
+
appendTo(parent) {
|
|
3867
|
+
// const intersect = new IntersectController(this.five)
|
|
3868
|
+
// intersect.appendTo(parent)
|
|
3869
|
+
parent.append(this.container);
|
|
3870
|
+
}
|
|
3871
|
+
dispose() {
|
|
3872
|
+
var _a, _b;
|
|
3873
|
+
this.disable();
|
|
3874
|
+
(_a = this.useUIController) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
3875
|
+
(_b = this.magnifier) === null || _b === void 0 ? void 0 : _b.dispose();
|
|
3876
|
+
this.five.needsRender = true;
|
|
3877
|
+
}
|
|
3878
|
+
/** 加载数据
|
|
3879
|
+
* @description 数据加载时会覆盖当前已保存的数据
|
|
3880
|
+
* @description 如果当前正在编辑中,会自动退出并保存编辑
|
|
3881
|
+
*/
|
|
3882
|
+
load(data) {
|
|
3883
|
+
this.model.parse(data);
|
|
3884
|
+
this.save();
|
|
3885
|
+
}
|
|
3886
|
+
/** 插件功能入口
|
|
3887
|
+
* @description 会隐藏鼠标的默认聚焦环
|
|
3888
|
+
* @description 会隐藏当前 VR 内的点位展示
|
|
3889
|
+
*/
|
|
3890
|
+
enable() {
|
|
3891
|
+
var _a, _b, _c;
|
|
3892
|
+
if (this.hasOpen)
|
|
3893
|
+
return;
|
|
3894
|
+
this.hasOpen = true;
|
|
3895
|
+
this.five.scene.add(this.group);
|
|
3896
|
+
// 修改透明度
|
|
3897
|
+
this.container.style.opacity = '1';
|
|
3898
|
+
if ((_a = this.params.openParams) === null || _a === void 0 ? void 0 : _a.isMobile) {
|
|
3899
|
+
this.controller = new MixedController(this.controllerParams);
|
|
3900
|
+
this.rangePieceController = new RangePieceController(this.controllerParams);
|
|
3901
|
+
}
|
|
3902
|
+
else {
|
|
3903
|
+
// 隐藏点位和鼠标聚焦环
|
|
3904
|
+
this.five.helperVisible = false;
|
|
3905
|
+
this.controller = new WatchController(this.controllerParams);
|
|
3906
|
+
}
|
|
3907
|
+
(_b = this.useUIController) === null || _b === void 0 ? void 0 : _b.show();
|
|
3908
|
+
(_c = this.useGuideController) === null || _c === void 0 ? void 0 : _c.show();
|
|
3909
|
+
this.shortcutKeyController = new ShortcutKeyController(this, this.five);
|
|
3910
|
+
this.hook.emit('enable', true);
|
|
3911
|
+
}
|
|
3912
|
+
/** 关闭插件功能
|
|
3913
|
+
* @description 清除标尺线条
|
|
3914
|
+
* @description 还原点位展示和默认鼠标 UI
|
|
3915
|
+
*/
|
|
3916
|
+
disable() {
|
|
3917
|
+
var _a, _b, _c, _d, _e;
|
|
3918
|
+
this.hasOpen = false;
|
|
3919
|
+
// 修改透明度
|
|
3920
|
+
this.container.style.opacity = '0';
|
|
3921
|
+
// 展示点位和鼠标聚焦环
|
|
3922
|
+
(_a = this.controller) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
3923
|
+
(_b = this.rangePieceController) === null || _b === void 0 ? void 0 : _b.dispose();
|
|
3924
|
+
(_c = this.useUIController) === null || _c === void 0 ? void 0 : _c.hide();
|
|
3925
|
+
(_d = this.useGuideController) === null || _d === void 0 ? void 0 : _d.hide();
|
|
3926
|
+
(_e = this.shortcutKeyController) === null || _e === void 0 ? void 0 : _e.dispose();
|
|
3927
|
+
this.controller = null;
|
|
3928
|
+
this.five.helperVisible = true;
|
|
3929
|
+
this.five.scene.remove(this.group);
|
|
3930
|
+
this.five.needsRender = true;
|
|
3931
|
+
this.hook.emit('disable', true);
|
|
3932
|
+
}
|
|
3933
|
+
/** 撤销编辑 */
|
|
3934
|
+
revoke() {
|
|
3935
|
+
if (!(this.controller instanceof EditController))
|
|
3936
|
+
return;
|
|
3937
|
+
this.controller.revoke();
|
|
3938
|
+
return;
|
|
3939
|
+
}
|
|
3940
|
+
removeLineByID(lineID) {
|
|
3941
|
+
this.model.removeLineByID(lineID);
|
|
3942
|
+
}
|
|
3943
|
+
/**
|
|
3944
|
+
* 高亮当前线段
|
|
3945
|
+
*/
|
|
3946
|
+
highlightLine(lineID) {
|
|
3947
|
+
if (this.getCurrentMode() !== 'Watch')
|
|
3948
|
+
return false;
|
|
3949
|
+
const line = this.model.getLineByID(lineID);
|
|
3950
|
+
if (!line)
|
|
3951
|
+
return false;
|
|
3952
|
+
this.controller.highlightLine(line);
|
|
3953
|
+
return true;
|
|
3954
|
+
}
|
|
3955
|
+
clearHighlightLines() {
|
|
3956
|
+
if (this.getCurrentMode() !== 'Watch')
|
|
3957
|
+
return false;
|
|
3958
|
+
this.controller.clearHighlightLines();
|
|
3959
|
+
return true;
|
|
3960
|
+
}
|
|
3961
|
+
/** 保存编辑 */
|
|
3962
|
+
save() {
|
|
3963
|
+
if (!(this.controller instanceof EditController))
|
|
3964
|
+
return this;
|
|
3965
|
+
this.model.mergeModel(this.controller.model);
|
|
3966
|
+
return this;
|
|
3967
|
+
}
|
|
3968
|
+
/** 把当前以保存的数据转换成 JSON 对象 */
|
|
3969
|
+
toJson() {
|
|
3970
|
+
return this.model.toJson();
|
|
3971
|
+
}
|
|
3972
|
+
/**
|
|
3973
|
+
* @description 改变插件的模式(pc端模式或移动端模式)
|
|
3974
|
+
* @param isMobile true为移动端模式,false为pc端
|
|
3975
|
+
*/
|
|
3976
|
+
changeIsMobile(isMobile) {
|
|
3977
|
+
var _a, _b;
|
|
3978
|
+
if (((_a = this.controllerParams.openParams) === null || _a === void 0 ? void 0 : _a.isMobile) === undefined) {
|
|
3979
|
+
this.controllerParams.openParams.isMobile = isMobile;
|
|
3980
|
+
}
|
|
3981
|
+
if (this.controllerParams.openParams.isMobile === isMobile)
|
|
3982
|
+
return;
|
|
3983
|
+
this.controllerParams.openParams.isMobile = isMobile;
|
|
3984
|
+
if (this.params.useUIController !== false)
|
|
3985
|
+
(_b = this.useUIController) === null || _b === void 0 ? void 0 : _b.dispose();
|
|
3986
|
+
this.useUIController = new UIController(this, this.controllerParams);
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
|
|
3990
|
+
const PanoMeasurePlugin = function PanoMeasurePlugin(five, params) {
|
|
3991
|
+
return new MeasureController(five, params);
|
|
3992
|
+
};
|
|
3993
|
+
|
|
3994
|
+
exports.Magnifier = Magnifier;
|
|
3995
|
+
exports.PanoMeasurePlugin = PanoMeasurePlugin;
|
|
3996
|
+
exports["default"] = PanoMeasurePlugin;
|