HTML 5 画布动画 - 一个接一个地移动多个对象

HTML 5 Canvas Animation - Move multiple objects one after another

本文关键字:一个 对象 移动 布动画 动画 HTML      更新时间:2023-09-26

我有这个动画,它将一排圆圈从A(x,y(移动到B(x,y(。但是我很难尝试将其复制到一个圆圈数组中,其中每一行(一个接一个(从 A 移动到 B。但是,我还想保持数组的原始位置,以便本质上它创建行的副本并移动副本。任何帮助将不胜感激!

编辑

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

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

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

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

原-----------------新

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

  2. p p
  3. p ------------ B.

  4. r r rg g g g
  5. g g g ------------ C. r r

因此,动画的顺序如下:

  1. 3 --- a.第 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;
    }
    

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;
}
<canvas id="canvas" width="580"></canvas>