DavidPetrov
4 weeks ago

Image from link doesn't load on mobile with marzipano 360 viewer

Posted 4 weeks ago by DavidPetrov

I didn't know where to properly categorize this topic, but I'm experiencing a very strange behaviour which I don't know whether it has to do with marzipano or laravel routing itself. Situation is as follows: I'm using marzipano to display an equirectangular 360 image in a proper 360 view. Since files are not public, but rather located in storage/app/files/order/{orderID}/, I can't access them directly via a link, so I've built a link on my website for authorised users only to see the images.

In web.php:

Route::get('/viewFile', '[email protected]');

And then in HomeController.php:

public function viewFile(Request $req)
{

    $name = basename($req->rel_path);
    header("Content-Disposition: filename=$name");

    if($req->is360)
        return view('display_360_image', ['path' => $req->rel_path]);

    return response()->file(Storage::disk('files')->url(urldecode($req->rel_path)));
}

Respectively, 360 images are marked and the user can choose whether to see the original image or the 360 version, which is the query parameter $req->is360. $req->rel_path is respectively the relative path of the file to the files disk.

Now, when a user wants to see the 360 variant of an image, I return the following view to him. display_360_image.blade.php

<!DOCTYPE html>
<html lang = "en">
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta charset="utf-8">
        <script type="text/javascript" src="{{asset('js/jquery-3.3.1.min.js')}}" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
        <script type="text/javascript" src="{{asset('js/jquery-migrate-3.0.0.min.js')}}"></script>

        <style rel="{{asset("css/marzipano/header_style.css")}}"></style>
        <title>Company CRM 360 Displayer</title>

    </head>

    <body>
        <div id="pano"></div>

        <script>
            window.sourceURL = "viewFile?rel_path={{urldecode($path)}}";
        </script>
        <script src="{{asset('js/marzipano/rAF.js')}}"></script>
        <script src="{{asset('js/marzipano/es5-shim-master/es5-shim.min.js')}}"></script>
        
        <script src="{{asset('js/marzipano/marzipano.js')}}"></script>
        <script src="{{asset('js/marzipano/display_page.js')}}"></script>
        <style>
            * {
                -webkit-box-sizing: border-box;
                -moz-box-sizing: border-box;
                box-sizing: border-box;
                -moz-user-select: none;
                -webkit-user-select: none;
                -ms-user-select: none;
                -webkit-user-drag: none;
                -webkit-touch-callout: none;
                -ms-content-zooming: none;
            }

            html, body {
                width: 100%;
                height: 100%;
                padding: 0;
                margin: 0;
                overflow: hidden;
            }

            #pano {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
            }
        </style>
    </body>
</html>

The .js file containing the displaying logic is the following display_page.js:

$(function () {
    var viewer = new Marzipano.Viewer(document.getElementById('pano'));

    // Create source.
    var source = Marzipano.ImageUrlSource.fromString(window.sourceURL); //tha's the variable I'm setting in the blade view

    // Create geometry.
    var geometry = new Marzipano.EquirectGeometry([{ width: 4000 }]);

    // Create view.
    var limiter = Marzipano.RectilinearView.limit.traditional(1024, 100*Math.PI/180);
    var view = new Marzipano.RectilinearView({ yaw: Math.PI }, limiter);

    // Create scene.
    var scene = viewer.createScene({
      source: source,
      geometry: geometry,
      view: view,
      pinFirstLevel: true
    });

    // Display scene.
    scene.switchTo();
});
        

Nothing more than a simplistic basic usage of marzipano.

So basically, marzipano wants to load the picture from a link in order for it to be provided as a source to the plugin and then be displayed. Everything works fine on PC browsers, but on mobile browsers the pictures simply don't appear when requested in a 360 variant. I've managed to come to the conclusion however, that if one does directly access a public picture on the marzipano plugin, then it shows on mobile as well! But I can't make my order files public, so I need then displayed from the storage folder.

Basically, the user is able to see the file under https://domain.com/viewFile?rel_path=order%2F5943%2FSAM_100_0043.jpg and the image renders, but when requested as https://domain.com/viewFile?rel_path=order%2F5943%2FSAM_100_0043.jpg&is360=1 only a blank page is displayed.

However, if the image is located in let's say public/images/order/{orderID}/, then it loads with no problem as well as in 360!

Does anybody have an idea whether the problem lies within marzipano or is it a general laravel concern with mobile browsers and resource security? If any further details are required, I'm here to provide a thorough cooperation! Thanks a lot in advance!

Please sign in or create an account to participate in this conversation.