排序算法可视化:Canvas动画实现

310 阅读2分钟

写代码的小伙伴都知道排序算法是计算机科学中的一个基础概念,本文将介绍如何使用HTML5的Canvas元素来创建排序算法的动画效果。

使用Canvas实现排序算法动画

Canvas是HTML5中一个强大的图形绘制元素,它允许使用JavaScript进行复杂的图形绘制和动画制作。以下是使用Canvas实现排序算法动画的基本步骤:

1. 创建Canvas元素

在HTML文档中,添加一个Canvas元素,并设置其宽高:

<canvas id="sortCanvas" width="800" height="600"></canvas>

2. 访问Canvas上下文

通过JavaScript获取Canvas的绘图上下文,这是进行绘图操作的起点:

const canvas = document.getElementById('sortCanvas');
const ctx = canvas.getContext('2d');

3. 绘制排序条形

在排序动画中,通常使用条形图来表示数组中的元素。可以编写一个函数来绘制数组的初始状态:

function drawBars(data) {
  ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除画布
  data.forEach((value, index) => {
    const barWidth = canvas.width / data.length;
    ctx.fillStyle = 'blue';
    ctx.fillRect(index * barWidth, canvas.height - value, barWidth, value);
  });
}

4. 实现排序算法

选择一个排序算法(如冒泡排序、快速排序等),并用JavaScript实现它:

function bubbleSort(arr) {
  let len = arr.length;
  for (let i = 0; i < len; i++) {
    for (let j = 0; j < len - i - 1; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
      }
    }
  }
  return arr;
}

5. 动画排序过程

使用动画技术逐步展示排序过程,可以使用requestAnimationFrame来创建平滑的动画效果,那么怎么在算法中加入requestAnimationFrame呢?下面提供一种思路,我们可以在元素交换时绘制图形,记录下当前遍历下标,并跳槽循环,等待下次屏幕刷新继续下一步的循环。

let frameQueue = [];
// 冒泡排序
function bubbleSort(arr) {
  let ci = 0;
  let cj = 0;

  function animation() {
    let len = arr.length;
    let next = false;
    for (let i = ci; i < len; i++) {
      for (let j = cj; j < len - i - 1; j++) {
        if (arr[j] > arr[j + 1]) {
          [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
          next = true;

          if (j === len - i - 2) {
            cj = 0;
            ci = i + 1;
          } else {
            cj = j + 1;
            ci = i;
          }

          // 这里绘制动画...
          drawBars(arr);
          
          frameQueue.push(requestAnimationFrame(() => {
            animation();
            frameQueue.shift();
          }))
          break;
        } else {
          if (j === len - i - 2) {
            cj = 0;
            ci = i + 1;
          }
        }
      }

      if (next) break;
    }
  }
}

6. 控制动画

提供按钮来控制动画的开始和暂停:

<button onclick="startSort()">开始排序</button>
<button onclick="startSort()">暂停排序</button>
// 开始动画
function startSort() {
  bubbleSort();
}

//暂停动画
function pauseSort() {
  while (frameQueue.length) {
    cancelAnimationFrame(frameQueue.pop()); // 取消动画
  }
}

6. 更多

到这里基本的冒泡排序动画效果已完成,我们可再加入其他算法,比如选择排序等,添加对排序数量的控制、重置等。具体可以查看源代码。源代码

结语

以上是通过使用Canvas和requestAnimationFrame对排序算法可视化尝试,我们还可以用其他算法和数学函数创建不同的类型的排序动画,增强学习体验。希望对初学的小伙伴有帮助。如果你有任何建议或问题,欢迎在评论区交流。