diff --git a/docs/plugins/plugin-markers.md b/docs/plugins/plugin-markers.md index dbf8795b2..ab922fe6f 100644 --- a/docs/plugins/plugin-markers.md +++ b/docs/plugins/plugin-markers.md @@ -129,6 +129,12 @@ _(This option is ignored for polygons and polylines)._ Size of the marker in pixels. _(This option is ignored for polygons and polylines)._ +#### `orientation` (only for `imageLayer`) +- type: `'front' | 'horizontal' | 'vertical-left' | 'vertical-right'` +- default: `'front'` + +Applies a perspective on the image to make it look like placed on the floor or on a wall. + #### `scale` - type: `double[] | { zoom: double[], longitude: [] }` - default: no scalling @@ -163,17 +169,23 @@ scale: { } ``` +#### `opacity` +- type: `number` +- default: `1` + +Opacity of the marker. (Works for `imageLayer` too). + #### `className` - type: `string` CSS class(es) added to the marker element. -_(This option is ignored for imageLayer markers)._ +_(This option is ignored for `imageLayer` markers)._ #### `style` - type: `object` CSS properties to set on the marker (background, border, etc.). -_(This option is ignored for imageLayer markers)._ +_(This option is ignored for `imageLayer` markers)._ ```js style: { diff --git a/example/assets/target.png b/example/assets/target.png new file mode 100644 index 000000000..5cc17283b Binary files /dev/null and b/example/assets/target.png differ diff --git a/example/plugin-markers.html b/example/plugin-markers.html index 199c2a5f4..bfcb88d14 100644 --- a/example/plugin-markers.html +++ b/example/plugin-markers.html @@ -106,7 +106,7 @@

Header Level 3

PhotoSphereViewer.GyroscopePlugin, PhotoSphereViewer.StereoPlugin, [PhotoSphereViewer.MarkersPlugin, { - markers : (() => { + markers: (() => { const a = []; // add markers all hover the sphere @@ -271,6 +271,18 @@

Header Level 3

tooltip : 'Image embedded in the scene', }); + a.push({ + id : 'imageLayerOrient', + imageLayer : 'assets/target.png', + width : 120, + height : 120, + latitude : -0.2, + longitude : 0.27, + opacity : 0.8, + orientation: 'horizontal', + tooltip : 'Image embedded in the scene with "horizontal" orientation', + }); + // SVG markers a.push({ id : 'svg-demo', diff --git a/src/plugins/markers/Marker.js b/src/plugins/markers/Marker.js index 1f6f4ffd0..492951ac0 100644 --- a/src/plugins/markers/Marker.js +++ b/src/plugins/markers/Marker.js @@ -395,6 +395,7 @@ export class Marker { } // apply style + this.$el.style.opacity = this.config.opacity ?? 1; if (this.config.style) { utils.deepmerge(this.$el.style, this.config.style); } @@ -627,7 +628,7 @@ export class Marker { // compute x/y/z positions this.props.positions3D = this.props.def.map((coord) => { - return this.psv.dataHelper.sphericalCoordsToVector3({ longitude: coord[0], latitude: coord[1] }); + return this.psv.dataHelper.sphericalCoordsToVector3({ longitude: coord[0], latitude : coord[1] }); }); } @@ -653,7 +654,11 @@ export class Marker { switch (this.type) { case MARKER_TYPES.imageLayer: if (!this.$el) { - const material = new THREE.MeshBasicMaterial({ transparent: true, depthTest: false }); + const material = new THREE.MeshBasicMaterial({ + transparent: true, + opacity : this.config.opacity ?? 1, + depthTest : false, + }); const geometry = new THREE.PlaneGeometry(1, 1); const mesh = new THREE.Mesh(geometry, material); mesh.userData = { [MARKER_DATA]: this }; @@ -676,7 +681,10 @@ export class Marker { if (this.psv.config.requestHeaders && typeof this.psv.config.requestHeaders === 'function') { this.loader.setRequestHeader(this.psv.config.requestHeaders(this.config.imageLayer)); } - this.$el.children[0].material.map = this.loader.load(this.config.imageLayer, () => this.psv.needsUpdate()); + this.$el.children[0].material.map = this.loader.load(this.config.imageLayer, (texture) => { + texture.anisotropy = 4; + this.psv.needsUpdate(); + }); this.props.def = this.config.imageLayer; } @@ -687,7 +695,25 @@ export class Marker { ); this.$el.position.copy(this.props.positions3D[0]); - this.$el.lookAt(0, 0, 0); + + switch (this.config.orientation) { + case 'horizontal': + this.$el.lookAt(0, this.$el.position.y, 0); + this.$el.rotateX(this.props.position.latitude < 0 ? -Math.PI / 2 : Math.PI / 2); + break; + case 'vertical-left': + this.$el.lookAt(0, 0, 0); + this.$el.rotateY(-Math.PI * 0.4); + break; + case 'vertical-right': + this.$el.lookAt(0, 0, 0); + this.$el.rotateY(Math.PI * 0.4); + break; + default: + this.$el.lookAt(0, 0, 0); + break; + } + // 100 is magic number that gives a coherent size at default zoom level this.$el.scale.set(this.config.width / 100 * SYSTEM.pixelRatio, this.config.height / 100 * SYSTEM.pixelRatio, 1); break; diff --git a/types/plugins/markers/index.d.ts b/types/plugins/markers/index.d.ts index 29f2559d8..2416c5329 100644 --- a/types/plugins/markers/index.d.ts +++ b/types/plugins/markers/index.d.ts @@ -35,7 +35,9 @@ export type MarkerProperties = Partial & { id: string; width?: number; height?: number; + orientation?: 'front' | 'horizontal' | 'vertical-left' | 'vertical-right'; scale?: number | [number, number] | { zoom?: [number, number], longitude?: [number, number] }; + opacity?: number; className?: string; style?: Record; svgStyle?: Record;