使用<svg>而不是</svg> <embed />时,必须如何调整ThumbnailViewer示例?

时间:2015-11-16 08:59:35

标签: svgpanzoom

我正在使用ariutta svg-pan-zoom库(https://github.com/ariutta/svg-pan-zoom)。 现在我想创建一个ThumbnailViewer,如演示文件中所述(view-source:http://ariutta.github.io/svg-pan-zoom/demo/thumbnailViewer.html)。

我没有使用标签嵌入svg.file,而是直接使用。我如何更改这个有效的演示代码?

我的代码是:

<div id="mainViewContainer">
  <!--<embed id="mainView" type="image/svg+xml" src="lib/svg-pan-zoom/demo/tiger.svg"/>-->

    <svg id="mainView" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 800"><rect fill="#00000", x="10"  y="20" width="100" height="100"></rect></svg>


</div>

<div id="thumbViewContainer" class="thumbViewClass">
  <svg id="scopeContainer" viewBox="0 0 500 500">
    <g>
      <rect id="scope" fill="red" fill-opacity="0.1" stroke="red" stroke-width="2px" x="0" y="0" width="0" height="0"/>
      <line id="line1" stroke="red" stroke-width="2px" x1="0" y1="0" x2="0" y2="0"/>
      <line id="line2" stroke="red" stroke-width="2px" x1="0" y1="0" x2="0" y2="0"/>
    </g>
  </svg>

    <svg id="thumbView" class="thumbViewClass" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 800" ><rect fill="#00000", x="10"  y="20" width="100" height="100" ></rect></svg>


  <!--<embed id="thumbView" type="image/svg+xml" src="lib/svg-pan-zoom/demo/tiger.svg" class="thumbViewClass"/>-->
</div>

2 个答案:

答案 0 :(得分:0)

您应该使用embed element,就像使用svg元素一样。

唯一的区别是,在您的案例中初始化svgPanZoom(或缩略图查看器)之前,您必须wait for embed element to load

答案 1 :(得分:0)

我明白了!

enter image description here

主要区别在于加载的SVG的大小。

  • 嵌入后,在加载时自动将svg调整为父div或标签容器的大小。
  • 使用svg内联时,将加载svg,并具有width和height本身的属性。

我逐行调试了库,发现在计算矩阵SVG转换时,从SVG标签中获取了clientHeight和clientWidth,并将视口的大小调整为我上面定义的大小。因此,简单的答案是,将样式的高度和宽度设置为等于100%。

#id_mainSVG, #id_thumbSVG {
   height: 100%;
   width: 100%;
}

var thumbnailViewer = function(options) {
  var getSVGDocument = function(objectElem) {
    var svgDoc = objectElem.contentDocument;
    if (!svgDoc) {
      if (typeof objectElem.getSVGDocument === "function") {
        svgDoc = objectElem.getSVGDocument();
      }
    }
    return svgDoc;
  }

  var bindThumbnail = function(main, thumb, scopeContainerId) {
    if (!window.main && main) {
      window.main = main;
    }
    if (!window.thumb && thumb) {
      window.thumb = thumb;
    }
    if (!window.main || !window.thumb) {
      return;
    }

    var resizeTimer;
    var interval = 300; //msec
    window.addEventListener('resize', function(event) {
      if (resizeTimer !== false) {
        clearTimeout(resizeTimer);
      }
      resizeTimer = setTimeout(function() {
        window.main.resize();
        window.thumb.resize();
      }, interval);
    });

    window.main.setOnZoom(function(level) {
      window.thumb.updateThumbScope();
      if (options.onZoom) {
        options.onZoom(window.main, window.thumb, level);
      }
    });

    window.main.setOnPan(function(point) {
      window.thumb.updateThumbScope();
      if (options.onPan) {
        options.onPan(window.main, window.thumb, point);
      }
    });

    var _updateThumbScope = function(main, thumb, scope, line1, line2) {
      var mainPanX = main.getPan().x,
        mainPanY = main.getPan().y,
        mainWidth = main.getSizes().width,
        mainHeight = main.getSizes().height,
        mainZoom = main.getSizes().realZoom,
        thumbPanX = thumb.getPan().x,
        thumbPanY = thumb.getPan().y,
        thumbZoom = thumb.getSizes().realZoom;

      var thumByMainZoomRatio = thumbZoom / mainZoom;

      var scopeX = thumbPanX - mainPanX * thumByMainZoomRatio;
      var scopeY = thumbPanY - mainPanY * thumByMainZoomRatio;
      var scopeWidth = mainWidth * thumByMainZoomRatio;
      var scopeHeight = mainHeight * thumByMainZoomRatio;

      scope.setAttribute("x", scopeX + 1);
      scope.setAttribute("y", scopeY + 1);
      scope.setAttribute("width", scopeWidth - 2);
      scope.setAttribute("height", scopeHeight - 2);
      /*
              line1.setAttribute("x1", scopeX + 1);
              line1.setAttribute("y1", scopeY + 1);
              line1.setAttribute("x2", scopeX + 1 + scopeWidth - 2);
              line1.setAttribute("y2", scopeY + 1 + scopeHeight - 2);
              line2.setAttribute("x1", scopeX + 1);
              line2.setAttribute("y1", scopeY + 1 + scopeHeight - 2);
              line2.setAttribute("x2", scopeX + 1 + scopeWidth - 2);
              line2.setAttribute("y2", scopeY + 1);
            */
    };

    window.thumb.updateThumbScope = function() {
      // TODO: Parametrizar estas varibales id del html
      var scope = document.getElementById('scope');
      var line1 = document.getElementById('line1');
      var line2 = document.getElementById('line2');
      _updateThumbScope(window.main, window.thumb, scope, line1, line2);
    }
    window.thumb.updateThumbScope();

    var _updateMainViewPan = function(clientX, clientY, scopeContainer, main, thumb) {
      var dim = scopeContainer.getBoundingClientRect(),
        mainWidth = main.getSizes().width,
        mainHeight = main.getSizes().height,
        mainZoom = main.getSizes().realZoom,
        thumbWidth = thumb.getSizes().width,
        thumbHeight = thumb.getSizes().height,
        thumbZoom = thumb.getSizes().realZoom;

      var thumbPanX = clientX - dim.left - thumbWidth / 2;
      var thumbPanY = clientY - dim.top - thumbHeight / 2;
      var mainPanX = -thumbPanX * mainZoom / thumbZoom;
      var mainPanY = -thumbPanY * mainZoom / thumbZoom;
      main.pan({
        x: mainPanX,
        y: mainPanY
      });
    };
    var updateMainViewPan = function(evt, scopeContainerId) {
      if (evt.which == 0 && evt.button == 0) {
        return false;
      }
      var scopeContainer = document.getElementById(scopeContainerId);
      _updateMainViewPan(evt.clientX, evt.clientY, scopeContainer, window.main, window.thumb);
    }

    var scopeContainer = document.getElementById(scopeContainerId);
    scopeContainer.addEventListener('click', function(evt) {
      updateMainViewPan(evt, scopeContainerId);
    });

    scopeContainer.addEventListener('mousemove', function(evt) {
      updateMainViewPan(evt, scopeContainerId);
    });
  };

  var initMainView = function() {
    var mainViewSVGDoc = getSVGDocument(mainViewObjectElem);
    if (options.onMainViewSVGLoaded) {
      options.onMainViewSVGLoaded(mainViewSVGDoc);
    }

    var beforePan = function(oldPan, newPan) {
      var stopHorizontal = false,
        stopVertical = false,
        gutterWidth = 100,
        gutterHeight = 100
        // Computed variables
        ,
        sizes = this.getSizes(),
        leftLimit = -((sizes.viewBox.x + sizes.viewBox.width) * sizes.realZoom) + gutterWidth,
        rightLimit = sizes.width - gutterWidth - (sizes.viewBox.x * sizes.realZoom),
        topLimit = -((sizes.viewBox.y + sizes.viewBox.height) * sizes.realZoom) + gutterHeight,
        bottomLimit = sizes.height - gutterHeight - (sizes.viewBox.y * sizes.realZoom);
      customPan = {};
      customPan.x = Math.max(leftLimit, Math.min(rightLimit, newPan.x));
      customPan.y = Math.max(topLimit, Math.min(bottomLimit, newPan.y));
      return customPan;
    };

    var main = svgPanZoom('#' + options.mainSVGId, {
      zoomEnabled: true,
      controlIconsEnabled: true,
      fit: true,
      center: true,
      beforePan: beforePan,
    });


    bindThumbnail(main, undefined, options.scopeContainerId);
    if (options.onMainViewShown) {
      options.onMainViewShown(mainViewSVGDoc, main);
    }
  };
  var mainViewObjectElem = document.getElementById(options.mainSVGId);
  mainViewObjectElem.addEventListener("load", function() {
    initMainView();
  }, false);

  var initThumbView = function() {
    var thumbViewSVGDoc = getSVGDocument(thumbViewObjectElem);
    if (options.onThumbnailSVGLoaded) {
      options.onThumbnailSVGLoaded(thumbViewSVGDoc);
    }

    var thumb = svgPanZoom('#' + options.thumbSVGId, {
      fit: true,
      zoomEnabled: false,
      panEnabled: false,
      controlIconsEnabled: false,
      dblClickZoomEnabled: false,
      preventMouseEventsDefault: true,
    });

    bindThumbnail(undefined, thumb, options.scopeContainerId);
    if (options.onThumbnailShown) {
      options.onThumbnailShown(thumbViewSVGDoc, thumb);
    }
  };
  var thumbViewObjectElem = document.getElementById(options.thumbSVGId);
  thumbViewObjectElem.addEventListener("load", function() {
    initThumbView();
  }, false);

  // Se inicializan los controles
  initThumbView();
  initMainView();
};
body {
  background: #f5f5f5;
}

html,
body {
  width: 100%;
  height: 100%;
}

#mainViewContainer {
  width: 95%;
  height: 95%;
  border: 1px solid black;
  margin: 10px;
  padding: 3px;
  overflow: hidden;
}

#mainView {
  width: 100%;
  height: 100%;
  min-height: 100%;
  display: inline;
}

.thumbViewClass {
  border: 1px solid black;
  position: absolute;
  bottom: 5px;
  left: 5px;
  width: 20%;
  height: 30%;
  margin: 3px;
  padding: 3px;
  overflow: hidden;
}

#thumbSVG,
#mainSVG {
  height: 100%;
  width: 100%;
}

#thumbView {
  z-index: 110;
  background: white;
}

#scopeContainer {
  z-index: 120;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <!--  Meta  -->
  <meta charset="UTF-8">
  <title>My New Project!</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="http://ariutta.github.io/svg-pan-zoom/dist/svg-pan-zoom.js"></script>
</head>

<body>
  <div id="mainViewContainer">
    <div id="mainView">
      <svg id="mainSVG" style="display: inline; width: inherit; min-width: inherit; max-width: inherit; height: inherit; min-height: inherit; max-height: inherit; " xmlns="http://www.w3.org/2000/svg" version="1.1">
          <defs>
            <linearGradient id="linear-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
              <stop offset="0%" style="stop-color:rgb(56,121,217);stop-opacity:1" />
              <stop offset="100%" style="stop-color:rgb(138,192,7);stop-opacity:1" />
            </linearGradient>
          </defs>
          <g fill="none">
            <g stroke="#000" fill="#FFF">
              <rect x="10" y="10" width="120" height="120" fill="url(#linear-gradient)"/>
              <path d="M 10 10  L 130 130 Z"/>
            </g>
          </g>
        </svg>
    </div>

  </div>

  <div id="thumbViewContainer">
    <svg id="scopeContainer" class="thumbViewClass">
        <g>
          <rect id="scope" fill="red" fill-opacity="0.1" stroke="red" stroke-width="2px" x="0" y="0" width="0" height="0"/>
          <line id="line1" stroke="red" stroke-width="2px" x1="0" y1="0" x2="0" y2="0"/>
          <line id="line2" stroke="red" stroke-width="2px" x1="0" y1="0" x2="0" y2="0"/>
        </g>
      </svg>
    <div id="thumbView" class="thumbViewClass">
      <svg id="thumbSVG" xmlns="http://www.w3.org/2000/svg" version="1.1">
          <defs>
            <linearGradient id="linear-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
              <stop offset="0%" style="stop-color:rgb(56,121,217);stop-opacity:1" />
              <stop offset="100%" style="stop-color:rgb(138,192,7);stop-opacity:1" />
            </linearGradient>
          </defs>
          <g fill="none">
            <g stroke="#000" fill="#FFF">
              <rect x="10" y="10" width="120" height="120" fill="url(#linear-gradient)"/>
              <path d="M 10 10  L 130 130 Z"/>
            </g>
          </g>
        </svg>
    </div>
  </div>

  <!-- Scripts -->
  <script>
    window.onload = function() {
      thumbnailViewer({
        mainSVGId: 'mainSVG',
        thumbSVGId: 'thumbSVG',
        scopeContainerId: 'scopeContainer'
      });
    }
  </script>
</body>

</html>

EZ。

https://codepen.io/vquilon/pen/MWedEYE

VQR。