Home  >  Article  >  Web Front-end  >  Share a powerful Vue image editing plug-in (come and try it!)

Share a powerful Vue image editing plug-in (come and try it!)

青灯夜游
青灯夜游forward
2021-11-26 19:43:257476browse

This article will share with you a Vue image editing plug-in that is so powerful that it has no friends. It can rotate, zoom, crop, graffiti, annotate, add text, etc. to images. Come and try it and save it!

Share a powerful Vue image editing plug-in (come and try it!)

[Related recommendation: "vue.js Tutorial"]

Recently, users have put forward a new requirement, and the teacher can correct it Students' picture assignments require rotating, scaling, cropping, graffiti, annotation, adding text, etc. to pictures. At first glance, it sounds like a lot of hair will be lost. Is there a powerful plug-in that can achieve the above functions, so that I can have more time to prevent women from buying tickets during Double Eleven? The answer is of course yes.

Effect display

Graffiti

Share a powerful Vue image editing plug-in (come and try it!)

Crop

Share a powerful Vue image editing plug-in (come and try it!)

Marking

Share a powerful Vue image editing plug-in (come and try it!)

Rotate

Share a powerful Vue image editing plug-in (come and try it!)

Filter

Share a powerful Vue image editing plug-in (come and try it!)

Isn’t it very powerful! There are many more functions that I won’t show you one by one. So what are you waiting for? Come use it with me~

Installation

npm i tui-image-editor
// or
yarn add tui-image-editor

Use

Quick Experience

Copy the following code and introduce the plug-in to yourself in the project.

<template>
  <div>
    <div id="tui-image-editor"></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 "tui-image-editor";
export default {
  data() {
    return {
      instance: null,
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      this.instance = new ImageEditor(
        document.querySelector("#tui-image-editor"),
        {
          includeUI: {
            loadImage: {
              path: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1d7a1feb60346449c1a64893888989a~tplv-k3u1fbpfcp-watermark.image",
              name: "image",
            },
            initMenu: "draw", // 默认打开的菜单项
            menuBarPosition: "bottom", // 菜单所在的位置
          },
          cssMaxWidth: 1000, // canvas 最大宽度
          cssMaxHeight: 600, // canvas 最大高度
        }
      );
      document.getElementsByClassName("tui-image-editor-main")[0].style.top = "45px"; // 图片距顶部工具栏的距离
    },
  },
};
</script>

<style scoped>
.drawing-container {
  height: 900px;
}
</style>

You can see that the living picture editing tool appears. Isn’t it very simple:

Share a powerful Vue image editing plug-in (come and try it!)

Internationalization

Because I am a foreigner Developed, the default text descriptions are all in English. Here we will Chineseize them first:

const locale_zh = {
  ZoomIn: "放大",
  ZoomOut: "缩小",
  Hand: "手掌",
  History: &#39;历史&#39;,
  Resize: &#39;调整宽高&#39;,
  Crop: "裁剪",
  DeleteAll: "全部删除",
  Delete: "删除",
  Undo: "撤销",
  Redo: "反撤销",
  Reset: "重置",
  Flip: "镜像",
  Rotate: "旋转",
  Draw: "画",
  Shape: "形状标注",
  Icon: "图标标注",
  Text: "文字标注",
  Mask: "遮罩",
  Filter: "滤镜",
  Bold: "加粗",
  Italic: "斜体",
  Underline: "下划线",
  Left: "左对齐",
  Center: "居中",
  Right: "右对齐",
  Color: "颜色",
  "Text size": "字体大小",
  Custom: "自定义",
  Square: "正方形",
  Apply: "应用",
  Cancel: "取消",
  "Flip X": "X 轴",
  "Flip Y": "Y 轴",
  Range: "区间",
  Stroke: "描边",
  Fill: "填充",
  Circle: "圆",
  Triangle: "三角",
  Rectangle: "矩形",
  Free: "曲线",
  Straight: "直线",
  Arrow: "箭头",
  "Arrow-2": "箭头2",
  "Arrow-3": "箭头3",
  "Star-1": "星星1",
  "Star-2": "星星2",
  Polygon: "多边形",
  Location: "定位",
  Heart: "心形",
  Bubble: "气泡",
  "Custom icon": "自定义图标",
  "Load Mask Image": "加载蒙层图片",
  Grayscale: "灰度",
  Blur: "模糊",
  Sharpen: "锐化",
  Emboss: "浮雕",
  "Remove White": "除去白色",
  Distance: "距离",
  Brightness: "亮度",
  Noise: "噪音",
  "Color Filter": "彩色滤镜",
  Sepia: "棕色",
  Sepia2: "棕色2",
  Invert: "负片",
  Pixelate: "像素化",
  Threshold: "阈值",
  Tint: "色调",
  Multiply: "正片叠底",
  Blend: "混合色",
  Width: "宽度",
  Height: "高度",
  "Lock Aspect Ratio": "锁定宽高比例",
};

this.instance = new ImageEditor(
  document.querySelector("#tui-image-editor"),
  {
    includeUI: {
      loadImage: {
        path: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1d7a1feb60346449c1a64893888989a~tplv-k3u1fbpfcp-watermark.image",
        name: "image",
      },
      initMenu: "draw", // 默认打开的菜单项
      menuBarPosition: "bottom", // 菜单所在的位置
      locale: locale_zh, // 本地化语言为中文
    },
    cssMaxWidth: 1000, // canvas 最大宽度
    cssMaxHeight: 600, // canvas 最大高度
  }
);

The effect is as follows:

Share a powerful Vue image editing plug-in (come and try it!)

Custom style

The default style is dark. If you want to change it to white, or want to change the size, color, etc. of the button, you can use a custom style.

const customTheme = {
  "common.bi.image": "", // 左上角logo图片
  "common.bisize.width": "0px",
  "common.bisize.height": "0px",
  "common.backgroundImage": "none",
  "common.backgroundColor": "#f3f4f6",
  "common.border": "1px solid #333",

  // header
  "header.backgroundImage": "none",
  "header.backgroundColor": "#f3f4f6",
  "header.border": "0px",
  
  // load button
  "loadButton.backgroundColor": "#fff",
  "loadButton.border": "1px solid #ddd",
  "loadButton.color": "#222",
  "loadButton.fontFamily": "NotoSans, sans-serif",
  "loadButton.fontSize": "12px",
  "loadButton.display": "none", // 隐藏

  // download button
  "downloadButton.backgroundColor": "#fdba3b",
  "downloadButton.border": "1px solid #fdba3b",
  "downloadButton.color": "#fff",
  "downloadButton.fontFamily": "NotoSans, sans-serif",
  "downloadButton.fontSize": "12px",
  "downloadButton.display": "none", // 隐藏

  // icons default
  "menu.normalIcon.color": "#8a8a8a",
  "menu.activeIcon.color": "#555555",
  "menu.disabledIcon.color": "#ccc",
  "menu.hoverIcon.color": "#e9e9e9",
  "submenu.normalIcon.color": "#8a8a8a",
  "submenu.activeIcon.color": "#e9e9e9",

  "menu.iconSize.width": "24px",
  "menu.iconSize.height": "24px",
  "submenu.iconSize.width": "32px",
  "submenu.iconSize.height": "32px",

  // submenu primary color
  "submenu.backgroundColor": "#1e1e1e",
  "submenu.partition.color": "#858585",

  // submenu labels
  "submenu.normalLabel.color": "#858585",
  "submenu.normalLabel.fontWeight": "lighter",
  "submenu.activeLabel.color": "#fff",
  "submenu.activeLabel.fontWeight": "lighter",

  // checkbox style
  "checkbox.border": "1px solid #ccc",
  "checkbox.backgroundColor": "#fff",

  // rango style
  "range.pointer.color": "#fff",
  "range.bar.color": "#666",
  "range.subbar.color": "#d1d1d1",

  "range.disabledPointer.color": "#414141",
  "range.disabledBar.color": "#282828",
  "range.disabledSubbar.color": "#414141",

  "range.value.color": "#fff",
  "range.value.fontWeight": "lighter",
  "range.value.fontSize": "11px",
  "range.value.border": "1px solid #353535",
  "range.value.backgroundColor": "#151515",
  "range.title.color": "#fff",
  "range.title.fontWeight": "lighter",

  // colorpicker style
  "colorpicker.button.border": "1px solid #1e1e1e",
  "colorpicker.title.color": "#fff",
};

this.instance = new ImageEditor(
  document.querySelector("#tui-image-editor"),
  {
    includeUI: {
      loadImage: {
        path: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1d7a1feb60346449c1a64893888989a~tplv-k3u1fbpfcp-watermark.image",
        name: "image",
      },
      initMenu: "draw", // 默认打开的菜单项
      menuBarPosition: "bottom", // 菜单所在的位置
      locale: locale_zh, // 本地化语言为中文
      theme: customTheme, // 自定义样式
    },
    cssMaxWidth: 1000, // canvas 最大宽度
    cssMaxHeight: 600, // canvas 最大高度
  }
);

The effect is as follows:

Share a powerful Vue image editing plug-in (come and try it!)

Button optimization

Through customizing the style, we see that the Load and Download buttons in the upper right corner have been Hidden, then we will hide other buttons that are not used (according to business needs), and add a button to save the picture.

<template>
  <div>
    <div id="tui-image-editor"></div>
    <el-button type="primary" size="small" @click="save">保存</el-button>
  </div>
</template>

// ...
methods: {
  init() {
    this.instance = new ImageEditor(
      document.querySelector("#tui-image-editor"),
      {
        includeUI: {
          loadImage: {
            path: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1d7a1feb60346449c1a64893888989a~tplv-k3u1fbpfcp-watermark.image",
            name: "image",
          },
          menu: ["resize", "crop", "rotate", "draw", "shape", "icon", "text", "filter"], // 底部菜单按钮列表 隐藏镜像flip和遮罩mask
          initMenu: "draw", // 默认打开的菜单项
          menuBarPosition: "bottom", // 菜单所在的位置
          locale: locale_zh, // 本地化语言为中文
          theme: customTheme, // 自定义样式
        },
        cssMaxWidth: 1000, // canvas 最大宽度
        cssMaxHeight: 600, // canvas 最大高度
      }
    );
    document.getElementsByClassName("tui-image-editor-main")[0].style.top ="45px"; // 调整图片显示位置
    document.getElementsByClassName("tie-btn-reset tui-image-editor-item help") [0].style.display = "none";  // 隐藏顶部重置按钮
  },
  // 保存图片,并上传
  save() {
    const base64String = this.instance.toDataURL(); // base64 文件
    const data = window.atob(base64String.split(",")[1]);
    const ia = new Uint8Array(data.length);
    for (let i = 0; i < data.length; i++) {
      ia[i] = data.charCodeAt(i);
    }
    const blob = new Blob([ia], { type: "image/png" }); // blob 文件
    const form = new FormData();
    form.append("image", blob);
    // upload file
  },
}

<style scoped>
.drawing-container {
  height: 900px;
  position: relative;
  .save {
    position: absolute;
    right: 50px;
    top: 15px;
  }
}
</style>

The effect is as follows:

Share a powerful Vue image editing plug-in (come and try it!)

You can see that the reset button at the top and the mirror and mask buttons at the bottom are gone. There is an additional save button of our own in the upper right corner. Click the button to get the base64 file and blob file.

Complete code

<template>
  <div>
    <div id="tui-image-editor"></div>
    <el-button type="primary" size="small" @click="save">保存</el-button>
  </div>
</template>
<script>
import &#39;tui-image-editor/dist/tui-image-editor.css&#39;
import &#39;tui-color-picker/dist/tui-color-picker.css&#39;
import ImageEditor from &#39;tui-image-editor&#39;
const locale_zh = {
  ZoomIn: &#39;放大&#39;,
  ZoomOut: &#39;缩小&#39;,
  Hand: &#39;手掌&#39;,
  History: &#39;历史&#39;,
  Resize: &#39;调整宽高&#39;,
  Crop: &#39;裁剪&#39;,
  DeleteAll: &#39;全部删除&#39;,
  Delete: &#39;删除&#39;,
  Undo: &#39;撤销&#39;,
  Redo: &#39;反撤销&#39;,
  Reset: &#39;重置&#39;,
  Flip: &#39;镜像&#39;,
  Rotate: &#39;旋转&#39;,
  Draw: &#39;画&#39;,
  Shape: &#39;形状标注&#39;,
  Icon: &#39;图标标注&#39;,
  Text: &#39;文字标注&#39;,
  Mask: &#39;遮罩&#39;,
  Filter: &#39;滤镜&#39;,
  Bold: &#39;加粗&#39;,
  Italic: &#39;斜体&#39;,
  Underline: &#39;下划线&#39;,
  Left: &#39;左对齐&#39;,
  Center: &#39;居中&#39;,
  Right: &#39;右对齐&#39;,
  Color: &#39;颜色&#39;,
  &#39;Text size&#39;: &#39;字体大小&#39;,
  Custom: &#39;自定义&#39;,
  Square: &#39;正方形&#39;,
  Apply: &#39;应用&#39;,
  Cancel: &#39;取消&#39;,
  &#39;Flip X&#39;: &#39;X 轴&#39;,
  &#39;Flip Y&#39;: &#39;Y 轴&#39;,
  Range: &#39;区间&#39;,
  Stroke: &#39;描边&#39;,
  Fill: &#39;填充&#39;,
  Circle: &#39;圆&#39;,
  Triangle: &#39;三角&#39;,
  Rectangle: &#39;矩形&#39;,
  Free: &#39;曲线&#39;,
  Straight: &#39;直线&#39;,
  Arrow: &#39;箭头&#39;,
  &#39;Arrow-2&#39;: &#39;箭头2&#39;,
  &#39;Arrow-3&#39;: &#39;箭头3&#39;,
  &#39;Star-1&#39;: &#39;星星1&#39;,
  &#39;Star-2&#39;: &#39;星星2&#39;,
  Polygon: &#39;多边形&#39;,
  Location: &#39;定位&#39;,
  Heart: &#39;心形&#39;,
  Bubble: &#39;气泡&#39;,
  &#39;Custom icon&#39;: &#39;自定义图标&#39;,
  &#39;Load Mask Image&#39;: &#39;加载蒙层图片&#39;,
  Grayscale: &#39;灰度&#39;,
  Blur: &#39;模糊&#39;,
  Sharpen: &#39;锐化&#39;,
  Emboss: &#39;浮雕&#39;,
  &#39;Remove White&#39;: &#39;除去白色&#39;,
  Distance: &#39;距离&#39;,
  Brightness: &#39;亮度&#39;,
  Noise: &#39;噪音&#39;,
  &#39;Color Filter&#39;: &#39;彩色滤镜&#39;,
  Sepia: &#39;棕色&#39;,
  Sepia2: &#39;棕色2&#39;,
  Invert: &#39;负片&#39;,
  Pixelate: &#39;像素化&#39;,
  Threshold: &#39;阈值&#39;,
  Tint: &#39;色调&#39;,
  Multiply: &#39;正片叠底&#39;,
  Blend: &#39;混合色&#39;,
  Width: &#39;宽度&#39;,
  Height: &#39;高度&#39;,
  &#39;Lock Aspect Ratio&#39;: &#39;锁定宽高比例&#39;
}

const customTheme = {
  "common.bi.image": "", // 左上角logo图片
  "common.bisize.width": "0px",
  "common.bisize.height": "0px",
  "common.backgroundImage": "none",
  "common.backgroundColor": "#f3f4f6",
  "common.border": "1px solid #333",

  // header
  "header.backgroundImage": "none",
  "header.backgroundColor": "#f3f4f6",
  "header.border": "0px",
  
  // load button
  "loadButton.backgroundColor": "#fff",
  "loadButton.border": "1px solid #ddd",
  "loadButton.color": "#222",
  "loadButton.fontFamily": "NotoSans, sans-serif",
  "loadButton.fontSize": "12px",
  "loadButton.display": "none", // 隐藏

  // download button
  "downloadButton.backgroundColor": "#fdba3b",
  "downloadButton.border": "1px solid #fdba3b",
  "downloadButton.color": "#fff",
  "downloadButton.fontFamily": "NotoSans, sans-serif",
  "downloadButton.fontSize": "12px",
  "downloadButton.display": "none", // 隐藏

  // icons default
  "menu.normalIcon.color": "#8a8a8a",
  "menu.activeIcon.color": "#555555",
  "menu.disabledIcon.color": "#ccc",
  "menu.hoverIcon.color": "#e9e9e9",
  "submenu.normalIcon.color": "#8a8a8a",
  "submenu.activeIcon.color": "#e9e9e9",

  "menu.iconSize.width": "24px",
  "menu.iconSize.height": "24px",
  "submenu.iconSize.width": "32px",
  "submenu.iconSize.height": "32px",

  // submenu primary color
  "submenu.backgroundColor": "#1e1e1e",
  "submenu.partition.color": "#858585",

  // submenu labels
  "submenu.normalLabel.color": "#858585",
  "submenu.normalLabel.fontWeight": "lighter",
  "submenu.activeLabel.color": "#fff",
  "submenu.activeLabel.fontWeight": "lighter",

  // checkbox style
  "checkbox.border": "1px solid #ccc",
  "checkbox.backgroundColor": "#fff",

  // rango style
  "range.pointer.color": "#fff",
  "range.bar.color": "#666",
  "range.subbar.color": "#d1d1d1",

  "range.disabledPointer.color": "#414141",
  "range.disabledBar.color": "#282828",
  "range.disabledSubbar.color": "#414141",

  "range.value.color": "#fff",
  "range.value.fontWeight": "lighter",
  "range.value.fontSize": "11px",
  "range.value.border": "1px solid #353535",
  "range.value.backgroundColor": "#151515",
  "range.title.color": "#fff",
  "range.title.fontWeight": "lighter",

  // colorpicker style
  "colorpicker.button.border": "1px solid #1e1e1e",
  "colorpicker.title.color": "#fff",
};
export default {
  data() {
    return {
      instance: null
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init() {
      this.instance = new ImageEditor(document.querySelector(&#39;#tui-image-editor&#39;), {
        includeUI: {
          loadImage: {
            path: &#39;https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1d7a1feb60346449c1a64893888989a~tplv-k3u1fbpfcp-watermark.image&#39;,
            name: &#39;image&#39;
          },
          menu: [&#39;resize&#39;, &#39;crop&#39;, &#39;rotate&#39;, &#39;draw&#39;, &#39;shape&#39;, &#39;icon&#39;, &#39;text&#39;, &#39;filter&#39;], // 底部菜单按钮列表 隐藏镜像flip和遮罩mask
          initMenu: &#39;draw&#39;, // 默认打开的菜单项
          menuBarPosition: &#39;bottom&#39;, // 菜单所在的位置
          locale: locale_zh, // 本地化语言为中文
          theme: customTheme // 自定义样式
        },
        cssMaxWidth: 1000, // canvas 最大宽度
        cssMaxHeight: 600 // canvas 最大高度
      })
      document.getElementsByClassName(&#39;tui-image-editor-main&#39;)[0].style.top = &#39;45px&#39; // 调整图片显示位置
      document.getElementsByClassName(
        &#39;tie-btn-reset tui-image-editor-item help&#39;
      )[0].style.display = &#39;none&#39; // 隐藏顶部重置按钮
    },
    // 保存图片,并上传
    save() {
      const base64String = this.instance.toDataURL() // base64 文件
      const data = window.atob(base64String.split(&#39;,&#39;)[1])
      const ia = new Uint8Array(data.length)
      for (let i = 0; i < data.length; i++) {
        ia[i] = data.charCodeAt(i)
      }
      const blob = new Blob([ia], { type: &#39;image/png&#39; }) // blob 文件
      const form = new FormData()
      form.append(&#39;image&#39;, blob)
      // upload file
    }
  }
}
</script>

<style scoped>
.drawing-container {
  height: 900px;
  position: relative;
  .save {
    position: absolute;
    right: 50px;
    top: 15px;
  }
}
</style>

Summary

The above is the basic usage of tui.image-editor. Compared with other plug-ins, tui.image-editor has the advantage of powerful functions. Simple and easy to use.

The plug-in is easy to use, but I also found a small bug. When you enlarge the picture, drag the display position with your palm, and then click the reset button, the picture may disappear. There are two solutions. One is to change the source code and call the resetZoom method to restore the zoom ratio before resetting; the other is to make a reset button yourself, and after clicking it, call the this.init method to re-render.

Gifts of roses, hand a fragrance. If you find it useful, just give it a thumbs up and give it a like~

For more APIs and Demo, please refer to:

github address: https://github.com/ nhn/tui.image-editor

API and Examples address: http://nhn.github.io/tui.image-editor/latest

This article is reproduced from :https://juejin.cn/post/7027943745530101773

Author: Front-end A Fei

For more programming-related knowledge, please visit:Introduction to Programming! !

The above is the detailed content of Share a powerful Vue image editing plug-in (come and try it!). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:掘金社区--前端阿飞. If there is any infringement, please contact admin@php.cn delete