欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

使用 fabric.js 開發移動端 H5 圖片編輯器

freeflydom
2024年12月10日 9:3 本文熱度 596

大家好,我是開源圖片編輯器的 https://github.com/ikuaitu/vue-fabric-editor 的作者,它是一款基于 PC 版本的開源圖片編輯器。

最近很多開發者咨詢,是否可以將開源圖片編輯器改造為一款適用于移動端的 H5 版本圖片編輯器,最近 H5 版本的圖片編輯器剛剛上線,就將實現思路和產品細節整理成筆記分享出來,供大家參考。

基礎

開源的圖片編輯器的基本功能都有了,例如切換模板、添加元素、自定義字體等,不過相較于移動端的交互會有很大的差異,做了很多改造,這次筆記主要分享一下移動端圖片編輯器實現思路和細節


大綱

  1. 切換模板
  2. 添加圖片
  3. 添加組合元素
  4. 設置背景色
  5. 修改畫布尺寸
  6. 快捷菜單
  7. 屬性工具條
  8. 特效字體
  9. 切換字體
  10. 輸入文字
  11. 文字排版
  12. 邊框
  13. 陰影
  14. 下載圖片

注:部分代碼示例為封裝后的代碼,非 fabric.js 原生方法。

1. 切換模板

編輯器基于 fabric.js 開發,所有的模板都是以 json 的格式存儲,切換模板只需要請求詳情接口,將 json 格式的數據調添加到畫布當中即可,需要注意的點是需要將模板中使用的字體名稱,并加載字體文件后再進行渲染,否則字體樣式沒辦法正常渲染。

const loadInfo = async (res: any) => {
  const info = res.data
  templName.value = info.name;
  await canvasEditor.getFontList(JSON.stringify(info.json));
  canvasEditor.loadJSON(JSON.stringify(info.json), () => LoadingPlugin(false));
};

2. 添加圖片

fabric.js 中添加圖片提供了很多種方法,我們使用通過最簡單的fabric.Image.fromURL即可,另外,經常有圖片尺寸大于畫布的情況,還需要將圖片按畫布寬度的一般進行縮放,更方便用戶操作。

const toEditor = async (e: MouseEvent) => {
  visible.value = false
  LoadingPlugin(true)
  const item = await canvasEditor.createImgByElement(e.target as HTMLImageElement)
  await canvasEditor.addBaseType(item, { scale: true })
  LoadingPlugin(false)
}

3. 添加組合元素

fabric.js 支持將單個元素按照 JSON 格式導出/導入,我們將導出的數據存儲在數據庫中的,導入時按元素類型導入即可,需要獲取 JSON 中元素的類型,并作為方法名調用,同樣需要在導入前做字體加載,倒入后做縮放。

const capitalizeFirstLetter = (str: string) => {
  return str.charAt(0).toUpperCase() + str.slice(1);
}
const toEditor = async (item: ItemProps) => {
  visible.value = false
  LoadingPlugin(true)
  await canvasEditor.downFontByJSON(JSON.stringify(item.json));
  const el = JSON.parse(JSON.stringify(item.json));
  const elType = capitalizeFirstLetter(el.type);
  new fabric[elType].fromObject(el, (fabricEl: fabric.Object) => {
    canvasEditor.dragAddItem(fabricEl);
    LoadingPlugin(false)
  });
}

4. 設置背景色

設置背景色較為簡單,按照 fabric.js 的 API 設置顏色即可,需要注意的是大部分 PC 端的顏色組件并不適配移動端 H5 的場景,不支持 touch 事件,我們使用了 @jaames/iro這個組件,它在移動端表現出色,完全適配我們的場景,而且它的 API 很靈活,我們將它封裝成一個通用的顏色組件,在多處調用。

<template>
  <div ref="pickerContainer">
  </div>
</template>
<script setup lang="ts">
import iro from '@jaames/iro';
const emit = defineEmits(['update:modelValue', 'change']);
const props = defineProps({
  modelValue: {
    type: String,
    default: '#000000'
  },
  width: {
    type: Number,
    default: 200
  }
});
const pickerContainer = ref<HTMLButtonElement | string>('');
let colorPicker: any = null;
onMounted(() => {
  // 創建iro.js顏色選擇器
  colorPicker = iro.ColorPicker(pickerContainer.value, {
    width: props.width,
    color: props.modelValue,
    borderWidth: 1,
    borderColor: "#fff",
    layoutDirection: 'horizontal',
    layout: [
      {
        component: iro.ui.Slider,
        options: {
          id: 'hue-slider',
          sliderType: 'hue'
        }
      },
      {
        component: iro.ui.Box,
      },
      {
        component: iro.ui.Slider,
        options: {
          sliderType: 'alpha'
        }
      }
    ]
  });
  // 監聽顏色變化事件并發射自定義事件
  colorPicker.on('color:change', (color: any) => {
    const rgbaString = color.rgbaString;
    emit('update:modelValue', rgbaString);
    emit('change', rgbaString);
  });
});
</script>

5. 修改畫布尺寸

日常使用圖片編輯器都有修改畫布尺寸的需要,在開源項目中已經封裝好了相應的方法,直接調用即可,需要注意的是,當修改尺寸彈框彈出時,為了達到所見即所得的效果,要避免彈框遮擋畫布,其他屬性修改同理。


const resizeEditor = async () => {
    await nextTick()
    const editorWorkspase = document.querySelector('#workspace') as HTMLElement
    const popElement = document.querySelector('.my-editor-popup') as HTMLElement
    const headerElement = document.querySelector('.t-navbar') as HTMLElement
    if (popElement) {
      editorWorkspase.style.height = `calc(100vh - ${popElement?.offsetHeight + headerElement?.offsetHeight || 0}px)`
    } else {
      editorWorkspase.style.height = ''
    }
  }

6. 快捷菜單

很多快捷操作需要能夠讓用戶快速找的并完成操作,我們為元素添加了快捷菜單功能,避免讓一些簡單的操作讓用戶在底部菜單欄點來點去,當選中元素時自動展示,取消選中時隱藏即可,需要注意的是在快捷菜單并不總是在元素上方,快捷菜單應該根據元素位置和畫布的尺寸進行定位,當菜單超出畫布區域時我們要及時調整菜單位置;另外 當屬性彈框出現,畫布尺寸變化時,需要同步修改菜單位置。

// 更新位置信息
const upDatePosition = async () => {
  const activeObject = canvasEditor.canvas.getActiveObject();
  if (activeObject) {
    canvasEditor.canvas.renderAll();
    fixLeft.value = 10;
    fixTop.value = 10;
    await nextTick();
    isIncluded(activeObject);
    await nextTick();
  }
}
// 監聽選中對象變化更新位置信息
getObjectAttr(upDatePosition)
canvasEditor.canvas.on('selection:updated', upDatePosition)
canvasEditor.canvas.on('mouse:move', upDatePosition)
canvasEditor.on('workspaceAutoEvent', upDatePosition)

7. 屬性工具條

參考了其他圖片編輯器,部分屬性在點擊元素后才會出現可修改選項,取消選中時便隱藏選項,另外 選中的元素不同,可修改選項也不同,這是一個在移動端做復雜圖片編輯器中非常棒的一個交互。

我們封裝了通用的選中類型和方法,針對每個屬性組件單獨設置隱藏/展示。

8. 特效字體

特效字體主要是文字元素的顏色、邊框、陰影的組合,我們將來文字設置樣式后的 JSON 導出并保存在數據庫中,當選中某一個特效時,將屬性按 JSON 中的數據設置給元素即可。

const setStyle = (item: ImgItem) => {
  const activeObject = canvasEditor.canvas.getActiveObjects()[0];
  if (activeObject) {
    const values = toRaw(item.json);
    const keys = ['fill', 'stroke', 'strokeWidth', 'shadow', 'strokeLineCap'];
    activeObject.set('paintFirst', 'stroke');
    keys.forEach((key) => {
      activeObject.set(key, values[key]);
      if (key === 'fill' && typeof values[key] != 'string') {
        activeObject.set(key, new fabric.Gradient(values[key]));
      }
    });
    canvasEditor.canvas.renderAll();
  }
};

9. 切換字體

修改字體只需要調用 fabric.js 元素的fontFamily屬性即可,在修改之前要確保字體加載完成。


const changeCommon = async (key: string, value: any) => {
  const activeObject = canvasEditor.canvas.getActiveObjects()[0];
  if (activeObject) {
    LoadingPlugin(true);
    baseAttr.fontFamily = value;
    try {
      await canvasEditor.loadFont(value)
    } catch (error) {
      console.log(error)
    }
    LoadingPlugin(false);
    activeObject && activeObject.set(key, value);
    canvasEditor.canvas.renderAll();
  }
};

10. 輸入文字

fabric.js 可直接雙擊文字元素進行修改,不過在移動端這種交互并不醒目,我們單獨為文本元素進行了修改,選中元素后,再次點擊時彈出輸入框,可以在底部菜單欄點擊按鈕進行修改。

11. 文字排版

文字排版較為簡單,我們只需要按照 fabric.js 的文字屬性對文字進行屬性設置即可,如 fontSize、lineHeight、charSpacing 等。

// 屬性值
const baseAttr = reactive({
  fontSize: 0,
  lineHeight: 0,
  charSpacing: 0,
  textAlign: '',
  fontWeight: '',
  fontStyle: '',
  underline: false,
  linethrough: false,
  overline: false,
});

12. 邊框

邊框樣式和文字樣式類似,配合顏色組件可以很快捷的實現功能。

// 屬性值
const baseAttr = reactive({
  stroke: '#fff',
  strokeWidth: 0,
  strokeDashArray: [],
});

13. 陰影

引用屬性主要是元素的 shadow 子屬性的修改,代碼如下:

// 屬性值
const baseAttr = reactive({
  shadow: {
    color: '#fff',
    blur: 0,
    offsetX: 1,
    offsetY: 1,
  }
});
// 通用屬性改變
const changeCommon = () => {
  const activeObject = canvasEditor.canvas.getActiveObjects()[0];
  if (activeObject) {
    activeObject.set('shadow', new fabric.Shadow(baseAttr.shadow));
    canvasEditor.canvas.renderAll();
  }
};

14. 下載圖片

fabric.js 可以導出 Png/Jpeg/Base64 格式的圖片,同時 JPEG 格式還可以指定圖片質量與尺寸倍數,詳見 fabric.js 的 API 文檔。

結尾

以上就是 fabric.js 開發移動端編輯器的實現細節了,結合我們的開源項目和插件化架構可以很方便的完成項目開發,如果你在做類似項目或者做類似的項目,歡迎與我交流。

開源項目:https://github.com/ikuaitu/vue-fabric-editor/blob/main/README-zh.md

?轉自https://www.cnblogs.com/nihaojob/p/18426386


該文章在 2024/12/10 9:03:32 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved