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

有没有个人做网站赚钱沈阳网站制作

有没有个人做网站赚钱,沈阳网站制作,成都市网站建设费用及企业,深圳市宝安区投资推广署官网在现代 Web 应用开发中,图片裁剪功能是一个常见需求,无论是用户头像上传、商品图片处理还是社交媒体内容发布,都需要对图片进行裁剪以满足特定的展示要求。本文将介绍如何使用 Vue.js 结合 vue-cropper 插件和 Element Plus UI 库实现一个功能…

在现代 Web 应用开发中,图片裁剪功能是一个常见需求,无论是用户头像上传、商品图片处理还是社交媒体内容发布,都需要对图片进行裁剪以满足特定的展示要求。本文将介绍如何使用 Vue.js 结合 vue-cropper 插件和 Element Plus UI 库实现一个功能完善的图片裁剪组件。

功能概述

我们实现的图片裁剪组件具有以下功能:

  • 支持图片上传( jpg/png 格式)

  • 可视化图片裁剪界面(600x600 像素)

  • 自定义裁剪框比例(可通过 props 配置)

  • 图片放大 / 缩小功能

  • 图片旋转功能(左右旋转)

  • 裁剪后图片数据处理(转换为 File 对象)

    技术栈

    本组件使用了以下技术和库:

  • Vue 3.x(Composition API)

  • Element Plus(UI 组件库)

  • vue-cropper(图片裁剪插件@1.0.5版本)

    组件实现解析

    模板部分解析

    模板部分主要包含三个核心区域:图片上传区域(因暂未对接后台接口,只测试功能,通过change事件来实现)、裁剪预览区域和操作按钮区域。

    <template><div class="w-full h-full flex-col items-center justify-center"><!-- action="#" #在实战中替换为实际的后台接口 --><ElUploadv-model:file-list="fileList"class="upload-demo"action="#"multiple:limit="1"accept="image/*"list-type="picture-card":on-change="onChange":auto-upload="false"><el-button type="primary">Click to upload</el-button><template #tip><div class="el-upload__tip">xxxxxxxxxxxxxxxxxxxxx</div></template></ElUpload><div :style="{ height: '600px', width: '600px', marginBottom: '30px' }"><VueCropperref="cropper":info="false":infoTrue="options.infoTrue":img="options.img":autoCrop="options.autoCrop":autoCropWidth="options.autoCropWidth":autoCropHeight="options.autoCropHeight":fixedBox="options.fixedBox":mode="options.cropperMode":centerBox="options.centerBox":enlarge="options.enlarge":fixedNumber="options.fixedNumber"outputType="png"@realTime="realTime"/></div><ElRow :style="{ textAlign: 'center' }"><ElCol :span="6"><ElButton type="default" :icon="ZoomOut" @click="changeScale(1)">放大</ElButton></ElCol><ElCol :span="6"><ElButton type="default" :icon="RefreshRight" @click="rotateLeft">左旋转</ElButton></ElCol><ElCol :span="6"><ElButton type="default" :icon="RefreshLeft" @click="rotateRight">右旋转</ElButton></ElCol><ElCol :span="6"><ElButton :icon="ZoomIn" type="default" @click="changeScale(-1)">缩小</ElButton></ElCol></ElRow><div><ElButton @click="handleSubmit()">提交事件</ElButton></div></div>
    </template>
    

    逻辑部分核心功能解析

    组件初始化与配置

    组件使用了 Vue 3 的 Composition API,通过reactiveref来管理响应式数据:

    图片上传与处理

    图片上传使用了 Element Plus 的ElUpload组件,通过onChange事件处理图片选择,通过getImageData函数计算裁剪框的初始尺寸:

    图片比例计算核心函数

    getImageData函数是整个组件的核心,它根据原图尺寸和裁剪比例计算出合适的裁剪框尺寸:

    裁剪结果处理

    提交事件处理函数获取裁剪后的图片数据,并将其转换为 File 对象以便上传到服务器:

    <script setup lang="ts">
    import "vue-cropper/dist/index.css";
    import { VueCropper } from "vue-cropper";
    import { ref, reactive, onMounted } from "vue";
    import { ElButton, ElRow, ElCol, ElUpload } from "element-plus";
    import {RefreshRight,RefreshLeft,ZoomIn,ZoomOut,
    } from "@element-plus/icons-vue";const previews = ref();
    const cropper = ref();
    const fileName = ref();
    const options = reactive({img: "", //裁剪图片的地址autoCrop: true, //是否默认生成截图框autoCropWidth: undefined, //默认生成截图框宽度autoCropHeight: undefined, //默认生成截图框高度enlarge: undefined, // 图片根据截图框输出比例倍数fixedBox: true, //是否固定截图框大小 不允许改变previewsCircle: false, //预览图是否是原圆形centerBox: true, //截图框是否被限制在图片里面fixedNumber: [1, 1], // 截图框的宽高比例infoTrue: true,title: "修改图片",cropperMode: "contain",
    });//上传图片组件数据
    const fileList = ref<any>([]);interface CropperProps {action?: string; //上传接口fixedWidthNumber?: any; // 截图框的宽高比例fixedHeightNumber?: any; // 截图框的宽高比例
    }
    const props = withDefaults(defineProps<CropperProps>(), {action: "后台接口",fixedWidthNumber: 1,fixedHeightNumber: 1,
    });// //图片上传前回调
    const onChange = (file: any, list: any) => {console.log("🚀 ~ beforeUpload ~ file:any, fileList:any:", file, list);if (file) {fileList.value[0] = file;options.img = file.url;fileName.value = file.name;const imgData: any = getImageData(600, file?.raw, [props.fixedWidthNumber,props.fixedHeightNumber,]);options.autoCropWidth = imgData.width;options.autoCropHeight = imgData.height;options.enlarge = imgData.ratio;options.fixedNumber = [props.fixedWidthNumber, props.fixedHeightNumber];}
    };/*** @Description: 计算原图与裁剪框显示的图片的比例,裁剪框的大小(需要传入原图的文件!!!, 裁剪弹框的高度)* 实现的功能:* 1.如果没有传截图框的比例,那么默认是1:1,那一边短那一边被当成截图框的长度。* 2.传入截图框比例,有六种情况,处理原则为截图框比例不会改变的情况下截取原图一边。* 三个重要核心:* 1.原图与裁剪弹框的比例。* 2.原图宽高比例。* 3.截图框宽高比例。*/
    function getImageData(maxHeight: number, file: any, fixed: number[]) {console.log("🚀 ~ getImageData ~ file:", file);return new Promise((resolve, reject) => {// 读取文件内容 new FileReader()const reader = new FileReader();// readAsDataURL: 方法可以将读取到的文件编码成DataURL (这里的reader.result是base64格式)reader.readAsDataURL(file);// onload:文件读取成功时触发reader.onload = () => {// 创建一个Image对象const image: any = new Image();// 定义Image对象的src: image.src = reader.result;  这样做就相当于给浏览器缓存了一张图片。image.src = reader.result;console.log("🚀 ~ returnnewPromise ~ reader.result:", reader.result);// onload:Image对象创建成功时触发image.onload = () => {let Ratio = 1;// 获取原图的宽和高const w = image.width;const h = image.height;// 获取原图的比例const imgRatio = w / h;//图片长的是那一边const imgLong = imgRatio > 1 ? "width" : "height";// 计算出原图被缩放到裁剪框缩小的比例const wRatio = w / maxHeight;const hRatio = h / maxHeight;// 按照功能需要,长的一边需要与裁剪弹框一样长,所以比例取长的一边Ratio = wRatio >= hRatio ? wRatio : hRatio;// 计算截图框的比例const fixedRatio = fixed[0] / fixed[1];// 截图比例长的是那一边const fixedLong = fixedRatio > 1 ? "width" : "height";// 初始情况即没有传入裁剪弹框比例const imgWidth = w > h ? h / Ratio : w / Ratio;let imgData = {ratio: Ratio,width: imgWidth,height: imgWidth,};// 传入裁剪框比例的六种情况if (imgLong === fixedLong) {if (imgLong === "width") {if (imgRatio > fixedRatio) {// 情况1 图的比例和裁剪框的比例都是宽大,但是图片比例大于截图比例。// 情况处理:在以一边为裁剪时,图放得下裁剪框,不用换边为裁剪框的基数,以高为基数。imgData = {ratio: Ratio,width: (h / Ratio) * fixedRatio,height: h / Ratio,};} else {// 情况2 图的比例和裁剪框的比例都是宽大,但是图片比例小于截图比例。// 情况处理:在以一边为裁剪时,图放不下裁剪框,换边为裁剪框的基数,以宽为基数。imgData = {ratio: Ratio,width: w / Ratio,height: (h / Ratio) * (w / Ratio / ((h / Ratio) * fixedRatio)),};}} else {if (imgRatio < fixedRatio) {// 情况3 图的比例和裁剪框的比例都是高大,但是图片比例小于于截图比例。(w/h 小于即大于)// 情况处理:在以一边为裁剪时,图放得下裁剪框,不用换边为裁剪框的基数,以宽为基数。imgData = {ratio: Ratio,width: w / Ratio,height: w / Ratio / fixedRatio,};} else {// 情况4 图的比例和裁剪框的比例都是高大,但是图片比例大于截图比例。(w/h 小于即大于)// 情况处理:在以一边为裁剪时,图放不下裁剪框,换边为裁剪框的基数,以高为基数。imgData = {ratio: Ratio,width: (w / Ratio) * (h / Ratio / (w / Ratio / fixedRatio)),height: h / Ratio,};}}} else {if (imgLong === "width") {// 情况5 图的比例大于1,裁剪框的比例小于1。// 情况处理:在以一边为裁剪时,图放得下裁剪框,不用换边为裁剪框的基数,以高为基数。imgData = {ratio: Ratio,width: (h / Ratio) * fixedRatio,height: h / Ratio,};} else {// 情况5 图的比例小于1,裁剪框的比例大于1。// 情况处理:在以一边为裁剪时,图放得下裁剪框,不用换边为裁剪框的基数,以宽为基数。imgData = {ratio: Ratio,width: w / Ratio,height: w / Ratio / fixedRatio,};}}resolve(imgData);};image.onerror = () => {reject(new Error("Image对象创建失败"));};};});
    }//移动框的事件
    const realTime = (data: any) => {previews.value = data;
    };//图片缩放
    function changeScale(num: number) {num = num || 1;cropper.value.changeScale(num);
    }
    //向左旋转
    function rotateLeft() {cropper.value.rotateLeft();
    }
    //向右旋转
    function rotateRight() {cropper.value.rotateRight();
    }// 提交事件
    async function handleSubmit() {// 提交事件cropper.value.getCropData(async (data: any) => {//拿到裁剪后的原始数据const file = dataURLtoFile(data, fileName.value);//调用接口--传递给后台--从后台再读取新的图片链接并赋值即可// const result = await 后台接口({ file });});
    }// base 64 转成二进制文件流
    const dataURLtoFile = (dataurl: any, filename: any) => {var arr = dataurl.split(","),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new File([u8arr], filename, { type: mime });
    };
    </script>
    

    注意

    getImageData中file字段传入的数据类型示例(也是提交事件中处理后的数据类型)

  • 实际使用需对接接口,并组件化封装拓展,本文章仅供参考,逻辑已通!
http://www.dtcms.com/a/425280.html

相关文章:

  • 北京企业建站系统费用韶关哪里做网站
  • 成都网站建设专家优秀的html5网站
  • 论坛网站开发教程推广网站发布文章
  • 网站建设询价公告thinkphp网站开发技术
  • 网站建设源文件东海做网站公司
  • 苏州网站设计公司兴田德润好不好徐州html5响应式网站建设
  • 加强网站队伍建设互联网站账户e服务平台
  • 把做的网站发布打万维网上惠州城乡规划建设局网站
  • 昆明定制网站建设wordpress大前端5.0下载
  • ADC如何写入缓冲区及其处理
  • 网站建设的风险识别西宁网站制作哪家公司好
  • 企业网络建站wordpress 协会主题
  • 信息系统项目的成本管理(智慧矿车)
  • 给别人做网站的话术宜州做网站需要多少钱
  • 网站建设商标注册多少类目设计教学网站推荐
  • 三级运放仪表放大电路与仿真
  • 设计商标的网站西海岸新区城市建设局公示网站
  • 政务公开网站建设工作情况汇报利用access做网站
  • 网络规划设计师希赛搜索引擎优化的方法包括
  • 网站建设什么意思合肥学室内设计学校
  • 医疗网站前置审批什么公司可以做网站等级保护
  • 学网站开发首先学哪些基础wordpress自动添加视频教程
  • 网站 要强化内容建设做外贸没有网站需要
  • 济南做网站个人网站建设遇到的问题
  • 绿化公司和苗圃做网站网站内容更新外包
  • 社区网站源码小公司简介ppt介绍范本
  • 云南大学网站建设做美食网站的素材图片
  • 商城网站开发技术福建省住房城乡建设厅网站
  • wordpress网站换主题服务器网站打开慢
  • 东莞高明网站设计做网站公司排行榜