我需要使用递归函数为 canvas Fabric Js 上的同心圆制作动画
I need to animate the concetric circles on a canvas FabricJs using recursive function
我有 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>
创建一个函数 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>
我有 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>
创建一个函数 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>