CSS-Tricks / AnythingZoomer

Zoom in on images or content
https://css-tricks.github.io/AnythingZoomer/
MIT License
207 stars 45 forks source link

Magnifying svgs #36

Closed auggywonger closed 8 years ago

auggywonger commented 8 years ago

I am experimenting with the anythingzoomer plugin to magnify svgs. I read the post http://stackoverflow.com/questions/38754427/using-jquery-anythingzoomer-plugin-to-magnify-svgs for how to do it but I am still stuck.

The code I am using is below:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Time Squared Prototype</title>
        <script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script src="js/jquery.anythingzoomer.js"></script>
        <style type="text/css">

            .small svg {
                width: 500px;
                height: 500px;
            }

            .large svg {
                width: 1000px;
                height: 1000px;
            }

            .large { background: #fff; }

            .zoom { display: block; margin: 0 auto; }

            /* AnythingZoomer */
            .az-wrap, .az-small, .az-large {
                position: relative;
            }
            .az-wrap-inner {
                display: block;
                margin: 0 auto; /* center small & large content */
            }
            /* This wraps the large image and hides it */
            .az-zoom {
                background: #fff;
                border: #333 1px solid;
                position: absolute;
                top: 0;
                left: 0;
                width: 110px;
                height: 110px;
                overflow: hidden;
                z-index: 100;
                display: none;
                -moz-box-shadow: inset 0px 0px 4px #000;
                -webkit-box-shadow: inset 0px 0px 4px #000;
                box-shadow: inset 0px 0px 4px #000;
            }
            /* Class applied to az-mover when large image is windowed */
            .az-windowed {
                overflow: hidden;
                position: absolute;
            }
            /* Class applied to az-mover when large image is fully shown */
            .az-expanded {
                height: auto;
                width: auto;
                position: static;
                overflow: visible;
            }

            /* overlay small area */
            .az-overlay {
                background-color: #000;
                opacity: 0.3;
                filter: alpha(opacity=30);
                z-index: 10;
            }

            /* fade out small content when hovering
            .az-hovered > * {
                opacity: 0.5;
                filter: alpha(opacity=50);
            }
            */

            /* edit mode coordinate styling */
            .az-coords {
                display: none; /* hidden when expanded */
            }
            .az-zoom .az-coords {
                display: block;
                position: absolute;
                top: 0;
                right: 0;
                background: #000;
                background: rgba(0,0,0,0.5);
                color: #fff;
            }

        </style>
    </head>
    <body>       

        <script type="text/javascript">

            var zoom_container = d3.select("body")
                                   .append("div")
                                   .attr("id", "zoom")

            var svg = zoom_container.append("div")
                                    .attr("class", "small")
                                    .append("svg")
                                    .attr("viewBox", "0,0,500,500");

            zoom_container.append("div")
                          .attr("class", "large")
                          .style("left", "0px")
                          .style("right", "0px")

             svg.append("rect")
               .attr("x", 0)
               .attr("y", 100)
               .attr("width", 20)
               .attr("height", 20)
               .attr("fill", "red")

            $("#zoom").anythingZoomer({
                edit: true,
                clone: true
            });

        </script>
    </body>
</html>

The good news is that the zoom window does show up when the mouse hovers over the svg. The problem is that nothing on the zoom window shows up. Doing a bit of digging, it turns out if I enlarge the zoom window to, say, 1000px by 1000px, I do see the red rectangle magnified in the zoom window. However, it stays stuck in the zoom window even if I am not directly hovering over the rectangle.

I used the web inspector to compare what's going on in my code to what's going on in working examples of anythingzoomer. I notice that in my code, the div class "large az-large" does not have a style applied when the zoom window appears.

not_working_zoomer

But the working examples of anythingzoomer do have a style applied to the class "large az-large":

working_zoomer

I am completely stumped. Any advice would be appreciated.

Thanks!

Mottie commented 8 years ago

Hi @auggywonger!

There are a few issues with the code:

Here is a working demo

$(function() {
  var zoom_container = d3.select("body")
    .append("div")
    .attr("id", "zoom")

  var svg = zoom_container.append("div")
    .attr("class", "small")
    .append("svg")
    .attr({
      viewBox: "0 0 50 50",
      width: 50,
      height: 50
    });

  svg.append("rect")
    .attr("x", 0)
    .attr("y", 0)
    .attr("width", 50)
    .attr("height", 50)
    .attr("fill", "red")

  zoom_container.append("div")
    .attr("class", "large");

  $("#zoom").anythingZoomer({
    edit: true,
    clone: true,
    initialized: function(e, zoomer) {
      zoomer.$large.find('svg').attr({
        width: 100,
        height: 100
      });
    },
  });
});
auggywonger commented 8 years ago

Thanks for the reply!

I can see that the code works on jsfiddle. However, when I copy the code over to my environment, I still have the same issue... This is the code I am running right now.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Time Squared Prototype</title>
        <script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script src="js/jquery.anythingzoomer.js"></script>
        <style type="text/css">

            .hostbar {
              position: absolute;
              left: 0;
            }

            .axis path,
            .axis line {
              fill: none;
              stroke: black;
              shape-rendering: crispEdges;
            }

            .axis text {
              font-family: sans-serif;
              font-size: 11px;
            }

            .small svg {
              width: 100px;
              height: 100px;
            }

            .large svg {
              width: 250px;
              height: 250px;
            }
            .az-wrap {
              margin-top: 50px;
            }

            /* AnythingZoomer */

            .az-wrap,
            .az-small,
            .az-large {
              position: relative;
            }

            .az-wrap-inner {
              display: block;
              margin: 0 auto;
              /* center small & large content */
            }

            /* This wraps the large image and hides it */

            .az-zoom {
              background: #fff;
              border: #333 1px solid;
              position: absolute;
              top: 0;
              left: 0;
              width: 200px;
              height: 200px;
              overflow: hidden;
              z-index: 100;
              display: none;
              -moz-box-shadow: inset 0px 0px 4px #000;
              -webkit-box-shadow: inset 0px 0px 4px #000;
              box-shadow: inset 0px 0px 4px #000;
            }

            /* Class applied to az-mover when large image is windowed */

            .az-windowed {
              overflow: hidden;
              position: absolute;
            }

            /* Class applied to az-mover when large image is fully shown */

            .az-expanded {
              height: auto;
              width: auto;
              position: static;
              overflow: visible;
            }

            /* overlay small area */

            .az-overlay {
              background-color: #000;
              opacity: 0.3;
              filter: alpha(opacity=30);
              z-index: 10;
            }

            /* fade out small content when hovering
                        .az-hovered > * {
                            opacity: 0.5;
                            filter: alpha(opacity=50);
                        }
                        */

            /* edit mode coordinate styling */

            .az-coords {
              display: none;
              /* hidden when expanded */
            }

            .az-zoom .az-coords {
              display: block;
              position: absolute;
              top: 0;
              right: 0;
              background: #000;
              background: rgba(0, 0, 0, 0.5);
              color: #fff;
            }

        </style>
    </head>
    <body>       

        <script type="text/javascript">

          var zoom_container = d3.select("body")
            .append("div")
            .attr("id", "zoom")

          var svg = zoom_container.append("div")
            .attr("class", "small")
            .append("svg")
            .attr({
              viewBox: "0 0 50 50",
              width: 50,
              height: 50
            });

          svg.append("rect")
            .attr("x", 0)
            .attr("y", 0)
            .attr("width", 50)
            .attr("height", 50)
            .attr("fill", "red")

          zoom_container.append("div")
            .attr("class", "large");

          $("#zoom").anythingZoomer({
            edit: true,
            clone: true,
            initialized: function(e, zoomer) {
              zoomer.$large.find('svg').attr({
                width: 100,
                height: 100
              });
            },
          });

        </script>
    </body>
</html>

I am developing my code on my Windows laptop and viewing it with Google chrome. My code is kept in a folder where I installed node.js. I also have a server.js script in the folder. The code from server.js is below:

#!/usr/bin/env node

var express = require('express');
var app = express();
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.use(express.static('./'));

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});

The html code is kept in index.html in the folder. To run the code, I run the command node server.js from the folder in the command prompt.

Perhaps I am doing something really obvious and silly that I missed?

Mottie commented 8 years ago

Press F12 to see if there are any javascript errors. Also, don't use jQuery v1.3.2, try something newer like v3.1.0.

auggywonger commented 8 years ago

Thanks! Updating my jquery version did the trick.

I have some follow-up questions:

1) If I have enabled the clone option, do I need to explicitly create a large div? I thought that a large div would be automatically created.

2) In http://stackoverflow.com/questions/38754427/using-jquery-anythingzoomer-plugin-to-magnify-svgs , how come the demo code works even though the dimensions of the svg were not specified in javascript?

Mottie commented 8 years ago

The large div content is created when clone is set to true, not the div itself.

If you mean the original demo, the dimensions are set for the rect:

svg.append("rect")
  .attr("x", 0)
  .attr("y", 100)
  .attr("width", 20)
  .attr("height", 20)
  .attr("fill", "red")

and the viewBox on the svg is set to 500x500.

For the large div, only the svg width and height need to be adjusted. Not the rect dimensions, nor the svg viewBox the css adjusts the size of the svg.

Update: provided the correct info.

auggywonger commented 8 years ago

Hi,

Apologies, I sent the wrong link in my last post. I meant the demo in http://stackoverflow.com/questions/21553145/how-to-achieve-magnifying-square-effect-for-d3-charts .

Mottie commented 8 years ago

Sorry, you're right... I provided incorrect information.

You only need the to set the dimensions of the svg using css. I think the original demo didn't appear to work because the dimensions of the rect were 20x20 and the viewBox was set to 500x500, so there was a very small target to find in a very small result window provided by jsFiddle.

auggywonger commented 8 years ago

Thanks! That clears things up.