跳到主要内容

跳跃兔子性能压力测试

弹跳兔子性能压力测试

此示例展示同时移动多个 Konva.Image 对象时的性能。它改编自 Bunnymark 示例,该示例属于 PixiJS 框架

注意:你可能发现 Konva 版本比原始 PixiJS 版本慢。这是因为 PixiJS 针对 WebGL 渲染和这种特定动画进行了高度优化。Konva 会继续优化内部实现,但此示例并不能代表使用 Konva 构建的典型应用的性能。

对于包含大量动画对象的应用,可以考虑使用原生 Canvas 访问,甚至改用其他框架。请根据应用的具体需求选择合适的工具。

**操作说明:**单击或触摸 Canvas 以添加更多兔子。计数器会显示当前参与动画的兔子数量。

import Konva from 'konva';

// Set up stage and layer
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);

// Create stats and counter display
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);

// Define variables
const bunnys = [];
const GRAVITY = 0.75;
const maxX = width;
const minX = 0;
const maxY = height;
const minY = 0;
const startBunnyCount = 100; // Starting with fewer bunnies for better initial performance
const amount = 10; // Add this many bunnies at a time
let isAdding = false;
let count = 0;
let wabbitTexture;

// Load the bunny image
wabbitTexture = new Image();
wabbitTexture.onload = function() {
  addBunnies(startBunnyCount);
  counterDiv.innerHTML = startBunnyCount + ' BUNNIES';
  count = startBunnyCount;
  
  // Start animation loop
  requestAnimationFrame(update);
};
wabbitTexture.src = 'https://konvajs.org/assets/bunny.png';

// Add event listeners
stage.on('mousedown touchstart', function() {
  isAdding = true;
});

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

// Function to add bunnies
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);
  }
}

// Animation update function
function update() {
  // Add more bunnies if mouse is down
  if (isAdding) {
    addBunnies(amount);
    count += amount;
    counterDiv.innerHTML = count + ' BUNNIES';
  }

  // Update all 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;

    // Bounce off the edges
    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);
}