vue中使用tui-image-editor图片编辑组件

时间:2025-02-16 19:19:47
<template> <div class="modal fade show p-4" style="display: block"> <div class="modal-dialog modal-dialog-centered m-0 h-100" style="max-width: 100%" > <div class="modal-content h-100"> <div class="modal-header bg-white p-3"> <input type="text" class="form-control" v-model="imageName" style="width: 16rem" placeholder="在此输入数据快照名称 " :class="{ 'is-invalid': isDownload && v$.imageName.$error }" /> <div v-if="isDownload && v$.imageName.$error" class="invalid-feedback" > <span v-if="v$..$message">{{ v$.imageName.maxLength.$message }}</span> </div> </div> <div class="model-body h-100"> <div class="drawing-container h-100"> <div id="tui-image-editor"></div> </div> </div> <div class="modal-footer"> <div class="hstack gap-2 justify-content-end"> <button type="button" class="btn btn-light" @click="handleClose"> 取消 </button> <button type="button" class="btn btn-primary" id="add-btn" @click="handleCanvas2Img" > 下载 </button> </div> </div> </div> </div> </div> <div class="modal-backdrop fade show"></div> </template> <script> import "tui-image-editor/dist/"; import "tui-color-picker/dist/"; import ImageEditor from "tui-image-editor"; import { maxLength, helpers } from "@vuelidate/validators"; import useVuelidate from "@vuelidate/core"; import moment from "moment"; import 'moment-timezone'; export default { emits: ["update:isShowImageEditor"], props: { imageUrl: String, }, setup() { return { v$: useVuelidate() //校验图片名称 }; }, validations: { imageName: { maxLength: helpers.withMessage("名称的长度不能超过20", maxLength(20)), }, }, data() { return { isDownload: false, instance: null, imageName: null, }; }, mounted() { this.init(); }, methods: { init() { 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 = { "": "", // 左上角logo图片 "": "0px", "": "0px", "": "none", "": "#f6f6f6", // "": "1px solid #333", // header "": "none", "": "#f3f4f6", "": "0px", "": "none", // load button "": "none", // download button "": "none", // icons default "": "#ffffff", "": "rgba(33, 37, 41, 0.6)", "": "rgba(102, 145, 231, 1)", "": "#ccc", "": "#e9e9e9", "": "#8a8a8a", "": "#e9e9e9", "": "24px", "": "24px", "": "32px", "": "32px", // submenu primary color "": "#1e1e1e", "": "#858585", // submenu labels "": "#858585", "": "lighter", "": "#fff", "": "lighter", // checkbox style "": "1px solid #ccc", "": "#fff", // rango style "": "#fff", "": "#666", "": "#d1d1d1", "": "#414141", "": "#282828", "": "#414141", "": "#fff", "": "lighter", "": "11px", "": "1px solid #353535", "": "#151515", "": "#fff", "": "lighter", // colorpicker style "": "1px solid #1e1e1e", "": "#fff", }; this.instance = new ImageEditor( document.querySelector("#tui-image-editor"), { includeUI: { loadImage: { path: this.imageUrl, name: "image", }, menu: [ "resize", //'crop', // 裁切 "draw", // 添加绘画 // 'rotate', // 旋转 // 'flip', // 翻转 "shape", // 添加形状 "text", // 添加文本 // 'icon', // 添加图标 // 'mask', // 添加覆盖 // 'filter' // 添加滤镜 ], menuBarPosition: "left", // 菜单所在的位置 locale: locale_zh, // 本地化语言为中文 theme: customTheme, // 自定义样式 }, cssMaxWidth: 4000, // canvas 最大宽度 cssMaxHeight: 4000, // canvas 最大高度 } ); document.getElementsByClassName("tui-image-editor-main")[0].style.top = 0; document.getElementsByClassName( "tui-image-editor-controls" )[0].style.backgroundColor = "#fff"; /* 对一些不需要的按钮进行样式隐藏*/ document.querySelector('[tooltip-content="反撤销"]').style.display = "none"; // 上一步 document.querySelector('[tooltip-content="放大"]').style.display = "none"; // 放大 document.querySelector('[tooltip-content="缩小"]').style.display = "none"; // 缩小 document.querySelector('[tooltip-content="手掌"]').style.display = "none"; // 拖动界面 document.querySelector('[tooltip-content="重置"]').style.display = "none"; // 拖动界面 document.querySelector('[tooltip-content="历史"]').style.display = "none"; document.querySelector( ".tui-image-editor-container ." ).style.height = "140px"; document.querySelector( ".tui-image-editor-container ." ).style.backgroundColor = "#fff"; // 隐藏分割线 document .querySelectorAll(".tui-image-editor-icpartition") .forEach((item) => { item.parentNode.style.display = "none"; }); }, /** 保存编辑后图片 */ handleCanvas2Img() { this.isDownload = true; this.v$.$touch(); if (this.v$.$invalid) return; // 调用组件官方方法,获取整个编辑后图片的base64数据 const el = document.createElement("a"); el.href = this.instance.toDataURL(); el.download = el.download = this.imageName || "数据快照" + moment().tz(this.$tz).format("YYYYMMDD"); const event = new MouseEvent("click"); el.dispatchEvent(event); }, /** 取消按钮关闭弹窗 */ handleClose() { this.$emit("update:isShowImageEditor", false); }, }, }; </script>