mistic100 / Photo-Sphere-Viewer

A JavaScript library to display 360° sphere panoramas.
https://photo-sphere-viewer.js.org
MIT License
1.94k stars 687 forks source link

Markers #5

Closed gp187 closed 8 years ago

gp187 commented 8 years ago

Great work! This is more a request than a bug.

Can you provide a clue on how to use 'position-updated' theta and phi to place / save markers on the 360 view and load them when they come into view?

I captured the mouse event for X,Y and theta and phi to get view port, but can't bind them together. Ideas?

mistic100 commented 8 years ago

I don't know how I could help you. It's simple trigonometry to know which area is visible knowing the viewport width and height, the current zoom level and the current camera position.

Simple but I don't know the formula, Wikipedia and math websites will help.


That being said it gave me the idea of a markers feature, actually displayed on the sphere it-self, with add, remove, show, hide, goto methods.

gp187 commented 8 years ago

Yes, would be a very useful feature and not hard to implement. I'm almost done with it, just need a more accurate way to adapt to current camera view. I used HTML overlay (instead of textures in render) because it allows easy interaction with Angular.


Can't get that damn formula right. It offsets faster than the view Markers have left and top in absolute and -/+ depending on direction

var offsetX = PSV.prop.theta - (pos.left - PSV.prop.mouse_x) * PSV.config.long_offset;

mistic100 commented 8 years ago

I think you are mixing spherical and orthogonal coordinates, hence the offset.

mistic100 commented 8 years ago

Did you managed to solve your offset ? I am facing the same problem naively thinking there is a linear relationship between angles and plane positions. https://github.com/mistic100/Photo-Sphere-Viewer/blob/feature/5-markers/src/js/PSVHUD.js#L128

But it's not linear, it's... strange. I'll have to study how PerspectiveCamera works.

mistic100 commented 8 years ago

It's working ! the method used is explained here http://stackoverflow.com/a/27448966 Now I'll make everything pretty and configurable :-)

mistic100 commented 8 years ago

You can see the WIP here http://www.strangeplanet.fr/work/photosphere/example/

mistic100 commented 8 years ago
gp187 commented 8 years ago

No, no I didn't. Please send your address so I send unlimited amounts of beer!

Is is set in version ?

gp187 commented 8 years ago

Also for the markers

Makes easier to provide an array of objects to set as markers and then interact with each one

gp187 commented 8 years ago

When your done with the marker feature I'm going to make a angular class so you can commit it as well

gp187 commented 8 years ago

After your done with markers I'll make an angular module for the plugin. That'll be cool

mistic100 commented 8 years ago

I'll prefer you publish the directive in a separate (your own) repository. I'll make a reference to it in the doc.

gp187 commented 8 years ago

OK. Will do

mistic100 commented 8 years ago

So I think it's done. But there will be a problem if you want to integrate with angular. When a marker is added a clone is done https://github.com/mistic100/Photo-Sphere-Viewer/blob/feature/5-markers/src/js/PSVHUD.js#L75 This will make any possible angular model detached. I could remove the clone but I also need to store some custom data on the marker (position2D, position3D, parsed anchor) and I don't really want to modify the object of the user. How should this be done correctly ?

gp187 commented 8 years ago

Cool. Let me test it because I will be integrating it with angular and I'll provide info how to make it the best

At first sight fast methods:: angular.merge on marker object will do. Will provide more info soon. Working

gp187 commented 8 years ago

Nice! Tested and started to integrate, also adding markers dynamically works fine with angular, got a good solution for that. The only problem is placing them. Fetching the click event from the canvas but no matter how I use offsetX, offsetY, clientX, clientY it doesn't come on the place clicked. Note: screenX, screenY is always 0 for canvas

Also using events from PSV.prop for mouseX is same thing. Any advice on how to calculate the X,Y needed from mouse click $event on the canvas ?

mistic100 commented 8 years ago

You forgot that you are working with a perspective projection of a 3D environment. What you need is to use the Raycaster to detect the click position in the sphere (x, y, z) then translate to geodesic coordinates (latitude, longitude) and if needed translate to texture coordinates.

If you can wait I'll add a "mouse-click" event on the viewer with the following properties :

gp187 commented 8 years ago

Tested. Using longitude, latitude from the 'click' data I made it add markers dynamically. Is the 'click' data stored in the PSV object like many other coordinates ? I can't find it.

Would be helpful to recover it from the root object

gp187 commented 8 years ago

Using longitude and latitude in Angular to add new marker works, but there is a slight error. For some reason there is a distance between place of click and the placement. Meaning, it's exactly under the click location. The error distance is constant.

mistic100 commented 8 years ago

constant by how many ? are you sure it's not related to the positioning of the marker itself ? by default the marker image is centered on the position, you can change it with the anchor marker attribute (for example "bottom center")

mistic100 commented 8 years ago

For me it doesn't make sense to store the last clicked position in the viewer, it's an ephemeral thing.

gp187 commented 8 years ago

It's a constant of about 30px by screen size, exactly under the clicked spot. It makes sense, because the click you use to save latitude and longitude and store info about the objects in the 360.

This is a inserted marker on click event

<div class="marker visible" style="width: 32px; height: 32px; transform: translate3d(183.264px, 232.993px, 0px); background-image: url(pin.png);"></div>

Something from here maybe? THREE.WebGLRenderer: image is not power of two (4095x2047). Resized to 4096x2048 <canvas width=​"4095" height=​"2047">​ This is automatic on each load of 360

mistic100 commented 8 years ago

I just tested with a simple code in the demo file

PSV.on('click', function(e) {
    PSV.addMarker({
      id: Math.random(),
      longitude: e.longitude,
      latitude: e.latitude,
      image: 'pin2.png',
      width: 32,
      height: 32,
      anchor: 'bottom center'
    });
  });

and it works perfectly, no offset

the THREE JS warning about the texture size has not impact

gp187 commented 8 years ago

Yes, working fine. I found the margin-top issue. When you have something on top of the container, the marker will drop by $height px

Ex:

<div style="height:40px"></div>
<div id="360ishereinthiscontainer">...</div>

the markers will drop vertically by the height of the top $element. A screen.Y problem maybe? Instead of canvas size

gp187 commented 8 years ago

Yes, just tested now. Alone in a page, it doesn't need a margin-top: -$some px If it's part of anything, like a table, div.col etc it requires further alignment

mistic100 commented 8 years ago

Forgot that "clientX" and "clientY" are always relative to the window. Now it's fixed.