场景:需要对图片进行旋转、缩放、裁剪、涂鸦、标注、添加文本等。
效果-图1

官网:https://ui.toast.com/tui-image-editor
官方GitHub地址:https://github.com/nhn/tui.image-editor
Api及Examples地址:http://nhn.github.io/tui.image-editor/latest/
Demo地址:https://github.com/frontend-afei/tui-image-editor-demo
参考文章:https://juejin.cn/post/7027943745530101773#heading-0
npm i tui-image-editoryarn add tui-image-editor
效果图-基础使用版

代码
由于是外国人开发的,默认的文字描述都是英文,这里我们先汉化一下:
const locale_zh = {ZoomIn: "放大",ZoomOut: "缩小",Hand: "手掌",History: '历史',Resize: '调整宽高',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 最大高度}
);
效果见图1
默认风格为暗黑系,如果想改成白底,或者想改变按钮的大小、颜色等样式,可以使用自定义样式。
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: 400, // canvas 最大宽度cssMaxHeight: 500, // canvas 最大高度}
);
效果见图1
通过自定义样式,我们看到右上角的 Load 和 Download 按钮已经被隐藏了,接下来我们再隐藏掉其他用不上的按钮(根据业务需要),并添加一个保存图片的按钮。
保存
可以看到顶部的重置按钮,以及底部的镜像和遮罩按钮都已经不见了。右上角多了一个我们自己的保存按钮,点击按钮,可以获取到 base64 文件和 blob 文件。
index.vue
保存
相比其他插件,tui.image-editor 的优势是功能强大,简单易上手。
插件固然好用,但本人也发现一个小 bug,当放大图片,用手掌拖动显示位置,再点击重置按钮时,图片很可能就消失不见了。解决办法有两个,一是改源码,在重置之前,先调用 resetZoom 方法,还原缩放比列;二是自己做一个重置按钮,点击之后调用 this.init 方法重新进行渲染。