iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 25
2
Modern Web

用 Javascript 當個影像魔術師系列 第 25

Day 25 - 做個梗圖編輯器 (上)

  • 分享至 

  • xImage
  •  

Day 25 - 做個梗圖編輯器 (上)

昨天介紹到了如何使用 fabricjs 的基本用法,今天就拿來做一些應用吧,這次主要是參考了 imgflip 的功能,主要是可以選擇圖片或匯入圖片,並且加入自己的文字,最後在匯出。

實作

首先, imgfilp 有提供一個接口,可以拿到圖片,所以我們就使用這個接口

getMemesJson() {
    return fetch('https://api.imgflip.com/get_memes')
    .then(response => response.json())
    }

接著在讀取完後讀入現在的圖片

loadCurrentImg() {
    const currentFile = this.memes[this.currentIndex]
    this.loadImg(currentFile.url)
  }

目前的做法是當換掉圖片時就把所有之前的東西都刪掉,也就是文字跟圖片這兩種,如果只想刪掉特定種類的話,可以使用 fabric CanvasgetObjects 方法,拿回現在所有的物件,並且挑選你想要的來刪除。

 cleanAll() {
    this.fabricCanvas.clear()
    this.editTexts = []
  }

接著用昨天介紹的讀取圖片方式來使用,傳入我們從 api 拿回來的位置,並且重設定一下寬高,目前是維持在等寬 600 高度照比例縮小的方式,所以一開始我們會需要算需要縮放的比例,接著更新到 canvas 身上,接著把 img 設定成不能選取及游標顯示不在是拖曳,因為我們希望圖片是當成背景來使用,所以把控制的操作都關閉。scaleToHeight 則是另一種使用方式讓圖片變成指定的高度,接著最後一樣要記得加到 canvas 裡面,這邊還有一點值得注意的是因為 fabric 是依照加入的先後順序來決定物件的層級,但因為我們需要圖片一直在最底部,所以使用了 sendToBack 把他移到最底層,不然可能會發生文字被圖片蓋住的情況。

  loadImg(path) {
    this.cleanAll()
    fabric.Image.fromURL(
      path,
      img => {
        const maxWidth = 600
        const scale = maxWidth / img.width
        this.height = scale * img.height
        this.width = scale * img.width
        this.fabricCanvas.setHeight(this.height)
        this.fabricCanvas.setWidth(this.width)
        const newImg = img.set({
          hoverCursor: 'default',
          selectable: false
        })
        newImg.scaleToHeight(this.height)
        newImg.scaleToWidth(this.width)
        this.fabricCanvas.add(newImg)
        this.addText()
        // 讓圖片一直在最底層 不會影響到字的顯示
        this.fabricCanvas.sendToBack(newImg)
      }
    )
  }

接著就可以繼續做修改文字的部分了,在新增文字的時候一樣可以選擇顏色、字體大小等等之類,接著除了加到 canvas 裡面之外,我們也自己另外存了一份給等下的編輯使用

addText() {
    const editText = new fabric.IText('點擊編輯', {
      fill: '#ffffff',
      stroke: '#000000',
      fontSize: 40,
      fontFamily: 'Microsoft JhengHei, PMingLiU, sans-serif'
    })

    this.editTexts.push(editText)
    this.fabricCanvas.add(editText)
  }

接著在畫面裡使用

<div
  v-for="(item, index) in editTexts"
  class="edit_texts"
>
  <el-input
    :value="item.text"
    @input="(val) => textChange(val, index)"
  ></el-input>
</div>

接著就是一般的更新,我們需要使用 set 來變更 IText 物件的值,有一點值得要注意的是需要在變更之後使用 renderAll

 textChange(val, index) {
    const target = this.editTexts[index]
    target.set('text', val)
    this.render()
  },
 render() {
    this.fabricCanvas.renderAll()
  }

到這邊應該基本的雛形就有出來了,成果像這樣

今天有做了一個雛型出來,明天繼續完善!


上一篇
Day 24 - Canvas 常用套件 - fabric js 介紹
下一篇
Day 26 - 做個梗圖編輯器 (下)
系列文
用 Javascript 當個影像魔術師30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
挖洗菜呱
iT邦新手 5 級 ‧ 2019-10-10 21:31:54

可以移動位置!!!太強la

套件太神la

我要留言

立即登入留言