Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
alxart committed Mar 25, 2024
1 parent 0a007f6 commit 6107623
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 58 deletions.
8 changes: 4 additions & 4 deletions demo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { REALTY_SCENE, REALTY_SCENE_1 } from './mocks';
let isDarkTheme = false;

async function start() {
const mapglAPI = await load('https://mapgl.2gis.com/api/js/v0.0.322');
const mapglAPI = await load('https://mapgl.2gis.com/api/js/v0.0.323');

const map = new mapglAPI.Map('container', {
center: [47.245286302641034, 56.134743473834099],
Expand All @@ -20,7 +20,7 @@ async function start() {
(window as any).map = map;

const plugin = new GltfPlugin(map, {
modelsLoadStrategy: 'waitAll',
modelsLoadStrategy: 'dontWaitAll',
modelsBaseUrl: 'https://disk.2gis.com/digital-twin/models_s3/realty_ads/zgktechnology/',
floorsControl: { position: 'centerRight' },
poiConfig: {
Expand All @@ -31,8 +31,8 @@ async function start() {
fontSize: 14,
},
},
hoverHighlight: {
intencity: 0.1,
hoverOptions: {
color: '#FFEFEF',
},
groundCoveringColor: 'rgba(0, 0, 0, 0.8)',
});
Expand Down
3 changes: 1 addition & 2 deletions src/defaultOptions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { PluginOptions } from './types/plugin';

export const defaultOptions: Required<PluginOptions> = {
hoverHighlight: {
hoverOptions: {
color: '#ffffff',
intencity: 0.0,
},
modelsBaseUrl: '',
modelsLoadStrategy: 'waitAll',
Expand Down
23 changes: 19 additions & 4 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import { concatUrl, isAbsoluteUrl } from './utils/url';
import { createModelEventData } from './utils/events';
import { RealtyScene } from './realtyScene/realtyScene';
import { GROUND_COVERING_LAYER } from './constants';
import { ModelStatus } from './types/plugin';

interface Model {
instance: any; // GltfModel
options: ModelOptions;
isLoaded: boolean;
}

const MODEL_DEFAULTS = {
Expand Down Expand Up @@ -121,17 +123,25 @@ export class GltfPlugin extends Evented<GltfPluginEventTable> {
hideOnInit:
this.options.modelsLoadStrategy === 'waitAll' ||
(modelIdsToShow && !modelIdsToShow.includes(options.modelId)),
hover: {
color: this.options.hoverOptions.color,
},
disableAnimation: true,
});

const model = {
const model: Model = {
options,
instance,
isLoaded: false,
};

this.models.set(options.modelId, model);

return new Promise<Model>((resolve) => {
instance.once('modelloaded', () => resolve(model));
instance.once('modelloaded', () => {
model.isLoaded = true;
resolve(model);
});
(['click', 'mousemove', 'mouseover', 'mouseout'] as const).forEach(
(eventType) => {
instance.on(eventType, (ev) => {
Expand All @@ -155,8 +165,13 @@ export class GltfPlugin extends Evented<GltfPluginEventTable> {
});
}

public isModelAdded(id: Id) {
return this.models.has(id);
public getModelStatus(id: Id) {
const model = this.models.get(id);
if (!model) {
return ModelStatus.NoModel;
}

return !model.isLoaded ? ModelStatus.Loading : ModelStatus.Loaded;
}

public removeModel(id: Id) {
Expand Down
115 changes: 87 additions & 28 deletions src/realtyScene/realtyScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import { GltfPlugin } from '../plugin';
import { GltfFloorControl } from '../control';
import classes from './realtyScene.module.css';

import type { BuildingState, Id, ModelOptions, PluginOptions } from '../types/plugin';
import {
ModelStatus,
type BuildingState,
type Id,
type ModelOptions,
type PluginOptions,
} from '../types/plugin';
import type {
BuildingOptions,
MapOptions,
Expand Down Expand Up @@ -78,44 +84,94 @@ export class RealtyScene {

private setState(newState: RealtySceneState) {
const prevState = this.state;

const buildingVisibility: RealtySceneState['buildingVisibility'] = new Map();
this.buildings.forEach((_, buildingId) => {
const prevModelOptions = prevState.buildingVisibility.get(buildingId);
const newModelOptions = newState.buildingVisibility.get(buildingId);
if (prevModelOptions) {
this.plugin.hideModel(prevModelOptions.modelId);
}

if (newModelOptions) {
this.plugin.isModelAdded(newModelOptions.modelId)
? this.plugin.showModel(newModelOptions.modelId)
: this.plugin.addModel(newModelOptions);
if (prevModelOptions?.modelId === newModelOptions?.modelId) {
buildingVisibility.set(buildingId, prevModelOptions);
return;
}
});

if (prevState.activeModelId !== newState.activeModelId) {
if (
prevState.activeModelId !== undefined &&
this.undergroundFloors.has(prevState.activeModelId)
prevModelOptions &&
(!newModelOptions ||
this.plugin.getModelStatus(newModelOptions.modelId) === ModelStatus.Loaded)
) {
this.switchOffGroundCovering();
}

if (newState.activeModelId !== undefined) {
const options =
this.buildings.get(newState.activeModelId) ??
this.floors.get(newState.activeModelId);
if (options) {
this.setMapOptions(options.mapOptions);
// this.addFloorPoi(activeFloor);
// this.clearPoiGroups();
this.plugin.hideModel(prevModelOptions.modelId);
buildingVisibility.set(buildingId, undefined);

if (
prevState.activeModelId !== undefined &&
prevState.activeModelId === prevModelOptions.modelId &&
this.undergroundFloors.has(prevModelOptions.modelId)
) {
this.switchOffGroundCovering();
}
}

if (this.undergroundFloors.has(newState.activeModelId)) {
this.switchOnGroundCovering();
if (newModelOptions) {
const modelStatus = this.plugin.getModelStatus(newModelOptions.modelId);
if (modelStatus === ModelStatus.Loaded) {
this.plugin.showModel(newModelOptions.modelId);
buildingVisibility.set(buildingId, newModelOptions);

if (
newState.activeModelId !== undefined &&
newState.activeModelId === newModelOptions.modelId
) {
const options =
this.buildings.get(newModelOptions.modelId) ??
this.floors.get(newModelOptions.modelId);

if (options) {
this.setMapOptions(options.mapOptions);
}

if (this.undergroundFloors.has(newModelOptions.modelId)) {
this.switchOnGroundCovering();
}
}
} else {
if (modelStatus === ModelStatus.NoModel) {
this.plugin.addModel(newModelOptions, true).then(() => {
if (this.state.activeModelId !== newModelOptions.modelId) {
return;
}

const currModelOptions = this.state.buildingVisibility.get(buildingId);
if (currModelOptions) {
this.plugin.hideModel(currModelOptions.modelId);
if (this.undergroundFloors.has(currModelOptions.modelId)) {
this.switchOffGroundCovering();
}
}

this.plugin.showModel(newModelOptions.modelId);
this.state.buildingVisibility.set(buildingId, newModelOptions);

const options =
this.buildings.get(newModelOptions.modelId) ??
this.floors.get(newModelOptions.modelId);

if (options) {
this.setMapOptions(options.mapOptions);
}

if (this.undergroundFloors.has(newModelOptions.modelId)) {
this.switchOnGroundCovering();
}
});
}

buildingVisibility.set(buildingId, prevModelOptions);
}
}
}
});

// this.addFloorPoi(activeFloor);
// this.clearPoiGroups();

const prevBuildingModelId = this.getBuildingModelId(prevState.activeModelId);
const newBuildingModelId = this.getBuildingModelId(newState.activeModelId);
Expand All @@ -140,7 +196,10 @@ export class RealtyScene {
}
}

this.state = newState;
this.state = {
buildingVisibility,
activeModelId: newState.activeModelId,
};
}

public async init(scene: BuildingOptions[], state?: BuildingState) {
Expand Down
32 changes: 12 additions & 20 deletions src/types/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
export type Id = string;

export type ColorModelString = `${'rgb' | 'hsl'}(${string})`;
export type HexColorString = `#${string}`;

/**
* Color representation can be rgb(), hsl(), or hex value
*/
export type ColorRepresentation = ColorModelString | HexColorString | number;

/**
* Configuration of the poi
*/
Expand Down Expand Up @@ -46,20 +38,14 @@ export interface ControlOptions {
}

/**
* Options for the highlight color of hovered models
* Options for the hover state of models
*/
export interface HightlightOptions {
// TODO: MAJOR. Rename to «HighlightOptions» in the next major release.
export interface HoverOptions {
/**
* Color of the hover
* Hover color
* @default '#ffffff'
*/
color?: ColorRepresentation;
/**
* Intensity of the color on the hover in the range from 0 to 1
* @default 0.0
*/
intencity: number; // TODO: MAJOR. Rename to «intensity» in the next major release.
color?: string;
}

/**
Expand Down Expand Up @@ -94,9 +80,9 @@ export interface PluginOptions {
*/
floorsControl?: ControlOptions;
/**
* Settings of the highlighted models
* Settings of the hovered models
*/
hoverHighlight?: HightlightOptions;
hoverOptions?: HoverOptions;
/**
* Color for the ground covering when an underground floor's plan is shown.
*/
Expand Down Expand Up @@ -235,3 +221,9 @@ export interface PoiGroupOptions {
*/
fontColor?: string;
}

export enum ModelStatus {
NoModel,
Loading,
Loaded,
}

0 comments on commit 6107623

Please sign in to comment.