fabric.js 封装雪碧动图

2 篇文章 0 订阅
2 篇文章 0 订阅

看到的效果如下:

图片来源: 

1.  fabric.js官网示例里----自己去下载png,

2. Knova 官网雪碧图示例里面的---自己去下载png。

说明下:

①  实现原理和fabric.js官网上雪碧图例子里面是不一样的,雪碧图切取是借鉴了 Knova中animation坐标模式----这样就可以实现非规则雪碧图的运动啦

② sprite 返回的是fabric.group,其实大家可以试一下,如果不放在组里面直接返回图,那么你后续无法对这个雪碧图拖动的,因为它每一帧都重新定位了,你设置的位置就会被覆盖。

  /**
   * 生成雪碧图工具
   * @param {ISprite} pload   雪碧图参数对象 ISprite是ts定义的接口
   * @returns {fabric.Group}   雪碧图group对象
   */

  let Sprite = function (pload) {
    let arrS = [];
    let pre = null;//前一帧
    let index = pload.index || 0;
    let len = pload.animations.length || 0;
    let endIndex = pload.endIndex || len;
    let orw = pload.animations[0][2];//起始 width
    let orh = pload.animations[0][3];//起始 height
    this.group = new fabric.Group();
    this.group.set({
      left: pload.x,
      top: pload.y,
      width: orw,
      height: orh,
    });
    let _this = this;
    //创建静态canvas 把雪碧每一帧绘制 并维护在arrS中
    fabric.Image.fromURL(pload.url, function (mainimg) {
      let tempCanvas = new fabric.StaticCanvas();
      tempCanvas.setDimensions({
        width: orw,
        height: orh,
      });
      mainimg.originX = 'left';
      mainimg.originY = 'top';

      tempCanvas.add(mainimg);

      for (let i = 0; i < len; i++) {

        mainimg.left = - pload.animations[i][0];
        mainimg.top = - pload.animations[i][1];
        mainimg.setCoords();

        tempCanvas.set({
          width: pload.animations[i][2],
          height: pload.animations[i][3],
        })
        tempCanvas.renderAll();

        let domimg = new fabric.Image(tempCanvas.toCanvasElement(),);
        arrS.push(domimg);
      }
      setInterval(() => {
        pre = arrS[index];
        index++;
        if (index > endIndex - 1) index = 0;
        arrS[index].set({
          left: -pload.animations[index][2] / 2,
          top: -pload.animations[index][3] / 2,
        });
        _this.group.remove(pre);
        _this.group.add(arrS[index]);
      }, pload.framTime);

    })
    return this.group;
  }

接口 如下

interface ISprite{
 url: string, 
 animations: [number, number, number, number][], 
 index: number, 
 framTime: number, 
 x: number, 
 y: number, 
 endIndex: number; 
}

下面就是使用了

    let startIndex = 0;
    let endIndex = animations.length;
    let framTime = 200;
    let x = 50;
    let y = 50;
     // x, y, width, height 每行数组的规则
    let animations2 = [
      [0, 0, 50, 72],
      [50, 0, 50, 72],
      [100, 0, 50, 72],
      [150, 0, 50, 72],
      [200, 0, 50, 72],
      [250, 0, 50, 72],
      [300, 0, 50, 72],
      [350, 0, 50, 72],
      [400, 0, 50, 72],
      [450, 0, 50, 72],
    ];
    let animations3 = [
      [2, 2, 70, 119],
      [71, 2, 74, 119],
      [146, 2, 81, 119],
      [226, 2, 76, 119],
      [2, 138, 74, 122],
      [76, 138, 84, 122],
      [346, 138, 120, 122]
    ];
    
    let dd = { url: '../assets/hi~.png', animations: animations2, index: startIndex, framTime, x, y,  };
    
    let ee = { url: '../assets/blob-sprite.png', animations: animations3, index: startIndex, framTime, x, y,  };

    let sayHi = new Sprite(dd);
    let monster = new Sprite(ee);

    canvas.add(sayHi, monster);
    renderThis();

    function renderThis() {
      canvas.renderAll();
      requestAnimationFrame(renderThis);
    }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值