【问题标题】:I need to animate the concetric circles on a canvas FabricJs using recursive function我需要使用递归函数为画布 Fabric Js 上的同心圆设置动画
【发布时间】:2021-09-23 15:36:39
【问题描述】:

我有 10 个同心圆,我想使用 FabricJs Canvas 制作动画。 我的目标是第一个内圈应该首先显示自己,然后是第二个,依此类推,使用递归或其他一些技术来避免代码重复。 我已经成功地为两个第一个内圈设置了动画,但使用了冗余代码。

const canvas = new fabric.Canvas('gameCanvas', {
  selection: false
});

fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';

let circles = [];

document.addEventListener('DOMContentLoaded', function() {
  drawCircles();
});

document.getElementById('animateBtn').addEventListener('click', function() {
 animateCircles();
});

function makeCircle(r) {
  return new fabric.Circle({
    left: 300,
    top: 120,
    strokeWidth: 1.5,
    radius: r,
    fill: 'white',
    stroke: 'black',
    selectable: false,
    hoverCursor: 'default',
    hasControls: false,
    hasBorders: false
  });

}

function drawCircles()
{
   for(let i = 9; i >= 0; i--)
     {
       let circle  = makeCircle(10*(i + 1));
         circles.push(circle);
         canvas.add(circle);
     }
   
     
}

function animateCircles()
{
    canvas.clear();
  
    
    circles[9].animate({
            opacity: 1
        },
        {
            duration: 2000,
            easing: fabric.util.ease['easeInElastic'],
            onChange: canvas.renderAll.bind(canvas),
            onComplete: function () {

                circles[9].setCoords();
                canvas.add(circles[9]);
                canvas.renderAll();
                circles[8].animate({
                    opacity: 1
                },
                {
                    duration: 2000,
                        easing: fabric.util.ease['easeInElastic'],
                        onChange: canvas.renderAll.bind(canvas),
                        onComplete: function () {
                            circles[8].setCoords();
                                canvas.add(circles[8]);
                                canvas.renderAll();
                                //On this line i need to use the code for animation
                        }
                }
                
                );
        }
    });
}
#container {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    align-items: center;
}

#animateBtn {
    margin-top: .5em;
}
<div id="container">
    <canvas id="gameCanvas" width="600" height="240" style="border: 2px solid green;"></canvas>
  <button id="animateBtn">Start Animation</button>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.0.0/fabric.min.js"></script>

【问题讨论】:

    标签: javascript recursion fabricjs


    【解决方案1】:

    创建一个函数loop(i),其中包含one 圆圈的重复代码(因此没有最初的clear() 调用)。设i 为圆的索引。然后在onComplete 回调中调用loop,但现在使用参数i-1。添加停止条件(当i 变为负数时)。

    这是您的实现代码:

    const canvas = new fabric.Canvas('gameCanvas', {
      selection: false
    });
    
    fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
    
    let circles = [];
    
    document.addEventListener('DOMContentLoaded', drawCircles);
    document.getElementById('animateBtn').addEventListener('click', animateCircles);
    
    function makeCircle(r) {
      return new fabric.Circle({
        left: 300,
        top: 120,
        strokeWidth: 1.5,
        radius: r,
        fill: 'white',
        stroke: 'black',
        selectable: false,
        hoverCursor: 'default',
        hasControls: false,
        hasBorders: false
      });
    }
    
    function drawCircles() {
        for (let i = 9; i >= 0; i--) {
            let circle  = makeCircle(10*(i + 1));
            circles.push(circle);
            canvas.add(circle);
        }
    }
    
    function animateCircles() {
        canvas.clear();
        
        function loop(i) {
            if (i < 0) return; // end the asynchronous loop
            circles[i].animate({
                opacity: 1
            }, {
                duration: 300,
                easing: fabric.util.ease['easeInElastic'],
                onChange: canvas.renderAll.bind(canvas),
                onComplete: function () {
                    circles[i].setCoords();
                    canvas.add(circles[i]);
                    canvas.renderAll();
                    loop(i - 1);
                }
            });
        }
        
        loop(9); // start the asynchronous loop
    }
    #container {
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        align-items: center;
    }
    
    #animateBtn {
        margin-top: .5em;
    }
    <div id="container">
        <canvas id="gameCanvas" width="600" height="240" style="border: 2px solid green;"></canvas>
      <button id="animateBtn">Start Animation</button>
    </div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.0.0/fabric.min.js"></script>

    【讨论】:

    • 是的,这行得通!如何使内圈在画布上保持可见?我很感激队友
    • 这是一个不同的问题。分别画内圈(数字9),用8开始“循环”?如果你不能让它工作,那么就问一个关于它的新问题。
    • 一点也不!我很感激队友!
    猜你喜欢
    • 2014-04-07
    • 2021-09-24
    • 2017-07-11
    • 2021-11-03
    • 2012-10-21
    • 1970-01-01
    • 1970-01-01
    • 2017-07-30
    • 2021-05-08
    相关资源
    最近更新 更多