使用KineticJS实时绘制路径

时间:2013-01-07 20:21:30

标签: kineticjs

我想在我的画布上画一条路径。我知道如何使用以下HTML5画布代码:

$('#drawing-canvas').mousedown(function(e){
    startx = e.pageX;
    starty = e.pageY;
    cxt.beginPath();
    cxt.moveTo(startx,starty);
 });

$('#drawing-canvas').mousemove(function(e){
    cxt.lineTo(e.pageX,e.pageY);
    cxt.strokeStyle='red'; 
    cxt.lineWidth = 1;     
    cxt.stroke();
 });

我的问题是如何使用KineticJS完成同样的事情。

更新

我认为这样的事情可能有用。

  $('#container').mousemove(function(e){
  var pen = new Kinetic.Shape({
    drawFunc: function(canvas) {
      var context = canvas.getContext();
      if(moving == false){ // grab the start xy coords from mousedown event
      context.beginPath();
      context.moveTo(startx,starty);
      moving = true;
      }
      context.lineTo(e.pageX,e.pageY);
      context.strokeStyle='#ff00ff'; 
      context.lineWidth = 1;     
      context.stroke();
   }
     penlayer.add(pen);
     stage.add(penlayer); 
  });
 });

然而,处理beginPath()和moveTo(..)被证明是有问题的。我需要在mousedown事件上设置这些。有什么想法吗?

更新

通过在http://www.redshiftsolutions.com/demos/whiteboard/whiteboard.html选择笔选项,可以看到我想要获得的效果。这是一个使用canvas和jQuery的简单协作白板。由于添加了拖放功能,我想将其转换为KineticJS。

3 个答案:

答案 0 :(得分:2)

在这里:http://jsfiddle.net/akhiyadav1/k4qB8/22/看看这个人是如何做到的。

基本上你会创建一个新的Kinetic.Line()并在每次鼠标移动时将其推向它。

试试这段代码:

<!DOCTYPE HTML>
<html>
  <head>
      <style>
        body {
            margin: 0px;
            padding: 0px;
        }
        canvas {
            border: 1px solid #9C9898;
        }
    </style>
    <script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.0.1.js"></script>
    <script>
        window.onload = function() {
            layer = new Kinetic.Layer();
            stage = new Kinetic.Stage({
                container: "container",
                width: 320,
                height: 320
            });

            background = new Kinetic.Rect({
                x: 0, 
                y: 0, 
                width: stage.getWidth(),
                height: stage.getHeight(),
                fill: "white"
            });

            line = new Kinetic.Line({
                points: [0, 0, 50, 50],
                stroke: "red"
            });

            layer.add(background);
            layer.add(line);
            stage.add(layer);

            moving = false;

            stage.on("mousedown", function(){
                if (moving){
                    moving = false;layer.draw();
                } else {
                    var mousePos = stage.getMousePosition();
                    //start point and end point are the same
                    line.getPoints()[0].x = mousePos.x;
                    line.getPoints()[0].y = mousePos.y;
                    line.getPoints()[1].x = mousePos.x;
                    line.getPoints()[1].y = mousePos.y;

                    moving = true;    
                    layer.drawScene();            
                }

            });

            stage.on("mousemove", function(){
                if (moving) {
                    var mousePos = stage.getMousePosition();
                    var x = mousePos.x;
                    var y = mousePos.y;
                    line.getPoints()[1].x = mousePos.x;
                    line.getPoints()[1].y = mousePos.y;
                    moving = true;
                    layer.drawScene();
                }
            });

            stage.on("mouseup", function(){
                moving = false; 
            });

        };
    </script>
</head>
<body>
    <div id="container" ></div>
</body>

答案 1 :(得分:0)

将你的代码放在jsfiddle中,我会玩弄它。但看着它,似乎你的代码有点不对劲。

每次鼠标移动时,您都要重新定义局部变量笔并重新添加相同的笔层。它的结构有点偏。尝试:

$('#container').mousemove(function(e){
   var pen = new Kinetic.Shape({
      drawFunc: function(canvas) {
          var context = canvas.getContext();
          if(moving == false){ 
              context.beginPath();
              context.moveTo(startx,starty);
              moving = true;
          }
          context.lineTo(e.pageX,e.pageY);
          context.strokeStyle='#ff00ff'; 
          context.lineWidth = 1;     
          context.stroke();
      } 
  });

  penlayer.add(pen);
  stage.add(penlayer);
});

如果您希望创建直线,那么使用其他鼠标事件以获得更好的控制效果也会更好。

 $('#container').mousedown(function(e){
       //draw temporary shape
 }
 $('#container').mousemove(function(e){
       //redraw shape
 }
 $('#container').mouseup(function(e){
       //add shape to layer
 }

另外,为什么不使用Kinetic.Line()和类似的东西:

 var startLine; // make this global because this can be redefined 
 $('#container').mousedown(function(e){
    startLine = new Kinetic.Line({
         points: [stage.getUserPosition().x, stage.getUserPosition().y],
         stroke: 'red',
         strokeWidth: 15,
         lineCap: 'round',
         lineJoin: 'round'
    });
 }
 $('#container').mouseUp(function(e){
    var endLine = new Kinetic.Line({
         points: [startLine.getX(), startLine.getY(), stage.getUserPosition().x, stage.getUserPosition().y],
         stroke: 'red',
         strokeWidth: 15,
         lineCap: 'round',
         lineJoin: 'round'
    });
    layer.add(endLine);
 }

这是一个非常粗略的解决方案,您必须解决startLine和endLine的范围。

答案 2 :(得分:0)

这里我是如何实现它的。关键是在mousemove和mouseup期间使用kineticJS的样条形状和推动点。 ev._x,ev._y是根据这篇文章计算的x和y点 Tracking mouse position in canvas when no surrounding element exists

如果有帮助请告诉我

tools.pencil = function () {
var tool = this;
this.started = false;
var drawObject;

this.mousedown = function (ev) {
    drawObject = new DrawObject();
    drawObject.Tool = DrawTool.Pencil;
    tool.started = true;
    drawObject.currentState = DrawState.Started;
    drawObject.StartX = ev._x;
    drawObject.StartY = ev._y;
    tool.DrawIt(drawObject);

};

this.mousemove = function (ev) {
    if (tool.started) {
        drawObject.currentState = DrawState.Inprogress;
        drawObject.CurrentX = ev._x;
        drawObject.CurrentY = ev._y;
        tool.DrawIt(drawObject);

    }
};

this.mouseup = function (ev) {
    if (tool.started) {
        tool.started = false;
        drawObject.currentState = DrawState.Completed;
        drawObject.CurrentX = ev._x;
        drawObject.CurrentY = ev._y;
        tool.DrawIt(drawObject);
    }
};
this.mouseout = function (ev) {
    if (tool.started) {
    }
    tool.started = false;

};

this.DrawIt = function (drawObject) {

        switch (drawObject.currentState) {
            case DrawState.Started:
                var x= drawObject.StartX, 
                    y = drawObject.StartY;
                var pencil = new Kinetic.Spline({
                    points: [{
                        x: x,
                        y: y
                    }],
                    stroke: 'red',
                    strokeWidth: 2,
                    lineCap: 'round',
                    tension: 1,
                    name: shapes.length
                });

                drawObject.Shape = pencil;
                layer.add(pencil);
                layer.draw();


                break;
            case DrawState.Inprogress:
            case DrawState.Completed:
                var x = drawObject.CurrentX,
                    y = drawObject.CurrentY;

                var pencil = drawObject.Shape;
                pencil.attrs.points.push({ x: x, y: y });
                pencil.setPoints(pencil.attrs.points);
                layer.draw();
                if (drawObject.currentState == DrawState.Completed) {
                    // dosomething
                }

                break;
        }

}

在javascript中绘制对象是简单的空函数

function DrawObject()
{
}

和drawstate是铅笔工具的所有可用状态

var DrawState =
{
 Started: 0,
 Inprogress: 1,
 Completed: 2
}

和“层”是在KineticJS阶段已添加的简单KineticJS层