使用 Fabric.js 玩转 H5 Canvas

标签: fabric js h5 | 发表时间:2019-02-05 00:50 | 作者:sugars
出处:https://www.v2ex.com/

前言

之前使用这个框架写过一个卡片 DIY 的项目,中间遇到很多问题都只能通过 google 或 github issues 才能解决,国内资料较少,所以才想写这篇文章来简单的做下总结,希望可以帮到其他人哈。

附上个人项目地址: vue-card-diy 欢迎 star~ ✨

什么是 Fabric.js?

Fabric.js 是一个强大的 H5 canvas 框架,在原生 canvas 之上提供了交互式对象模型,通过简洁的 api 就可以在画布上进行丰富的操作。

该框架是个开源项目,项目地址: github

Fabric.js 有什么功能?

使用 Fabric.js ,你可以在画布上创建和填充对象; 比如简单的几何形状 - 矩形,圆形,椭圆形,多边形,自定义图片或由数百或数千个简单路径组成的更复杂的形状。 另外,还可以使用鼠标缩放,移动和旋转这些对象; 修改它们的属性 - 颜色,透明度,z-index 等。也可以将画布上的对象进行组合。下面我将会介绍我常用的功能以及场景,更多功能可以参考 官方文档

安装

npm 安装

  npm install fabric --save

通过 cdn 引用

  <script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>

初始化

首先在 html 页面中写一个 350 x 200 的 canvas 标签, 这里不写宽高也行,后面可以通过 js 来设置宽高

  <canvas id="canvas" width="350" height="200"></canvas>

初始化 fabric 的 canvas 对象,创建一个卡片(后面都用 card表示画布对象)

  const card = new fabric.Canvas('canvas') 

// ...这里可以写 canvas 对象的一些配置,后面将会介绍

// 如果<canvas>标签没设置宽高,可以通过 js 动态设置
card.setWidth(350)
card.setHeight(200)

就是这么简单,这样就创建了一个基本的画布。

开始花样操作

监听画布上的事件

官方提供了很多事件,以下为常用的事件:

  • object:added 添加图层
  • object:modified 编辑图层
  • object:removed 移除图层
  • selection:created 初次选中图层
  • selection:updated 图层选择变化
  • selection:cleared 清空图层选中
  // 在 canvas 对象初始化后,通过以下方式监听
// 比如监听画布的图层编辑事件
card.on('object:modified', (e) => {
    console.log(e.target) // e.target 为当前编辑的 Object
    // ...旋转,缩放,移动等编辑图层的操作都监听到
    // 所以如果有撤销 /恢复的场景,这里可以保存编辑状态
});

设置画布背景

  // 读取图片地址,设置画布背景
fabric.Image.fromURL('xx/xx/bg.jpg', (img) => {
  img.set({
   // 通过 scale 来设置图片大小,这里设置和画布一样大
    scaleX: card.width / img.width,
    scaleY: card.height / img.height,
  });
  // 设置背景
  card.setBackgroundImage(img, card.renderAll.bind(card));
  card.renderAll();
});

如果要设置画布的背景颜色,可以在 canvas 初始化时设置

  const card = new fabric.Canvas('canvas', {
  backgroundColor: 'blue' // 画布背景色为蓝色
});

// 或者
card.backgroundColor = 'blue';

// 或者
card.setBackgroundColor('blue');

向画布添加图层对象

fabric.js 提供了很多对象,除了基本的 RectCircleLineEllipsePolygonPolylineTriangle对象外,还有如 Image TextboxGroup等更高级的对象,这些都是继承自 Fabric 的 Object 对象

下面我就介绍如何添加图片和文字,其他对象大同小异

  /**
* 如何向画布添加一个 Image 对象?
*/

// 方式一(通过 img 元素添加)
const imgElement = document.getElementById('my-image');
const imgInstance = new fabric.Image(imgElement, {
  left: 100, // 图片相对画布的左侧距离
  top: 100, // 图片相对画布的顶部距离
  angle: 30, // 图片旋转角度
  opacity: 0.85, // 图片透明度
  // 这里可以通过 scaleX 和 scaleY 来设置图片绘制后的大小,这里为原来大小的一半
  scaleX: 0.5, 
  scaleY: 0.5
});
// 添加对象后, 如下图
card.add(imgInstance);

  // 方式二(通过图片路径添加)
fabric.Image.fromURL('xx/xx/vue-logo.png', (img) => {
  img.set({
    hasControls: false, // 是否开启图层的控件
    borderColor: 'orange', // 图层控件边框的颜色
  });
  // 添加对象后, 如下图
  canvas.add(img);
});

  /**
* 如何向画布添加一个 Textbox 对象?
*/

const textbox = new fabric.Textbox('这是一段文字', {
    left: 50,
    top: 50,
    width: 150,
    fontSize: 20, // 字体大小
    fontWeight: 800, // 字体粗细
    // fill: 'red', // 字体颜色
    // fontStyle: 'italic',  // 斜体
    // fontFamily: 'Delicious', // 设置字体
    // stroke: 'green', // 描边颜色
    // strokeWidth: 3, // 描边宽度
    hasControls: false,
    borderColor: 'orange',
    editingBorderColor: 'blue' // 点击文字进入编辑状态时的边框颜色
});
// 添加文字后,如下图
card.add(textbox);

获取当前选中的图层对象

  // 方式一
this.selectedObj = card.getActiveObject(); // 返回当前画布中被选中的图层 

// 方式二
card.on('selection:created', (e) => {
    // 选中图层事件触发时,动态更新赋值
    this.selectedObj = e.target
})

旋转图层

  // 顺时针 90°旋转
const currAngle = this.selectedObj.angle; // 当前图层的角度
const angle = currAngle === 360 ? 90 :currAngle + 90;
this.selectedObj.rotate(angle);
// 如果是通过滑块的方式控制旋转
// this.selectedObj.rotate(slideValue);

// 所有图层的操作之后,都需要调用这个方法
card.renderAll()

翻转图层

  // 水平翻转,同理垂直翻转改为 scaleY 属性
this.selectedObj.set({
    scaleX: -this.selectedObj.scaleX,
})

card.renderAll()

移除图层

  card.remove(this.selectedObj) // 传入需要移除的 object
card.renderAll()

控制画布上的图层层级

向画布添加图层,默认是依次往上叠加,但是当你选中一个图层进入 active状态时,该图层会默认置于顶层,如果像禁止选中图层时指定,可以:

  // 在画布初始化后设置
card.preserveObjectStacking = true // 禁止选中图层时自定置于顶部

设置之后,我选中 vue logo 就是这个样子,不会置顶。

如何上移和下移图层?

  // 上移图层
this.selectedObj.bringForward();

// 下移图层
this.selectedObj.sendBackwards();

// 也可以使用 canvas 对象的 moveTo 方法,移至图层到指定位置
card.moveTo(object, index);

画布状态记录

框架提供了如 toJSONloadFromJSON 方法,作用分别为导出当前画布的 json 信息,加载 json 画布信息来还原画布状态。

  // 导出当前画布信息
const currState = card.toJSON(); // 导出的 Json 如下图

  // 加载画布信息
card.loadFromJSON(lastState, () => {
  card.renderAll();
});

将画布导出成图片

  const dataURL = card.toDataURL({
  format: 'jpeg', // jpeg 或 png
  quality: 0.8 // 图片质量,仅 jpeg 时可用
  // 截取指定位置和大小
  //left: 100, 
  //top: 100,
  //width: 200,
  //height: 200
});

Fabric.js 的基本介绍就到这里,这个框架很强大,还有很多功能可以去试试,欢迎大家评论交流哈!

如转载本文请注明文章作者及出处!

相关 [fabric js h5] 推荐:

Hyperledger Fabric V1.0 跳坑玩耍

- - SegmentFault 最新的文章
       最近有个项目需要用到超级账本的概念,随后在网上查阅相关的信息. 最后相中了 Fabric作为实验玩耍的目标. 要玩就要玩最新的啦,所以舍弃了v0.6的版本,但是截至这篇文章摸出来,v1.0还处于alpha阶段. 以下环境的搭建步骤很大一部分来自于 hyperledger-fabric.readthedocs.io,英语好的同学也可以直接看那边的教程.

使用 Fabric.js 玩转 H5 Canvas

- - V2EX - 技术
之前使用这个框架写过一个卡片 DIY 的项目,中间遇到很多问题都只能通过 google 或 github issues 才能解决,国内资料较少,所以才想写这篇文章来简单的做下总结,希望可以帮到其他人哈. 附上个人项目地址: vue-card-diy 欢迎 star~ ✨. 什么是 Fabric.js?.

Fabric批量远程执行操作

- - CSDN博客推荐文章
最近有个需求就是要在一个集群的多个机器上运行一些命令,比如启动、停止服务,运行一些脚本收集一些数据等,于是找到了python的一个框架Fabric. Fabric是一个Python库,用于简化使用SSH的应用程序部署或系统管理任务. 它提供的主要功能包括:执行本地或远程shell命令,上传/下载文件,以及其他辅助功能,如提示用户输入、中止执行等.

配置 fabric 穿越跳板机

- - 膘叔
在转这篇文章的时候,我觉得 很懒,所以我几乎没有排版就直接ctrl+c,ctrl+v就过来了. 下面是正文,链接来源是:https://mozillazg.com/2013/12/python-fabric-gateway.html. 说实话,跳板机给研发的日常工作添加了些许麻烦. 幸好 fabric 提供了穿越跳板机的功能,使跳板机不再影响我们的工作.

移动端 H5 图片压缩上传

- - IT瘾-dev
大体的思路是,部分API的兼容性请参照 caniuse:. 利用 FileReader,读取 blob对象,或者是 file对象,将图片转化为 data uri的形式. 使用 canvas,在页面上新建一个画布,利用 canvas提供的API,将图片画入这个画布当中. 利用 canvas.toDataURL(),进行图片的压缩,得到图片的 data uri的值.

H5与Native交互之JSBridge技术

- - SegmentFault 最新的文章
做过混合开发的很多人都知道Ionic和PhoneGap之类的框架,这些框架在web基础上包了一层Native,然后通过Bridge技术使得js可以调用视频、位置、音频等功能. 本文就是介绍这层Bridge的交互原理,通过阅读本文你可以了解到js与ios及android底层的通讯原理及JSBridge的封装技术及调试方法.

H5 移动调试全攻略

- - IT瘾-dev
随着移动设备的高速发展, H5开发也成为了 F2E不可或缺的能力. 而移动开发的重中之重就是掌握调试技巧,定 Bug于无形. 文章首发于 Jartto’s blog,转载请标明出处. 因为移动端操作系统分为 iOS和 Android两派,所以本文的调试技巧也会按照不同的系统来区分.

WebView JS 交互

- - ITeye博客
WebView加jquery做页面会怎么样呢. // 创建WebView对象. // 把programList添加到js的全局对象window中,. // 这样就可以使用window.programList来获取数据. * 定义js回调java函数. // 绑定键盘的向上,向下按钮事件触发相应的js事件.

基于fabric和hg的自动化部署

- - CSDN博客推荐文章
fabric是个很好用的自动化部署工具,虽然功能比起puppet,saltstack之类要弱一些,但胜在用python,而且免安装服务端. 当然你要说docker更好我也同意,然而我是经常使用FreeBSD的,而且还有一些32位的低配系统,并不适合用docker. 自动化部署的目的主要是简化手工部署的麻烦,包括初次安装部署和代码修改后的更新部署.

Hyperledger Fabric V1.0 环境搭建 - 个人文章 - SegmentFault

- -
学习区块链技术有段时间了,刚好晚上有空把超级账本子项目fabric v1.0部署运行及开发环境的搭建过程整理下,编写的内容主要参照官方文档. 由于fabric项目目前还处于孵化阶段,正式版本预计5月份才会到来. 近期官方示例和文档也频繁更新中,本文内容主要基于源码中 “examples” 和 “devenv” 来完成fabric入门示例的快速部署运行和统一开发环境的搭建.