Skip to content

Commit

Permalink
Close #1293 markers: support polygons with holes
Browse files Browse the repository at this point in the history
  • Loading branch information
mistic100 committed May 17, 2024
1 parent 9d0b53d commit 8540fdb
Show file tree
Hide file tree
Showing 5 changed files with 313 additions and 70 deletions.
275 changes: 232 additions & 43 deletions docs/plugins/markers.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ const viewer = new Viewer({
// polygon marker
id: 'polygon',
polygon: [
[6.2208, 0.0906], [0.0443, 0.1028], [0.2322, 0.0849], [0.4531, 0.0387],
[6.2208, 0.0906], [0.0443, 0.1028], [0.2322, 0.0849], [0.4531, 0.0387],
[0.5022, -0.0056], [0.4587, -0.0396], [0.252, -0.0453], [0.0434, -0.0575],
[6.1302, -0.0623], [6.0094, -0.0169], [6.0471, 0.032], [6.2208, 0.0906],
[6.1302, -0.0623], [6.0094, -0.0169], [6.0471, 0.0320], [6.2208, 0.0906],
],
svgStyle: {
fill: 'rgba(200, 0, 0, 0.2)',
Expand Down Expand Up @@ -247,43 +247,53 @@ You can try markers live in [the playground](../playground.md).
One, and only one, of these options is required for each marker.
| Name | Type | Description |
| ---------------- | ---------------------------------------- | ----------------------------------------------------------------------------- |
| `image` | `string` | Path to an image file. Requires `width` and `height` to be defined. |
| `imageLayer` | `string` | Path to an image file. |
| `videoLayer` | `string` | Path to a video file. |
| `html` | `string` | HTML content of the marker. It is recommended to define `width` and `height`. |
| `element` | `HTMLElement` | Existing DOM element. |
| `square` | `integer` | Size of the square. |
| `rect` | `integer[2]`<br>`{width:int,height:int}` | Size of the rectangle. |
| `circle` | `integer` | Radius of the circle. |
| `ellipse` | `integer[2]`<br>`{rx:int,ry:int}` | Radiuses of the ellipse. |
| `path` | `string` | Definition of the path (0,0 will be placed at the defined `position`). |
| `polygon` | `double[2][]`<br>`string[2][]` | Array of points defining the polygon in spherical coordinates. |
| `polygonPixels` | `integer[2][]` | Same as `polygon` but in pixel coordinates on the panorama image. |
| `polyline` | `double[2][]`<br>`string[2][]` | Same as `polygon` but generates a polyline. |
| `polylinePixels` | `integer[2][]` | Same as `polygonPixels` but generates a polyline. |
**Examples :**
#### `image`
- type: `string`
Path to an image file. Requires `size` to be defined.
```js{3}
{
id: 'marker-1',
image: 'pin-red.png',
position: { yaw: 0, pitch: 0 },
size: { width: 32, height: 32 },
}
```
#### `imageLayer`
- type: `string`
Path to an image file.
::: tip "Layers" positionning
There is two ways to position `imageLayer` and `videoLayer` markers:
- `position` (one value) + `size` + `anchor` (optional) + `orientation` (optional)
- `position` with four values defining the corners of the image/video
[Check the demo](../demos/markers/layers.md)
:::
```js{3}
{
id: 'marker-1',
imageLayer: 'pin-red.png',
position: { yaw: 0, pitch: 0 },
size: { width: 32, height: 32 },
}

```js
{
image: 'pin-red.png',
imageLayer: 'pin-blue.png',
videoLayer: 'intro.mp4',
html: 'Click here',
element: document.querySelector('#my-marker'),
square: 10,
rect: [10, 5],
rect: {width: 10, height: 5},
circle: 10,
ellipse: [10, 5],
ellipse: {rx: 10, ry: 5},
path: 'M 0 0 L 60 60 L 60 0 L 0 60 L 0 0',
polygon: [[0.2, 0.4], [0.9, 1.1], [1.5, 0.7]],
polygonPixels: [[100, 200], [150, 300], [300, 200]],
polyline: [[0.2, 0.4], [0.9, 1.1]],
polylinePixels: [[100, 200], [150, 300]],
id: 'marker-2',
imageLayer: 'pin-red.png',
position: [
{ yaw: -0.2, pitch: 0.2 },
{ yaw: 0.2, pitch: 0.2 },
{ yaw: 0.2, pitch: -0.2 },
{ yaw: -0.2, pitch: -0.2 },
],
}
```
Expand All @@ -292,6 +302,50 @@ Both allows to display an image but the difference is in the rendering technique
And `image` marker is rendered flat above the viewer but and `imageLayer` is rendered inside the panorama itself, this allows for more natural movements and scaling.
:::
#### `videoLayer`
- type: `string`
Path to a video file. It is positionned exactly like `imageLayer`. It can be used with the [`chromaKey`](#chromakey) option.
```js{3}
{
id: 'marker-1',
videoLayer: 'intro.mp4',
position: { yaw: 0, pitch: 0 },
size: { width: 600, height: 400 },
}
```
#### `html`
- type: `string`
HTML content of the marker. It is recommended to define th `size`.
```js{3}
{
id: 'marker-1',
html: '<string>Click here</strong>',
position: { yaw: 0, pitch: 0 },
size: { width: 100, height: 30 },
}
```
#### `element`
- type: `HTMLElement`
Existing DOM element.
```js{3}
{
id: 'marker-1',
element: document.querySelector('#my-marker'),
position: { yaw: 0, pitch: 0 },
}
```
::: tip Custom element markers
The `element` marker accepts [Web Components](https://developer.mozilla.org/docs/Web/API/Web_components/Using_custom_elements).
If your component has an `updateMarker()` method it will be called by the plugin on each render with a bunch of properties:
Expand All @@ -305,14 +359,149 @@ If your component has an `updateMarker()` method it will be called by the plugin
[Check the demo](../demos/markers/custom-element.md)
:::
::: tip "Layers" positionning
There is two ways to position `imageLayer` and `videoLayer` markers:
#### `polygon`
- `position` (one value) + `size` + `anchor` (optional) + `orientation` (optional)
- `position` with four values defining the corners of the image/video
- type: `number[2][] | number[2][][] | string[2][] | string[2][][]`
Array of points defining the polygon in spherical coordinates (degrees or radians).
The polygon can have one or more holes by defined them in a nested array (the syntax is [similar to GeoJSON](https://geojson.readthedocs.io/en/latest/#polygon)).
```js{3,8-11}
{
id: 'marker-1',
polygon: [[0.2, 0.4], [0.9, 1.1], [1.5, 0.7]];
}

{
id: 'marker-2',
polygon: [
[[0.2, 0.4], [0.9, 1.1], [1.5, 0.7]],
[[0.3, 0.5], [1.4, 0.8], [0.8, 1.0]], // holes coordinates must be in reverse order
],
}
```
#### `polygonPixels`
- type: `number[2][] | number[2][][]`
Same as `polygon` but in pixel coordinates on the panorama image.
```js{3}
{
id: 'marker-1',
polygonPixels: [[100, 200], [150, 300], [300, 200]],
}
```
#### `polyline`
- type: `number[2][] | string[2][]`
Same as `polygon` but generates a polyline.
```js{3}
{
id: 'marker-1',
polyline: [[0.2, 0.4], [0.9, 1.1]],
}
```
#### `polylinePixels`
- type: `number[2][] | string[2][]`
Same as `polygonPixels` but generates a polyline.
```js{3}
{
id: 'marker-1',
polylinePixels: [[100, 200], [150, 300]],
}
```
#### `square`
- type: `integer`
Size of the square.
```js{3}
{
id: 'marker-1',
square: 10,
position: { yaw: 0, pitch: 0 },
}
```
#### `rect`
- type: `integer[2] | { width: integer, height: integer }`
Size of the rectangle.
```js{3,9}
{
id: 'marker-1',
rect: [10, 5],
position: { yaw: 0, pitch: 0 },
}

{
id: 'marker-2',
rect: { width: 10, height: 5 },
position: { yaw: 0, pitch: 0 },
}
```
#### `circle`
- type: `integer`
Radius of the circle.
```js{3}
{
id: 'marker-1',
circle: 10,
position: { yaw: 0, pitch: 0 },
}
```
#### `ellipse`
- type: `integer[2] | { rx: integer, ry: integer }`;
Radiuses of the ellipse.
```js{3,9}
{
id: 'marker-1',
ellipse: [10, 5],
position: { yaw: 0, pitch: 0 },
}

{
id: 'marker-2',
ellipse: { rx: 10, ry: 5 },
position: { yaw: 0, pitch: 0 },
}
```
#### `path`
- type: `string`
Definition of the path (0,0 will be placed at the defined `position`).
```js{3}
{
id: 'marker-1',
path: 'M0,0 L60,60 L60,0 L0,60 L0,0',
position: { yaw: 0, pitch: 0 },
}
```
[Check the demo](../demos/markers/layers.md)
:::
### Options
Expand Down
17 changes: 11 additions & 6 deletions examples/plugin-markers.html
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ <h2>Lorem ipsum</h2>
polygon: [
[6.0848, 0.1806], [0.1022, 0.3166], [0.6333, 0.3836], [1.2396, 0.5112],
[1.7922, 0.5544], [2.7635, 0.7853], [3.3688, 0.4723], [3.6902, 0.6161],
[4.2981, 0.6942], [4.6605, 0.6618], [5.4694, 0.188], [5.7125, 0.1302],
[4.2981, 0.6942], [4.6605, 0.6618], [5.4694, 0.1880], [5.7125, 0.1302],
],
hideList: true,
});
Expand All @@ -210,16 +210,21 @@ <h2>Lorem ipsum</h2>
id: 'polygon-1',
// prettier-ignore
polygonPixels: [
[2941, 1413], [3042, 1402], [3041, 1555], [2854, 1559],
[2739, 1516], [2775, 1469], [2941, 1413],
[
[2941, 1413], [3042, 1402], [3041, 1555], [2854, 1559],
[2739, 1516], [2775, 1469], [2941, 1413],
],
[
[2900, 1450], [2900, 1500], [2950, 1500], [2950, 1450],
],
],
svgStyle: {
fill: 'rgba(255,0,0,0.2)',
stroke: 'rgba(255, 0, 50, 0.8)',
strokeWidth: '2px',
},
tooltip: {
content: 'Simple polygon',
content: 'Polygon with hole',
position: 'bottom right',
},
});
Expand Down Expand Up @@ -248,8 +253,8 @@ <h2>Lorem ipsum</h2>
id: 'polyline',
// prettier-ignore
polylinePixels: [
2478, 1635, 2184, 1747, 1674, 1953, 1166, 1852,
709, 1669, 301, 1519, 94, 1399, 34, 1356,
[2478, 1635], [2184, 1747], [1674, 1953], [1166, 1852],
[709, 1669], [301, 1519], [94, 1399], [34, 1356],
],
svgStyle: {
stroke: 'rgba(80, 150, 50, 0.8)',
Expand Down
4 changes: 4 additions & 0 deletions packages/markers-plugin/src/markers/Marker3D.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ export class Marker3D extends Marker {
}
}, { once: true });

if (video.autoplay) {
video.play();
}

this.definition = this.config.videoLayer;
} else {
material.alpha = this.config.opacity;
Expand Down

0 comments on commit 8540fdb

Please sign in to comment.