99微分销系统,seo 网站分析,最好的做法是()。,南充高端网站建设一、前言
最近做项目中遇到一个需求#xff0c;需要对海报图片按照一定的比例进行裁剪并上传到oss。一开始这个需求思路有两个#xff0c;使用canvas原生或者寻找现成的第三方库#xff0c;对比了一番觉得canvas实现时间耗费较长#xff0c;且秉承着不重复造轮子的原则需要对海报图片按照一定的比例进行裁剪并上传到oss。一开始这个需求思路有两个使用canvas原生或者寻找现成的第三方库对比了一番觉得canvas实现时间耗费较长且秉承着不重复造轮子的原则其实是菜。
在进行技术调研后决定使用vue-cropper插件来实现预想会顺利可结果恰恰相反安装vue-cropper设置参数封装完组件后发现裁剪框和裁剪的图片在h5页面上不能拖动在web页面上可以看源码里面也有兼容移动端的方法代码在github上的issue里面也没发现有人遇到相同问题难道就我遇到了问度娘发现大家都可以为什么我的就不行呢后来又使用了vue-cropper-h5也存在各种问题。其实vue-cropper、vue-cropper-h5、vue-cropperjs等插件都是基于cropper.js实现的最终决定使用cropper.js去实现。官方封装了很多参数、方法、事件上手容易文档阅读体验较好、而且便于扩展。下面就来详细介绍一个cropper.js的详细用法吧
cropper.js可以对指定的图片进行裁剪可以自己选择裁剪的交互方式如大小、纵横比等裁剪后可以生成一个包含裁剪图的canvas对象借助canvas的toDataURL方法可以生成一张Base64格式的图片再通过toBlob转换成blob类型文件再通过new File()转换成file文件上传当然也可以直接上传裁剪后生成的base64。还有另外一种不使用canvas的方式利用该工具丰富的api可以拿到裁剪区域相对于原图的各项数据使用这些数据进行css绝对定位即可展示裁剪后的图该方式可以保证图片不失真和完整。
二、项目环境
1.node
v16.0.02.vue
vue: ^3.2.453.vant
vant: ^4.0.24.cropper.js
cropperjs: ^1.5.13三、使用
1.安装
yarn add cropperjs2.引入要导入样式不然不会生效
import Cropper from cropperjs
import cropperjs/dist/cropper.min.css3.模板
div classv-simple-croppervan-uploader:after-readafterReadtemplate #defaultimg v-ifimgUrl classupload-img :srcimgUrl altdiv v-else classupload-area //template/van-uploaderdiv v-showshowlayer classv-cropper-layervan-row classlayer-header :gutter36van-col :span8van-button typedanger plain block sizesmall clickcancelHandle取消/van-button/van-colvan-col :span8van-button typesuccess block sizesmall clickrotateHandle旋转/van-button/van-colvan-col :span8van-button typeprimary block sizesmall clickconfirmHandle裁剪并上传/van-button/van-col/van-rowimg refcropperImg/div/div
/template4.js
script setup langts
import Cropper from cropperjs
import cropperjs/dist/cropper.min.css
import { onMounted, ref, watch } from vue
import { closeToast, showFailToast, showLoadingToast, showToast } from vant
import { useRequest } from vue-request
import { fileUpload } from /api/basic/indexconst props defineProps({url: {type: String,default: ,},width: {type: Number,},height: {type: Number,},scale: {type: Number,default: 0.8}
})
const emit defineEmits([update:url])const cropperImg refany(null)
const cropper refany(null)
const showlayer ref(false)
const imgUrl ref(props.url)watch(() props.url, (val) {if (val)imgUrl.value val
})function init() {cropper.value new Cropper(cropperImg.value, {viewMode: 1,// 根据所需图片宽高计算比例aspectRatio: props.width props.height ? (Number(props.width) / Number(props.height)) : 1 / 0.618,dragMode: move,cropBoxResizable: false,autoCropArea: 1,})
}
// 选择图片
function afterRead(file) {// 判断扩展名const tmpCnt file.file.name.lastIndexOf(.)const exName file.file.name.substring(tmpCnt 1)const names [jpg, jpeg, png]if (!names.includes(exName)) {showToast(不支持的格式!)return}const URL window.URL || window.webkitURLconst binaryData []binaryData.push(file.file)cropper.value.replace(URL.createObjectURL(new Blob(binaryData)))showlayer.value true
}// 旋转
function rotateHandle() {cropper.value.rotate(90)
}
function cancelHandle() {cropper.value.reset()showlayer.value false
}
// 上传方法
const { run: runUplaod } useRequest(fileUpload, {manual: true,onSuccess: (res) {closeToast()imgUrl.value res.imgUrlemit(update:url, res.imgUrl)},onError: (err) {closeToast()showFailToast(err.message)},
})
// 裁剪并上传
function confirmHandle() {const cropBox cropper.value.getCropBoxData();const scale props.scale || 1;cropper.value.getCroppedCanvas({width: cropBox.width * scale,height: cropBox.height * scale,})// 把裁剪的图片转换成blob类型文件在通过new File()转换成file文件.toBlob(async (blob) {// 重置file的name以时间戳作为文件名const timeString new Date().getTime()const imgFile new File([blob], ${timeString}.jpg, {type: image/jepg,})showlayer.value falseshowLoadingToast({message: 上传中...,duration: 0,forbidClick: true,})runUplaod(imgFile)})
}onMounted(() {init()
})
/script5.style
style langless scoped
.v-simple-cropper {text-align: center;padding-top: 10px;.upload-area {width: 190px;height: 120px;background: url(/assets/bg-upload-box.png);background-size: 100% 100%;}.upload-img {width: 190px;height: 120px;}/deep/.van-uploader__upload {margin: 0 !important;}.v-cropper-layer {position: fixed;top: 0;bottom: 0;left: 0;right: 0;background: #fff;z-index: 200;.layer-header {position: absolute;bottom: 0;left: 0;z-index: 200;width: 100%;padding: 0 16px 12px;box-sizing: border-box;}img {position: inherit !important;border-radius: inherit !important;float: inherit !important;}}
}
/style在上面的代码中我们使用了cropperjs组件来实现图片裁剪功能。在afterRead方法中我们获取用户上传的图片并将其转换为URL对象。在confirmHandle方法中我们使用getCroppedCanvas方法获取裁剪后的canvas对象并使用toBlob方法将其转换为Blob对象最后将其转换为File对象并上传oss返回一个oss url。
四、其他
1.预览功能
上面创建cropper的时候我们可以在选项中添加了如下代码实现预览功能。
preview:[document.querySelector(.previewBox), document.querySelector(.previewBoxRound)
]preview就是用来设置我们需要实时预览的地方但是设置完成之后要给上述的两个div添加一下样式才可以正常显示。
.previewBox {box-shadow: 0 0 5px #adadad;width: 100px;height: 100px;margin-top: 30px;/*这个超出设置为隐藏很重要否则就会整个显示出来了*/overflow: hidden;
}2. 官方文档
(1)官网示例
https://fengyuanchen.github.io/cropper/
(2)官方github文档
https://github.com/fengyuanchen/cropperjs
(3)npm官方网站
https://www.npmjs.com/package/cropper