简体   繁体   中英

How to scale Canvas shapes?

Please check out this code :

    (function() {
        var cnv = document.getElementById('canvas');
        if (cnv.getContext) {
          var ctx = cnv.getContext('2d');
        } else {
          alert('God Damn it ...');
        }

        function initialize() {
            window.addEventListener('resize', resizeCanvas, false);
            resizeCanvas();
        }

        function draw() {
            for (var i = 0; i < 25; i++) {

            width = Math.random() * cnv.width;
            height = Math.random() * cnv.height;

            ctx.beginPath();
            ctx.arc(width, height, 15, 0, Math.PI * 2);
            ctx.strokeStyle = '#E1E1E1';
            ctx.lineWidth = 1;

            ctx.stroke();
          }
        }

        function resizeCanvas() {
            cnv.width = window.innerWidth;
            cnv.height = window.innerHeight;
            draw();
        }

        initialize();

    })();

I have created 25 Circle shape with random position and I want to create an animation that scales up or down in a interval time. I know about setInterval but how should I call my shape to do something on it?

The first thing you will want to do is to have a place to store the position of your circles, since they are all going to be the same radius we can just store the x and y position. For that we can create a Circle function ( "class" ) and have an array of circles:

  var circles = [];      // Array to store our circles
  var minRadius = 1;     // The smallest radius we can hit
  var maxRadius = 100;   // The largest radius we can hit
  var currentRadius = 15;// The current radius of all our circles
  var scaleBy = 1;       // How the radius changes  
  var cnv = document.getElementById('canvas');
  // ...

  function initialize() {
    window.addEventListener('resize', resizeCanvas, false);
    resizeCanvas();  
    // Populating the array of circles to use when drawing
    for (var i = 0; i < 25; i++) { // Make sure to do this after re-sizing the canvas
      width = Math.random() * cnv.width;
      height = Math.random() * cnv.height;
      circles.push(new Circle(width, height));
    }
  }
  // ...
  function Circle(x, y){
    this.x = x;
    this.y = y;
  }

  Circle.prototype.draw = function(){
      ctx.beginPath();
      ctx.arc(this.x, this.y, currentRadius, 0, Math.PI * 2);
      ctx.strokeStyle = '#E1E1E1';
      ctx.lineWidth = 5;
      ctx.stroke();
  }

Now that you have some circles when you call draw you can iterate through the array and call circle.draw() for each circle element in your array:

  function draw() {
    // Clear the screen and draw the circles in our array
    ctx.clearRect(0,0, cnv.width, cnv.height);
    for (var i = 0; i < circles.length; i++) {
      circles[i].draw();
    }
  }

One note is you will want to use ctx.clearRect(0,0, cnv.width, cnv.height) to clear the screen before drawing.

Finally you can now use setInterval to change the currentRadius (*While there is nothing wrong with setInterval I'd recommend using window.requestAnimationFrame for animation as it's a bit more smooth and efficient method). Then when you call draw it will draw the circles with the new value of currentRadius . In this example I'm going to have it start at 15 . Then increase by 1 until it hits maxRadius , then we can flip the sign of scaleBy to start decreasing the radius to make them smaller. Finally when it his our minRadius you can flip the sign of scaleBy again to make it start scaling up again:

  var timer = setInterval( function(){
    // If we hit our min or max start scaling in the other direction
    if(currentRadius > maxRadius || currentRadius < minRadius){
      scaleBy *= -1;
    }
    currentRadius += scaleBy;
    draw();
  }, 50);

Below is a code snippet of the complete program:

 (function() { var circles = []; var minRadius = 1; var maxRadius = 100; var currentRadius = 15; var scaleBy = 1; var cnv = document.getElementById('canvas'); if (cnv.getContext) { var ctx = cnv.getContext('2d'); } else { alert('God Damn it ...'); } function initialize() { window.addEventListener('resize', resizeCanvas, false); resizeCanvas(); for (var i = 0; i < 25; i++) { width = Math.random() * cnv.width; height = Math.random() * cnv.height; circles.push(new Circle(width, height)); } } function draw() { ctx.clearRect(0,0, cnv.width, cnv.height); for (var i = 0; i < circles.length; i++) { circles[i].draw(); } } function resizeCanvas() { cnv.width = window.innerWidth; cnv.height = window.innerHeight; } function Circle(x, y){ this.x = x; this.y = y; } Circle.prototype.draw = function(){ ctx.beginPath(); ctx.arc(this.x, this.y, currentRadius, 0, Math.PI * 2); ctx.strokeStyle = '#E1E1E1'; ctx.lineWidth = 5; ctx.stroke(); } initialize(); var timer = setInterval( function(){ if(currentRadius > maxRadius || currentRadius < minRadius){ scaleBy *= -1; } currentRadius += scaleBy; draw(); }, 50); })();
 <canvas id="canvas"></canvas>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM