当前位置: 首页 > news >正文

利用vue-capper封装一个可以函数式调用图片裁剪组件

1. 效果

	const cropData = await wqCrop({prop:{img,autoCrop: true, // 是否开启截图框maxImgSize: 600,autoCropWidth: 30,canMove: true, // 图片是否可移动canMoveBox: true, // 截图框是否可移动fixedBox: false, // 截图框是否固定}});console.log(cropData);

在这里插入图片描述
在这里插入图片描述

使用wqCrop会开启一个截图弹出框, 当截取完毕后会返回一个 Promise<{file: File, blob:Blob, data: string} | null>, 为截取后的图片

2. 代码

type.ts

export type CropProp = {// 裁剪图片的地址img?: string; // 默认为空,可选值为 url 地址、base64 或 blob// 生成图片的质量outputSize?: number; // 默认值为 1,范围 0.1 ~ 1// 生成图片的格式outputType?: 'jpeg' | 'png' | 'webp'; // 默认值为 'jpg'(需传入 'jpeg')// 是否显示裁剪框的大小信息info?: boolean; // 默认值为 true// 图片是否允许滚轮缩放canScale?: boolean; // 默认值为 true// 是否默认生成截图框autoCrop?: boolean; // 默认值为 false// 默认生成截图框宽度autoCropWidth?: number; // 默认值为容器的 80%,范围 0 ~ max// 默认生成截图框高度autoCropHeight?: number; // 默认值为容器的 80%,范围 0 ~ max// 是否开启截图框宽高固定比例fixed?: boolean; // 默认值为 false// 截图框的宽高比例,开启 `fixed` 生效fixedNumber?: [number, number]; // 默认值为 [1, 1]// 是否输出原图比例的截图full?: boolean; // 默认值为 false// 是否固定截图框大小fixedBox?: boolean; // 默认值为 false// 上传图片是否可以移动canMove?: boolean; // 默认值为 true// 截图框能否拖动canMoveBox?: boolean; // 默认值为 true// 上传图片是否按照原始比例渲染original?: boolean; // 默认值为 false// 截图框是否被限制在图片里面centerBox?: boolean; // 默认值为 false// 是否按照设备的 dpr 输出等比例图片high?: boolean; // 默认值为 true// 是否展示真实输出图片宽高infoTrue?: boolean; // 默认值为 false// 限制图片最大宽度和高度maxImgSize?: number; // 默认值为 2000,范围 0 ~ max// 图片根据截图框输出比例倍数enlarge?: number; // 默认值为 1,范围 0 ~ max(建议不要太大)// 图片默认渲染方式mode?: 'contain' | 'cover' | '100px' | '100%' | 'auto'; // 默认值为 'contain'// 裁剪框限制最小区域limitMinSize?: number | number[] | string; // 默认值为 10// 导出时背景颜色填充fillColor?: string; // 默认为空,可选值为 #ffffff、white
};export type CropEvents = {// 实时预览事件realTime?: (data?: { w: number; h: number }) => void;// 图片移动事件imgMoving?: () => void;// 截图框移动回调函数cropMoving?: () => void;// 图片加载的回调, 返回结果imgLoad?: () => void;
};export type CropOptions = {prop?: CropProp;events?: CropEvents;
};

defaultOptions.ts

// 默认值对象
import { CropOptions } from './type';export const defaultCropOptions: CropOptions = {prop: {img: '',outputSize: 1,outputType: 'jpeg',info: true,canScale: true,autoCrop: false,autoCropWidth: 0,autoCropHeight: 0,fixed: false,fixedNumber: [1, 1],full: false,fixedBox: false,canMove: true,canMoveBox: true,original: false,centerBox: false,high: true,infoTrue: false,maxImgSize: 2000,enlarge: 1,mode: 'contain',limitMinSize: 10,fillColor: '',},events: {// 实时预览事件realTime: () => {},// 图片移动事件imgMoving: () => {},// 截图框移动回调函数cropMoving: () => {},// 图片加载的回调, 返回结果imgLoad: () => true,},
};

crop-dialog.vue

<template><el-dialog v-model="dialogVisible" :before-close="dialogClose" class="crop-dialog"><div class="crop-dialog__container center"><vue-cropper v-bind="options.prop" ref="cropper" v-on="options.events" /></div><template #footer><el-space><el-button type="primary" @click="submitHandle">截取</el-button><el-button @click="dialogClose">取消</el-button></el-space></template></el-dialog>
</template><script setup lang="ts">
import { ref, defineProps, defineExpose, defineEmits } from 'vue';
import { VueCropper } from 'vue-cropper/next';
import 'vue-cropper/next/dist/index.css';
import { CropOptions } from '@/components/CropDialog/type';
import { defaultCropOptions } from '@/components/CropDialog/defaultOptions';type Prop = {options?: CropOptions;
};
const props = withDefaults(defineProps<Prop>(), {options: () => ({ ...defaultCropOptions }),
});
// 定义emits
const emit = defineEmits(['submit', 'closed']);const cropper = ref();const showForm = ref('login');
// 定义表单数据
let dialogVisible = ref(false);// 关闭弹窗
function dialogClose() {dialogVisible.value = false;emit('closed');
}const getCropBlob = (): Promise<Blob> => {return new Promise((resolve, reject) => {cropper.value.getCropBlob((blob: Blob) => {resolve(blob);});});
};
const getCropData = (): Promise<string> => {return new Promise((resolve, reject) => {cropper.value.getCropData((data: string) => {resolve(data);});});
};const getCropFile = () => {const outputType = props.options?.prop?.outputType || 'jpeg';return new Promise((resolve, reject) => {getCropBlob().then((blob) => {resolve(new File([blob], `cropped-image.${outputType}`, { type: `image/${outputType}` }));});});
};const submitHandle = async () => {const file = await getCropFile();const data = await getCropData();const blob = await getCropBlob();emit('submit', { file, data, blob });dialogClose();
};defineExpose({showDialog: () => {dialogVisible.value = true;},hideDialog: () => {dialogVisible.value = false;},
});
</script>
<style lang="scss" scoped>
.crop-dialog {min-width: 314px;background: #eeeeee;color: #999999;&__container {width: 600px;height: 600px;position: relative;display: flex;justify-content: center;}
}
</style>

wq-crop.ts

import { createApp, h, ref } from 'vue';
import CropDialog from './crop-dialog.vue';
import { CropOptions } from './type';
import { defaultCropOptions } from './defaultOptions';type SubmitData = {data: string;file: File;blob: Blob;
};export function wqCrop(options: CropOptions): Promise<SubmitData | null> {const propOptions: CropOptions = {prop: options.prop || defaultCropOptions.prop,events: options.events || defaultCropOptions.events,};// console.log(propOptions);return new Promise((resolve, reject) => {const wqCropRef = ref();const mountNode = document.createElement('div');// const appendTo = document.querySelector('body')document.body.appendChild(mountNode);// 创建节点const app = createApp({render() {return h(CropDialog, {ref: wqCropRef,options: propOptions,onSubmit: (data: SubmitData) => {resolve(data);},onClosed: () => {mountNode.remove();},});},});// 挂载容器,instance就是容器的实例const instance = app.mount(mountNode);wqCropRef.value.showDialog();});
}

3. 最后

使用该组件需要vue-cropper
可以使用 npm install vue-cropper
这里用到是 "vue-cropper": "^0.6.5" 版本

本组件用到了element-uidialog, 这里也可以使用其他的dialog组件

函数传入的参数, 参照type.ts 中的 type CropOptions

如果组件封装有不合理的地方, 或者哪里有问题, 欢迎评论与私信

相关文章:

利用vue-capper封装一个可以函数式调用图片裁剪组件

1. 效果 const cropData await wqCrop({prop:{img,autoCrop: true, // 是否开启截图框maxImgSize: 600,autoCropWidth: 30,canMove: true, // 图片是否可移动canMoveBox: true, // 截图框是否可移动fixedBox: false, // 截图框是否固定}});console.log(cropData);使用wqCrop会…...

在系统开发中提升 Excel 数据导出一致性与可维护性的统一规范与最佳实践

背景&#xff1a; 在系统开发过程中&#xff0c;数据导出为 Excel 格式是一个常见的需求。然而&#xff0c;由于各个开发人员的编码习惯和实现方式不同&#xff0c;导致导出代码风格不一。有的人使用第三方库&#xff0c;有的人则自定义实现。这种多样化不仅影响了代码的一致性…...

SpringAOP学习

面向切面编程&#xff0c;指导开发者如何组织程序结构 增强原始设计的功能 oop:面向对象编程 1.导入aop相关坐标&#xff0c;创建 <!--spring依赖--><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spri…...

智能网联汽车飞速发展,安全危机竟如影随形,如何破局?

随着人工智能、5G通信、大数据等技术的飞速发展&#xff0c;智能网联汽车正在成为全球汽车行业的焦点。特别是我国智能网联汽车市场规模近年来呈现快速增长态势&#xff0c;彰显了行业蓬勃发展的活力与潜力。然而&#xff0c;车联网技术的广泛应用也带来了一系列网络安全问题&a…...

Android常用C++特性之std::function

声明&#xff1a;本文内容生成自ChatGPT&#xff0c;目的是为方便大家了解学习作为引用到作者的其他文章中。 std::function 是 C 标准库中的一个 函数包装器&#xff0c;用于存储、复制、调用任何可以调用的目标&#xff08;如普通函数、lambda 表达式、函数对象、成员函数等&…...

人工智能与机器学习原理精解【27】

文章目录 集成学习集成学习概述集成学习的定义集成学习的性质集成学习的算法过程集成学习的算法描述集成学习的例子和例题Julia实现集成学习 集成学习数学原理一、基学习器的生成Bagging&#xff08;装袋法&#xff09;Boosting&#xff08;提升法&#xff09; 二、基学习器的结…...

XXL-JOB在SpringBoot中的集成

在SpringBoot中&#xff0c;XXL-JOB作为一个轻量级的分布式任务调度平台&#xff0c;提供了灵活的任务分片处理功能&#xff0c;这对于处理大规模、复杂的任务场景尤为重要。以下将详细探讨如何在SpringBoot中利用XXL-JOB实现灵活控制的分片处理方案&#xff0c;涵盖配置、代码…...

前端工程规范-3:CSS规范(Stylelint)

样式规范工具&#xff08;StyleLint&#xff09; Stylelint 是一个灵活且强大的工具&#xff0c;适用于保持 CSS 代码的质量和一致性。结合其他工具&#xff08;如 Prettier 和 ESLint&#xff09;&#xff0c;可以更全面地保障前端代码的整洁性和可维护性。 目录 样式规范工具…...

Qt系列-1.Qt安装

Qt安装 0 简介 1.安装步骤 1.1 下载 进入qt中文网站:https://www.qt.io/zh-cn/ Qt开源社区版本:https://www.qt.io/download-open-source#source 1.2 安装 chmod +x qt-online-installer-linux-x64-4.8.0.run ./qt-online-installer-linux-x64-4.8.0.run 外网不能下载…...

《自控原理》最小相位系统

在复平面右半平面既没有零点&#xff0c;也没有极点的系统&#xff0c;称为最小相位系统&#xff0c;其余均为非最小相位系统。 从知乎看了一篇答案&#xff1a; https://www.zhihu.com/question/24163919 证明过程大概率比较难&#xff0c;我翻了两本自控的教材&#xff0c;…...

SpringBoot3脚手架

MySpringBootAPI SpringBoot3脚手架&#xff0c;基于SpringBoot3DruidPgSQLMyBatisPlus13FastJSON2Lombok&#xff0c;启动web容器为Undertow(非默认tomcat)&#xff0c;其他的请自行添加和配置。 <java.version>17</java.version> <springboot.version>3.3…...

【C语言软开面经】

C语言软开面经 malloc calloc realloc free动态分配内存malloccalloc函数&#xff1a;realloc 函数&#xff1a;free函数&#xff1a; 堆栈-内存分区栈区&#xff08;Stack&#xff09;&#xff1a;堆区&#xff08;Heap&#xff09;&#xff1a;全局&#xff08;静态&#xff…...

YOLOv11训练自己的数据集(从代码下载到实例测试)

文章目录 前言一、YOLOv11模型结构图二、环境搭建三、构建数据集四、修改配置文件①数据集文件配置②模型文件配置③训练文件配置 五、模型训练和测试模型训练模型验证模型推理 总结 前言 提示&#xff1a;本文是YOLOv11训练自己数据集的记录教程&#xff0c;需要大家在本地已…...

HTML粉色烟花秀

目录 系列文章 写在前面 完整代码 下载代码 代码分析 写在最后 系列文章 序号目录1HTML满屏跳动的爱心(可写字)2HTML五彩缤纷的爱心3HTML满屏漂浮爱心4...

从零开发操作系统

没有操作系统 要考虑放到什么位置 org 07c00h 我用nasm&#xff08;汇编编译&#xff09; 放到7c00处 ibm兼容机 AX发生变化 -寄存器 不可能做存储 内存- 代码段数据段 if else --指令 代码 int a -数据段 必须告诉计算机代码段从哪里开始 改变cs寄存器里面的值可以改变推进寄…...

SigmaStudio中部分滤波器算法有效性频谱分析

一、各类滤波器参数如下图设置 1.1、输入源白噪音经过如下算法处理后Notch\Band Pass\Band Stop&#xff0c;如下频谱分析图 1.2、输入源白噪音经过low pass后处理前后的频谱分析如如下 二、Notch滤波器配置图&#xff0c;如下 2.1、两串联、五个串联和未串联的Notch对白噪音…...

ArcGIS与ArcGIS Pro去除在线地图服务名单

我们之前给大家分享了很多在线地图集&#xff0c;有些地图集会带有制作者信息&#xff0c;在布局制图的时候会带上信息影响出图美观。 一套GIS图源集搞定&#xff01;清新规划底图、影像图、境界、海洋、地形阴影图、导航图 比如ArcGIS&#xff1a; 比如ArcGIS Pro&#xff1a…...

滚雪球学MySQL[10.1讲]:常见问题与解决

全文目录&#xff1a; 前言10. 常见问题与解决10.1 数据库连接问题10.1.1 无法连接到数据库10.1.2 连接超时10.1.3 连接数过多 10.2 性能问题10.2.1 查询速度慢10.2.2 数据库锁等待 10.3 数据完整性问题10.3.1 违反外键约束10.3.2 重复记录 10.4 安全问题10.4.1 SQL注入攻击10.…...

利用 Llama-3.1-Nemotron-51B 推进精度-效率前沿的发展

今天&#xff0c;英伟达™&#xff08;NVIDIA&#xff09;发布了一款独特的语言模型&#xff0c;该模型具有无与伦比的准确性和效率性能。Llama 3.1-Nemotron-51B 源自 Meta 的 Llama-3.1-70B&#xff0c;它采用了一种新颖的神经架构搜索&#xff08;NAS&#xff09;方法&#…...

SpringBoot+Thymeleaf发票系统

> 这是一个基于SpringBootSpringSecurityThymeleafBootstrap实现的简单发票管理系统。 > 实现了用户登录&#xff0c;权限控制&#xff0c;客户管理&#xff0c;发票管理等功能。 > 并且支持导出为 CSV / PDF / EXCEL 文件。 > 本项目是一个小型发票管理系统…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...