Using Canvas to animate a sorting algorithm in JS

前端 未结 2 1309
滥情空心
滥情空心 2020-12-21 18:30

For fun I am trying to create a visualization of different sorting algorithms, but I\'ve run into an issue with Canvas animations.

I assumed I would just be able to

相关标签:
2条回答
  • 2020-12-21 18:43

    You need a render loop. requestAnimationFrame() is your friend here. With this method you give the browser a callback that is called before the next frame draw.

    Within that callback you draw your stuff and call requestAnimationFrame() again with your same callback like this:

    requestAnimationFrame(renderLoop);
    function renderLoop()
    {
        // visualize your array `l` at this point
    
        // call the render callback for the next frame draw
        requestAnimationFrame(renderLoop);
    }
    

    https://developer.mozilla.org/de/docs/Web/API/window/requestAnimationFrame

    You get a smooth animation with usually a framerate of 60 fps.

    For integrating that approach in your code:

    1. Delete the lines

      draw();
      setTimeout(function() {}, 10);
      
    2. call the initial

      requestAnimationFrame(renderLoop);

      when your program start.

    0 讨论(0)
  • 2020-12-21 18:50

    One solution is the ES6 Generator function* along with its yield statement.

    That allows you to pause a function and restart it later where it has been paused:

    N = 100; // Array Size
    XYs = 5; // Element Visual Size
    Xp = 1; // Start Pos X
    Yp = 1; // Start Pos Y
    var canvas;
    var l = Array.apply(null, {
      length: N
    }).map(Number.call, Number);
    
    Array.prototype.shuffle = function() {
      var i = this.length,
        j, temp;
      if (i == 0) return this;
      while (--i) {
        j = Math.floor(Math.random() * (i + 1));
        temp = this[i];
        this[i] = this[j];
        this[j] = temp;
      }
      return this;
    }
    
    function map_range(x, in_min, in_max, out_min, out_max) {
      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }
    
    function rainbow(x) {
      var m = map_range(x, 0, N, 0, 359);
      return 'hsl(' + m + ',100%,50%)';
    }
    
    function init() {
      canvas = document.getElementById('canvas');
      l.shuffle();
      var sort = bubbleSort(l);
      // an anim function triggered every 60th of a second
      function anim(){
        requestAnimationFrame(anim);
        draw();
        sort.next(); // call next iteration of the bubbleSort function
      }
      anim();
    }
    
    function draw() {
      if (canvas.getContext) {
        var ctx = canvas.getContext('2d');
        for (var i = 0; i < l.length; i++) {
          ctx.fillStyle = rainbow(l[i]);
          ctx.fillRect((Xp * i) * XYs, Yp * XYs, XYs, XYs);
        }
      }
    }
    
    function* bubbleSort(a) { // * is magic
      var swapped;
      do {
        swapped = false;
        for (var i = 0; i < a.length - 1; i++) {
          if (a[i] > a[i + 1]) {
            var temp = a[i];
            a[i] = a[i + 1];
            a[i + 1] = temp;
            swapped = true;
            yield swapped; // pause here
          }
        }
      } while (swapped);
    }
    init();
    <canvas id="canvas" width="500" height="20">

    0 讨论(0)
提交回复
热议问题