fabric.js Animate动画实现

说明

实现方式有两种

元素的.animate() - 慎用

fabric对象有 .animate() 函数,可简化动画

官网:http://fabricjs.com/fabric-intro-part-2#animation

更多参考:
https://www.hangge.com/blog/cache/detail_2629.html
https://juejin.cn/post/7405774566566232127

动画涉及到一个属性

const cancelFun = element.animate(
    'left', // 动画的属性
    leftTarget  , // 最终值
    {
        duration: duration, // 动画执行时间
        onChange: canvasFab.renderAll.bind(canvasFab), // 渲染
        easing:easing, // 缓动函数
        onComplete: () => { // 结束函数
            // 结束时执行的代码
        },
    });

返回:取消函数对象

动画涉及到多个属性-传入对象

如果动画中设计到 多个属性,可传入对象,如下:

最终元素移动到 left:10,top:20,且 透明度是 0.5

const cancelFuns = element.animate({
    'left': 10,
    'top':20,
    'opacity':0.5
    },{
    duration: duration,
    onChange: canvasFab.renderAll.bind(canvasFab),
    easing:easing
});

返回的 cancelFuns 是数组,其元素是各个属性动画的取消函数对象

坑

使用这种方法,很多动画执行结束后,会有一些问题

坑1

用此方法将元素移动到 fabric Canvas之外,不能超过 宽度+边框,高度+边框 ,否则会导致 元素失效,即使移动回来也无反应
相关文章:
https://cloud.tencent.com/developer/information/Fabric.js%3A%E7%94%BB%E5%B8%83%E5%A4%96%E7%9A%84%E5%88%9D%E5%A7%8B%E4%BD%8D%E7%BD%AE%E5%AF%B9%E8%B1%A1%E4%B8%8D%E5%86%8D%E5%B7%A5%E4%BD%9C

坑2

水平缩放动画,即使缩放成 0,结束后仍然会显示边框(也算勉强说得通),为了让边框也消失,最后设置隐藏。但之后只能点击那个边框才能选中该元素,点击其他位置都不好使

const cancelFun = element.animate(
    'scaleX', // 动画的属性
    0  , // 最终值
    {
        duration: duration, // 动画执行时间
        onChange: canvasFab.renderAll.bind(canvasFab), // 渲染
        easing:easing, // 缓动函数
        onComplete: () => { // 结束函数
            element.opacity = 0
            canvasFab.renderAll()
        },
    });

// 重新实现取消函数
const cancelFunNew = ()=>{
    cancelFun()

    element.opacity = 1
    element.setCoords()
    canvasFab.renderAll()
})

fabric.util.animate

这种方式灵活,但是复杂,过渡效果需要自己实现

返回:取消函数对象

const cancelFun = fabric.util.animate({
    startValue: 0, // 开始值
    endValue: 1, // 结束值
    // byValue: // 步长,一般可不用设置,不能随意设置,应为:endValue - startValue
    duration: duration, // 动画执行时长
    easing:easing, // 缓动函数
    onChange: (value) => { // 过程函数
      element.opacity = value;
      canvasFab.renderAll(); // 渲染
    },
    onComplete: () => { // 结束函数
      element.opacity = 1; // 完全不透明
      canvasFab.renderAll();
    },
    abort:()=>{ // 一般不用
        // 返回true,终止动画
        return fales
    },
  })

原文出处:/show_1IX8YEkT5aVP.html