2017-01-01 149 views
0

我正在嘗試編寫調整圖像頂部的SVG疊加層的代碼。我正在使用的服務器返回圖像並通過API返回需要疊加在圖像頂部的多邊形點列表。SVG是否調整了這個難度?我錯過了什麼?

這是它應該看起來像(下面的圖像是一個正確對齊的SVG圖層)。圖像大小爲1280x720(我已經縮小下來) enter image description here

我需要在我的應用程序(離子V1應用程序)做的是確保SVG覆蓋調整大小的瀏覽器窗口大小調整,它似乎是很難。這裏是我的做法:

我捕獲一個窗口大小調整事件,當圖像調整大小時,我縮放相對於繪製窗口大小的SVG多邊形點,因爲看起來真的沒有辦法「自動」縮放瀏覽器的SVG就像它與圖像一樣。

Here is my code pen正如你所看到的那樣,當我重新調整尺寸時(以及當它的全尺寸覆蓋圖不準確時)它不能正常工作。疊加看起來不準確,當我調整大小時,一切都搞砸了。有人可以幫忙嗎?

鑑於SO需求codepen鏈接代碼塊在這裏它是,但它只是更容易看codepen如果你想運行它

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]); 
        } 


       }); 
      } 
+0

「鑑於等都需要在這裏codepen鏈接它是一個代碼塊」 - 不,不這樣做。只需在帖子中包含你的代碼,而不是試圖欺騙過濾器! – Aurora0001

+1

完成 - 我這樣做的原因是有不同的部分張貼它是有意義的,並且codepen只是它的所有工作和運行 – user1361529

+0

是否有一個原因,你不能加載SVG到''元素和讓瀏覽器爲你調整大小? – Dai

回答

1

您的代碼有幾個問題。

主要問題是你不能使用ng-attr-viewBox,因爲角會將屬性「歸一化」爲小寫。它將屬性變成viewbox(小寫字母B),它是(當前)無效的。 viewBox區分大小寫。

解決方案是使用Angular的特殊技巧來保護駱駝案件。如果使用ng-attr-view_box,它將生成正確的駝峯屬性名稱viewBox

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

另一件事是,您正在使用viewBox的寬度和高度值不正確。您需要在viewBox中使用自然/固有圖像尺寸。

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

Link to updated code pen

+0

謝謝保羅。我做了一個快速檢查 - 適用於Chrome,但SVG在Safari上完全不顯示。正在調試過程中! – user1361529

+0

不太清楚您的codepen存在什麼問題,但是將您的建議合併到我的codepen http://codepen.io/pliablepixels/pen/apoJyj中,效果非常好!做更多的測試。那個viewBox技巧對我來說是不可能的(根據我的知識)。謝謝! – user1361529

+0

Paul,快速提問,如果我將圖像從'object-fit:contains'更改爲'object-fit:cover',那麼我需要什麼樣的魔法才能正確映射svg?將其樣式更改爲相同的對象似乎根本不起作用 – user1361529