Andy Fortman
Andy Fortman

Reputation: 1

SVG custom polygon image stretch not working

I'm trying to both stretch and rotate an image into an SVG polygon (Basically an arc).

What I need is to stretch the image to fit, not tile or clip it.

What I'd like is : The stretched/distorted image in the arc without the image clipped.

What I have is: Clipped arc image

Here's the fiddle I've been working on - https://jsfiddle.net/eLrgfnxb/57/

<svg style="overflow:visible; margin-left:111px; margin-top:22px; " height="1000" width="1000">
    <defs>
        <pattern id="blip1" patternUnits="userSpaceOnUse" width="100%" height="100%">
             <image  preserveAspectRatio="none" xlink:href="http://i.imgur.com/uTDpE6J.jpg" ></image>
        </pattern>
    </defs>
    <polygon points="453,372 67,184 70,177 73,171 77,164 81,158 85,151 88,145 92,138 97,132 101,126 105,120 110,114 114,108 115,107" x="1" y="1" style="stroke-linejoin:round; fill:url(#blip1); stroke-width:2; stroke:hsl(212,45%,26%); ">
    </polygon>
</svg>

I've seen a few ones:

I was thinking about switching to a canvas to see if that worked. I saw a couple interesting things here: Stretch image to fit polygon html5 canvas

Thanks for the help!

Upvotes: 0

Views: 97

Answers (1)

Andy Fortman
Andy Fortman

Reputation: 1

After some work, I'm able to do it by going layer by layer through the image and putting it in an isosceles triangle. Then rotating it to about the right area.

Its a bit of a hairy assumption for the arc to be an isosceles, but lets make it better later.

Updated jfiddle - http://jsfiddle.net/gobfink/w1Lake9f/210/

<!DOCTYPE html>
<html>
<body>

<p>Tiger</p>
<!--
<img id="tiger" width="220" height="277" src="http://i.imgur.com/uTDpE6J.jpg" alt="the tiger" />
-->
<img id="tiger" width="340" height="429" src="http://i.imgur.com/uTDpE6J.jpg" alt="the tiger" />

<p>TigerCanvas:</p>
<canvas id="tigerCanvas" width="500" height="500" style="border:1px solid #d3d3d3;" >
</canvas>

<p>PolygonCanvas:</p>
<canvas id="polygonCanvas" width="500" height="500" style="border:1px solid #d3d3d3;" >
</canvas>

<p>PolygonTigerCanvas</p>
<canvas id="polygonTigerCanvas" width="1000" height="500" style="border:1px solid #d3d3d3;" >
</canvas>
<p>MousePosition: </p>
<canvas id="mousePositionCanvas" width="400" height="100" style="border:1px solid #d3d3d3;" >
</canvas>
<script>
window.onload = function() {
  var p_canvas=document.getElementById("polygonCanvas");
  var p_ctx = p_canvas.getContext("2d");
  var p_maxX,p_minX, p_maxY, p_minY;
  var poly_points = [[453,372] ,[67,184], [70,177], [73,171], [77,164], [81,158], [85,151], [88,145], [92,138], [97,132], [101,126], [105,120], [110,114], [114,108], [115,107]];
  p_ctx.fillStyle='#f00';
  p_ctx.beginPath();
  p_ctx.moveTo(poly_points[0][0],poly_points[0],[1]);
  poly_points.forEach(function(point) {
    if (p_minX == null || point[0] < p_minX[0] ){
        p_minX = point;
    }
    if (p_minY == null || point[1] < p_minY[1] ){
        p_minY = point;
    }
    if (p_maxX == null || point[0] > p_maxX[0] ){
        p_maxX = point;
    }
    if (p_maxY == null || point[1] > p_maxY[1] ){
        p_maxY = point;
   }
    p_ctx.lineTo(point[0],point[1]) ;
  });
  console.log("p_minX: ", p_minX,", p_minY: ", p_minY, ", p_maxY: ", p_maxY, ", p_maxX: ", p_maxX);
  p_ctx.closePath();
  p_ctx.fill();
  
  p_ctx.font= '8px serif';
  p_ctx.fillStyle='#000';
  p_ctx.fillText("maxX:" + p_maxX[0] + ","+ p_maxX[1] , p_maxX[0], p_maxX[1]);
  p_ctx.fillText("minX:" + p_minX[0] + ","+ p_minX[1] , p_minX[0], p_minX[1]);
  p_ctx.fillText("minY:" + p_minY[0] + ","+ p_minY[1] , p_minY[0], p_minY[1]);

  //p_ctx.fillText(p_maxX[0] + ","+ p_maxX[1] , p_maxX[0], p_maxX[1]);
  //p_ctx.fillText(p_maxX[0] + ","+ p_maxX[1] , p_maxX[0], p_maxX[1]);

  var leg_distance = Math.floor(Math.hypot(p_maxX[0] - p_minX[0],p_maxX[1] - p_minX[1]));
  var base_distance = Math.floor(Math.hypot(p_minX[0]- p_minY[0], p_minX[1]-p_minY[1]));
  var arc_height = Math.floor(Math.sqrt(Math.pow(leg_distance,2) - Math.pow(base_distance/2,2)));
  
  var p1 = [0,0];
  var p2 = [base_distance,0];
  var p3 = [base_distance/2, arc_height];
  
  var p13_slope = (p3[1] - p1[1]) / (p3[0] - p1[0]);
  var p13_intercept = p3[1] - p13_slope * p3[0];
  var p23_slope = (p3[1] - p2[1]) / (p3[0] - p2[0]);
  var p23_intercept = p3[1] - p23_slope * p3[0];
  
  
  var orientation_angle = Math.asin((p_maxX[0] - p_minY[0]) /leg_distance);
  
  console.log("leg_distance:",leg_distance,", base_distance: ", base_distance, ", arc_height: ", arc_height);
  console.log("p1:", p1, ", p2: ",p2,", p3: ", p3);
  console.log("p13_slope:", p13_slope, ", p13_intercept: ",p13_intercept);
  console.log("p23_slope:", p23_slope, ", p23_intercept: ",p23_intercept);
  console.log("orientation angle: ", orientation_angle);
  var c = document.getElementById("tigerCanvas");
  var ctx = c.getContext("2d");
  var img = document.getElementById("tiger");
  
  //var c_height = distance;
  //var c_width = img.width/img.height * distance;
  img.width = img.width/img.height * leg_distance ; //normalize the width
  img.height = arc_height;
  
  //ctx.drawImage(img, 1, 1);
  ctx.drawImage(img, 1, 1,img.width,img.height);//, c_width, c_height);
  var p_tiger_canvas = document.getElementById("polygonTigerCanvas");
  var pt_ctx = p_tiger_canvas.getContext("2d");
  //Assumes MaxX== MaxY
  var slopeA = (p_maxX[1] - p_minX[1])/(p_maxX[0] - p_minX[0]) ;
  var slopeB = (p_maxX[1] - p_minY[1])/(p_maxX[0] - p_minY[0]) ;
  
  var inceptA = (p_maxX[1] - slopeA * p_maxX[0]);
  var inceptB = (p_maxX[1] - slopeB * p_maxX[0]);
  
  console.log("slopeA: ",slopeA, ", slopeB: ", slopeB, ", inceptA:", inceptA, "inceptB: ",inceptB);
  console.log("img.width - ", img.width, " img.height -",img.height);
  pt_ctx.font= '8px serif';
  pt_ctx.fillStyle='#000';
  p_ctx.fillText("maxX:" + p_maxX[0] + ","+ p_maxX[1] , p_maxX[0], p_maxX[1]);
  p_ctx.fillText("minX:" + p_minX[0] + ","+ p_minX[1] , p_minX[0], p_minX[1]);
  p_ctx.fillText("minY:" + p_minY[0] + ","+ p_minY[1] , p_minY[0], p_minY[1]);
  //pt_ctx.translate(p_maxX[0]/4,p_maxX[1]);
  pt_ctx.setTransform(1,0,0,1,p_minX[0],p_minX[1])
  pt_ctx.rotate(-orientation_angle);
  var i;
  for (i = 0; i < arc_height; i++){
    var Bx = (i - inceptB) / slopeB;
    var Ax = (i - inceptA) / slopeA;
    var p13x = (i - p13_intercept)/ p13_slope;
    var p23x = (i - p23_intercept)/ p23_slope;
    var d12_23= Math.hypot( p13x-p23x ,0);
    var dAB = Math.hypot(Bx-Ax,0);
    //console.log("i: ", i, ", Bx - ", Bx, ", Ax - ", Ax, ", dAB - ", dAB);
    pt_ctx.drawImage(c,0,i,img.width,1,p13x,i,d12_23,1);
    if (i % 10 == 0){
      pt_ctx.fillText(Math.round(p13x) , p13x, i);
      pt_ctx.fillText(Math.round(p23x) + ","+ i , p23x, i);
    }
  }
  var mousePositionCanvas = document.getElementById('mousePositionCanvas');
  function writeMessage(canvas, message) {
        var context = canvas.getContext('2d');
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.font = '18pt Calibri';
        context.fillStyle = 'black';
        context.fillText(message, 10, 25);
      }
  function getMousePos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return {
          x: evt.clientX - rect.left,
          y: evt.clientY - rect.top
        };
      }
  p_tiger_canvas.addEventListener('mousemove', function(evt) {
        var mousePos = getMousePos(p_tiger_canvas, evt);
        var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
        writeMessage(mousePositionCanvas, message);
      }, false)
  
}
</script>
</body>
</html>

Upvotes: 0

Related Questions