我有两张地图,其中地图1有5个点,地图2有4个点,并且地图上的每个点都由点连接。这是代码段
const canvas = new fabric.Canvas('gameCanvas', {selection: false});
let circles_map1 = [];
let circles_map2 = [];
let lines_map1 = [];
let lines_map2 = [];
let playBack = {
circles: [],
lines: []
};
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
document.addEventListener('DOMContentLoaded', function()
{
displayMap(1);
});
document.getElementById('animateBtn').addEventListener('click', function(){
animateLinesDrawing().then(() => {
//..clear the playBack
playBack.circles = [];
playBack.lines = [];
displayMap(2);
animateLinesDrawing().then(() => {
console.log('animation finished');
});
});
});
function displayMap(map)
{
canvas.clear();
makeCircles_map(map);
makeLinesByMap(map);
}
function makeCircle(x, y)
{
return new fabric.Circle({
left: x,
top: y,
strokeWidth: 2,
radius: 10,
fill: 'white',
stroke: '#666',
selectable: false,
hoverCursor: 'default',
hasControls: false,
hasBorders: false
});
}
function makeCircles_map(map)
{
if(map === 1)
{
displayLabelText(1);
//5 circles for map 1
for(let i = 1; i <= 5; i++)
{
const randX = Math.floor((Math.random() * 360) + 30); //between 10 and 400
const randY = Math.floor((Math.random() * 190) + 10); //between 10 and 200
const circle = makeCircle(randX, randY);
playBack.circles.push(circle);
circles_map1.push(circle);
}
}
else if(map === 2)
{
displayLabelText(2);
//4 circles for map 2
for(let i = 1; i <= 4; i++)
{
const randX = Math.floor((Math.random() * 390) + 10); //between 10 and 400
const randY = Math.floor((Math.random() * 190) + 10); //between 10 and 200
const circle = makeCircle(randX, randY);
playBack.circles.push(circle);
circles_map2.push(circle);
}
}
}
function displayLabelText(map)
{
//..label text for the map number
canvas.add(new fabric.Text('MAP ' + map.toString(), {
left: 460,
top: 280,
fontFamily: 'Arial',
fontWeight: 'bold',
fontSize: 20,
fill: 'black',
originX: 'center',
originY: 'center'
}));
}
function makeLinesByMap(map)
{
if(map === 1)
{
for(i = 0; i < circles_map1.length - 1; i++)
{
const circle1 = circles_map1[i];
const circle2 = circles_map1[i + 1];
const line = makeLine([circle1.left, circle1.top, circle2.left, circle2.top]);
playBack.lines.push(line);
canvas.add(line);
//..Add the circle and text to the map1(canvas)
canvas.add(circle1);
canvas.add(new fabric.Text((i + 1).toString(), {
left: circle1.left,
top: circle1.top,
fontFamily: 'Arial',
fontWeight: 'bold',
fontSize: 14,
fill: 'black',
originX: 'center',
originY: 'center'
}));
canvas.add(circle2);
canvas.add(new fabric.Text((i + 2).toString(), {
left: circle2.left,
top: circle2.top,
fontFamily: 'Arial',
fontWeight: 'bold',
fontSize: 14,
fill: 'black',
originX: 'center',
originY: 'center'
}));
}
canvas.backgroundColor="gray";
canvas.renderAll();
}
else if(map === 2)
{
for(i = 0; i < circles_map2.length - 1; i++)
{
const circle1 = circles_map2[i];
const circle2 = circles_map2[i + 1];
const line = makeLine([circle1.left, circle1.top, circle2.left, circle2.top]);
playBack.lines.push(line);
canvas.add(line);
//..Add the circle and text to the map1(canvas)
canvas.add(circle1);
canvas.add(new fabric.Text((i + 6).toString(), {
left: circle1.left,
top: circle1.top,
fontFamily: 'Arial',
fontWeight: 'bold',
fontSize: 14,
fill: 'black',
originX: 'center',
originY: 'center'
}));
canvas.add(circle2);
canvas.add(new fabric.Text((i + 7).toString(), {
left: circle2.left,
top: circle2.top,
fontFamily: 'Arial',
fontWeight: 'bold',
fontSize: 14,
fill: 'black',
originX: 'center',
originY: 'center'
}));
}
canvas.backgroundColor="orange";
canvas.renderAll();
}
}
function makeLine(coords)
{
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 4,
originX: 'right',
originY: 'center',
selectable: false,
hoverCursor: 'default'
});
}
async function animateLinesDrawing()
{
setLinesCoords();
for(let i = 0; i < playBack.lines.length; i++)
{
await makeAnimation(playBack.lines[i], playBack.circles[i + 1]);
}
}
function setLinesCoords()
{
for(let i = 0; i < playBack.lines.length; i++)
{
playBack.lines[i].set({
x1: playBack.circles[i].left,
y1: playBack.circles[i].top,
x2: playBack.circles[i].left,
y2: playBack.circles[i].top
})
}
}
function makeAnimation(line, circle)
{
return new Promise(resolve => {
line.animate({
x2: circle.left,
y2: circle.top
},
{
duration: 2000,
onChange: canvas.renderAll.bind(canvas),
onComplete: function(){
line.setCoords();
//line.setCoords.bind(line);
resolve();
}
});
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.0.0/fabric.min.js"></script>
<canvas id="gameCanvas" width="500" height="300" style="border: 2px solid green;"></canvas>
<button id="animateBtn">Animate Lines Drawing</button>
我的问题在动画按钮的事件处理程序内,简而言之,当地图#1的动画结束时,我会显示地图#2,并再次在同一函数内调用动画函数我做递归效率低下。我如何以有效的方式进行递归,这样当我有多个映射时,我应该只调用一个函数,其余函数呢? 感谢您的帮助