我需要一个应用程序,有大约30k对象,用户可以潘,缩放或“选择点击”任何这些对象。正在使用Fabric.js画布
我使用svg和svg-pan-缩放插件(没有画布元素)做了同样的工作,取得了更好的效果。
问题:在单击缩放、摇摄或对象时,存在明显的滞后。
已经尝试过织物的特定选项
fabric.Object.prototype.objectCaching = false;
fabric.Object.prototype.statefullCache = false;
fabric.Object.prototype.noScaleCache = true;
fabric.Object.prototype.needsItsOwnCache = false;
更新将更新小提琴
供参考:
发布于 2017-04-01 05:28:03
不要在IO事件中呈现!
虽然没有完全修正更新速度,但这个答案将是交互速度的两倍。
鼠标和与画布(和DOM)的事件交互所犯的一个常见的、几乎是标准的错误是将呈现委托给鼠标/触摸事件。这是非常糟糕的做法,因为鼠标事件以比显示器所能显示的更高的速度发射。当您的呈现时间很长时,当您排队处理鼠标事件(伪呈现事件)并对鼠标的每一个移动执行重新呈现时,情况会变得更糟。
备注阻塞代码将停止鼠标事件,但一旦引擎空闲,鼠标将再次以完全速度启动。
使用鼠标事件来获取鼠标状态。使用与显示器同步的动画循环,仅在需要时才呈现,并且有可用的时间。像轮子和鼠标运动的三角洲应该被累计记录下来。
mouse.dx += event.movementX;
mouse.dy += event.movementY;
mouse.wheel += event.wheelDelta;
然后在主渲染循环中消耗它们..。
function update(){
// ... code to use mouse
// consume deltas
mouse.x = mouse.y = mouse.wheel = 0;
...this确保在呈现更新之间可能有许多鼠标事件时,鼠标状态会被准确地遵循。
例如,将事件与呈现分离。
更改您提供的小提琴代码如下,在我的机器上,它的渲染速度大约翻了一倍(这仍然非常慢)。
// from just after the function applyZoom replace all the code
var mouse = { // holds the mouse state
x : 0,
y : 0,
down : false,
w : 0,
delta : new fabric.Point(0,0),
}
// event just track mouse state
function zoom(e) {
if(e != null) { e.preventDefault() }
var evt=window.event || e;
mouse.x = e.offsetX;
mouse.y = e.offsetY;
mouse.w += evt.detail? evt.detail*(-120) : evt.wheelDelta;
return false;
}
canvas.on('mouse:up', function (e) { mouse.down = false });
canvas.on('mouse:out', function (e) { mouse.down = false });
canvas.on('mouse:down', function (e) { mouse.down = true });
canvas.on('mouse:move', function(e) {
if (e && e.e) {
mouse.delta.x += e.e.movementX;
mouse.delta.y += e.e.movementY;
}
});
// main animation loop
function update(){
if(mouse.w !== 0){ // if the wheel has moved do zoom
var curZoom = canvas.getZoom();
canvas.zoomToPoint(
{ x : mouse.x, y: mouse.y },
canvas.getZoom() + mouse.w / 4000
);
mouse.w = 0; // consume wheel delta
}else if(mouse.down) { // if mouse button down
canvas.relativePan(mouse.delta);
}
// consume mouse delta
mouse.delta.x = 0;
mouse.delta.y = 0;
requestAnimationFrame(update);
}
requestAnimationFrame(update);
https://stackoverflow.com/questions/43139328
复制相似问题