1. 安装依赖
npm install cropperjs
2. 创建组件 名为 cropper-img
ng g c /pages/component/cropper-img --module=app
3. cropper-img.component.html
文件
<div class="cropper-img">
<label for="btn" class="upload-btn" >上传需要被裁剪的图片(裁剪宽高比:{{width}} / {{height}})</label>
<input id="btn" #imageInput accept=".jpg,.png,.jpeg" type="file" style="display: none;" (change)="imageChangeEvent($event)">
<div class="copperArea">
<div class="leftCopper">
<img #imgCropper class="cropperMain" />
</div>
<div class="rightPreview">
<div>
<div class="liTitle">预览</div>
<img class="preImg" [src]="croppedImage" />
</div>
<div>
<div class="liTitle">工具</div>
<div class="toolArea ">
<div class="J_KnowBtn btnTheme" (click)="rotateImage()">旋转图片</div>
<div class="J_KnowBtn btnTheme" (click)="sureCropper()">确认裁剪</div>
</div>
</div>
</div>
</div>
</div>
4. cropper-img.component.less
文件
自己写的样式,难看死了。你们自己改改
.cropper-img {
.copperArea {
display: flex;
justify-content: space-between;
.leftCopper {
width: 400px;
height: 300px;
.cropperMain {
width: 100%;
height: 100%;
border: solid 1px #000000;
}
}
.rightPreview {
width: 230px;
height: 300px;
.preImg {
width: 200px;
border-radius: 10px;
border: solid 1px #000000;
}
.toolArea {
display: flex;
justify-content: flex-start;
align-items: center;
.J_KnowBtn {
width: 100px;
height: 30px;
border-radius: 5px;
color: #ffffff;
font-size: 14px;
font-weight: 600;
margin-right: 10px;
background: #00d7c6;
text-align: center;
line-height: 30px;
&:last-child {
margin-right: 0;
}
}
}
}
}
.liTitle {
font-size: 18px;
font-weight: 600;
color: #000000;
}
input {
width: 100%;
height: 30px;
border-radius: 5px;
border: solid 1px #00d7c6;
color: #00d7c6;
font-size: 14px;
font-weight: 600;
margin-left: 10px;
}
.upload-btn {
height: 30px;
line-height: 30px;
padding: 0 20px;
background-color: #00d7c6;
color: #ffffff;
text-align: center;
display: inline-block;
border-radius: 4px;
}
}
5. cropper-img.component.ts
文件
import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { ApiService } from '../../service/api/api.service';
import { RequestService } from '../../service/request/request.service';
import Cropper from '../../../assets/cropperjs/cropper.min.js';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'app-cropper-img',
templateUrl: './cropper-img.component.html',
styleUrls: ['./cropper-img.component.less','../../../assets/cropperjs/cropper.min.css'],
encapsulation:ViewEncapsulation.None//样式不进行封装
})
export class CropperImgComponent implements OnInit {
@Input () width ; // 裁剪的宽度
@Input () height ; // 裁剪的高度
@Input () imgUrl ; // 回显图片url
@Output () getImgUrl: EventEmitter<boolean> = new EventEmitter(); // 裁剪后传给father的图片对象
@ViewChild('imageInput') imgInput:ElementRef;//input=file的事件容器
@ViewChild('imgCropper') imgCropper:ElementRef;//装裁剪图片的容器
myCropper: any;//当前的裁剪对象
croppedImage: any = '';//当前实时裁剪后的base64
nowRotate=0;//旋转度数
constructor(
private res:RequestService,
private message : NzMessageService
) {
setTimeout(() => {
this.imgCropper.nativeElement.src=this.imgUrl;
this.iniCropper()
}, 0);
}
imageChangeEvent(event: any): void {
// console.log(event);
const fr = new FileReader();
fr.readAsDataURL(event.path[0].files[0]);
fr.onload = ()=>{
this.imgCropper.nativeElement.src=fr.result;
this.iniCropper();
};
}
iniCropper() {
this.myCropper = new Cropper(this.imgCropper.nativeElement, {
aspectRatio: (this.width&&this.height)? this.width / this.height : 'auto',
dragMode : 'move',
viewMode : 1,
autoCropArea : 1,
// preview: '.preImg',//自动存放原图供预览,定义一个div用class名即可
//其他还有很多属性,可以参见官方文档或文章末尾
crop:event=> {
this.croppedImage= this.myCropper.getCroppedCanvas({//直接转了base64
imageSmoothingQuality: 'high'
}).toDataURL('image/png')
},
replace:event =>{
if(this.imgUrl){
this.myCropper.replace(this.imgUrl)
}
}
});
this.myCropper.replace(this.imgCropper.nativeElement.src)
}
rotateImage(){
this.nowRotate+=90;
this.myCropper.rotateTo(this.nowRotate)
}
sureCropper(){
// this.base64toFile(this.croppedImage)//可以自己将base64转file对象然后传输
// console.log(this.base64toFile(this.croppedImage))
this.uploadImg()
this.imgInput.nativeElement.value="";//补坑,防止第二次点击不触发imageChangeEvent事件
}
base64toFile() {//将base64转换为文件
let base = this.croppedImage
var arr = base.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
let filename = new Date().getTime()
return new File([u8arr], filename+".png", {type:mime});
}
uploadImg(){
const formData = new FormData();
let file = this.base64toFile()
formData.append('file', file)
formData.append('type', '3')
this.res.post(ApiService.common_post_commonFileUpload,formData).subscribe(res=>{
this.message.success('上传成功')
// 向父组件传值
this.getImgUrl.emit(res.data);
})
}
ngOnInit(): void {
}
}
6.使用方式
<!-- html文件-->
<app-cropper-img
[width]="cropperWidth"
[height]="cropperHeight"
[imgUrl]="validateForm.value.coverUrl"
(getImgUrl)="getImgUrl($event)"
></app-cropper-img>
// ts文件
cropperWidth : number = 64;
cropperHeight : number = 64;
coverUrl : string = '';
getImgUrl(e){
this.coverUrl : e.absolutePath
}
注:如果npm
引入的cropper
不能使用,到这里下载 【cropperjs】静态资源引入项目中。
反正我是没有npm引入成功,就下载静态资源了