【问题标题】:svg element location in broswer浏览器中的 svg 元素位置
【发布时间】:2021-03-19 13:16:15
【问题描述】:

我想控制 SVG 在浏览器中的位置(视口?)

我正在使用某种地图 API。所以我想将 SVG 图像添加到地图中。

但是有一个问题是我无法应用 SVG 图像的绝对位置。

当我使用 Canvas 时,它工作得很好。

我认为改变协调时有错误。

使用画布:它工作正常。 // 创建画布元素

function GroundOverlay(bounds) {
        this.bounds = bounds;
        this.node = document.createElement("canvas");
        //this.node.style.backgroundColor = "yellow";
        //this.node.style.opacity = "0.5";
        this.node.style.position = "absolute";
        this.node.style.border = "1px solid red";
        this.node.width = 300;
        this.node.height = 200;
        this.node.style.zIndex = 3;
        this.ctx = this.node.getContext("2d");
        this.width = 300;
        this.height = 10;
        this.startX = 0;
        this.startY = 100;

        this.ctx.translate(200, 30);
        this.ctx.rotate((31.5 * Math.PI) / -180);
        this.ctx.translate(-225, -69);

        // calculate gradient line based on angle
        this.x1 = 60;
        this.y1 = 10;
        this.x2 = this.x1 + Math.cos(31.5) * 600;
        this.y2 = this.y1 + Math.sin(31.5) * 600;
        this.gradientUp = this.ctx.createLinearGradient(this.x1, this.y1, this.x2, this.y2);
        this.gradientUp.addColorStop(0, "grey");
        this.gradientUp.addColorStop(1, "rgba(0, 0, 255, 0.5)");
        this.ctx.fillStyle = this.gradientUp;
        this.ctx.fillRect(this.startX, this.startY, this.width, this.height);
      }

      
      GroundOverlay.prototype = new kakao.maps.AbstractOverlay();

      
      GroundOverlay.prototype.onAdd = function() {
        var panel = this.getPanels().overlayLayer;
        panel.appendChild(this.node);
      };

      // when event happend (zoom, center, mapType)
      // location of element is changed.
      GroundOverlay.prototype.draw = function() {
        var projection = this.getProjection();
        var ne = projection.pointFromCoords(this.bounds.getNorthEast());
        var sw = projection.pointFromCoords(this.bounds.getSouthWest());

        var width = ne.x - sw.x;
        var height = sw.y - ne.y;

        this.node.style.top = ne.y + "px";
        this.node.style.left = sw.x + "px";
        this.node.style.width = width + "px";
        this.node.style.height = height + "px";
      };

使用 SVG:当事件发生时,位置不是绝对的

  function GroundOverlay(bounds) {
          this.bounds = bounds;
          this.node = document.createElement("div");
          this.node.style.position = "absolute";
          this.svg1 = document.createElementNS("http://www.w3.org/2000/svg", "svg");
          this.svg1.setAttribute("position", "absolute");
          this.svg1.style.position = "absolute";

          // create a circle
          this.cir1 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
          this.cir1.style.position = "absolute";
          this.cir1.setAttribute("cx", "80");
          this.cir1.setAttribute("cy", "80");
          this.cir1.setAttribute("r", "30");
          this.cir1.setAttribute("fill", "red");
          this.cir1.setAttribute("position", "absolute");

          // attach it to the container
          this.svg1.appendChild(this.cir1);

          // attach container to document
          this.node.appendChild(this.svg1);
        }
       
        GroundOverlay.prototype = new kakao.maps.AbstractOverlay();

        GroundOverlay.prototype.onAdd = function() {
          var panel = this.getPanels().overlayLayer;
          panel.appendChild(this.node);
        };

        GroundOverlay.prototype.draw = function() {
          var projection = this.getProjection();
          var ne = projection.pointFromCoords(this.bounds.getNorthEast());
          var sw = projection.pointFromCoords(this.bounds.getSouthWest());

          var width = ne.x - sw.x;
          var height = sw.y - ne.y;

          this.node.style.top = ne.y + "px";
          this.node.style.left = sw.x + "px";
          this.node.style.width = width + "px";
          this.node.style.height = height + "px";
        };

svg(circle): 不能是绝对位置

https://s8.gifyu.com/images/marker1.gif

canvas(square): 可以是绝对位置

https://s8.gifyu.com/images/marker2.gif

我试过这种方式(https://www.sitepoint.com/how-to-translate-from-dom-to-svg-coordinates-and-back-again/

  • 强调 svgPoint

  • 将此点更改为顶部,浏览器的左侧

    GroundOverlay.prototype.draw = function() {

           var projection = this.getProjection();
           var ne = projection.pointFromCoords(this.bounds.getNorthEast());
           var sw = projection.pointFromCoords(this.bounds.getSouthWest());
    
           var width = ne.x - sw.x;
           var height = sw.y - ne.y;
    
           this.node.style.top = ne.y + "px";
           this.node.style.left = sw.x + "px";
           this.node.style.width = width + "px";
           this.node.style.height = height + "px";
    
    
           var pt = this.svg1.createSVGPoint();
           pt.x = sw.x;
           pt.y = ne.y;
         };
    

【问题讨论】:

  • 正确,SVG 不能那样工作。
  • 将整个 SVG 直接放置在与图像尺寸相同的图像顶部。现在您不再需要绝对定位,因为所有点都是相对于图像的。

标签: javascript html svg canvas


【解决方案1】:

但是有一个问题是我无法应用 SVG 图像的绝对位置。

我不太清楚你在这里的意思。您绝对定位了包装 SVG 的 <div>。为什么还要在圈子上设置position="absolute"

无论如何,position="absolute" 上的 <circle> 什么都不做。这是一个 HTML 属性,而不是 SVG 属性。但是,如果 <svg> 元素是 HTML 元素的子元素(例如 <div>),则该属性确实适用于该元素。

否则,您的其余代码看起来或多或少是正确的。但是如果没有一个可行的例子,就很难 100% 确定。请使用实际(最小)工作示例更新您的问题。

【讨论】:

  • 我添加了 gif 屏幕。我想让 sgv 圆形定位绝对像画布正方形
猜你喜欢
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 2018-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多