cropper.js 패키지 vue 기반 온라인 이미지 재단 구성 요소 기능 구현
17748 단어 cropper.jsvue그림 재단
github:demo 다운로드
cropper.js
github:cropper.js
홈 페이지(demo)
cropper.js 설치
npm install cropper
# or
bower install cropper
clone 다운로드:다운로드 주소git clone https://github.com/fengyuanchen/cropper.git
cropper.js 참조
주로 cropper.js 와 cropper.css 두 파일 을 참조 합 니 다.
<script src="/path/to/jquery.js"></script><!-- jQuery is required -->
<link href="/path/to/cropper.css" rel="external nofollow" rel="stylesheet">
<script src="/path/to/cropper.js"></script>
메모:jquery 파일 을 먼저 도입 해 야 cropper.js 플러그 인 을 사용 할 수 있 습 니 다.간단히 사용 하 다
캡 처 에 사용 할 div 용기 구축
<!-- Wrap the image or canvas element with a block element (container) -->
<div>
![](picture.jpg)
</div>
용기 의 스타일 을 추가 하여 img 을 전체 용기 에 채 우 는 것 이 중요 합 니 다(중요 합 니 다)
/* Limit image width to avoid overflow the container */
img {
max-width: 100%; /* This rule is very important, please do not ignore this! */
}
cropper.js 방법 을 호출 하여 캡 처 컨트롤 을 초기 화 합 니 다.
$('#image').cropper({
aspectRatio: 16 / 9,
crop: function(e) {
// Output the result data for cropping image.
console.log(e.x);
console.log(e.y);
console.log(e.width);
console.log(e.height);
console.log(e.rotate);
console.log(e.scaleX);
console.log(e.scaleY);
}
});
기타 상세 api 참조:github:cropper.jsvue 구성 요소 로 밀봉
vue 구성 요소 로 봉 인 된 문제
그림 재단 다시 선택
재단 을 확인 하고 base 64 형식의 그림 정 보 를 가 져 옵 니 다.
아 날로 그 input 상 자 를 누 르 면 그림 을 선택 하고 선택 한 그림 의 형식,크기 제한 을 합 니 다.
숨겨 진 input 탭 을 만 들 고 이 input 를 모 의 클릭 하여 그림 을 선택 할 수 있 는 기능 을 수행 합 니 다.
<!-- input -->
<input id="myCropper-input" type="file" :accept="imgCropperData.accept" ref="inputer" @change="handleFile">
//
document.getElementById('myCropper-input').click();
input 에 감청 내용 의 변 화 를 연결 하 는 방법 으로 업 로드 된 파일 을 가 져 오고 형식,크기 검 사 를 실시 합 니 다.
// imgCropperData: {
// accept: 'image/gif, image/jpeg, image/png, image/bmp',
// }
handleFile (e) {
let _this = this;
let inputDOM = this.$refs.inputer;
// DOM
_this.file = inputDOM.files[0];
//
if (_this.imgCropperData.accept.indexOf(_this.file.type) == -1) {
_this.$Modal.error({
title: ' ',
content: ' !'
});
return;
}
//
if (_this.file.size > 5242880) {
_this.$Modal.error({
title: ' ',
content: ' , 5MB !'
});
return;
}
var reader = new FileReader();
// base64
reader.readAsDataURL(_this.file);
reader.onload = function () {
_this.imgCropperData.imgSrc = this.result;
_this.initCropper();
}
}
그림 재단 다시 선택처음 그림 을 선택 한 후에 그림 을 다시 선택해 야 하 는 문제 에 직면 하 게 될 것 입 니 다.그러면 재단 상자 에 있 는 그림 을 어떻게 교체 하 는 지 에 직면 하 게 될 것 입 니 다.위의 절 차 는 그림 을 선택 한 후에FileRender()방법 으로 그림 의 주요 정 보 를 얻 었 습 니 다.지금 은 재단 상 자 를 다시 구축 하면 문 제 를 해결 할 수 있 습 니 다.cropper.js 가 제시 한공식 데모을 살 펴 보 세 요.공식 적 으로 는 동적 으로 용 기 를 자 르 는 방법 을 추가 하여 조작 한 것 으로 밝 혀 졌 으 며,여기 서 우 리 는 공식 적 으로 이 루어 졌 다.
//
initCropper () {
let _this = this;
//
_this.imgObj = $('![](' + _this.imgCropperData.imgSrc + ')');
let $avatarPreview = $('.avatar-preview');
$('#myCropper-workspace').empty().html(_this.imgObj);
_this.imgObj.cropper({
aspectRatio: _this.proportionX / _this.proportionY,
preview: $avatarPreview,
crop: function(e) {
}
});
}
재단 을 확인 하고 base 64 형식의 그림 정 보 를 가 져 옵 니 다.
let $imgData = _this.imgObj.cropper('getCroppedCanvas')
imgBase64Data = $imgData.toDataURL('image/png');
업로드 에 사용 할 데 이 터 를 구성 합 니 다.
//
let formData = new FormData();
//
let photoType = imgBase64Data.substring(imgBase64Data.indexOf(",") + 1);
//
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for(let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for(let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {
type: contentType
});
return blob;
}
const contentType = 'image/jepg';
const b64Data2 = photoType;
const blob = b64toBlob(b64Data2, contentType);
formData.append("file", blob, "client-camera-photo.png")
formData.append("type", _this.imgType)
비 부자 구성 요소 간 통신 문제이전 항목 에 서 는 부자 구성 요소 간 의 통신 인삼 을 자주 사용 하 며,일반적으로 두 가지 방법 을 사용한다.
router 에 파 라 메 터 를 설치 한 후 route.params.xxx 또는 route.query.xxx 를 호출 하여 가 져 옵 니 다.
props 를 통 해 통신 하 다
여기 서 이벤트 버스 를 사용 하여 구성 요소 간 의 통신 을 진행 합 니 다.
순서
1.bus 구성 요 소 는 B 구성 요소 가 A 구성 요소 에 인 자 를 전달 하 는 데 사 용 됩 니 다.
//bus.js
import Vue from 'vue';
export default new Vue();
2.A 구성 요소 에서 bus 구성 요 소 를 참조 하고 매개 변수 변 화 를 실시 간 으로 감청 합 니 다.
// A.vue
import Bus from '../../components/bus/bus.js'
export default {
components: { Bus },
data () {},
created: function () {
Bus.$on('getTarget', imgToken => {
var _this = this;
console.log(imgToken);
...
});
}
}
3.B 구성 요소 에서 도 bus 구성 요 소 를 참조 하여 인 자 를 A 구성 요소 에 전달 합 니 다.
// B.vue
//
Bus.$emit('getTarget', imgToken);
참고:vue-$on
vue-$emit
vue.js 의 길(4)-vue 2.0 s 에서 eventBus 는 형제 구성 요소 통신 을 실현 합 니 다.
vue 선택 캡 처 플러그 인 전체 코드
<template>
<div class="myCropper-container">
<div id="myCropper-workspace">
<div class="myCropper-words" v-show="!imgCropperData.imgSrc"> </div>
</div>
<div class="myCropper-preview" :class="isShort ? 'myCropper-preview-short' : 'myCropper-preview-long'">
<div class="myCropper-preview-1 avatar-preview">
![](!imgCropperData.imgUploadSrc ? '/images/thumbnail/thumbnail-img.jpg' : imgCropperData.imgUploadSrc)
</div>
<div class="myCropper-preview-2 avatar-preview">
![](!imgCropperData.imgUploadSrc ? '/images/thumbnail/thumbnail-img.jpg' : imgCropperData.imgUploadSrc)
</div>
<div class="myCropper-preview-3 avatar-preview">
![](!imgCropperData.imgUploadSrc ? '/images/thumbnail/thumbnail-img.jpg' : imgCropperData.imgUploadSrc)
</div>
<input id="myCropper-input" type="file" :accept="imgCropperData.accept" ref="inputer" @change="handleFile">
<Button type="ghost" class="myCropper-btn" @click="btnClick"> </Button>
<Button type="primary" class="myCropper-btn" :loading="cropperLoading" @click="crop_ok"> </Button>
</div>
</div>
</template>
<script>
var ezjsUtil = Vue.ezjsUtil;
import Bus from './bus/bus.js'
export default {
components: { Bus },
props: {
imgType: {
type: String
},
proportionX: {
type: Number
},
proportionY: {
type: Number
}
},
data () {
return {
imgCropperData: {
accept: 'image/gif, image/jpeg, image/png, image/bmp',
maxSize: 5242880,
file: null, //
imgSrc: '', // img base64
imgUploadSrc: '', // img base64
},
imgObj: null,
hasSelectImg: false,
cropperLoading: false,
isShort: false,
}
},
created: function () {
let _this = this;
},
mounted: function () {
let _this = this;
//
let maxWidthNum = Math.floor(300 / _this.proportionX);
let previewWidth = maxWidthNum * _this.proportionX;
let previewHeight = maxWidthNum * _this.proportionY;
if (previewWidth / previewHeight <= 1.7) {
previewWidth = previewWidth / 2;
previewHeight = previewHeight / 2;
_this.isShort = true;
}
//
$('.myCropper-preview-1').css('width', previewWidth + 'px');
$('.myCropper-preview-1').css('height', previewHeight + 'px');
//
$('.myCropper-container .myCropper-preview .myCropper-preview-2').css('width',( previewWidth / 2) + 'px');
$('.myCropper-container .myCropper-preview .myCropper-preview-2').css('height', (previewHeight / 2) + 'px');
//
$('.myCropper-container .myCropper-preview .myCropper-preview-3').css('width',( previewWidth / 4) + 'px');
$('.myCropper-container .myCropper-preview .myCropper-preview-3').css('height', (previewHeight / 4) + 'px');
},
methods: {
//
btnClick () {
let _this = this;
// input
document.getElementById('myCropper-input').click();
},
//
handleFile (e) {
let _this = this;
let inputDOM = this.$refs.inputer;
// DOM
_this.file = inputDOM.files[0];
//
if (_this.imgCropperData.accept.indexOf(_this.file.type) == -1) {
_this.$Modal.error({
title: ' ',
content: ' !'
});
return;
}
//
if (_this.file.size > 5242880) {
_this.$Modal.error({
title: ' ',
content: ' , 5MB !'
});
return;
}
var reader = new FileReader();
// base64
reader.readAsDataURL(_this.file);
reader.onload = function () {
_this.imgCropperData.imgSrc = this.result;
_this.initCropper();
}
},
//
initCropper () {
let _this = this;
//
_this.imgObj = $('![](' + _this.imgCropperData.imgSrc + ')');
let $avatarPreview = $('.avatar-preview');
$('#myCropper-workspace').empty().html(_this.imgObj);
_this.imgObj.cropper({
aspectRatio: _this.proportionX / _this.proportionY,
preview: $avatarPreview,
crop: function(e) {
}
});
_this.hasSelectImg = true;
},
//
crop_ok () {
let _this = this, imgToken = null, imgBase64Data = null;
//
if (_this.hasSelectImg == false) {
_this.$Modal.error({
title: ' ',
content: ' , !'
});
return false;
}
//
_this.cropperLoading = true;
let $imgData = _this.imgObj.cropper('getCroppedCanvas')
imgBase64Data = $imgData.toDataURL('image/png');
//
let formData = new FormData();
//
let photoType = imgBase64Data.substring(imgBase64Data.indexOf(",") + 1);
//
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for(let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for(let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {
type: contentType
});
return blob;
}
const contentType = 'image/jepg';
const b64Data2 = photoType;
const blob = b64toBlob(b64Data2, contentType);
formData.append("file", blob, "client-camera-photo.png")
formData.append("type", _this.imgType)
// ajax
$.ajax({
url: _this.$nfs.uploadUrl,
method: 'POST',
data: formData,
// true, false ajax ( ) $.ajax(...)
async: false,
// , FormData ,contentType , jquery ( )。
cache: false,
contentType: false,
processData: false,
type: _this.imgType,
success: function(res) {
let imgToken = res.data.token;
_this.cropperLoading = false;
//
Bus.$emit('getTarget', imgToken);
},
error: function(error) {
_this.cropperLoading = false;
_this.$Modal.error({
title: ' ',
content: ' !'
});
}
});
},
}
}
</script>
<style lang="less" scoped>
.myCropper-container {
height: 400px;
}
.myCropper-container #myCropper-input {
width: 0px;
height: 0px;
}
.myCropper-container #myCropper-workspace {
width: 500px;
height: 400px;
border: 1px solid #dddee1;
float: left;
}
//
.myCropper-container #myCropper-workspace .myCropper-words{
text-align: center;
font-size: 18px;
padding-top: 180px;
}
//
.myCropper-container .myCropper-preview-long {
width: 300px;
}
.myCropper-container .myCropper-preview-short {
width: 200px;
}
.myCropper-container .myCropper-preview {
float: left;
height: 400px;
margin-left: 10px;
}
.myCropper-container .myCropper-preview .myCropper-preview-1 {
border-radius: 5px;
overflow: hidden;
border: 1px solid #dddee1;
box-shadow: 3px 3px 3px #dddee1;
img {
width: 100%;
height: 100%;
}
}
.myCropper-container .myCropper-preview .myCropper-preview-2 {
margin-top: 20px;
border-radius: 5px;
overflow: hidden;
border: 1px solid #dddee1;
box-shadow: 3px 3px 3px #dddee1;
img {
width: 100%;
height: 100%;
}
}
.myCropper-container .myCropper-preview .myCropper-preview-3 {
margin-top: 20px;
border-radius: 5px;
overflow: hidden;
border: 1px solid #dddee1;
box-shadow: 3px 3px 3px #dddee1;
img {
width: 100%;
height: 100%;
}
}
//
.myCropper-btn {
float: left;
margin-top: 20px;
margin-right: 10px;
}
</style>
BY-LucaLJXgithub: lucaljx
총결산
위 에서 말 한 것 은 소 편 이 소개 한 cropper.js 패키지 vue 를 바탕 으로 온라인 이미지 재단 구성 요소 기능 을 실현 하 는 것 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
cropper.js 로 두상 을 자 르 는 인 스 턴 스 코드 를 사용 합 니 다.최근 프로젝트 는 프로필 컷 기능 이 필요 하 다.인터넷 에서 찾 아 보 니 github 의 cropper 프로젝트 가 괜 찮 은 것 을 발견 하고 참고 했다.사용 하기 가 매우 간단 하 다.다음은 내 가 만 든 작...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.