渲染跟随鼠标的线最终会使用Fabricjs在画布上使用多行来减慢速度

问题描述 投票:1回答:1

我有代码,在画布上每次点击都会绘制线条。它显示了鼠标移动线条的优先级,当鼠标移动时,该线条结束并从相同位置开始一个新线条。

我将两个示例代码拼凑在一起以生成此代码。其中一个例子允许我只要我按住鼠标就可以简单地绘制线条,这就构成了应用程序的主要内容。奇怪的是,使用原始示例代码,无论我在画布上有多少行,新行总是在mouse:move上顺利移动。当我在绘图时添加了不必按住鼠标的功能时,由于某种原因,在我向画布添加更多行之后,可移动线对鼠标的反应变得非常慢。你可以在下面看到我的意思。带红线的第一个画布是原始示例代码。第二个是我用一堆线调整。第三个是我的再次调整,我只是刷新了页面并摆脱了所有的线条。您可以看到线路在屏幕上只有几行反应的速度有多快。

enter image description here

mouse:move代码在这两个方面几乎完全相同,所以我不能为我的生活弄清楚为什么在添加大约50个对象之后我的调整非常缓慢。

红线小提琴,注意鼠标移动时新线的反应性:https://codepen.io/morrowsend/pen/YgBxvj?editors=0010

我的调整小提琴,注意最新的一行是对鼠标移动的反应延迟。这是由于鼠标:在其中移动canvas.renderAll()。画布上的线条越多,反应就越小。:https://codepen.io/morrowsend/pen/EMeWpM

现在你可能会说“只使用动画”,我试过了。我还没有得到那些,但我尝试使用Fabric的动画,我不喜欢。它可以达到的最快速度是1ms,但这并不是非常活跃,并且在绘制几行后会给我一些伪影,有时新线会偏离鼠标。此外,它将动画设置为前一行,以便将端点移动到最新的行。更容易看到这种行为。在下图中,我在动画代码中已经有很多行,你可以看到它表现不佳。当我刷新并开始使用干净的画布时,事情看起来似乎工作正常,但是我获得的线越多,结果就越不正确:enter image description here

这是使用Fabric内置动画的动画代码。 https://codepen.io/morrowsend/pen/YgBxvj?editors=0010

我找到了一个只使用画布动画的例子,但是我希望用户在绘制之后可以编辑我的线条(尚未实现)。看起来很顺利,但它在画布上还没有man对象,所以它可能会像我一样陷入困境,如果添加更多:html canvas a line following mouse relavent fiddle:http://jsfiddle.net/dFjodorov/XQpzU/5171/

即使屏幕上有几百个对象,如何平滑地绘制线条?我觉得我已经尝试了很多东西但无济于事。

canvas jquery-animate fabricjs render
1个回答
1
投票

在鼠标移动处理程序上设置行的x2和y2值,无需使用动画。并在编辑模式下删除鼠标手柄并添加绘图模式。

var canvas = new fabric.Canvas('c');

var isDown;

var point1;
var line = null;
var drawMode = true;

function addListener() {
  canvas.on('mouse:down', onMouseDown);
  canvas.on('mouse:dblclick', onDblClick);
  canvas.on('mouse:move', onMouseMove)
}

function removeListener() {
  canvas.off('mouse:down', onMouseDown);
  canvas.off('mouse:dblclick', onDblClick);
  canvas.off('mouse:move', onMouseMove)
}

function setSelectable(value) {
  canvas.forEachObject(function(object) {
    object.selectable = value;
    object.setCoords()
  })
  canvas.selection = value;
}

function onMouseDown(options) {
  isDown = true;
  var pointer = canvas.getPointer(options.e);
  var points = [pointer.x, pointer.y, pointer.x, pointer.y];
  line = new fabric.Line(points, {
    stroke: 'black',
    hasControls: false,
    hasBorders: false,
    lockMovementX: false,
    lockMovementY: false,
    hoverCursor: 'default',
    selectable: false
  });
  canvas.add(line);
};

function onDblClick() {
  //alert('dblclick')
  line.setCoords()
  isDown = false;
  line = null;
};

function onMouseMove(o) {
  if (!isDown) return;
  var pointer = canvas.getPointer(o.e);
  line.set({
    x2: pointer.x,
    y2: pointer.y
  });
  canvas.requestRenderAll();
}; //end mouse:move

document.addEventListener("keydown", function(event) {
  var keyPressed = event.keyCode;
  if (keyPressed === 27) { //escape key code
    edit();
  } //end if delete  
}); //end keydown


function draw() {
  drawMode = true
  addListener()
  setSelectable(false);
  // console.log(drawMode)
}


function edit() {
  // bool = false
  if (drawMode) {
    var canvas_objects = canvas._objects;
    var sel = canvas_objects[canvas_objects.length - 1]; //Get last object 
    canvas.remove(sel);
    drawMode = false;
  }
  removeListener();
  setSelectable(true);
}
var enableDraw = document.getElementById("drawEnabled");
enableDraw.addEventListener("click", draw);
var enableEdit = document.getElementById("editEnabled");
enableEdit.addEventListener("click", edit);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>
        
<button id="drawEnabled">Draw Mode</button>
<button id="editEnabled">Edit Mode</button>
<canvas id="c" width="500" height="500" style="border:1px solid #aaa"></canvas>
© www.soinside.com 2019 - 2024. All rights reserved.