Skip to main content

跳跃兔子性能压力测试

跳跃兔子性能压力测试

本演示展示了同时移动许多 Konva.Image 对象的性能。这是基于 PixiJS 框架Bunnymark 演示进行的改编。

注意:您可能会注意到,Konva 版本的性能比原始的 PixiJS 版本慢。这是因为 PixiJS 对WebGL渲染和此类动画进行了高度优化。而 Konva 仍在不断优化其内部实现,请记住此演示并不代表使用 Konva 构建的典型应用的性能。

对于具有大量动画对象的应用,您可以考虑使用 Native Canvas 访问 或甚至其他框架。根据您的具体应用需求选择合适的工具。

操作指南: 点击或触摸画布以添加更多兔子。计数器将显示当前正在动画的兔子数量。

import Konva from 'konva';

// 设置舞台和图层
const width = window.innerWidth;
const height = window.innerHeight;

const stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height,
});

const layer = new Konva.FastLayer();
stage.add(layer);

// 创建状态显示和计数器
const counterDiv = document.createElement('div');
counterDiv.style.position = 'absolute';
counterDiv.style.top = '50px';
counterDiv.style.backgroundColor = 'white';
counterDiv.style.fontSize = '12px';
counterDiv.style.padding = '5px';
counterDiv.innerHTML = '0 BUNNIES';
document.getElementById('container').appendChild(counterDiv);

// 定义变量
const bunnys = [];
const GRAVITY = 0.75;
const maxX = width;
const minX = 0;
const maxY = height;
const minY = 0;
const startBunnyCount = 100; // 初始较少兔子以提升初始性能
const amount = 10; // 每次添加的兔子数量
let isAdding = false;
let count = 0;
let wabbitTexture;

// 载入兔子图片
wabbitTexture = new Image();
wabbitTexture.onload = function() {
  addBunnies(startBunnyCount);
  counterDiv.innerHTML = startBunnyCount + ' BUNNIES';
  count = startBunnyCount;
  
  // 开始动画循环
  requestAnimationFrame(update);
};
wabbitTexture.src = 'https://konvajs.org/assets/bunny.png';

// 添加事件监听
stage.on('mousedown touchstart', function() {
  isAdding = true;
});

stage.on('mouseup touchend', function() {
  isAdding = false;
});

// 添加兔子函数
function addBunnies(num) {
  for (let i = 0; i < num; i++) {
    const bunny = new Konva.Image({
      image: wabbitTexture,
      transformsEnabled: 'position',
      perfectDrawEnabled: false,
      x: Math.random() * width,
      y: Math.random() * height,
    });

    bunny.speedX = Math.random() * 10;
    bunny.speedY = Math.random() * 10 - 5;

    bunnys.push(bunny);
    layer.add(bunny);
  }
}

// 动画更新函数
function update() {
  // 如果鼠标按下,添加更多兔子
  if (isAdding) {
    addBunnies(amount);
    count += amount;
    counterDiv.innerHTML = count + ' BUNNIES';
  }

  // 更新所有兔子位置
  for (let i = 0; i < bunnys.length; i++) {
    const bunny = bunnys[i];
    let x = bunny.x();
    let y = bunny.y();

    x += bunny.speedX;
    y += bunny.speedY;
    bunny.speedY += GRAVITY;

    // 边界反弹
    if (x > maxX - wabbitTexture.width) {
      bunny.speedX *= -1;
      x = maxX - wabbitTexture.width;
    } else if (x < minX) {
      bunny.speedX *= -1;
      x = minX;
    }

    if (y > maxY - wabbitTexture.height) {
      bunny.speedY *= -0.85;
      y = maxY - wabbitTexture.height;
      if (Math.random() > 0.5) {
        bunny.speedY -= Math.random() * 6;
      }
    } else if (y < minY) {
      bunny.speedY = 0;
      y = minY;
    }

    bunny.position({ x, y });
  }

  layer.batchDraw();
  requestAnimationFrame(update);
}