分享一个强大的 Vue 图片编辑插件(快来试试!)
Posted moiom
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分享一个强大的 Vue 图片编辑插件(快来试试!)相关的知识,希望对你有一定的参考价值。
本篇文章给大家分享一款强大到没朋友的Vue图片编辑插件,可以对图片进行旋转、缩放、裁剪、涂鸦、标注、添加文本等,快来试试并收藏吧!
【相关推荐:《vue.js教程》】
最近用户提出了一个新的需求,老师可以批改学生的图片作业,需要对图片进行旋转、缩放、裁剪、涂鸦、标注、添加文本等。乍一听,又要掉不少头发。有没有功能强大的插件实现以上功能,让我有更多的时间去阻止女票双十一剁手呢?答案当然是有的。
效果展示
涂鸦
裁剪
标注
旋转
滤镜
是不是很强大!还有众多功能我就不一一展示了。那么还等什么,跟我一起用起来吧~
安装
npm i tui-image-editor // or yarn add tui-image-editor
使用
快速体验
复制以下代码,将插件引入到自己的项目中。
<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>
可以看到活生生的图片编辑工具就出现了,是不是很简单:
国际化
由于是老外开发的,默认的文字描述都是英文,这里我们先汉化一下:
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 最大高度 );
效果如下:
自定义样式
默认风格为暗黑系,如果想改成白底,或者想改变按钮的大小、颜色等样式,可以使用自定义样式。
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 最大高度 );
效果如下:
按钮优化
通过自定义样式,我们看到右上角的 Load 和 Download 按钮已经被隐藏了,接下来我们再隐藏掉其他用不上的按钮(根据业务需要),并添加一个保存图片的按钮。
<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>
效果如下:
可以看到顶部的重置按钮,以及底部的镜像和遮罩按钮都已经不见了。右上角多了一个我们自己的保存按钮,点击按钮,可以获取到 base64 文件和 blob 文件。
完整代码
<template> <div> <div id="tui-image-editor"></div> <el-button type="primary" size="small" @click="save">保存</el-button> </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\' 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\': \'锁定宽高比例\' 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(\'#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 </script> <style scoped> .drawing-container height: 900px; position: relative; .save position: absolute; right: 50px; top: 15px; </style>
总结
以上就是 tui.image-editor 的基本使用方法,相比其他插件,tui.image-editor 的优势是功能强大,简单易上手。
插件固然好用,但本人也发现一个小 bug,当放大图片,用手掌拖动显示位置,再点击重置按钮时,图片很可能就消失不见了。解决办法有两个,一是改源码,在重置之前,先调用 resetZoom 方法,还原缩放比列;二是自己做一个重置按钮,点击之后调用 this.init 方法重新进行渲染。
赠人玫瑰,手有余香。如果觉得有用,就动动发财的小手,点个赞把~
更多 API 及 Demo 请参考:
github地址:https://github.com/nhn/tui.image-editor
API 及 Examples 地址:http://nhn.github.io/tui.image-editor/latest
更多编程相关知识,请访问:编程入门!!
以上是关于分享一个强大的 Vue 图片编辑插件(快来试试!)的主要内容,如果未能解决你的问题,请参考以下文章