【问题标题】:HTML 5 Canvas Animation - Move multiple objects one after anotherHTML 5 Canvas Animation - 一个接一个地移动多个对象
【发布时间】:2016-05-11 09:55:48
【问题描述】:

我有这个动画,它将一排圆从 A(x,y) 移动到 B(x,y)。但是我在尝试将其复制到一个圆数组中时遇到了麻烦,其中每一行(一个接一个)从 A 移动到 B。但是,我也想保持数组的原始位置,这样基本上,它会复制行并移动副本。任何帮助将不胜感激!

编辑:我已经编辑了代码,现在它有两行在移动时保持静止 - 但现在,我希望能够移动多行(如下面的示例所述)。

编辑 2:这是一个 jsfiddle,所以更容易理解我的意思。

https://jsfiddle.net/vLvk1bsc/2/

例如,我想模拟这样的东西。

原创 ----------------- 新

  1. r r r r r。 --------------- A. g g g g g g

  2. p p p p p p ------------ B. r r r r r r

  3. g g g g g g ------------ C. r r r r r r

因此动画的顺序如下:

  1. 3 --- 一个。第 3 行的副本移动到 A 行

  2. 1 --- b。第 1 行的副本移动到 B 行

  3. 1 --- c.第 1 行的副本移动到 C 行

    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    
    window.requestAnimFrame = (function (callback) {
        return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
            window.setTimeout(callback, 1000 / 60);
        };
    })();
    
    setTimeout(function () {
        draw();
        animate(movingRow2);
    }, 100);
    
    var movingRow = [];
    var frozenRow = [];
    
    var cx = 50;
    var cy = 70;
    
    for (var i = 0; i < 6; i++) {
        movingRow.push({ x: cx, y: cy, borderWidth: 1, color: "orange"});
        frozenRow.push({ x: cx, y: cy, borderWidth: 1, color: "blue"});
    
        cx += 40;
    }
    
    var movingRow2 = [];
    var frozenRow2 = [];
    
    var cx = 50;
    var cy = 110;
    
    for (var i = 0; i < 6; i++) {
        movingRow2.push({ x: cx, y: cy, borderWidth: 1, color: "green"});
        frozenRow2.push({ x: cx, y: cy, borderWidth: 1, color: "pink"});
    
        cx += 40;
    }
    
    function drawCircle(myCircle, context) {
        context.beginPath();
        context.arc(myCircle.x, myCircle.y, 15, 0, 2 * Math.PI);
        context.fillStyle = myCircle.color;
        context.fill();
        context.stroke();
        context.closePath();
    }   
    
    function draw() {
        context.save();
        context.clearRect(0, 0, canvas.width, canvas.height);
    
        for (var i = 0; i < movingRow.length; i++) {
            drawCircle(movingRow[i], context);
            drawCircle(frozenRow[i], context);
    
            drawCircle(movingRow2[i], context);
            drawCircle(frozenRow2[i], context);
       }
    }
    
    var newX = 320;
    var newY = 70;
    
    var pathArray = [];
    
    pathArray.push({
        x: movingRow2[0].x,
        y: movingRow2[0].y
    });
    
    pathArray.push({
        x: newX,
        y: newY
    });
    
    var polyPoints = makePolyPoints(pathArray);
    
    var position = 0;
    var speed = 1;
    
    function animate(m) {
    
        // calculate the new position
        position += speed;
    
        if (position > polyPoints.length - 1) {
            return;
        }
    
        // a single point in the array
        var pt = polyPoints[position];
    
        var step = 0;
    
        // update x and y
        for (var i = 0; i < m.length; i++) {
            m[i].x = pt.x + step;
            m[i].y = pt.y;
    
            step += 40;
        }
    
        draw();
    
        // request new frame
        requestAnimationFrame(function() {
            animate(m);
        });
    }
    
    function makePolyPoints(pathArray) {
    
        // list of points for each frame of the shape
        var points = [];
        // how quickly the transition occurs
        var speed = 150;
    
        for (var i = 1; i < pathArray.length; i++) {
    
            var startPt = pathArray[i - 1];
            var endPt = pathArray[i];
    
            // calculate difference between start and end points 
            var dx = endPt.x - startPt.x;
            var dy = endPt.y - startPt.y;
    
            for (var n = 0; n <= speed; n++) {  
                // calculate the x and y positions for each frame
                var x = startPt.x + dx * n / speed;
                var y = startPt.y + dy * n / speed;
    
                // append the points to the array to be used in the animation
                points.push({
                    x: x,
                    y: y
                });
            }
        }
    
        return points;
    }
    

【问题讨论】:

  • 你能设置一支笔吗? codepen.io
  • 嘿艾伦,如果这就是你的意思,我已经在主要问题上添加了一个 jsfiddle?不熟悉codepen :)

标签: javascript html animation canvas


【解决方案1】:

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

window.requestAnimFrame = (function (callback) {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
        window.setTimeout(callback, 1000 / 60);
    };
})();



setTimeout(function () {
    draw();
    var a = anims[anims_i];
    animate(a[0], a[1]);
}, 100);

var rowA = [];
var rowB = [];
var rowC = [];

var cx = 50;
var cy = 70;

for (var i = 0; i < 6; i++) {
    rowA.push({ x: cx, y: cy-40, borderWidth: 1, color: "orange"});
    rowB.push({ x: cx, y: cy, borderWidth: 1, color: "blue"});
    rowC.push({ x: cx, y: cy+40, borderWidth: 1, color: "pink"});
    cx += 40;
}

var rowACopy1 = JSON.parse(JSON.stringify(rowA));
var rowACopy2 = JSON.parse(JSON.stringify(rowA));
var rowCCopy = JSON.parse(JSON.stringify(rowC));

var offsetX = 270;
var polyPointsA1 = makePolyPoints([
  {x: rowA[0].x, y: rowA[0].y},
  {x: rowB[0].x+offsetX, y: rowB[0].y}
]);

var polyPointsA2 = makePolyPoints([
  {x: rowA[0].x, y: rowA[0].y},
  {x: rowC[0].x+offsetX, y: rowC[0].y}
]);

var polyPointsC = makePolyPoints([
  {x: rowC[0].x, y: rowC[0].y},
  {x: rowA[0].x+offsetX, y: rowA[0].y}
]);

var anims = [
 [rowCCopy, polyPointsC],
 [rowACopy1, polyPointsA1],
 [rowACopy2, polyPointsA2]
];

var anims_i = 0;

function drawCircle(myCircle, context) {
    context.beginPath();
    context.arc(myCircle.x, myCircle.y, 15, 0, 2 * Math.PI);
    context.fillStyle = myCircle.color;
    context.fill();
    context.stroke();
    context.closePath();
}   

function draw() {
    context.save();
    context.clearRect(0, 0, canvas.width, canvas.height);

    for (var i = 0; i < rowA.length; i++) {
        drawCircle(rowA[i], context);
        drawCircle(rowB[i], context);
        drawCircle(rowC[i], context);

        drawCircle(rowACopy1[i], context);
        drawCircle(rowACopy2[i], context);
        drawCircle(rowCCopy[i], context);
   }
}

var position = 0;
var speed = 1;

function animate(m, polyPoints) {

    // calculate the new position
    position += speed;

    if (position > polyPoints.length - 1) {
      position = 0;
      anims_i++;
        if (anims_i < anims.length) {
          var a = anims[anims_i];
          requestAnimationFrame(function() {
            animate(a[0], a[1]);
          });
        }
        return;
    }

    // a single point in the array
    var pt = polyPoints[position];

    var step = 0;

    // update x and y
    for (var i = 0; i < m.length; i++) {
        m[i].x = pt.x + step;
        m[i].y = pt.y;

        step += 40;
    }

    draw();

    // request new frame
    requestAnimationFrame(function() {
        animate(m, polyPoints);
    });
}

function makePolyPoints(pathArray) {

    // list of points for each frame of the shape
    var points = [];
    // how quickly the transition occurs
    var speed = 150;

    for (var i = 1; i < pathArray.length; i++) {

        var startPt = pathArray[i - 1];
        var endPt = pathArray[i];

        // calculate difference between start and end points 
        var dx = endPt.x - startPt.x;
        var dy = endPt.y - startPt.y;

        for (var n = 0; n <= speed; n++) {  
            // calculate the x and y positions for each frame
            var x = startPt.x + dx * n / speed;
            var y = startPt.y + dy * n / speed;

            // append the points to the array to be used in the animation
            points.push({
                x: x,
                y: y
            });
        }
    }

    return points;
}
#canvas {
  border:1px solid red;
}
&lt;canvas id="canvas" width="580"&gt;&lt;/canvas&gt;

【讨论】:

  • 嘿狼锤,谢谢你,真的很感激!它非常接近我正在寻找的东西。而不是上下移动,我打算将副本移动,以便您将原始圆圈和新圆圈并排放置,即移动圆圈的 x 坐标将像 200。另外,我怎样才能得到它它一个接一个地做动作,而不是全部动作,即它移动第 1 行,停止,移动第 2 行,停止,移动第 3 行,停止?谢谢!
  • 不客气。我添加了右移和动画排序。如果不准确,您应该可以从那里定位它。
  • 非常感谢!是的,我可以解决这个问题,非常感谢:)
猜你喜欢
  • 1970-01-01
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
相关资源
最近更新 更多