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.Layer({ listening: false });
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);
}