jquery: fancybox 3, responsive image maps and zoomable content





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I want to use image-maps inside fancybox 3. Goal is to display mountain panoramas, where the user could point on a summit and get name and data. The usual recommendation is to use a SVG based image map for this like in this pen. Due to the size of the images the fancybox zoom functionality is important.



While fancybox will display SVGs as an image like in this pen it is not possible to use the <image> tag with an external source inside the SVG file. Even worse: SVG files used as source of an <img> tag would not show the map functionality (see this question).



I tried to replace the <img> tag in fancybox with an <object> tag using the SVG file as data attribute. This shows the image with the map functionality correctly but fancybox won't zoom it any more.



So eventually the question boils down to how I can make an <object> (or an inline SVG or an iframe) zoomable just like an image in fancybox 3.



I'm open to other solutions as well. I only want to use fancybox to keep the appearance and usage the same as other image galleries on the same page. I'd even use an old style <map>, where I would change the coords using jquery to have it responsive. I tried that, attaching the map manually in developer tools as well as programmatically in afterLoad event handler, but apparently this doesn't work in fancybox 3 either.



The areas are polygons, so using positioned div's as overlays is no solution.



Edit: I just discovered that I can replace <img> with a <canvas> in fancybox without loosing the zoom and drag functionality. So in theory it would be possible to use canvas paths and isPointInPath() methode. Unfortunately I need more than one path, which requires the Path2D object, which is not available in IE...










share|improve this question

























  • Currently, zoom functionality is available for images only, therefore you either use some 3rd party script (like in this example - codepen.io/anon/pen/bvjeLZ?editors=1010) or wait for v4, where zoom api will be much more powerful

    – Janis
    Nov 22 '18 at 12:02


















0















I want to use image-maps inside fancybox 3. Goal is to display mountain panoramas, where the user could point on a summit and get name and data. The usual recommendation is to use a SVG based image map for this like in this pen. Due to the size of the images the fancybox zoom functionality is important.



While fancybox will display SVGs as an image like in this pen it is not possible to use the <image> tag with an external source inside the SVG file. Even worse: SVG files used as source of an <img> tag would not show the map functionality (see this question).



I tried to replace the <img> tag in fancybox with an <object> tag using the SVG file as data attribute. This shows the image with the map functionality correctly but fancybox won't zoom it any more.



So eventually the question boils down to how I can make an <object> (or an inline SVG or an iframe) zoomable just like an image in fancybox 3.



I'm open to other solutions as well. I only want to use fancybox to keep the appearance and usage the same as other image galleries on the same page. I'd even use an old style <map>, where I would change the coords using jquery to have it responsive. I tried that, attaching the map manually in developer tools as well as programmatically in afterLoad event handler, but apparently this doesn't work in fancybox 3 either.



The areas are polygons, so using positioned div's as overlays is no solution.



Edit: I just discovered that I can replace <img> with a <canvas> in fancybox without loosing the zoom and drag functionality. So in theory it would be possible to use canvas paths and isPointInPath() methode. Unfortunately I need more than one path, which requires the Path2D object, which is not available in IE...










share|improve this question

























  • Currently, zoom functionality is available for images only, therefore you either use some 3rd party script (like in this example - codepen.io/anon/pen/bvjeLZ?editors=1010) or wait for v4, where zoom api will be much more powerful

    – Janis
    Nov 22 '18 at 12:02














0












0








0


0






I want to use image-maps inside fancybox 3. Goal is to display mountain panoramas, where the user could point on a summit and get name and data. The usual recommendation is to use a SVG based image map for this like in this pen. Due to the size of the images the fancybox zoom functionality is important.



While fancybox will display SVGs as an image like in this pen it is not possible to use the <image> tag with an external source inside the SVG file. Even worse: SVG files used as source of an <img> tag would not show the map functionality (see this question).



I tried to replace the <img> tag in fancybox with an <object> tag using the SVG file as data attribute. This shows the image with the map functionality correctly but fancybox won't zoom it any more.



So eventually the question boils down to how I can make an <object> (or an inline SVG or an iframe) zoomable just like an image in fancybox 3.



I'm open to other solutions as well. I only want to use fancybox to keep the appearance and usage the same as other image galleries on the same page. I'd even use an old style <map>, where I would change the coords using jquery to have it responsive. I tried that, attaching the map manually in developer tools as well as programmatically in afterLoad event handler, but apparently this doesn't work in fancybox 3 either.



The areas are polygons, so using positioned div's as overlays is no solution.



Edit: I just discovered that I can replace <img> with a <canvas> in fancybox without loosing the zoom and drag functionality. So in theory it would be possible to use canvas paths and isPointInPath() methode. Unfortunately I need more than one path, which requires the Path2D object, which is not available in IE...










share|improve this question
















I want to use image-maps inside fancybox 3. Goal is to display mountain panoramas, where the user could point on a summit and get name and data. The usual recommendation is to use a SVG based image map for this like in this pen. Due to the size of the images the fancybox zoom functionality is important.



While fancybox will display SVGs as an image like in this pen it is not possible to use the <image> tag with an external source inside the SVG file. Even worse: SVG files used as source of an <img> tag would not show the map functionality (see this question).



I tried to replace the <img> tag in fancybox with an <object> tag using the SVG file as data attribute. This shows the image with the map functionality correctly but fancybox won't zoom it any more.



So eventually the question boils down to how I can make an <object> (or an inline SVG or an iframe) zoomable just like an image in fancybox 3.



I'm open to other solutions as well. I only want to use fancybox to keep the appearance and usage the same as other image galleries on the same page. I'd even use an old style <map>, where I would change the coords using jquery to have it responsive. I tried that, attaching the map manually in developer tools as well as programmatically in afterLoad event handler, but apparently this doesn't work in fancybox 3 either.



The areas are polygons, so using positioned div's as overlays is no solution.



Edit: I just discovered that I can replace <img> with a <canvas> in fancybox without loosing the zoom and drag functionality. So in theory it would be possible to use canvas paths and isPointInPath() methode. Unfortunately I need more than one path, which requires the Path2D object, which is not available in IE...







svg imagemap fancybox-3






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 '18 at 20:32







Erik Krause

















asked Nov 22 '18 at 9:38









Erik KrauseErik Krause

11




11













  • Currently, zoom functionality is available for images only, therefore you either use some 3rd party script (like in this example - codepen.io/anon/pen/bvjeLZ?editors=1010) or wait for v4, where zoom api will be much more powerful

    – Janis
    Nov 22 '18 at 12:02



















  • Currently, zoom functionality is available for images only, therefore you either use some 3rd party script (like in this example - codepen.io/anon/pen/bvjeLZ?editors=1010) or wait for v4, where zoom api will be much more powerful

    – Janis
    Nov 22 '18 at 12:02

















Currently, zoom functionality is available for images only, therefore you either use some 3rd party script (like in this example - codepen.io/anon/pen/bvjeLZ?editors=1010) or wait for v4, where zoom api will be much more powerful

– Janis
Nov 22 '18 at 12:02





Currently, zoom functionality is available for images only, therefore you either use some 3rd party script (like in this example - codepen.io/anon/pen/bvjeLZ?editors=1010) or wait for v4, where zoom api will be much more powerful

– Janis
Nov 22 '18 at 12:02












1 Answer
1






active

oldest

votes


















0














Since all options discussed in the question turned out to be not feasible and I found the pnpoly point in polygon algorithm, I did the whole thing on my own. I put the coordinates as percentages (in order to be size-independent) in an array of javascript objects like so:



    var maps = {
alpen : [
{type:'poly',name:'Finsteraarhorn (4274m)',vertx:[56.48,56.08,56.06,56.46], verty:[28.5,28.75,40.25,40.25]},
{type:'rect',name:'Fiescherhörner (4049m)',coords:[58.08,29.5,59.26,43.5]},
{type:'poly',name:'Eiger (3970m)',vertx:[61.95,61.31,61.31,60.5,60.5], verty:[43,35.25,30.25,30.25,45.5]}
]
}; // maps


Since the pnpoly function requires the vertices for x and y separately I provide the coordinates this way already.



The Id of the map is stored in a data attribute in the source link:



  <a href="/img/bilder/Alpen.jpg" data-type='image' data-Id='alpen' data-fancybox="img" data-caption="<h5>panorama of the alps from the black forest Belchen at sunset</h5>">
<img src="/_pano/bilder/Alpen.jpg">
</a>


CSS for the tooltip:



.my-tooltip {
color: #ccc;
background: rgba(30,30,30,.6);
position: absolute;
padding: 5px;
text-align: left;
border-radius: 5px;
font-size: 12px;
}


pnpoly and pnrect are provided as simple functions, the handling of that all is done in the afterShow event handler:



// PNPoly algorithm checkes whether point in polygon
function pnpoly(vertx, verty, testx, testy) {
var i, j, c = false;
var nvert = vertx.length;
for(i=0, j=nvert-1; i<nvert; j=i++) {
if (((verty[i] > testy) != (verty[j] > testy)) &&
(testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
c = !c;
}
}
return c;
}

// checks whether point in rectangle
function pnrect(coords,testx,testy) {
return ((testx >= coords[0]) && (testx <= coords[2]) && (testy >= coords[1]) && (testy <= coords[3]));
}

$("[data-fancybox]").fancybox({
afterShow: function( instance, slide ) {
var map = maps[$(slide.opts.$orig).data('id')]; // Get map name from source link data-ID
if (map && map.length) { // if map present
$(".fancybox-image")
.after("<span class='my-tooltip' style='display: none'></span>") // append tooltip after image
.mousemove(function(event) { // create mousemove event handler
var offset = $(this).offset(); // get image offset, since mouse coords are global
var perX = ((event.pageX - offset.left)*100)/$(this).width(); // calculate mouse coords in image as percentages
var perY = ((event.pageY - offset.top)*100)/$(this).height();
var found = false;
var i;
for (i = 0; i < map.length; i++) { // loop over map entries
if (found = (map[i].type == 'poly') // depending on area type
?pnpoly(map[i].vertx, map[i].verty, perX, perY) // look whether coords are in polygon
:pnrect(map[i].coords, perX, perY)) // or coords are in rectangle
break; // if found stop looping
} // for (i = 0; i < map.length; i++)
if (found) {
$(".my-tooltip")
.css({bottom: 'calc(15px + '+ (100 - perY) + '%'}) // tooltip 15px above mouse coursor
.css((perX < 50) // depending on which side we are
?{right:'', left: perX + '%'} // tooltip left of mouse cursor
:{right: (100 - perX) + '%', left:''}) // or tooltip right of mouse cursor
.text(map[i].name) // set tooltip text
.show(); // show tooltip
} else {
$(".my-tooltip").hide(); // if nothing found: hide.
}
});
} else { // if (map && map.length) // if no map present
$(".fancybox-image").off('mousemove'); // remove event mousemove handler
$(".my-tooltip").remove(); // remove tooltip
} // else if (map && map.length)
} // function( instance, slide )
});


Things left to do: Find a solution for touch devices, f.e. provide a button to show all tooltips (probably rotated 90°).



As soon as the page is online I'll provide a link here to see it working...






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53427853%2fjquery-fancybox-3-responsive-image-maps-and-zoomable-content%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Since all options discussed in the question turned out to be not feasible and I found the pnpoly point in polygon algorithm, I did the whole thing on my own. I put the coordinates as percentages (in order to be size-independent) in an array of javascript objects like so:



        var maps = {
    alpen : [
    {type:'poly',name:'Finsteraarhorn (4274m)',vertx:[56.48,56.08,56.06,56.46], verty:[28.5,28.75,40.25,40.25]},
    {type:'rect',name:'Fiescherhörner (4049m)',coords:[58.08,29.5,59.26,43.5]},
    {type:'poly',name:'Eiger (3970m)',vertx:[61.95,61.31,61.31,60.5,60.5], verty:[43,35.25,30.25,30.25,45.5]}
    ]
    }; // maps


    Since the pnpoly function requires the vertices for x and y separately I provide the coordinates this way already.



    The Id of the map is stored in a data attribute in the source link:



      <a href="/img/bilder/Alpen.jpg" data-type='image' data-Id='alpen' data-fancybox="img" data-caption="<h5>panorama of the alps from the black forest Belchen at sunset</h5>">
    <img src="/_pano/bilder/Alpen.jpg">
    </a>


    CSS for the tooltip:



    .my-tooltip {
    color: #ccc;
    background: rgba(30,30,30,.6);
    position: absolute;
    padding: 5px;
    text-align: left;
    border-radius: 5px;
    font-size: 12px;
    }


    pnpoly and pnrect are provided as simple functions, the handling of that all is done in the afterShow event handler:



    // PNPoly algorithm checkes whether point in polygon
    function pnpoly(vertx, verty, testx, testy) {
    var i, j, c = false;
    var nvert = vertx.length;
    for(i=0, j=nvert-1; i<nvert; j=i++) {
    if (((verty[i] > testy) != (verty[j] > testy)) &&
    (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
    c = !c;
    }
    }
    return c;
    }

    // checks whether point in rectangle
    function pnrect(coords,testx,testy) {
    return ((testx >= coords[0]) && (testx <= coords[2]) && (testy >= coords[1]) && (testy <= coords[3]));
    }

    $("[data-fancybox]").fancybox({
    afterShow: function( instance, slide ) {
    var map = maps[$(slide.opts.$orig).data('id')]; // Get map name from source link data-ID
    if (map && map.length) { // if map present
    $(".fancybox-image")
    .after("<span class='my-tooltip' style='display: none'></span>") // append tooltip after image
    .mousemove(function(event) { // create mousemove event handler
    var offset = $(this).offset(); // get image offset, since mouse coords are global
    var perX = ((event.pageX - offset.left)*100)/$(this).width(); // calculate mouse coords in image as percentages
    var perY = ((event.pageY - offset.top)*100)/$(this).height();
    var found = false;
    var i;
    for (i = 0; i < map.length; i++) { // loop over map entries
    if (found = (map[i].type == 'poly') // depending on area type
    ?pnpoly(map[i].vertx, map[i].verty, perX, perY) // look whether coords are in polygon
    :pnrect(map[i].coords, perX, perY)) // or coords are in rectangle
    break; // if found stop looping
    } // for (i = 0; i < map.length; i++)
    if (found) {
    $(".my-tooltip")
    .css({bottom: 'calc(15px + '+ (100 - perY) + '%'}) // tooltip 15px above mouse coursor
    .css((perX < 50) // depending on which side we are
    ?{right:'', left: perX + '%'} // tooltip left of mouse cursor
    :{right: (100 - perX) + '%', left:''}) // or tooltip right of mouse cursor
    .text(map[i].name) // set tooltip text
    .show(); // show tooltip
    } else {
    $(".my-tooltip").hide(); // if nothing found: hide.
    }
    });
    } else { // if (map && map.length) // if no map present
    $(".fancybox-image").off('mousemove'); // remove event mousemove handler
    $(".my-tooltip").remove(); // remove tooltip
    } // else if (map && map.length)
    } // function( instance, slide )
    });


    Things left to do: Find a solution for touch devices, f.e. provide a button to show all tooltips (probably rotated 90°).



    As soon as the page is online I'll provide a link here to see it working...






    share|improve this answer




























      0














      Since all options discussed in the question turned out to be not feasible and I found the pnpoly point in polygon algorithm, I did the whole thing on my own. I put the coordinates as percentages (in order to be size-independent) in an array of javascript objects like so:



          var maps = {
      alpen : [
      {type:'poly',name:'Finsteraarhorn (4274m)',vertx:[56.48,56.08,56.06,56.46], verty:[28.5,28.75,40.25,40.25]},
      {type:'rect',name:'Fiescherhörner (4049m)',coords:[58.08,29.5,59.26,43.5]},
      {type:'poly',name:'Eiger (3970m)',vertx:[61.95,61.31,61.31,60.5,60.5], verty:[43,35.25,30.25,30.25,45.5]}
      ]
      }; // maps


      Since the pnpoly function requires the vertices for x and y separately I provide the coordinates this way already.



      The Id of the map is stored in a data attribute in the source link:



        <a href="/img/bilder/Alpen.jpg" data-type='image' data-Id='alpen' data-fancybox="img" data-caption="<h5>panorama of the alps from the black forest Belchen at sunset</h5>">
      <img src="/_pano/bilder/Alpen.jpg">
      </a>


      CSS for the tooltip:



      .my-tooltip {
      color: #ccc;
      background: rgba(30,30,30,.6);
      position: absolute;
      padding: 5px;
      text-align: left;
      border-radius: 5px;
      font-size: 12px;
      }


      pnpoly and pnrect are provided as simple functions, the handling of that all is done in the afterShow event handler:



      // PNPoly algorithm checkes whether point in polygon
      function pnpoly(vertx, verty, testx, testy) {
      var i, j, c = false;
      var nvert = vertx.length;
      for(i=0, j=nvert-1; i<nvert; j=i++) {
      if (((verty[i] > testy) != (verty[j] > testy)) &&
      (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
      c = !c;
      }
      }
      return c;
      }

      // checks whether point in rectangle
      function pnrect(coords,testx,testy) {
      return ((testx >= coords[0]) && (testx <= coords[2]) && (testy >= coords[1]) && (testy <= coords[3]));
      }

      $("[data-fancybox]").fancybox({
      afterShow: function( instance, slide ) {
      var map = maps[$(slide.opts.$orig).data('id')]; // Get map name from source link data-ID
      if (map && map.length) { // if map present
      $(".fancybox-image")
      .after("<span class='my-tooltip' style='display: none'></span>") // append tooltip after image
      .mousemove(function(event) { // create mousemove event handler
      var offset = $(this).offset(); // get image offset, since mouse coords are global
      var perX = ((event.pageX - offset.left)*100)/$(this).width(); // calculate mouse coords in image as percentages
      var perY = ((event.pageY - offset.top)*100)/$(this).height();
      var found = false;
      var i;
      for (i = 0; i < map.length; i++) { // loop over map entries
      if (found = (map[i].type == 'poly') // depending on area type
      ?pnpoly(map[i].vertx, map[i].verty, perX, perY) // look whether coords are in polygon
      :pnrect(map[i].coords, perX, perY)) // or coords are in rectangle
      break; // if found stop looping
      } // for (i = 0; i < map.length; i++)
      if (found) {
      $(".my-tooltip")
      .css({bottom: 'calc(15px + '+ (100 - perY) + '%'}) // tooltip 15px above mouse coursor
      .css((perX < 50) // depending on which side we are
      ?{right:'', left: perX + '%'} // tooltip left of mouse cursor
      :{right: (100 - perX) + '%', left:''}) // or tooltip right of mouse cursor
      .text(map[i].name) // set tooltip text
      .show(); // show tooltip
      } else {
      $(".my-tooltip").hide(); // if nothing found: hide.
      }
      });
      } else { // if (map && map.length) // if no map present
      $(".fancybox-image").off('mousemove'); // remove event mousemove handler
      $(".my-tooltip").remove(); // remove tooltip
      } // else if (map && map.length)
      } // function( instance, slide )
      });


      Things left to do: Find a solution for touch devices, f.e. provide a button to show all tooltips (probably rotated 90°).



      As soon as the page is online I'll provide a link here to see it working...






      share|improve this answer


























        0












        0








        0







        Since all options discussed in the question turned out to be not feasible and I found the pnpoly point in polygon algorithm, I did the whole thing on my own. I put the coordinates as percentages (in order to be size-independent) in an array of javascript objects like so:



            var maps = {
        alpen : [
        {type:'poly',name:'Finsteraarhorn (4274m)',vertx:[56.48,56.08,56.06,56.46], verty:[28.5,28.75,40.25,40.25]},
        {type:'rect',name:'Fiescherhörner (4049m)',coords:[58.08,29.5,59.26,43.5]},
        {type:'poly',name:'Eiger (3970m)',vertx:[61.95,61.31,61.31,60.5,60.5], verty:[43,35.25,30.25,30.25,45.5]}
        ]
        }; // maps


        Since the pnpoly function requires the vertices for x and y separately I provide the coordinates this way already.



        The Id of the map is stored in a data attribute in the source link:



          <a href="/img/bilder/Alpen.jpg" data-type='image' data-Id='alpen' data-fancybox="img" data-caption="<h5>panorama of the alps from the black forest Belchen at sunset</h5>">
        <img src="/_pano/bilder/Alpen.jpg">
        </a>


        CSS for the tooltip:



        .my-tooltip {
        color: #ccc;
        background: rgba(30,30,30,.6);
        position: absolute;
        padding: 5px;
        text-align: left;
        border-radius: 5px;
        font-size: 12px;
        }


        pnpoly and pnrect are provided as simple functions, the handling of that all is done in the afterShow event handler:



        // PNPoly algorithm checkes whether point in polygon
        function pnpoly(vertx, verty, testx, testy) {
        var i, j, c = false;
        var nvert = vertx.length;
        for(i=0, j=nvert-1; i<nvert; j=i++) {
        if (((verty[i] > testy) != (verty[j] > testy)) &&
        (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
        c = !c;
        }
        }
        return c;
        }

        // checks whether point in rectangle
        function pnrect(coords,testx,testy) {
        return ((testx >= coords[0]) && (testx <= coords[2]) && (testy >= coords[1]) && (testy <= coords[3]));
        }

        $("[data-fancybox]").fancybox({
        afterShow: function( instance, slide ) {
        var map = maps[$(slide.opts.$orig).data('id')]; // Get map name from source link data-ID
        if (map && map.length) { // if map present
        $(".fancybox-image")
        .after("<span class='my-tooltip' style='display: none'></span>") // append tooltip after image
        .mousemove(function(event) { // create mousemove event handler
        var offset = $(this).offset(); // get image offset, since mouse coords are global
        var perX = ((event.pageX - offset.left)*100)/$(this).width(); // calculate mouse coords in image as percentages
        var perY = ((event.pageY - offset.top)*100)/$(this).height();
        var found = false;
        var i;
        for (i = 0; i < map.length; i++) { // loop over map entries
        if (found = (map[i].type == 'poly') // depending on area type
        ?pnpoly(map[i].vertx, map[i].verty, perX, perY) // look whether coords are in polygon
        :pnrect(map[i].coords, perX, perY)) // or coords are in rectangle
        break; // if found stop looping
        } // for (i = 0; i < map.length; i++)
        if (found) {
        $(".my-tooltip")
        .css({bottom: 'calc(15px + '+ (100 - perY) + '%'}) // tooltip 15px above mouse coursor
        .css((perX < 50) // depending on which side we are
        ?{right:'', left: perX + '%'} // tooltip left of mouse cursor
        :{right: (100 - perX) + '%', left:''}) // or tooltip right of mouse cursor
        .text(map[i].name) // set tooltip text
        .show(); // show tooltip
        } else {
        $(".my-tooltip").hide(); // if nothing found: hide.
        }
        });
        } else { // if (map && map.length) // if no map present
        $(".fancybox-image").off('mousemove'); // remove event mousemove handler
        $(".my-tooltip").remove(); // remove tooltip
        } // else if (map && map.length)
        } // function( instance, slide )
        });


        Things left to do: Find a solution for touch devices, f.e. provide a button to show all tooltips (probably rotated 90°).



        As soon as the page is online I'll provide a link here to see it working...






        share|improve this answer













        Since all options discussed in the question turned out to be not feasible and I found the pnpoly point in polygon algorithm, I did the whole thing on my own. I put the coordinates as percentages (in order to be size-independent) in an array of javascript objects like so:



            var maps = {
        alpen : [
        {type:'poly',name:'Finsteraarhorn (4274m)',vertx:[56.48,56.08,56.06,56.46], verty:[28.5,28.75,40.25,40.25]},
        {type:'rect',name:'Fiescherhörner (4049m)',coords:[58.08,29.5,59.26,43.5]},
        {type:'poly',name:'Eiger (3970m)',vertx:[61.95,61.31,61.31,60.5,60.5], verty:[43,35.25,30.25,30.25,45.5]}
        ]
        }; // maps


        Since the pnpoly function requires the vertices for x and y separately I provide the coordinates this way already.



        The Id of the map is stored in a data attribute in the source link:



          <a href="/img/bilder/Alpen.jpg" data-type='image' data-Id='alpen' data-fancybox="img" data-caption="<h5>panorama of the alps from the black forest Belchen at sunset</h5>">
        <img src="/_pano/bilder/Alpen.jpg">
        </a>


        CSS for the tooltip:



        .my-tooltip {
        color: #ccc;
        background: rgba(30,30,30,.6);
        position: absolute;
        padding: 5px;
        text-align: left;
        border-radius: 5px;
        font-size: 12px;
        }


        pnpoly and pnrect are provided as simple functions, the handling of that all is done in the afterShow event handler:



        // PNPoly algorithm checkes whether point in polygon
        function pnpoly(vertx, verty, testx, testy) {
        var i, j, c = false;
        var nvert = vertx.length;
        for(i=0, j=nvert-1; i<nvert; j=i++) {
        if (((verty[i] > testy) != (verty[j] > testy)) &&
        (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
        c = !c;
        }
        }
        return c;
        }

        // checks whether point in rectangle
        function pnrect(coords,testx,testy) {
        return ((testx >= coords[0]) && (testx <= coords[2]) && (testy >= coords[1]) && (testy <= coords[3]));
        }

        $("[data-fancybox]").fancybox({
        afterShow: function( instance, slide ) {
        var map = maps[$(slide.opts.$orig).data('id')]; // Get map name from source link data-ID
        if (map && map.length) { // if map present
        $(".fancybox-image")
        .after("<span class='my-tooltip' style='display: none'></span>") // append tooltip after image
        .mousemove(function(event) { // create mousemove event handler
        var offset = $(this).offset(); // get image offset, since mouse coords are global
        var perX = ((event.pageX - offset.left)*100)/$(this).width(); // calculate mouse coords in image as percentages
        var perY = ((event.pageY - offset.top)*100)/$(this).height();
        var found = false;
        var i;
        for (i = 0; i < map.length; i++) { // loop over map entries
        if (found = (map[i].type == 'poly') // depending on area type
        ?pnpoly(map[i].vertx, map[i].verty, perX, perY) // look whether coords are in polygon
        :pnrect(map[i].coords, perX, perY)) // or coords are in rectangle
        break; // if found stop looping
        } // for (i = 0; i < map.length; i++)
        if (found) {
        $(".my-tooltip")
        .css({bottom: 'calc(15px + '+ (100 - perY) + '%'}) // tooltip 15px above mouse coursor
        .css((perX < 50) // depending on which side we are
        ?{right:'', left: perX + '%'} // tooltip left of mouse cursor
        :{right: (100 - perX) + '%', left:''}) // or tooltip right of mouse cursor
        .text(map[i].name) // set tooltip text
        .show(); // show tooltip
        } else {
        $(".my-tooltip").hide(); // if nothing found: hide.
        }
        });
        } else { // if (map && map.length) // if no map present
        $(".fancybox-image").off('mousemove'); // remove event mousemove handler
        $(".my-tooltip").remove(); // remove tooltip
        } // else if (map && map.length)
        } // function( instance, slide )
        });


        Things left to do: Find a solution for touch devices, f.e. provide a button to show all tooltips (probably rotated 90°).



        As soon as the page is online I'll provide a link here to see it working...







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 24 '18 at 21:36









        Erik KrauseErik Krause

        11




        11
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53427853%2fjquery-fancybox-3-responsive-image-maps-and-zoomable-content%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            鏡平學校

            ꓛꓣだゔៀៅຸ໢ທຮ໕໒ ,ໂ'໥໓າ໼ឨឲ៵៭ៈゎゔit''䖳𥁄卿' ☨₤₨こゎもょの;ꜹꟚꞖꞵꟅꞛေၦေɯ,ɨɡ𛃵𛁹ޝ޳ޠ޾,ޤޒޯ޾𫝒𫠁သ𛅤チョ'サノބޘދ𛁐ᶿᶇᶀᶋᶠ㨑㽹⻮ꧬ꧹؍۩وَؠ㇕㇃㇪ ㇦㇋㇋ṜẰᵡᴠ 軌ᵕ搜۳ٰޗޮ޷ސޯ𫖾𫅀ल, ꙭ꙰ꚅꙁꚊꞻꝔ꟠Ꝭㄤﺟޱސꧨꧼ꧴ꧯꧽ꧲ꧯ'⽹⽭⾁⿞⼳⽋២៩ញណើꩯꩤ꩸ꩮᶻᶺᶧᶂ𫳲𫪭𬸄𫵰𬖩𬫣𬊉ၲ𛅬㕦䬺𫝌𫝼,,𫟖𫞽ហៅ஫㆔ాఆఅꙒꚞꙍ,Ꙟ꙱エ ,ポテ,フࢰࢯ𫟠𫞶 𫝤𫟠ﺕﹱﻜﻣ𪵕𪭸𪻆𪾩𫔷ġ,ŧآꞪ꟥,ꞔꝻ♚☹⛵𛀌ꬷꭞȄƁƪƬșƦǙǗdžƝǯǧⱦⱰꓕꓢႋ神 ဴ၀க௭எ௫ឫោ ' េㇷㇴㇼ神ㇸㇲㇽㇴㇼㇻㇸ'ㇸㇿㇸㇹㇰㆣꓚꓤ₡₧ ㄨㄟ㄂ㄖㄎ໗ツڒذ₶।ऩछएोञयूटक़कयँृी,冬'𛅢𛅥ㇱㇵㇶ𥄥𦒽𠣧𠊓𧢖𥞘𩔋цѰㄠſtʯʭɿʆʗʍʩɷɛ,əʏダヵㄐㄘR{gỚṖḺờṠṫảḙḭᴮᵏᴘᵀᵷᵕᴜᴏᵾq﮲ﲿﴽﭙ軌ﰬﶚﶧ﫲Ҝжюїкӈㇴffצּ﬘﭅﬈軌'ffistfflſtffतभफɳɰʊɲʎ𛁱𛁖𛁮𛀉 𛂯𛀞నఋŀŲ 𫟲𫠖𫞺ຆຆ ໹້໕໗ๆทԊꧢꧠ꧰ꓱ⿝⼑ŎḬẃẖỐẅ ,ờỰỈỗﮊDžȩꭏꭎꬻ꭮ꬿꭖꭥꭅ㇭神 ⾈ꓵꓑ⺄㄄ㄪㄙㄅㄇstA۵䞽ॶ𫞑𫝄㇉㇇゜軌𩜛𩳠Jﻺ‚Üမ႕ႌႊၐၸဓၞၞၡ៸wyvtᶎᶪᶹစဎ꣡꣰꣢꣤ٗ؋لㇳㇾㇻㇱ㆐㆔,,㆟Ⱶヤマފ޼ޝަݿݞݠݷݐ',ݘ,ݪݙݵ𬝉𬜁𫝨𫞘くせぉて¼óû×ó£…𛅑הㄙくԗԀ5606神45,神796'𪤻𫞧ꓐ㄁ㄘɥɺꓵꓲ3''7034׉ⱦⱠˆ“𫝋ȍ,ꩲ軌꩷ꩶꩧꩫఞ۔فڱێظペサ神ナᴦᵑ47 9238їﻂ䐊䔉㠸﬎ffiﬣ,לּᴷᴦᵛᵽ,ᴨᵤ ᵸᵥᴗᵈꚏꚉꚟ⻆rtǟƴ𬎎

            Why https connections are so slow when debugging (stepping over) in Java?