0

Hey I have created a triangle in canvas, I have used 2 methods: main method: createTriangle which called to createInterval 3 times. The triangle is composed of 3 vertices only. Now I want to add zoom option to current canvas. Zoom In and Zoom out, but I don't know from where to start? The problen start from the fact that,I don't have any center point for current triangle and O don't know how to calculate it.

Any guidance will be helpfull :).

Update

What about directives or libraries which can be installed over the canvas?

$(function() {
  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");
  //define triangle vertices: 3 vertices for one triangle.
  var ver0 = {
    x: 114,
    y: 366
  };
  var ver1 = {
    x: 306,
    y: 30
  };
  var ver2 = {
    x: 498,
    y: 366
  }
  var triangle = [ver0, ver1, ver2]



  drawTriangle(triangle);




  function drawTriangle(triangle) {
    console.log('drawTriangle', triangle);
    var v0 = triangle[0];
    var v1 = triangle[1];
    var v2 = triangle[2];
    ctx.beginPath();
    createInterval(v0, v1);
    createInterval(v1, v2);
    createInterval(v0, v2);
    ctx.closePath();
  }

  function createInterval(point1, point2) {
    console.log('createInterval', point1, point2);
    ctx.moveTo(point1.x, point1.y);
    ctx.lineTo(point2.x, point2.y);
    ctx.strokeStyle = "black";
    ctx.stroke();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width=650 height=500></canvas>
Brk
  • 1,247
  • 2
  • 23
  • 55
  • I've edited my answer to correct a mistake ... I forgot to divide the sum of X's & Y's by the vertex count. Use the calculated `zoomX, zoomY` as your focal point for zooming. `context.translate` to the zoom point and redraw the polygon to the desired zoom size (large or smaller). `context.scale` makes the scaling easier. – markE Apr 10 '16 at 18:42
  • https://github.com/epistemex/transformation-matrix-js, see method `fromTriangles()` –  Apr 10 '16 at 23:56

3 Answers3

2

Given the vertices of a polygon, you can calculate an acceptable zoom point by calculating the arithmetic mean of the vertices X's & Y's. This is actually the polygon's center of mass, but it's a good point to use for zooming.

var sumX=vert0.x+vert1.x+vert2.x;
var sumY=vert0.y+vert1.y+vert2.y;
var zoomX=sumX/3;  // 3 vertices
var zoomY=sumY/3;
markE
  • 102,905
  • 11
  • 164
  • 176
  • Oops! I edited my answer because I originally forgot to divide by the number of vertices to get the mean. :-O – markE Apr 10 '16 at 18:32
  • after I have the center point,how can I zoom in/out on this specific point? – Brk Apr 12 '16 at 12:09
  • There are several techniques. Some people like using transformations (translate & scale). For simple zooming, I like using the scaling form of drawImage. [An example](http://stackoverflow.com/questions/27339747/zoom-and-pan-in-animated-html5-canvas/27340533#27340533). – markE Apr 12 '16 at 18:29
  • Can I apply this tecnique on elements which aren't images? like shapes ? – Brk Apr 12 '16 at 20:05
  • @Brk. Sure. `drawImage` the canvas to a second offscreen canvas and use that second canvas just like you would use an image (Yes, a canvas can be an image source for `drawImage`). This drawImage form of scaling is muuuuch more efficient than redrawing the shapes with every scaling. ;-) – markE Apr 12 '16 at 20:07
1

Using the Scale method, you should be able to zoom in and out.

  • do I need to draw the triangle again for each scale in or out? – Brk Apr 10 '16 at 18:44
  • Yes. Clear the canvas, translate to the zoom focal point and then redraw all the scaled polygon(s). You can use `scale` to simplify the scaling process. – markE Apr 10 '16 at 18:46
  • no js library which can do it for me? like angular directive? – Brk Apr 10 '16 at 19:15
1

From the example. You could do something like this with your triangle function:

<!DOCTYPE html>
<html>

<head>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>

<body>

  <canvas id="myCanvas" width="800" height="400" style="border:1px solid #d3d3d3;">
    Your browser does not support the HTML5 canvas tag.</canvas>
  <p>
    <button id="zoomIn">+</button>
    <button id="zoomOut">-</button>
    <script>
      $(document).ready(function() {
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");

        ctx.strokeRect(5, 5, 25, 15);

        $('#zoomIn').click(function() {
          ctx.clearRect(0, 0, c.width, c.height);
          ctx.scale(1.10, 1.10);
          ctx.strokeRect(5, 5, 25, 15);
        });

        $('#zoomOut').click(function() {
          ctx.clearRect(0, 0, c.width, c.height);
          ctx.scale(0.90, 0.90);
          ctx.strokeRect(5, 5, 25, 15);
        });

      });
    </script>

</body>

</html>

The zoom increases/decreases the size of your image by 10% each time.

  • 2
    I would just like to point out that your solution will not bring the zoom back to any of the previous zoom. Multiplying a number by 1.1 and then by 0.9 will not give you the original number back. You should select one scaling factor (up or down matters not) and then for the reverse scale use the inverse of that value. ie `scaling = 0.9` to zoom out `ctx,scale(scaling, scaling)` then to zoom in is ctx.scale( 1 / scaling, 1 / scaling)` this will return the scale precisely (within floating point limits of course) – Blindman67 Apr 10 '16 at 20:34