Skip to content

Commit bdfa6b7

Browse files
authored
Merge pull request #3 from openglobus/components
Components
2 parents fd4a4a9 + db0aac6 commit bdfa6b7

File tree

13 files changed

+272
-26
lines changed

13 files changed

+272
-26
lines changed

.storybook/preview.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {Preview} from "@storybook/react";
22

33
const preview: Preview = {
4+
tags: ['autodocs'],
45
parameters: {
56
controls: {
67
matchers: {

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openglobus/openglobus-react",
3-
"version": "0.1.0",
3+
"version": "0.1.1",
44
"description": "Openglobus React Components",
55
"main": "./dist/index.umd.cjs",
66
"private": false,
@@ -28,7 +28,7 @@
2828
"author": "Pavel Sukhodolski",
2929
"license": "MIT",
3030
"dependencies": {
31-
"@openglobus/og": "^0.20.2",
31+
"@openglobus/og": "^0.20.3",
3232
"react": "^18.2.0"
3333
},
3434
"devDependencies": {

src/Globe/Globe.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {IGlobeParams} from "@openglobus/og/lib/js/Globe";
77
import "@openglobus/og/css/og.css";
88
import {Layer, Vector} from "@/layer";
99

10-
type LayerChildren = React.ReactElement<{ type: typeof Layer|typeof Vector}>;
10+
type LayerChildren = React.ReactElement<{ type: typeof Layer | typeof Vector }>;
11+
1112
export interface GlobusProps extends IGlobeParams {
1213
children?: LayerChildren | LayerChildren[]
1314
atmosphereEnabled?: boolean,
@@ -68,7 +69,8 @@ const Globe: React.FC<GlobusProps> = ({children, onDraw, ...rest}) => {
6869
nightTextureCoefficient: 2.7,
6970
urlRewrite: function (s: any, u: string) {
7071
// @ts-ignore
71-
return utils.stringTemplate(u, {s: this._getSubdomain(), quad: toQuadKey(s.tileX, s.tileY, s.tileZoom)});},
72+
return utils.stringTemplate(u, {s: this._getSubdomain(), quad: toQuadKey(s.tileX, s.tileY, s.tileZoom)});
73+
},
7274
});
7375

7476
gRef.current = new GlobusGlobe({
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from 'react';
2+
import type {Meta, StoryObj} from '@storybook/react';
3+
4+
import {Globe, GlobeContextProvider} from "@/Globe";
5+
import {PlanetCamera, PlanetCameraParams} from "@/camera/PlanetCamera/PlanetCamera";
6+
7+
/**
8+
* This story about Billboard component. Billboard is a component that represents a 2d object which always faced to camera.
9+
*/
10+
const meta = {
11+
component: PlanetCamera,
12+
title: 'Components/Camera/PlanetCamera',
13+
} satisfies Meta<typeof PlanetCamera>;
14+
15+
export default meta;
16+
17+
type Story = StoryObj<typeof meta>;
18+
19+
export const Default: {
20+
args: PlanetCameraParams
21+
render: (args: PlanetCameraParams) => React.JSX.Element
22+
} = {
23+
24+
args: {
25+
lon: 0,
26+
lat: 0,
27+
alt: 100000,
28+
lookLon: 10,
29+
lookLat: 10,
30+
lookAlt: 100000,
31+
viewAngle:47
32+
},
33+
render: (args: PlanetCameraParams) => <GlobeContextProvider>
34+
<Globe>
35+
<PlanetCamera {...args} />
36+
</Globe>
37+
</GlobeContextProvider>
38+
};
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import * as React from "react";
2+
import {useEffect} from "react";
3+
import {LonLat} from "@openglobus/og";
4+
import {IPlanetCameraParams} from "@openglobus/og/lib/js/camera/PlanetCamera";
5+
import {useGlobeContext} from "@/Globe";
6+
7+
export interface PlanetCameraParams extends IPlanetCameraParams {
8+
lon?: number;
9+
lat?: number;
10+
alt?: number;
11+
yaw?: number;
12+
viewAngle?: number;
13+
lookLon?: number;
14+
lookLat?: number;
15+
lookAlt?: number;
16+
}
17+
18+
const PlanetCamera: React.FC<PlanetCameraParams> = ({
19+
lon,
20+
lat,
21+
alt,
22+
lookLon,
23+
lookLat,
24+
lookAlt,
25+
viewAngle,
26+
...params
27+
}) => {
28+
const {globe} = useGlobeContext();
29+
30+
31+
useEffect(() => {
32+
if (globe && typeof lon === "number" && typeof lat === "number" && typeof alt === "number") {
33+
globe.planet.flyLonLat(new LonLat(lon, lat, alt), new LonLat(lookLon, lookLat, lookAlt))
34+
}
35+
}, [lon, lat, alt, lookLon, lookLat, lookAlt, globe]);
36+
37+
useEffect(() => {
38+
if (globe && typeof viewAngle === "number") {
39+
globe.planet.camera.setViewAngle(viewAngle)
40+
}
41+
}, [viewAngle, globe]);
42+
43+
return null;
44+
};
45+
46+
export {PlanetCamera};

src/entity/Entity/Entity.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ const Entity: React.FC<EntityParams> = ({visibility, lon, lat, alt, lonlat, name
8181
useEffect(() => {
8282
if (globe) {
8383
entityRef.current = new GlobusEntity({
84-
lonlat, name, ...rest
84+
lonlat: lonlat? lonlat : new LonLat(lon,lat,alt), name, ...rest
8585
});
8686
addEntity(entityRef.current);
8787

src/layer/Layer/Layer.stories.tsx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import type {Meta, StoryObj} from '@storybook/react';
2+
3+
import {Billboard, Entity} from "@/entity";
4+
import {Globe, GlobeContextProvider} from "@/Globe";
5+
import {action} from '@storybook/addon-actions';
6+
import React from "react";
7+
import {Layer, Vector, VectorProps} from "@/layer";
8+
9+
const meta = {
10+
title: 'Components/Layer/Layer',
11+
component: Layer,
12+
} satisfies Meta<typeof Layer>;
13+
14+
export default meta;
15+
16+
type Story = StoryObj<typeof meta>;
17+
18+
19+
export const Default: Story = {
20+
parameters: {
21+
actions: {depth: 1, maxDepth: 1},
22+
},
23+
argTypes: {
24+
onVisibilityChange: {table: {disable: true}},
25+
onAdd: {table: {disable: true}},
26+
onRemove: {table: {disable: true}},
27+
onMouseMove: {table: {disable: true}},
28+
onMouseEnter: {table: {disable: true}},
29+
onMouseLeave: {table: {disable: true}},
30+
onLclick: {table: {disable: true}},
31+
onRclick: {table: {disable: true}},
32+
onMclick: {table: {disable: true}},
33+
onLdblclick: {table: {disable: true}},
34+
onRdblclick: {table: {disable: true}},
35+
onMdblclick: {table: {disable: true}},
36+
onLup: {table: {disable: true}},
37+
onRup: {table: {disable: true}},
38+
onMup: {table: {disable: true}},
39+
onLdown: {table: {disable: true}},
40+
onRdown: {table: {disable: true}},
41+
onMdown: {table: {disable: true}},
42+
onLhold: {table: {disable: true}},
43+
onRhold: {table: {disable: true}},
44+
onMhold: {table: {disable: true}},
45+
onMouseWheel: {table: {disable: true}},
46+
onTouchMove: {table: {disable: true}},
47+
onTouchStart: {table: {disable: true}},
48+
onTouchEnd: {table: {disable: true}},
49+
onDoubleTouch: {table: {disable: true}},
50+
onTouchLeave: {table: {disable: true}},
51+
onTouchEnter: {table: {disable: true}},
52+
},
53+
args: {
54+
name: 'test',
55+
onMouseEnter: action('onMouseEnter', {depth: 1, maxDepth: 1}),
56+
onLclick: action('onLclick', {depth: 1, maxDepth: 1}),
57+
onMouseLeave: action('onMouseLeave', {depth: 1, maxDepth: 1}),
58+
onMouseMove: action('onMouseMove', {depth: 1, maxDepth: 1}),
59+
onLdblclick: action('onLdblclick', {depth: 1, maxDepth: 1}),
60+
// onDraw: action('onDraw', {depth: 1, maxDepth: 1}),
61+
},
62+
render: (args: VectorProps) => <GlobeContextProvider>
63+
<Globe>
64+
<Vector {...args}>
65+
<Entity name="Custom Entity" lon={0} lat={0} alt={0}>
66+
<Billboard
67+
size={[96, 96]}
68+
color={"#ff5959"}
69+
src={'https://openglobus.org/examples/examples/billboards/carrot.png'}
70+
/>
71+
</Entity>
72+
</Vector>
73+
</Globe>
74+
</GlobeContextProvider>
75+
};
76+

src/layer/Layer/Layer.tsx

Lines changed: 84 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,93 @@
1+
import * as React from 'react';
12
import {useEffect} from 'react';
2-
import {useGlobeContext} from '@/Globe';
33
import {ILayerParams, Layer as GlobusLayer} from '@openglobus/og';
4+
import {EventCallback} from '@openglobus/og/lib/js/Events';
45

5-
const Layer = ({props, name}: { props: ILayerParams, name: string }) => {
6-
const {globe} = useGlobeContext();
6+
export interface LayerProps extends ILayerParams {
7+
name: string
8+
layerRef?: React.MutableRefObject<GlobusLayer | null>,
9+
children?: React.ReactNode;
10+
onVisibilityChange?: EventCallback;
11+
onAdd?: EventCallback;
12+
onRemove?: EventCallback;
13+
onMouseMove?: EventCallback;
14+
onMouseEnter?: EventCallback;
15+
onMouseLeave?: EventCallback;
16+
onLclick?: EventCallback;
17+
onRclick?: EventCallback;
18+
onMclick?: EventCallback;
19+
onLdblclick?: EventCallback;
20+
onRdblclick?: EventCallback;
21+
onMdblclick?: EventCallback;
22+
onLup?: EventCallback;
23+
onRup?: EventCallback;
24+
onMup?: EventCallback;
25+
onLdown?: EventCallback;
26+
onRdown?: EventCallback;
27+
onMdown?: EventCallback;
28+
onLhold?: EventCallback;
29+
onRhold?: EventCallback;
30+
onMhold?: EventCallback;
31+
onMouseWheel?: EventCallback;
32+
onTouchMove?: EventCallback;
33+
onTouchStart?: EventCallback;
34+
onTouchEnd?: EventCallback;
35+
onDoubleTouch?: EventCallback;
36+
onTouchLeave?: EventCallback;
37+
onTouchEnter?: EventCallback;
38+
}
739

40+
const Layer: React.FC<LayerProps> = ({opacity, children, name, layerRef, ...params}) => {
41+
const [refPassed, setRefPassed] = React.useState(false);
842
useEffect(() => {
9-
if (globe) {
10-
const newLayer = new GlobusLayer(name, props);
11-
globe.planet.addLayer(newLayer);
12-
13-
return () => {
14-
globe.planet.removeLayer(newLayer);
15-
};
43+
if (layerRef) {
44+
if (layerRef.current && typeof opacity === 'number' && refPassed) {
45+
layerRef.current.opacity = opacity;
46+
}
1647
}
17-
}, [globe]);
18-
19-
return null;
48+
}, [opacity]);
49+
useEffect(() => {
50+
if (refPassed && layerRef && layerRef.current) {
51+
if (params.onVisibilityChange) layerRef.current?.events.on("visibilitychange", params.onVisibilityChange)
52+
if (params.onAdd) layerRef.current?.events.on("add", params.onAdd)
53+
if (params.onRemove) layerRef.current?.events.on("remove", params.onRemove)
54+
if (params.onMouseMove) layerRef.current?.events.on("mousemove", params.onMouseMove)
55+
if (params.onMouseEnter) layerRef.current?.events.on("mouseenter", params.onMouseEnter)
56+
if (params.onMouseLeave) layerRef.current?.events.on("mouseleave", params.onMouseLeave)
57+
if (params.onLclick) layerRef.current?.events.on("lclick", params.onLclick)
58+
if (params.onRclick) layerRef.current?.events.on("rclick", params.onRclick)
59+
if (params.onMclick) layerRef.current?.events.on("mclick", params.onMclick)
60+
if (params.onLdblclick) layerRef.current?.events.on("ldblclick", params.onLdblclick)
61+
if (params.onRdblclick) layerRef.current?.events.on("rdblclick", params.onRdblclick)
62+
if (params.onMdblclick) layerRef.current?.events.on("mdblclick", params.onMdblclick)
63+
if (params.onLup) layerRef.current?.events.on("lup", params.onLup)
64+
if (params.onRup) layerRef.current?.events.on("rup", params.onRup)
65+
if (params.onMup) layerRef.current?.events.on("mup", params.onMup)
66+
if (params.onLdown) layerRef.current?.events.on("ldown", params.onLdown)
67+
if (params.onRdown) layerRef.current?.events.on("rdown", params.onRdown)
68+
if (params.onMdown) layerRef.current?.events.on("mdown", params.onMdown)
69+
if (params.onLhold) layerRef.current?.events.on("lhold", params.onLhold)
70+
if (params.onRhold) layerRef.current?.events.on("rhold", params.onRhold)
71+
if (params.onMhold) layerRef.current?.events.on("mhold", params.onMhold)
72+
if (params.onMouseWheel) layerRef.current?.events.on("mousewheel", params.onMouseWheel)
73+
if (params.onTouchMove) layerRef.current?.events.on("touchmove", params.onTouchMove)
74+
if (params.onTouchStart) layerRef.current?.events.on("touchstart", params.onTouchStart)
75+
if (params.onTouchEnd) layerRef.current?.events.on("touchend", params.onTouchEnd)
76+
if (params.onDoubleTouch) layerRef.current?.events.on("doubletouch", params.onDoubleTouch)
77+
}
78+
return () => {
79+
if (params.onLclick) layerRef?.current?.events.off('lclick', params.onLclick)
80+
setRefPassed(false)
81+
}
82+
}, [refPassed]);
83+
if (layerRef?.current && !refPassed) {
84+
setRefPassed(true)
85+
}
86+
return (
87+
<>
88+
{children}
89+
</>
90+
);
2091
};
2192

2293
export {Layer};
23-

src/layer/Vector/Vector.stories.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {Meta, StoryObj} from '@storybook/react';
22

33
import {Vector, VectorProps} from './Vector';
4+
import {Default as LayerDefault} from '../Layer/Layer.stories';
45
import {Billboard, Entity} from "@/entity";
56
import {Globe, GlobeContextProvider} from "@/Globe";
67
import {action} from '@storybook/addon-actions';
@@ -20,10 +21,12 @@ export const Default: Story = {
2021
parameters: {
2122
actions: {depth: 1, maxDepth: 1},
2223
},
24+
argTypes:{
25+
...LayerDefault.argTypes
26+
},
2327
args: {
2428
name: 'test',
25-
onMouseEnter: action('onMouseEnter', {depth: 1, maxDepth: 1}),
26-
// onDraw: action('onDraw', {depth: 1, maxDepth: 1}),
29+
opacity: 1
2730
},
2831
render: (args: VectorProps) => <GlobeContextProvider>
2932
<Globe>

src/layer/Vector/Vector.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from "react";
22
import {createContext, useCallback, useEffect, useRef, useState} from "react";
3-
import {useGlobeContext} from '../../index';
3+
import {Layer, LayerProps, useGlobeContext} from '../../index';
44
import type {Billboard, Entity, Geometry, GeoObject, Label, Polyline, Strip} from '@openglobus/og';
55
import {Vector as GlobusVector} from '@openglobus/og';
66
import {IVectorParams} from '@openglobus/og/lib/js/layer/Vector';
@@ -54,13 +54,15 @@ const VectorContext = createContext<{
5454

5555
type EntityElement = React.ReactElement<{ type: typeof Entity }>;
5656

57-
export interface VectorProps extends IVectorParams {
57+
export interface VectorPropsBase extends IVectorParams {
5858
children?: EntityElement | EntityElement[]
5959
name: string
6060
onMouseEnter?: EventCallback
6161
onDraw?: EventCallback
6262
}
6363

64+
export type VectorProps = VectorPropsBase & LayerProps;
65+
6466
const Vector: React.FC<VectorProps> = ({visibility, children, name, ...rest}) => {
6567
const {globe} = useGlobeContext();
6668
const vectorRef = useRef<GlobusVector | null>(null);
@@ -179,7 +181,9 @@ const Vector: React.FC<VectorProps> = ({visibility, children, name, ...rest}) =>
179181
addStrip,
180182
removeStrip
181183
}}>
182-
{children}
184+
<Layer layerRef={vectorRef} name={name} {...rest}>
185+
{children}
186+
</Layer>
183187
</VectorContext.Provider>
184188
);
185189
};

0 commit comments

Comments
 (0)