react使用fabric.js生成海报

1,805 阅读3分钟

最近搞了一个pc生成海报,搞得精疲力竭的,由于之前没接触过这方面的业务和技术,所以记录一下

需求:

1. 要能替换背景图片  
2. 需要设置默认文字  
3. 需要自定义一些文字的样式  
4. 需要能拖拽功能  

技术选型:

1.Konva
2.fabricjs
konva的文档是中文的(ps:其实就是基本的demo是中文,一些属性和api还都是英文的),不论是百度,还是google,可以参考的资料都不是很多。
fabric的文档虽然是英文的,但是好在网上可以参考的文章很多,基本上有什么需求单靠百度就可以解决,Konva实现插入花里胡哨文字是要依靠html2canvas去实现,而fabric自带这个功能,所以我选择了fabric

创建canvas画布

1. 我们在dom结构中, 需要创建canvas标签,并声明其尺寸,并赋予一个id

<canvas width="375" height="667" id="canvas"></canvas>

2. 在生命周期钩子中,我们需要使用fabric来管理我们的canvas,因为后续许多操作会用到这个实例,所以我把他挂载到了this上

// 可编辑画布(画布内的元素可以拖拽、放大缩小、旋转-通常用于新增/编辑)
this.canvas = new fabric.Canvas('canvas')
// 不可编辑画布(画布内的元素不可以拖拽、放大缩小、旋转-通常用于查看详情)
this.canvas = new fabric.StaticCanvas('canvas')

3. 设置画布背景图

   使用fabric的方法为画布设置背景图,替换背景图的时候,只需要更改url,就能完成背景图的更换
/**
 * 设置背景图片
 * @param url {String} 图片地址
 */
setDefaultBackgroundImg = (url = defaultImgUrl) => {
  fabric.Image.fromURL(
    url,
    (img) => {
      // 设置背景图
      this.canvas.setBackgroundImage(
        img,
        this.canvas.renderAll.bind(this.canvas),
        {
          scaleX: this.canvas.width / img.width,
          scaleY: this.canvas.height / img.height,
          name: 'bgImage'
        }
      )
    }
  )
}

4. 添加默认文字和图片

添加默认文字

let defaultText = new fabric.Text('我是默认文字', {
  left: 83,
  top: 255,
  fontFamily: 'Microsoft YaHei, Microsoft YaHei-Bold',
  fontSize: 30,
  fontWeight: 700,
  fill: posterTextColor,
  lockRotation: true,
  hasControls: false,
  name: 'defaultText'
})
// 这里要将文字的实例挂载到this上,以便我们以后不想要这个了可以将其删除
this.defaultPosterWord = defaultPosterWord
this.canvas.add(defaultPosterWord) // 将文字放入画布

添加默认图片

fabric.Image.fromURL(qrCodeUrl, img => {
  img.scale(0.5) // 缩放
  img.set({
    left: 90,
    top: 350,
    lockRotation: true,
    hasControls: false,
    name: 'qrCode'
  })
  this.canvas.add(img) // 将图片加入到画布
})

元素的移除

this.canvas.remove(this.defaultText)
this.defaultText = null

5. 使用Itext绘制花里胡哨的文字

在我们使用 IText绘制花里胡哨的文字之前,我们先要创建并获取到IText实例

创建IText实例

const iText = new fabric.IText('双击编辑自定义文字', {
  left: 83,
  top: 255,
  fontFamily: 'Microsoft YaHei, Microsoft YaHei-Bold',
  fontSize: 20,
  fill: posterTextColor,
  lockRotation: true, // 根据需求,我这里禁用了旋转功能,默认是开启的
  hasControls: false, // 根据需求,我这里禁用了放大缩小功能,默认是开启的
  name: 'diyText'
})
this.iText = iText
this.canvas.add(iText)
// 这里的name是可以自定义的,不是fabric属性,这里定义name就是为了方便我们获取IText实例

获取IText实例

// 这里我们就可以用我们自定义的name去查找我们需要操作的实例
const index = this.canvas.getObjects().findIndex(i => i.name === 'diyText')
const ITextObj = this.canvas.getObjects()[index]

对文字的一些操作

// 设置字体加粗
ITextObj.fontWeight = 'bold'
// 设置字体倾斜
ITextObj.fontStyle =  'italic'
// 设置字体下划线(有的时候直接设置值不生效,我们就可以使用其set方法去更改)
ITextObj.set('underline', true)
// 修改文字颜色
ITextObj.set('fill', '#333333')
// 修改字体大小
ITextObj.fontSize = 20

// 每次修改完都要调用这个方法让画布重新渲染一下,才能看出来效果
this.canvas.renderAll()

6. 序列化与反序列化

// 序列化
const canvasJsonData = JSON.stringify(this.canvas)
// 反序列化
this.canvas.loadFromJSON(canvasJsonData)

这里只是简单的记录一下用法,如果你想更深入的学习 fabric,建议去看主任的《Fabric.js 从入门到放弃》