使用vue+html2canvas+exif-js
github地址
線上demo
主要功能
- 上傳圖片
- 對圖片進行操作:移動、放大、縮小
- 合成海報
具體功能:
上傳圖片
html:
<input type="file" value="" accept="image/*" @click="getPhoto" id="image-input">
複製程式碼
js
getPhoto () {
var imageInput = document.querySelector('#image-input')
var that = this
imageInput.addEventListener('change', function (e) {
reads = new FileReader()
reads.readAsDataURL(this.files[0])
reads.addEventListener('load', function (e) {
that.imgUrl = this.result
that.myImg.position.x = 0
that.myImg.position.y = 0
that.myImg.scale = 1
var orientation
that.previewImg.addEventListener('load', function () {
Exif.getData(that.previewImg, function() { // 獲取影象的資料
Exif.getAllTags(this); // 獲取影象的全部資料,值以物件的方式返回
orientation = Exif.getTag(this, "Orientation"); // 獲取影象的拍攝方向
var rotateCanvas = document.createElement("canvas"),
rotateCtx = rotateCanvas.getContext("2d");
// 針對影象方向進行處理
switch (orientation) {
case 1 :
rotateCanvas.width = that.previewImg.width;
rotateCanvas.height = that.previewImg.height;
rotateCtx.drawImage(that.previewImg, 0, 0, that.previewImg.width, that.previewImg.height);
break;
case 6 : // 順時針 90 度
rotateCanvas.width = that.previewImg.height;
rotateCanvas.height = that.previewImg.width;
rotateCtx.translate(0, 0);
rotateCtx.rotate(90 * Math.PI / 180);
rotateCtx.drawImage(that.previewImg, 0, -that.previewImg.height, that.previewImg.width, that.previewImg.height);
break;
case 8 :
rotateCanvas.width = that.previewImg.height;
rotateCanvas.height = that.previewImg.width;
rotateCtx.translate(0, 0);
rotateCtx.rotate(-90 * Math.PI / 180);
rotateCtx.drawImage(that.previewImg, -that.previewImg.width, 0, that.previewImg.width, that.previewImg.height);
break;
case 3 : // 180 度
rotateCanvas.width = that.previewImg.width;
rotateCanvas.height = that.previewImg.height;
rotateCtx.translate(0, 0);
rotateCtx.rotate(Math.PI);
rotateCtx.drawImage(that.previewImg, -that.previewImg.width, -that.previewImg.height, that.previewImg.width, that.previewImg.height);
break;
default :
rotateCanvas.width = that.previewImg.width;
rotateCanvas.height = that.previewImg.height;
rotateCtx.drawImage(that.previewImg, 0, 0, that.previewImg.width, that.previewImg.height);
}
var rotateBase64 = rotateCanvas.toDataURL("image/jpeg", 0.5);
});
})
})
})
}
複製程式碼
移動圖片
對圖片和相框繫結@touchstart @touchmove @touchend
getInitPosition (e) {
event.preventDefault()
if (this.imgUrl) {
var length = e.touches.length
if (length > 1) {
let pointOne = e.touches[0]
let pointTwo = e.touches[1]
this.initTouchX = pointOne.clientX - pointTwo.clientX
this.initTouchY = pointOne.clientY - pointTwo.clientY
} else {
var touches = e.touches[0]
this.initTouchX = touches.clientX
this.initTouchY = touches.clientY
}
}
},
getMovePosition (e) {
event.preventDefault()
if (this.imgUrl) {
var length = e.touches.length
if (length > 1) {
let pointOne = e.touches[0]
let pointTwo = e.touches[1]
this.changeTouchX = pointOne.clientX - pointTwo.clientX
this.changeTouchY = pointOne.clientY - pointTwo.clientY
var scale = (this.changeTouchX - this.initTouchX) > (this.changeTouchY - this.initTouchY) ? (this.changeTouchX / this.initTouchX) : (this.changeTouchY / this.initTouchY)
scale *= this.myImg.lastScale
this.myImg.scale = scale > 3 ? 3 : scale < 0.5 ? 0.5 : scale
} else {
var touches = e.touches[0]
this.changeTouchX = touches.clientX - this.initTouchX
this.changeTouchY = touches.clientY - this.initTouchY
this.myImg.position.x = this.lastTouchX + (this.changeTouchX / this.myImg.scale)
this.myImg.position.y = this.lastTouchY + (this.changeTouchY / this.myImg.scale)
}
}
},
getLeavePosition (e) {
this.myImg.lastScale = this.myImg.scale
if (e.touches.length > 0) {
var touches = e.touches[0]
this.initTouchX = touches.clientX
this.initTouchY = touches.clientY
}
this.lastTouchX = this.myImg.position.x
this.lastTouchY = this.myImg.position.y
},
複製程式碼
合成圖片
createPhoto () {
if (this.imgUrl) {
let photoBox = document.querySelector('.photo-box')
newImgWidth = photoBox.style.offsetWidth
let newImgHeight = photoBox.style.offsetHeight
let scale = window.devicePixelRatio
let that = this
html2canvas(photoBox, {
width: newImgWidth,
height: newImgHeight,
scale: scale,
useCORS: true
}).then(function (canvas) {
var dataUrl = canvas.toDataURL('image/jpg')
localStorage.imgData = dataUrl
that.$router.push({
name: 'share',
params: {
storage: 'imgData'
}
})
})
} else {
alert('請上傳圖片')
}
}
複製程式碼
遇到的問題
- 在瀏覽器上阻止縮放的問題
在tounchmove時使用event.preventDefault() - 合成圖片的清晰度 在html2canvas寫引數時,scale = window.devicePixelRatio
- 對圖片進行縮放時,對距離的判斷
這裡需要區分兩種情況:- 兩指縮放
- 一指移動
在兩指縮放後會有一個手放手另一個手繼續操作的情況。這樣在touchend時,e.touches還存在一個元素。所以需要在這裡做一個判斷。
- 使用vue的:style="內聯樣式"時遇上的寫法問題
:style="{transform:'scale('+ myImg.scale+ ') translate('+myImg.position.x+'px,'+myImg.position.y+'px)'}" 複製程式碼