簡體   English   中英

通過更新自定義形狀的KineticJS動畫

[英]KineticJS Animation by updating customized shape

我現在有一個自定義的Shape,並且此形狀由一個全局變量控制。 因此,我假設我只需要由於frame.time更改此全局變量,擦除舊形狀,然后創建新形狀。

但是它似乎不起作用。 以下是簡化的代碼。

<script>
  var toControlShape;
  var myDrawFunction(context) {
    // toControlShape will be used here. 
  }

  window.onload = function() {
    var stage = new Kinetic.Stage({...});
    var layer = new Kinetic.Layer();

    var myShape = new Kinetic.Shape({
      drawFunc: myDrawFunction,
      ...
    });

    layer.add(myShape);
    stage.add(layer);

    var animation = new Kinetic.Animation(function(frame) {
      toControlShape = someFunction(frame.time);
      myShape.remove();
      myShape = new Kinetic.Shape({
        drawFunc: myDrawFunction,
        ...
      });
      layer.add(myShape);
    }, layer);

    animation.start();
  };
</script>

形狀正確顯示為其初始狀態。 但是沒有動畫。

我對Javascript和HTML5很陌生。 因此,此代碼中可能有很多反模式。 向我指出他們。

完整的代碼是在這里上的jsfiddle

我認為您做錯了。 從文檔:

  • “ Kinetic.Animation,用於在每個動畫幀中修改形狀的位置。”

所以我認為您應該停止刪除形狀,而只是更新形狀。 然后,動畫部分應該可以為您工作。

HTML-

<!DOCTYPE html>

<html>
    <head>
        <title>Strath</title>
        <meta http-equiv="X-UA-Compatible" content="IE=9" />
    <script  type="text/javascript" src="kinetic-v4.1.2.min.js"></script>

    <script src="fiddle.js"></script>
        <style type="text/css">

        </style>
    </head>
    <body>


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

js-

    var segsToSkip = 0;
      var triangle;
      window.onload = function() {
        var stage = new Kinetic.Stage({
          container: "PureHTML5",
          width: 300,
          height: 300
        });
        var layer = new Kinetic.Layer();


        /*
         * create a triangle shape by defining a
         * drawing function which draws a triangle
         */
        var box = new Kinetic.Shape({
          drawFunc: myDrawFunction,
          stroke: "white",
          strokeWidth: 8
        });
        var bbox= new Kinetic.Rect({
            x:10,
            y:10,
            width:10,
            height:10,
            fill: 'green'
        });

          triangle = new Kinetic.Shape({
        drawFunc: function(context) {
          context.beginPath();
          context.moveTo(10, 10);
          context.lineTo(20, 80);
          context.quadraticCurveTo(30, 10, 26, 17);
          context.closePath();
          context.stroke();  

        },
        fill: '#00D2FF',
        stroke: 'black',
        strokeWidth: 4
      }); 
        layer.add(bbox);
        // add the triangle shape to the layer
        layer.add(box);
        layer.add(triangle);
        // add the layer to the stage
        stage.add(layer);

         var animation = new Kinetic.Animation(function(frame) {
            console.log(frame.time);
             var newSegsToSkip = Math.round(frame.time / 200);
                  triangle.setX(newSegsToSkip);
         triangle.setDrawFunc(function(context) {
          context.beginPath();
          context.moveTo(newSegsToSkip, 10);
          context.lineTo(newSegsToSkip+20, 80);
          context.quadraticCurveTo(30, 10, 26, 17);
          context.closePath();
          context.stroke();  
                 });
             }, layer);



         var animation2 = new Kinetic.Animation(function(frame) {
            var newSegsToSkip = Math.round(frame.time / 200);
            if (newSegsToSkip == segsToSkip) return;
            else {
                segsToSkip = newSegsToSkip;
                box.remove();
                box = new Kinetic.Shape({
                  drawFunc: myDrawFunction,
                  stroke: "black",
                  strokeWidth: 8
                });
                layer.add(box);
            }
        }, layer);
        animation.start();
           animation2.start();
      };

var myDrawFunction = function(context) {
    var x = 50;
    var y = 50;
    var width = 200;
    var height = 200;
    var radius = 20;
    var dashedLength = 6;
    var segsToDraw = 58;

    context.beginPath();

    context.drawDashedBox(x, y, width, height, radius, dashedLength, segsToSkip, segsToDraw);

    context.closePath();
    //   context.stroke();  
    //this.fill(context);
    this.stroke(context);
}

var CP = window.CanvasRenderingContext2D && CanvasRenderingContext2D.prototype;
CP.drawDashedBox = function(x, y, width, height, radius, dashedLength, segsToSkip, segsToDraw) {
    // init
    var env = getStratEnvForRCBox(x, y, width, height, radius, dashedLength, segsToSkip, segsToDraw);

    // 'right'->'upper-right'->'down'->'bottom-right'->'left'->'bottom-left'->'up'->'upper-left'->'right'->...
    while (env.segsToDraw > 0) {
        console.log('drawing direction: ', env.direction, 'segsToDraw:', env.segsToDraw);
        env.putToConsole();
        if (env.direction == 'right') {
            env = drawDashedLineNew(env, x + width - radius, y + height, dashedLength, this);
            env.direction = 'bottom-right';
        }
        else if (env.direction == 'upper-right') {
            env = drawDashedArcNew(env, x + width - radius, y + radius, radius, 0, Math.PI / 2, dashedLength, this);    
            env.direction = 'left';
        }
        else if (env.direction == 'down') {
            env = drawDashedLineNew(env, x, y + height - radius, dashedLength, this);
            env.direction = 'bottom-left';
        }
        else if (env.direction == 'bottom-right') {
            env = drawDashedArcNew(env, x + width - radius, y + height - radius, radius, 3 * Math.PI / 2, 2 * Math.PI, dashedLength, this);
            env.direction = 'up';
        }
        else if (env.direction == 'left') {
            env = drawDashedLineNew(env, x + radius, y, dashedLength, this);
            env.direction = 'upper-left';
        }
        else if (env.direction == 'bottom-left') {
            env = drawDashedArcNew(env, x + radius, y + height - radius, radius, Math.PI, 3 * Math.PI / 2, dashedLength, this);
            env.direction = 'right';
        }
        else if (env.direction == 'up') {
            env = drawDashedLineNew(env, x + width, y + radius, dashedLength, this);
            env.direction = 'upper-right';
        }
        else if (env.direction == 'upper-left') {
            env = drawDashedArcNew(env, x + radius, y + radius, radius, Math.PI / 2, Math.PI, dashedLength, this);
            env.direction = 'down';
        }
    }
}

function getStratEnvForRCBox(x, y, width, height, radius, dashLength, segsToSkip, segsToDraw) {
    var direction = 'right';
    var startX, startY;
    if (direction == 'down') {
        startX = x; startY = y + radius;
    } else if (direction == 'right') {
        startX = x + radius; startY = y + height;
    } else if (direction == 'up') {
        startX = x + width; startY = y + height - radius;
    } else if (direction == 'left') {
        startX = x + width - radius; startY = y;
    }
    var env = new Environment(startX, startY, 'gap', 0, direction, segsToSkip, segsToDraw);
    return env;
}

function drawDashedLineNew(env, endX, endY, dashedLength, context) {
    var dx = (endX - env.x), dy = (endY - env.y);
    var angle = Math.atan2(dy, dx);
    console.log('drawing line: angle =', angle, ' , ', env.gapOrDash, ' =', env.remainingLengthFromLastDraw);

    var fromX = env.x, fromY = env.y;
    // deal with remining
    // we start loop from a fresh dash
    if (env.gapOrDash == 'dash') {
        // check if we need to skip
        if (env.segsToSkip > 0) {
            env.segsToSkip --;
        } else {
            context.moveTo(env.x, env.y);
            context.lineTo(env.x + env.remainingLengthFromLastDraw * Math.cos(angle), env.y + env.remainingLengthFromLastDraw * Math.sin(angle));
            // check if we quit
            env.segsToDraw --;
            if (env.segsToDraw == 0) return env;
        }

        // a full gap
        fromX = env.x + (env.remainingLengthFromLastDraw + dashedLength) * Math.cos(angle);
        fromY = env.y + (env.remainingLengthFromLastDraw + dashedLength) * Math.sin(angle);
    } else if (env.gapOrDash == 'gap') {
        fromX = env.x + env.remainingLengthFromLastDraw * Math.cos(angle);
        fromY = env.y + env.remainingLengthFromLastDraw * Math.sin(angle);
    }

    var length = (endX - fromX) / Math.cos(angle);
    if (endX - fromX == 0) length = Math.abs(endY - fromY);
    var n = length / dashedLength;
    var draw = true;
    var x = fromX, y = fromY;
    context.moveTo(x, y);
    for (var i = 0; i < n; i++) {
        x += dashedLength * Math.cos(angle);
        y += dashedLength * Math.sin(angle);
        if (draw) {
            // check if we need to skip
            if (env.segsToSkip > 0) {
                env.segsToSkip --;
            } else {
                context.lineTo(x,y);

                // check if we quit
                env.segsToDraw --;
                if (env.segsToDraw == 0) return env;
            }
        } else context.moveTo(x, y);
        draw = !draw;
    }

    // deal with remaining
    if (draw) {
        // check if we need to skip
        if (env.segsToSkip > 0) {
            env.segsToSkip --;
        } else
            context.lineTo(endX, endY);
    }
    env.x = endX;
    env.y = endY;
    draw ? env.gapOrDash = 'dash' : env.gapOrDash = 'gap';
    env.remainingLengthFromLastDraw = dashedLength - (endX - x) / Math.cos(angle);

    return env;
}

function drawDashedArcNew(env, x, y, radius, startAngle, endAngle, dashedLength, context) {
    var points = [];
    var n = radius * Math.PI * 2/ dashedLength;
    var stepAngle = Math.PI * 2 / n;

    // deal with remaining
    var angle = Math.asin(env.remainingLengthFromLastDraw / 2 / radius) * 2;
    if (env.gapOrDash == 'dash') {
        var angle = Math.asin(env.remainingLengthFromLastDraw / 2 / radius) * 2;
        points.push({
            x : (Math.cos(startAngle) * radius) + x,
            y : - (Math.sin(startAngle) * radius) + y,
            ex : (Math.cos(startAngle + angle) * radius) + x,
            ey : - (Math.sin(startAngle + angle) * radius) + y
        });

        startAngle += stepAngle + angle;
    } else {
        startAngle += angle;
    }

    var draw = true;
    while(startAngle + stepAngle <= endAngle) {
        if (draw) {
            points.push({
            x : (Math.cos(startAngle) * radius) + x,
            y : - (Math.sin(startAngle) * radius) + y,
            ex : (Math.cos(startAngle + stepAngle) * radius) + x,
            ey : - (Math.sin(startAngle + stepAngle) * radius) + y
            });    
        }

        startAngle += stepAngle;
        draw = !draw;
    }

    // deal with the remaining
    var endX = (Math.cos(endAngle) * radius) + x;
    var endY = - (Math.sin(endAngle) * radius) + y;
    //console.log('drawing arc: end-x:', endX, ',end-y:', endY);
    if (draw) {
        points.push({
            x : (Math.cos(startAngle) * radius) + x,
            y : - (Math.sin(startAngle) * radius) + y,
            ex : endX,
            ey : endY
        });
    }
    env.x = endX;
    env.y = endY;
    draw ? env.gapOrDash = 'dash' : env.gapOrDash = 'gap';
    env.remainingLengthFromLastDraw = dashedLength - radius * Math.sin( (endAngle - startAngle) / 2) * 2;

    for(p = 0; p < points.length; p++){
        //console.log('draw arc seg: from(', points[p].x, ',', points[p].y, ') to (', points[p].ex, ',', points[p].ey, ')');
        // check if we need to skip
        if (env.segsToSkip > 0) {
            env.segsToSkip --;
        } else {
            context.moveTo(points[p].x, points[p].y);
            context.lineTo(points[p].ex, points[p].ey);

            // check if we quit
            env.segsToDraw --;
            if (env.segsToDraw == 0) return env;
        }
    }

    return env;
}

function Environment(x, y, gapOrDash, remainingLengthFromLastDraw, direction, segsToSkip, segsToDraw) {
    this.x = x;
    this.y = y;
    this.gapOrDash = gapOrDash;
    this.remainingLengthFromLastDraw = remainingLengthFromLastDraw;
    this.direction = direction;
    this.segsToSkip = segsToSkip;
    this.segsToDraw = segsToDraw;
}
Environment.prototype.putToConsole = function() {
    //console.log('Environment:');
    //console.log('x:', this.x, ',y:', this.y, 'direction:', this.direction);
    //console.log('toSkip:', this.segsToSkip, 'toDraw:', this.segsToDraw);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM