跳跃兔子性能压力测试

该演示展示了同时移动多个 Konva.Image 的性能。

这是从 PixiJS 框架 中采纳的 示例

你会注意到 Konva 版本的性能比 PixiJS 版本要慢得多。

所以首先我要说明的是,其他框架在某些情况下可能表现得更好。PixiJS 针对这类图形和动画进行了非常优化(它使用 WebGL 进行渲染)。

目前正在进行的工作是优化一些 Konva 的内部结构,以使其在该演示中也能更快地运行。

但请记住,该演示并不能代表使用 Konva 制作的典型应用程序的性能。如果你在执行很多像演示中一样的动画,并且涉及大量对象,可能需要使用其他解决方案,比如 原生 Canvas 访问 或者甚至是不同的框架。

因此,为你的应用程序明智地选择工具。

说明:在画布上按下鼠标增加更多兔子。

Konva Bunnies Demoview raw
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva@9.3.18/konva.min.js"></script>
<meta charset="utf-8" />
<title>Konva Jumping Bunnies Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}

#counter {
position: absolute;
top: 50px;
background-color: white;
font-size: 12px;
}
</style>
</head>

<body>
<div id="container"></div>
<div id="counter"></div>
<script src="https://mrdoob.github.io/stats.js/build/stats.min.js"></script>
<script defer="defer">
var lastTime = 0;

var width = window.innerWidth;
var height = window.innerHeight;

var bunnys = [];
var GRAVITY = 0.75;

var maxX = width;
var minX = 0;
var maxY = height;
var minY = 0;

var startBunnyCount = 1000;
var isAdding = false;
var count = 0;
var amount = 10;

var stage = new Konva.Stage({
container: 'container',
width: width,
height: height,
});
var layer = new Konva.FastLayer();
stage.add(layer);

var wabbitTexture = new Image();
wabbitTexture.onload = function () {
_handleTextureLoaded();
};
wabbitTexture.src = 'https://konvajs.org/assets/bunny.png';

var stats = new Stats();
document.body.appendChild(stats.domElement);
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';

window.requestAnimationFrame(update);

var counter = document.getElementById('counter');

count = startBunnyCount;
counter.innerHTML = startBunnyCount + ' BUNNIES';

stage.on('mousedown', function () {
isAdding = true;
});

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

document.addEventListener('touchstart', onTouchStart, true);
document.addEventListener('touchend', onTouchEnd, true);

function _handleTextureLoaded(event) {
for (var i = 0; i < startBunnyCount; i++) {
var bunny = new Konva.Image({
image: wabbitTexture,
transformsEnabled: 'position',
perfectDrawEnabled: false,
x: 10,
y: 10,
});

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

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

function onTouchStart(event) {
isAdding = true;
}

function onTouchEnd(event) {
isAdding = false;
}

function update() {
stats.begin();
if (isAdding) {
for (var i = 0; i < amount; i++) {
var bunny = new Konva.Image({
image: wabbitTexture,
transformsEnabled: 'position',
perfectDrawEnabled: false,
x: 0,
y: 0,
});
bunny.speedX = Math.random() * 10;
bunny.speedY = Math.random() * 10 - 5;
bunnys.push(bunny);
layer.add(bunny);

count++;
}
counter.innerHTML = count + ' BUNNIES';
}

for (var i = 0; i < bunnys.length; i++) {
var bunny = bunnys[i];
var pos = {
x: bunny.x(),
y: bunny.y(),
};
pos.x = pos.x + bunny.speedX;
pos.y = pos.y + bunny.speedY;
bunny.speedY += GRAVITY;
if (pos.x > maxX - wabbitTexture.width) {
bunny.speedX *= -1;
pos.x = maxX - wabbitTexture.width;
} else if (pos.x < minX) {
bunny.speedX *= -1;
pos.x = minX;
}

if (pos.y > maxY - wabbitTexture.height) {
bunny.speedY *= -0.85;
pos.y = maxY - wabbitTexture.height;
if (Math.random() > 0.5) {
bunny.speedY -= Math.random() * 6;
}
} else if (pos.y < minY) {
bunny.speedY = 0;
pos.y = minY;
}
bunny.position({
x: pos.x,
y: pos.y,
});
}
requestAnimationFrame(update);
stats.end();
}
</script>
</body>
</html>