【问题标题】:KineticsJS/PaperJS is not responsive for mouse interactionKinetics JS/Paper JS 对鼠标交互没有响应
【发布时间】:2014-01-04 19:28:50
【问题描述】:

我正在尝试使用 Kinetic/Paper/Fabric JS 编写一个简单的手绘应用程序。但是我注意到所有使用these libraries 的手绘示例都没有响应。

响应式是指 KineticJS/PaperJS 在我拖动鼠标时不会更新正在绘制的线条,就像 jSignature 那样。

有没有办法解决这个问题?

【问题讨论】:

  • Fabric 是如何反应迟钝的? fabricjs.com/freedrawing
  • 对不起,我在 firefox linux 中进行测试,似乎与画布相关的所有内容都很慢。在 linux 上的 firefox windows 和 Chrome 上一切都很好。

标签: canvas kineticjs fabricjs paperjs


【解决方案1】:

这是一个使用 KineticJS 的示例:http://jsfiddle.net/m1erickson/EsFSg/

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Prototype</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.2.min.js"></script>

<style>
#container{
  border:solid 1px #ccc;
  margin-top: 10px;
}
</style>        
<script>
$(function(){

        // create a stage and a layer
        var stage = new Kinetic.Stage({
            container: 'container',
            width: 350,
            height: 350
        });
        var layer = new Kinetic.Layer();
        stage.add(layer);

        // an empty stage does not emit mouse-events
        // so fill the stage with a background rectangle
        // that can emit mouse-events
        var background = new Kinetic.Rect({
            x: 0,
            y: 0,
            width: stage.getWidth(),
            height: stage.getHeight(),
            fill: 'white',
            stroke: 'black',
            strokeWidth: 1,
        })        
        layer.add(background);
        layer.draw();

        // a flag we use to see if we're dragging the mouse
        var isMouseDown=false;
        // a reference to the line we are currently drawing
        var newline;
        // a reference to the array of points making newline
        var points=[];

        // on the background
        // listen for mousedown, mouseup and mousemove events
        background.on('mousedown', function(){onMousedown();});
        background.on('mouseup', function(){onMouseup();});
        background.on('mousemove', function(){onMousemove();});

        // On mousedown
        // Set the isMouseDown flag to true
        // Create a new line,
        // Clear the points array for new points
        // set newline reference to the newly created line
        function onMousedown(event) {
            isMouseDown = true;
            points=[];
            points.push(stage.getMousePosition());
            var line = new Kinetic.Line({
                points: points,
                stroke: "green",
                strokeWidth: 5,
                lineCap: 'round',
                lineJoin: 'round'
            });
            layer.add(line);
            newline=line;
        }

        // on mouseup end the line by clearing the isMouseDown flag
        function onMouseup(event) {
            isMouseDown=false;
        }

        // on mousemove
        // Add the current mouse position to the points[] array
        // Update newline to include all points in points[]
        // and redraw the layer
        function onMousemove(event) {
            if(!isMouseDown){return;};
            points.push(stage.getMousePosition());
            newline.setPoints(points);
            // use layer.drawScene
            // This avoids unnecessarily updating the hit canva
            layer.drawScene();
        }


}); // end $(function(){});

</script>       
</head>

<body>
    <div id="container"></div>
</body>
</html>

[补充答案:进一步优化]

进一步的性能涉及将鼠标点捕获与绘图分离。

在 mousemove 中: 仅捕获鼠标位置——不要尝试在 mousemove 中绘制任何内容。

  • accumulatedPointsArray.push({x:mouseX,y:mouseY});

您甚至可以考虑忽略一些鼠标点,因为更少的点仍然可以绘制相当好的折线。也许只需保存每三个传入的鼠标点。

绘制:设置一个动画循环:

  • 将累积点添加到 Kinetic.Line--myLine.setPoints(accumulatedPointsArray)

  • 只做一个 myLine.draw()。

要充分发挥性能,请考虑使用 Kinetic.Shape 而不是 Kinetic.Line 来显示用户创建的折线。 Kinetic.Shape 为您提供了一个可以使用的画布上下文,因此它“更接近金属”并提供比“托管”Kinetic.Line 更好的绘图性能。当用户完成定义他们的线时,您可以将这些累积的点移动到 Kinetic.Line 并隐藏 Kinetic.Shape - 两全其美。

无论如何,祝你的项目好运!

【讨论】:

  • 感谢您的帮助。这在 chrome 中完美运行,但在 Firefox 上提供相同的旧性能(读取速度慢)。我观察到在 Firefox 中更快地移动鼠标会导致 KineticJS 被阻止。有没有你能想到的解决方法?
  • 在我的回答中将分段添加到单个 Kinetic.Line 时,我在 Firefox/26.0 中没有遇到任何减速:-\ 如果您遇到延迟,请检查您的代码以查看您是否正在尝试在 mousemove 中做太多事情(每秒触发 20 次以上)。请参阅我的答案中有关如何优化鼠标移动的补充内容。
猜你喜欢
  • 1970-01-01
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 2018-12-17
  • 1970-01-01
  • 2015-10-07
  • 2021-07-13
  • 2015-10-25
相关资源
最近更新 更多