【导语】:ToastUI Image Editor 是一个基于 HTML5 画布的图片编辑器,它应用起来非常简单,而且内置了丰盛的图片编辑性能。

简介

ToastUI Image Editor 是一个基于 HTML5 Canvas 的图片编辑器,它应用起来非常简单,而且内置了丰盛的图片编辑性能。它反对原生 JavaScript、Vue 组件 和  React 组件三种应用形式。

根底应用

Javascript

最简略的形式装置就是间接取援用它在线的 CDN 资源,咱们间接看一个 html 的例子:

<!DOCTYPE html>  <html>    <head>    <meta charset="UTF-8">    <title>ImageEditor Demo</title>    <link type="text/css" href="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.css" rel="stylesheet">    <link rel="stylesheet" href="https://uicdn.toast.com/tui-image-editor/latest/tui-image-editor.css">    <style>        html,      body {        height: 100%;        margin: 0;      }    </style>  </head>    <body>      <div id="tui-image-editor-container"></div>    <!-- 依赖的第三方库 -->    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.0/fabric.js"></script>    <!-- 一些工具函数 -->    <script type="text/javascript" src="https://uicdn.toast.com/tui.code-snippet/v1.5.0/tui-code-snippet.min.js"></script>    <!-- 色彩抉择 -->    <script type="text/javascript" src="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.js"></script>    <!-- 文件下载的库 -->    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>     <!-- 外围库 -->    <script src="https://uicdn.toast.com/tui-image-editor/latest/tui-image-editor.js"></script>    <script>      var imageEditor = new tui.ImageEditor('#tui-image-editor-container', {        includeUI: {          initMenu: 'filter',          menuBarPosition: 'left'        },        cssMaxWidth: 700,        cssMaxHeight: 500,        usageStatistics: false      });      window.onresize = function () {        imageEditor.ui.resizeEditor();      }    </script>  </body>    </html>  

咱们能够看到,引入了很多 CDN 资源,每个资源的作用都有解释。咱们来看一下这个编辑器都应用。首先咱们实例化了一个 ImageEditor 类,它第一个参数是挂载点,这里示意将编辑器挂载到 id 为 tui-image-editor-container 的元素上;接着第二个参数是这个编辑器的属性,上面是对属性的简略介绍:

  • includeUI:示意应用它内置的 UI 控件

    • initMenu:示意编辑器加载后,第一个被选中的操作菜单,这里选的是 filter,也就是滤镜
    • menuBarPosition:示意菜单栏的地位,有四个选项可选:'top', 'bottom', 'left', 'right'
  • cssMaxWidth:编辑器 Canvas 的最大宽度
  • cssMaxHeight:编辑器 Canvas 的最大高度
  • usageStatistics:是否开启 GA (Google Analytics)来收集数据。它是默认开启的,不想应用的话能够设置为 false

还有一些属性咱们会在前面用到。这里要留神,无论是原生 JavaScript 的应用形式,还是 Vue、React 的组件应用形式,他们的配置属性简直统一,所以你不必放心要依据不同状况批改配置的问题。 实际上,Vue、React 组件就是对这个原生形式的一层包装,实质上是一回事。

介绍完了,咱们先来看看下面例子的运行成果:

咱们来感受一下它弱小的性能吧!

(视频在这里,请戳链接。)

能够看到,当咱们加载一张图片进入工作区的时候,默认高亮开启的操作是最初一个滤镜(filter)的操作,咱们对图片进行了滤镜、增加文字、增加图标、镜像翻转、裁剪等操作后,点击 Download 下载了咱们操作后的图片。只是简略的几行代码,就能实现如此弱小的图片编辑性能,是不是很神奇!接下来咱们看看,如何在咱们的前端框架中集成它。

Vue

咱们应用 vue-cli 搭建一个简略的我的项目,而后装置 tui-image-editor

npm install --save @toast-ui/vue-image-editor  

接着咱们在 App.vue 中应用这个组件:

<template>    <div id="app">      <ImageEditor :include-ui="useDefaultUI" :options="options"></ImageEditor>    </div>  </template>    <script>  // 引入款式  import "tui-image-editor/dist/tui-image-editor.css";  import "tui-color-picker/dist/tui-color-picker.css";  // 引入组件  import ImageEditor from "@toast-ui/vue-image-editor/src/ImageEditor.vue";  import Logo from "@/assets/logo.png";    export default {    name: "App",    components: {      ImageEditor,    },    data() {      return {        useDefaultUI: true,        options: {          includeUI: {            // 默认开启绘图的性能            initMenu: "draw",            // 反对的菜单            menu: [              "crop",              "draw",              "icon",              "text",            ],            // 菜单地位在上面            menuBarPosition: "bottom",            // 默认加载的图片            loadImage: {              // 图片门路              path: Logo,              // 图片的名字,能够省略              name: "sample",            },          },        },      };    },  };  </script>    <style>  html,  body {    height: 100%;    margin: 0;  }  #app {    height: 100%;  }  </style>  

能够看到,咱们新加了 loadImage 的配置,它示意默认加载的图片;又新加了一个 menu 的配置,它的值是一个数组,示意咱们须要的性能菜单,如果没有配置的话,默认是开启所有性能。咱们运行 npm run serve 看一下成果:

果然,咱们的性能菜单只有四个了。全副的性能菜单如下:

menu: [    "crop", // 裁切    "flip", // 翻转    "rotate", // 旋转    "draw", // 增加绘画    "shape", // 增加形态    "icon", // 增加图标    "text", // 增加文本    "mask", // 增加笼罩    "filter", // 增加滤镜  ],  

能够依据我的项目的具体须要来进行适当的增减。

React

在 React 应用也很简略,咱们能够基于 create-react-app 创立一个简略的我的项目,而后装置依赖:

npm install --save @toast-ui/react-image-editor  

咱们接着在 App.js 中应用组件:

import 'tui-image-editor/dist/tui-image-editor.css'  import ImageEditor from '@toast-ui/react-image-editor'    function App() {    return (      <div className="App">        <h1>ImageEditor React Demo</h1>        <ImageEditor          includeUI= {{            initMenu: "draw",            menu: ["crop", "draw", "icon", "text"],            menuBarPosition: "left",            loadImage: {              path: 'logo192.png',              name: "sample",            },            uiSize: {              height: '600px'            },          }}          />      </div>    );  }    export default App;  

咱们的配置项与上例中 Vue 组件的形式基本一致。运行 npm start 看一下成果,应该与上例一样:

进阶用法

理解了根底用法之后,咱们来深刻的学习一下它的其余性能。把握这些之后,在理论我的项目中用到它就能够熟能生巧了。留神,这里的例子都会以 Vue 组件的模式来介绍,其余形式的应用能够类比。

本地化(国际化)

这个 tui-image-editor 组件默认是英文的,所以它的各种提示信息也都是英文的。咱们平时的应用场景大都是中文的环境,所以做好这些信息的本地化转换是很有必要的。tui-image-editor 也提供了相干的配置,咱们只有补充须要翻译的文本就能够了。接着下面 Vue 的例子来看一下如何配置:

<script>  import "tui-image-editor/dist/tui-image-editor.css";  import "tui-color-picker/dist/tui-color-picker.css";  import ImageEditor from "@toast-ui/vue-image-editor/src/ImageEditor.vue";  import Logo from "@/assets/logo.png";    const localeCN = {    Crop: "裁剪",    Draw: "涂鸦",    Icon: "增加图标",    Text: "增加文本",    Free: "任意线条",    Straight: "直线",    Color: "色彩",    Range: "范畴",  };    export default {    name: "App",    components: {      ImageEditor,    },    data() {      return {        useDefaultUI: true,        options: {          includeUI: {            initMenu: "draw",            menu: ["crop", "draw", "icon", "text"],            menuBarPosition: "bottom",            locale: localeCN,            loadImage: {              path: Logo,              name: "sample",            },          },        },      };    },  };  </script>  

咱们增加了 includeUI.locale 属性,来看一下成果:

咱们看到了,菜单的悬浮提醒,和编辑图片的提醒都变成了中文。残缺的本地化的 Key 值列表能够参考 tui-image-editor localization,你能够依据我的项目状况进行批改。

主题

如果你不喜爱它这个款式,你能够本人定制一份。它的配置相似于下面的本地化配置,也是提供一组 key-value 的映射对象。比方咱们持续在下面的例子上增加主题配置:

<script>  import "tui-image-editor/dist/tui-image-editor.css";  import "tui-color-picker/dist/tui-color-picker.css";  import ImageEditor from "@toast-ui/vue-image-editor/src/ImageEditor.vue";  import Logo from "@/assets/logo.png";    const localeCN = {    Crop: "裁剪",    Draw: "涂鸦",    Icon: "增加图标",    Text: "增加文本",    Free: "任意线条",    Straight: "直线",    Color: "色彩",    Range: "范畴",  };    const customTheme = {    // 菜单-一般状态 - 绿色    "menu.normalIcon.color": "green",    // 菜单-选中状态 - 蓝色    "menu.activeIcon.color": "blue",    // 菜单-禁用状态 - 灰色    "menu.disabledIcon.color": "grey",    // 菜单-鼠标悬浮状态 - 黄色    "menu.hoverIcon.color": "yellow",    // 整体背景色彩    "common.backgroundColor": "#eaeaea",    // 头部的背景色彩    "header.backgroundColor": "#556677",    // 下载按钮背景色彩    "downloadButton.backgroundColor": "lightgreen",    // 下载按钮文字色彩    "downloadButton.color": "#fff",    // 下载按钮边框款式    "downloadButton.border": "none",  };    export default {    name: "App",    components: {      ImageEditor,    },    data() {      return {        useDefaultUI: true,        options: {          includeUI: {            initMenu: "draw",            menu: ["crop", "draw", "icon", "text"],            menuBarPosition: "bottom",            locale: localeCN,            loadImage: {              path: Logo,              name: "sample",            },            theme: customTheme,          },        },      };    },  };  </script>  

咱们增加了一组款式到 includeUI.theme 属性上,来看看成果:

残缺的款式主题能够参考源码中 src/js/ui/theme/standard.js 文件。

如果你想要批改他的 icon 文件的话,能够参考这个链接 menu-submenu-svg-icon-setting,要留神的是要思考到每个状态下的icon(normal,active,disable,hover)。

办法调用

tui-image-editor 也提供了许多内置的办法,不便咱们本人解决一些逻辑。它的办法列表文档能够参考:http://nhn.github.io/tui.image-editor/latest/ImageEditor/咱们持续批改下面的例子,这次咱们减少几个内部的按钮,来本人手动的操作图片:

<template>    <div id="app">      <ImageEditor ref="editor" :include-ui="useDefaultUI" :options="options"></ImageEditor>      <div class="actions">        <button @click="addText">Add Text</button>        <button @click="rotate">Rotate</button>        <button @click="flip">Flip Y</button>        <button @click="undo">Undo</button>      </div>    </div>  </template>    <script>  import "tui-image-editor/dist/tui-image-editor.css";  import "tui-color-picker/dist/tui-color-picker.css";  import ImageEditor from "@toast-ui/vue-image-editor/src/ImageEditor.vue";  import Logo from "@/assets/logo.png";    const localeCN = {    Crop: "裁剪",    Draw: "涂鸦",    Icon: "增加图标",    Text: "增加文本",    Free: "任意线条",    Straight: "直线",    Color: "色彩",    Range: "范畴",  };    const customTheme = {    // 菜单-一般状态 - 绿色    "menu.normalIcon.color": "green",    // 菜单-选中状态 - 蓝色    "menu.activeIcon.color": "blue",    // 菜单-禁用状态 - 灰色    "menu.disabledIcon.color": "grey",    // 菜单-鼠标悬浮状态 - 黄色    "menu.hoverIcon.color": "yellow",    // 整体背景色彩    "common.backgroundColor": "#eaeaea",    // 头部的背景色彩    "header.backgroundColor": "#556677",    // 下载按钮背景色彩    "downloadButton.backgroundColor": "lightgreen",    // 下载按钮文字色彩    "downloadButton.color": "#fff",    // 下载按钮边框款式    "downloadButton.border": "none",  };    export default {    name: "App",    components: {      ImageEditor,    },    data() {      return {        useDefaultUI: true,        options: {          includeUI: {            initMenu: "draw",            menu: ["crop", "draw", "icon", "text"],            menuBarPosition: "bottom",          &nbsnbsp; locale: localeCN,            loadImage: {              path: Logo,              name: "sample",            },            theme: customTheme,          },        },      };    },    methods: {      addText() {        // 增加文字 Hello Jerry        // 默认在工作区的两头        // 文字填充色彩 - 红色;文字大小 22px;        this.$refs.editor.invoke("addText", "Hello Jerry", {          styles: {            fontSize: 22,            fill: "red",          },        });      },      // 旋转 20 度      rotate() {        this.$refs.editor.invoke("rotate", 10);      },      // 沿 Y 轴翻转      flip() {        this.$refs.editor.invoke("flipY");      },      // 撤销上一次操作      undo() {        this.$refs.editor.invoke("undo");      },    },  };  </script>    <style>  html,  body {    height: 100%;    margin: 0;  }  #app {    height: 80%;  }  button {    height: 30px;    line-height: 30px;    margin: 30px;  }  </style>    

咱们增加了四个操作按钮,别离是 增加文字,旋转,沿Y轴翻转,撤销,来看一下成果:

.gif)

能够看到,与咱们在编辑器内的操作无异。其实编辑器内简直所有的操作,咱们都能够应用办法调用的形式本人实现。这样,咱们就能够充沛的施展自由性,联合需要本人封装出一个更贴合理论的组件。

事件监听

Vue 组件提供了如下的事件监听:

  • addText: 增加文字
  • mousedown: 鼠标按下
  • objectActivated: Canvas 中 有元素被选中
  • objectMoved: Canvas 中有元素挪动
  • objectScaled: 元素缩放
  • redoStackChanged: 操作栈中的 redo 事件
  • textEditing: 文字编辑
  • undoStackChanged: 操作栈中的 undo 事件

咱们在下面的例子上增加几个监听事件:

<template>    // .....    <ImageEditor      ref="editor"      @addText="onAddText"      @textEditing="onEditText"      @objectMoved="onObjectMove"      :include-ui="useDefaultUI"      :options="options"    ></ImageEditor>  </template>    <script>  export default {    // ....    methods: {      onAddText(pos) {        console.info(`Adding Text on (${pos.originPosition.x}, ${pos.originPosition.y})`);      },      onEditText() {        console.info("Text Editing");      },      onObjectMove(e) {        console.info(`Object moving... `, e);      }    }  }  </script>    

来看一下成果:

.gif)

通过控制台的日志能够看到,咱们的事件回调函数都被触发了。更多事件的应用办法请参考 官网文档

参考资料

开源前哨 日常分享热门、乏味和实用的开源我的项目。参加保护 10万+ Star 的开源技术资源库,包含:Python、Java、C/C++、Go、JS、CSS、Node.js、PHP、.NET 等。