I am developing a 360map app, until now I have something very simple. What I want is to show an image and give the user the chance to add a marker in real time in the position of the mouse where he clicks, and then the marker should just appear on the clicked position. I can do that but I can't update the component whithout having to upload the entire website.
Here is a sample code:
import React, { useState, useEffect, useRef } from "react";
import { CompassPlugin, MarkersPlugin, ReactPhotoSphereViewer } from 'react-photo-sphere-viewer';
import PANO_TEST from './assets/img/Test_Pano.jpg';
import SAG from './assets/img/SAG.png';
import drone from './assets/img/drone.png';
import pin from './assets/img/pin-blue.png';
function App() {
const pSRef = useRef();
var add_pin = false
var markers = []
const plugins = [
[
MarkersPlugin,
{
markers: markers
}
]
]
const handleClick = (data) => {
if (add_pin) {
const chart = pSRef.current
var id = localStorage.getItem('marker_id')
markers.push(
{
// image marker that opens the panel when clicked
id: id,
position: { yaw: (data.data.yaw/0.01746)+"deg", pitch: (data.data.pitch/0.01752)+"deg" },
image: pin,
anchor: "bottom center",
size: { width: 50, height: 50 },
tooltip: "Mountain peak. <b>Click me!</b>",
}
)
localStorage.setItem('markers',JSON.stringify(markers))
add_pin = false
localStorage.setItem('marker_id',parseInt(id)+1)
/** HERE IS THE RELOAD THAT i WANT TO AVOID*/
window.location.reload()
}
};
const AddPin = () => {
add_pin = true
}
const handleReady = (instance) => {
console.log(instance)
}
return (
<React.Fragment>
<div style={{ height: 20, padding: "10px" }}>
<span style={{ fontWeight: "bold", marginRight: "10px" }}>Añadir pin:</span>
<button onClick={() => AddPin()}>AÑADIR PIN</button>
</div>
<div>
<ReactPhotoSphereViewer
ref={pSRef}
src={SAG}
height={'95vh'}
width={"100%"}
plugins={plugins}
onClick={handleClick}
navbar={false}
onReady={handleReady}
moveInertia={false}
></ReactPhotoSphereViewer>
</div>
</React.Fragment>
);
}
export default App;
Any help given will be helpfull. Thanks ;)
I have tried to use useRef to update the componente, sadly it doesn't seem to have a function that allows me to update the component instantly. I listed the functions attached to the component and none of them are usefull for this case.
you shouldn't add the new marker into a plain array inside of a component.
there are multiple reasons some of which are, that every time the component is rendered the variable is reassigned, and when the said variable is updated it won't cause the react component to rerender.
that said, I think either you should use a state
like the following:
const [markers, setMarkers] = useState([]);
const handleClick = (data) => {
if (add_pin) {
setMarkers([...markers, {
// image marker that opens the panel when clicked
id: id,
position: { yaw: (data.data.yaw/0.01746)+"deg", pitch: (data.data.pitch/0.01752)+"deg" },
image: pin,
anchor: "bottom center",
size: { width: 50, height: 50 },
tooltip: "Mountain peak. <b>Click me!</b>",
}])
}
};
or for another option take a look at this in the documentation you can add a new pointer like the following example:
const handleReady = (instance) => {
const markersPlugs = instance.getPlugin(MarkersPlugin);
if (!markersPlugs)
return;
markersPlugs.addMarker({
id: "imageLayer2",
image: "drone.png",
size: { width: 220, height: 220 },
position: { yaw: '130.5deg', pitch: '-0.1deg' },
tooltip: "Image embedded in the scene"
});
}
return (
<div className="App">
<ReactPhotoSphereViewer src="Test_pano.jpg" plugins={plugins} height={'100vh'} width={"100%"} onReady={handleReady}></ReactPhotoSphereViewer>
</div>
);
you can simply save the markersPlugs
into a ref and call it as you please.