You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fabric.js Canvas线条逐段绘制动画问题求助

解决Fabric.js线条绘制动画的问题

我看了你的代码,问题出在几个关键细节上,咱们一步步修正,实现从point1→point2再到point3的流畅线条绘制动画:

问题分析

  1. 动画方向错误:你当前是动画线条的起点坐标(x1/y1),这会让线条看起来像是在“收缩”而非从起点延伸到终点。正确的做法应该是固定起点,动画线条的终点坐标(x2/y2)。
  2. 线条原点设置不当:originX: 'right'会让线条的动画基准点偏移,导致动画轨迹不符合预期,需要调整原点设置。
  3. 动画顺序未控制:你没有处理两条线的动画顺序,应该等第一条线绘制完成后再启动第二条线的动画。

修正后的完整代码

JavaScript部分

const canvas = new fabric.Canvas('gameCanvas', {selection: false});
let circle1, circle2, circle3;
let line1, line2;
let circles = [];
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';

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

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

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 drawCircles() {
 circle1 = makeCircle(52.69, 17.77);
 circle2 = makeCircle(262.69, 120.77);
 circle3 = makeCircle(272.69, 232.77);
 circles.push(circle1);
 circles.push(circle2);
 circles.push(circle3);
}

function makeLine(coords) {
 return new fabric.Line(coords, {
 fill: 'red',
 stroke: 'red',
 strokeWidth: 2,
 // 移除错误的originX设置,避免动画基准点偏移
 selectable: false,
 hoverCursor: 'default'
 });
}

function animateLinesDrawing() {
 // 先添加所有圆圈和文字到画布
 addCirclesTextToCanvas();

 // 创建line1:初始时起点和终点都是circle1的坐标(线条长度为0)
 line1 = makeLine([circle1.left, circle1.top, circle1.left, circle1.top]);
 canvas.add(line1);

 // 动画line1的终点到circle2的坐标
 line1.animate('x2', circle2.left, {
 onChange: canvas.renderAll.bind(canvas),
 duration: 1000,
 // line1完成后启动line2的动画
 onComplete: function() {
   // 创建line2:初始时起点和终点都是circle2的坐标
   line2 = makeLine([circle2.left, circle2.top, circle2.left, circle2.top]);
   canvas.add(line2);
   // 动画line2的终点到circle3的坐标
   line2.animate('x2', circle3.left, {
     onChange: canvas.renderAll.bind(canvas),
     duration: 1000
   });
   line2.animate('y2', circle3.top, {
     onChange: canvas.renderAll.bind(canvas),
     duration: 1000
   });
 }
 });
 line1.animate('y2', circle2.top, {
 onChange: canvas.renderAll.bind(canvas),
 duration: 1000
 });
}

function addCirclesTextToCanvas() {
 canvas.add(circle1, circle2, circle3);
 // 添加圆圈内的文字
 for(let i = 0; i < circles.length; i++) {
 canvas.add(new fabric.Text((i + 1).toString(), {
 left: circles[i].left,
 top: circles[i].top,
 fontFamily: 'Arial',
 fontWeight: 'bold',
 fontSize: 14,
 fill: 'black',
 originX: 'center',
 originY: 'center'
 }));
 }
}

HTML部分

<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>

关键修改说明

  • 动画目标调整:将动画的目标从x1/y1改为x2/y2,让线条从起点开始逐步延伸到终点。
  • 线条初始化:创建线条时,初始的起点和终点设为同一个点(即线条初始长度为0),这样动画开始时是从无到有的绘制效果。
  • 顺序动画控制:使用onComplete回调函数,在第一条线动画完成后再启动第二条线的动画,实现连贯的绘制流程。
  • 原点修正:移除了originX: 'right'的设置,避免线条动画的基准点偏移。

内容的提问来源于stack exchange,提问作者Kenzo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:51:31