最近在做一個項目,需要實現類似QQ截圖后,就是能夠在富文本編輯器中粘貼截圖並預覽。
先看一下效果:
分析一下實現步驟:
- QQ截圖后在編輯器中粘貼,肯定會有一個粘貼事件,即
paste
事件 - 在事件回調函數中對前端進行圖片的一次壓縮
- 前端壓縮多是使用canvas,返回的是base64,這里我使用了一個
localResizeIMG.js
的插件 - 將生成好的base64傳給后台,后台可以進行圖片的第二次壓縮,但是感覺沒必要
- 后台先得到七牛雲的upToken,即一個上傳的憑證,然后執行七牛sdk提供的上傳函數
接下來,一步步的來實現:
瀏覽器paste
事件
這個paste
事件的兼容性不是很好,但是可以對用戶做友好提示,如果不能使用剪切板事件的話,就在dialog中上傳圖片也是可以的。
當QQ截圖之后,在富文本編輯器中右鍵黏貼或者CTRL V就會觸發這個事件,這個事件有一個clipboardData
屬性,
這里面就是跟paste
有關的數據了。詳細知識可以看這一篇博文http://m.jb51.net/show/80657
我就直接復制粘貼一把梭了,>_>)
function paste(event) {
var clipboardData = event.clipboardData;
var items, item, types;
if (clipboardData) {
items = clipboardD
a//ta.items;
if (!items) {
return;
}
// 保存在剪貼板中的數據類型
types = clipboardData.types || [];
for (var i = 0; i < types.length; i++) {
if (types[i] === 'Files') {
item = items[i];
break;
}
}
// 判斷是否為圖片數據
if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
// 讀取該圖片
var file = item.getAsFile(),
reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
var image = reader.result;
}
}
}
}
//綁定事件
$('#editormd').on('paste', paste);
localResizeIMG.js
的使用
這是一個前端壓縮的插件,項目地址是https://github.com/think2011/localResizeIMG,
兼容IE10以上,所以還得做個IE版本判斷,然后看自己是否需要使用干這個插件,我這里就不寫IE的判斷了。
使用方法也很簡單,lrz方法接受一個文件路徑或者base64的圖片,可以設置一個壓縮寬度的對象,低於這個寬度的圖片不會壓縮,大於這個寬度的就會壓縮,然后在then
方法中取得壓縮后的圖片:
得先引入這個插件,可以使用src
引入,也支持amd or cmd模塊化
<script src="./dist/lrz.bundle.js"></script>
接着開始使用:
//image就是經過paste事件后得到的圖片
lrz(image, {width: 1080}).then(function (res) {
var base64 = res.base64;
}
七牛雲sdk
七牛雲注冊好像就送10G的雲儲存,需要的可以去注冊,先下載七牛雲sdk,我使用的是php,地址https://developer.qiniu.com/kodo/sdk/php
配置這個上傳的文件也很簡單。將下載后的壓縮包解壓,刪掉一下沒用的文件,然后拖到項目中
uploadImageToQiliu.php:
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
// 引入上傳類
use Qiniu\Storage\UploadManager;
$accessKey = '你的accessKey';
$secretKey = '你的secretKey';
// 初始化簽權對象。
$auth = new Auth($accessKey, $secretKey);
$bucket = "空間名字";
$upToken = $auth->uploadToken($bucket);
// 初始化 UploadManager 對象並進行文件的上傳。
$uploadMgr = new UploadManager();
$key = $_POST['name'];
$filePath = $_POST['image'];
list($ret, $err) = $uploadMgr->putFile($upToken, $key, $filePath);
if ($err !== null) {
echo json_encode($err);
} else {
echo json_encode($ret);
}
accessKey
和secretKey
注冊后就可以看到,bucket
是雲儲存空間名字,下圖的nuc-web-images
接下來是前台傳圖片和圖片名給后台,圖片名我就直接用 new Date().getTime()
了
$.ajax({
url: './apis/qiniu-sdk/myApis/uploadImageToQiliu.php',
type: 'post',
data: {
"image": res.base64,
"name": new Date().getTime()
},
contentType: 'application/x-www-form-urlencoded;charest=UTF-8',
success: function (data) {
var imageName;
try {
imageName = JSON.parse(data).key;
} catch (e) {
alert(e.toString);
}
var qiniuUrl = '';
testEditor.insertValue(qiniuUrl);
}
})
testEditor
是我使用的markdown編輯器的對象實例,testEditor.insertValue(qiniuUrl);
就是把格式化好的markdown語句插到光標處。
整個前端代碼如下:
function paste(event) {
var clipboardData = event.clipboardData;
var items, item, types;
if (clipboardData) {
items = clipboardData.items;
if (!items) {
return;
}
// 保存在剪貼板中的數據類型
types = clipboardData.types || [];
for (var i = 0; i < types.length; i++) {
if (types[i] === 'Files') {
item = items[i];
break;
}
}
// 判斷是否為圖片數據
if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
// 讀取該圖片
var file = item.getAsFile(),
reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
//前端壓縮
lrz(reader.result, {width: 1080}).then(function (res) {
$.ajax({
url: './apis/qiniu-sdk/myApis/uploadImageToQiliu.php',
type: 'post',
data: {
"image": res.base64,
"name": new Date().getTime()
},
contentType: 'application/x-www-form-urlencoded;charest=UTF-8',
success: function (data) {
var imageName;
try {
imageName = JSON.parse(data).key;
} catch (e) {
alert(e.toString);
}
var qiniuUrl = '';
testEditor.insertValue(qiniuUrl);
}
})
});
}
}
}
}
$('#editormd').on('paste', paste);
另外這個markdown編輯器也是開源的,項目地址是:https://github.com/pandao/editor.md