SVG是否很难调整大小?我想念什么? [英] Is SVG resizing this hard ? What am I missing?

查看:173
本文介绍了SVG是否很难调整大小?我想念什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写代码,以调整图像顶部SVG叠加层的大小.我正在使用的服务器同时返回图像并通过API,我需要在图像顶部覆盖的多边形点列表.

I am trying to write code that resizes an SVG overlay on top of an image. The server I am working with returns both the image and via an API, a list of polygon points I need to overlay on top of the image.

这是它的外观(下图是正确对齐的SVG层).图像尺寸为1280x720(我已将其按比例缩小)

This is what it should look like (the image below is a correctly aligned SVG layer). The image size is 1280x720 (I've scaled it down)

在我的应用程序(ionic v1应用程序)中,我需要做的是确保随着浏览器窗口大小的改变,SVG覆盖层的大小也会随之改变,这似乎很难.这是我的方法:

What I need to do in my app (ionic v1 app) is to make sure the SVG overlay resizes as the browser window resizes and it seems to be very hard. Here is my approach:

我正在捕获窗口调整大小事件,调整图像大小时,我缩放了SVG多边形点相对于绘制窗口的大小,因为似乎真的没有办法像浏览器那样自动"缩放SVG它与图像有关.

I am trapping a window resize event and when the image is resized, I scale the SVG polygon points relative to the size of the drawn window as it seems there is really no way to "automatically" scale the SVG by the browser like it does with an image.

这是我的代码笔,因为当我看到它时,它无法正常工作重新缩放(就此而言,重叠大小不正确).叠加层看起来不准确,当我调整大小时,一切都弄糟了.有人可以帮忙吗?

Here is my code pen as you see it doesn't work as intended when I rescale (and for that matter in when its full size the overlays are not accurate). The overlays don't look accurate and when I resize it all messed up. Can someone help?

鉴于SO在这里需要代码块链接的代码块,但是如果您想运行它,则更容易查看代码块

Given SO needs a code block for codepen links here it is, but its just easier to look at the codepen if you want to run it

CSS:

.imagecontainer{position:relative; margin:0 auto;}

.zonelayer
{
    position:absolute;
    top:0;
    left:0;
    background:none;

}

.zonelayer polygon {
    fill-opacity: 0.25;
    stroke-width: 2px;
}

.Active {
    stroke: #ff0000;
    fill: #ff0000;
}

HTML代码:

<ion-content>
        image:{{disp}}<br/>
      <small>points: <span ng-repeat="item in zoneArray">{{item}}</span></small>
        <div class="imagecontainer">

            <img id="singlemonitor" style="width:100vw; height:100vh;object-fit:contain" ng-src="http://m9.i.pbase.com/o9/63/103963/1/164771719.2SfdldRy.nphzms.jpeg"  />
            <div class="zonelayer">
                <svg ng-attr-width="{{cw}}" ng-attr-height="{{ch}}" class="zonelayer" ng-attr-viewBox="0 0 {{cw}} {{ch}}">
                    <polygon ng-repeat="item in zoneArray"  ng-attr-points="{{item}}" class="Active"/> </polygon>

                </svg>
            </div>
        </div>

    </ion-content>

JS控制器:

window.addEventListener('resize', liveloaded);
  liveloaded();
  // credit: http://stackoverflow.com/questions/41411891/most-elegant-way-to-parse-scale-and-re-string-a-string-of-number-co-ordinates?noredirect=1#41411927
    function scaleCoords(string, sx, sy) {
        var f = [sx, sy];
        return string.split(' ').map(function (a) {
            return a.split(',').map(function (b, i) {
                return Math.round(b * f[i]);
            }).join(',');
        }).join(' ');
    }

  function liveloaded()
  {

        $timeout (function () {
                    console.log ("IMAGE LOADED");
                    var img =document.getElementById("singlemonitor");

                    //var offset = img.getBoundingClientRect();
                    $scope.cw = img.clientWidth;
                    $scope.ch = img.clientHeight;
                    $scope.vx = img.offsetWidth;
                    $scope.vy = img.offsetHeight;

                    var rect = img.getBoundingClientRect();
                    //console.log(rect.top, rect.right, rect.bottom, rect.left);
                    $scope.disp = img.clientWidth+ "x"+img.clientHeight + " with offsets:"+$scope.vx+"/"+$scope.vy;

                    $scope.zoneArray = [
                    "598,70 700,101 658,531 516,436",
                    "531,243 687,316 663,593 360,717 191,520",
                    "929,180 1108,248 985,707 847,676",
                    "275,17 422,45 412,312 271,235",
                    ];

                    var ow = 1280;
                    var oh = 720;

                    for (var i=0; i < $scope.zoneArray.length; i++)
                    {
                        var sx = $scope.cw/ow;
                        var sy = $scope.ch/oh;
                        $scope.zoneArray[i] = scaleCoords($scope.zoneArray[i],sx,sy);
                        console.log ("SCALED:"+$scope.zoneArray[i]);
                    }


                });
            }

推荐答案

您的代码有两个问题.

主要问题是您不能使用ng-attr-viewBox,因为angular会将属性标准化"为小写.它将属性转换为(当前)无效的viewbox(小写字母B). viewBox区分大小写.

The main problem is you can't use ng-attr-viewBox, because angular will "normalise" the attribute to lower case. It turns the attribute into viewbox (lower case B) which is (currently) invalid. viewBox is case sensitive.

解决方案是使用Angular的特殊技巧来保存驼峰式的情况.如果使用ng-attr-view_box,它将生成正确的驼峰式属性名称viewBox.

The solution is to use a special trick of Angular to preserve camel-case. If you use ng-attr-view_box, it will generate the correctly camel-cased attribute name of viewBox.

<svg width="100vw" height="100vh" class="zonelayer" ng-attr-view_box="0 0 {{cw}} {{ch}}">

另一件事是您为viewBox使用了错误的宽度和高度值.您需要在viewBox中使用自然/固有图像尺寸.

The other thing is that you are using the wrong width and height values for the viewBox. You need to use the natural/intrinsic image dimensions in your viewBox.

$scope.cw = img.naturalWidth;
$scope.ch = img.naturalHeight;

链接到更新的代码笔

这篇关于SVG是否很难调整大小?我想念什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆