演示地址
源碼地址
首先從元素拖拽開始祥国,大概包含以下幾個(gè)步驟
1.設(shè)置可拖拽目標(biāo)(就是右邊那兩張圖),設(shè)置它的draggable屬性為true,實(shí)現(xiàn)元素的可拖拽
2.監(jiān)聽dragstart : 當(dāng)拖拽元素開始被拖拽的時(shí)候觸發(fā)的事件铁坎,此事件作用在被拖拽的元素上
3.可以為拖拽操作設(shè)置反饋圖標(biāo)(可選),setDragImage,我這里圖方便往核,就沒(méi)有設(shè)置
4.監(jiān)聽dragenter:當(dāng)拖拽元素進(jìn)入目標(biāo)元素時(shí)候觸發(fā)(目標(biāo)元素就是左邊的框),這個(gè)事件作用于目標(biāo)元素上
5.然后繼續(xù)監(jiān)聽dragover:拖拽元素在目標(biāo)元素上移動(dòng)的時(shí)候觸發(fā)蹬跃,也是作用在目標(biāo)元素上
6.drop事件:被拖拽的元素在目標(biāo)元素上,并且鼠標(biāo)松開鼠標(biāo)時(shí)觸發(fā)铆铆,這個(gè)作用在目標(biāo)元素上
7.dragend:當(dāng)拖拽完成后觸發(fā)的事件蝶缀,此事件作用在被拖拽元素上
8.event.preventDefault()方法:阻止默認(rèn)的某些事件方法執(zhí)行。在dragover中一定要執(zhí)行preventDefault(),否則drop事件不會(huì)被觸發(fā)薄货。另外翁都,如果是從其它引用軟件或是文件夾中拖東西進(jìn)來(lái),尤其是圖片的時(shí)候谅猾,默認(rèn)的動(dòng)作是顯示這個(gè)圖片或是相關(guān)信息柄慰,并不是真的執(zhí)行drop。此時(shí)需要用document的dragover事件把它干掉
9.enevt.effectAllowed:拖拽的效果
源碼如下:
// 圖片拖拽功能
var $container = $('#ele'); //目標(biāo)元素
var $dragItem = $('.drag-item'); // 可以拖動(dòng)的元素
var eleDrag = null; //緩存當(dāng)前被拖動(dòng)的元素
var endPosition = {left : '', top : ''}; // 放開元素時(shí)的鼠標(biāo)坐標(biāo)税娜,為了給在放開鼠標(biāo)時(shí)定位用
監(jiān)聽拖拽元素
$dragItem.on('selectstart',function(){//拖拽元素不可選擇坐搔,避免選擇到一些文本信息之類的
return false;
}).on('dragstart',function(ev){
// 拖拽開始 jquery里面需要使用ev.originalEvent.dataTransfer 原生js使用ev.dataTransfer就行了
ev.originalEvent.dataTransfer.effectAllowed = 'move';
eleDrag = ev.target;//記錄當(dāng)前被拖動(dòng)的元素
return true;
}).on('dragend',function(ev){
// 拖拽結(jié)束,清空緩存元素
eleDrag = null;
return false;
});
監(jiān)聽目標(biāo)元素
$container.on('dragover',function(ev){
ev.preventDefault();
return true;
}).on('dragenter',function(ev){
// 給目標(biāo)元素設(shè)置邊框效果,提示元素進(jìn)入
$(this).toggleClass('active');
return true;
}).on('drop',function(ev){
// 記錄當(dāng)前的坐標(biāo)敬矩,為拖拽結(jié)束時(shí)概行,拉伸框定位用
endPosition.left = ev.originalEvent.x;
endPosition.top = ev.originalEvent.y;
if(eleDrag){
setHtml(eleDrag)
}
$(this).toggleClass('active');
});
// 這里是把拖拽元素,加上一些編輯效果弧岳,然后加入到目標(biāo)元素里面
function setHtml(eleDrag){
// 這里用的是attr拿圖片地址
// 其實(shí)也可以用 src = ev.originalEvent.dataTransfer.getData('url') getData來(lái)拿拖拽元素的url,不過(guò)這個(gè)就要放到drop事件里面才能拿到了
// https://developer.mozilla.org/zh-CN/docs/Web/API/DataTransfer/getData
var src = $(eleDrag).attr('src');
var $img = $('<img>');
var $dragEle = $('<div>');
var directionBtn = $('.cacheEle').html();
$img.attr('src',$(eleDrag).attr('src')).attr('data-type','drag');
$dragEle.addClass('drag').attr('data-type','drag').html($img).append(directionBtn);
$dragEle.css({
'left' : endPosition.left - (100/2),
'top' : endPosition.top - (100/2),
});
$container.append($dragEle);
}
拖拽的效果到這里就結(jié)束了
接著說(shuō)說(shuō)圖片移動(dòng)凳忙,拉伸的實(shí)現(xiàn)
其實(shí)這個(gè)地方實(shí)現(xiàn)這個(gè)外框就行了,里面的圖片根據(jù)外框拉伸
首先是布局禽炬,就是需要一個(gè)框步淹,然后8個(gè)點(diǎn)暑塑,后面控制這8個(gè)點(diǎn)來(lái)進(jìn)行拉伸健民。其實(shí)我們是沒(méi)有必要為4個(gè)頂角單獨(dú)來(lái)寫方法憾朴,我們只需要同時(shí)調(diào)用左右移動(dòng)&上下移動(dòng)的方法就行了,所以這里只需要兩個(gè)方法(左右移動(dòng)热幔,上下移動(dòng)),詳細(xì)的解釋在源碼里面有標(biāo)示出來(lái)
最后就是把我們剛才做出來(lái)的效果乐设,生成圖片并且上傳了
這個(gè)地方我使用了html2canvas這個(gè)庫(kù),它會(huì)先把dom節(jié)點(diǎn)轉(zhuǎn)換成canvas,然后我們通過(guò)canvas的toDataURL返回包含圖片展示的 data URI断凶。并且這個(gè)方法還支持壓縮伤提,不過(guò)只能轉(zhuǎn)換為jpeg的時(shí)候生效
然后我們就可以把這個(gè)data URI上傳給后臺(tái)了巫俺,下面是php的代碼
$file = $_POST['base64'];
$tmp = base64_decode($file);
$randStr = getRandChar(5);
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $file, $result)){
$type = $result[2];
$new_file = "./upload/".$randStr.".{$type}";//這里要注意upload文件夾的權(quán)限
if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $file)))){
echo '新文件保存成功:', $new_file;
}
}
function getRandChar($length){
$str = null;
$strPol = "0123456789abcdefghijklmnopqrstuvwxyz";
$max = strlen($strPol)-1;
for($i=0;$i<$length;$i++){
$str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max兩個(gè)數(shù)之間的一個(gè)隨機(jī)整數(shù)
}
return $str;
}
參考資料:
HTML5 drag & drop 拖拽與拖放簡(jiǎn)介
JS原生拖拽拖放事件
原生 JavaScript 圖片裁剪效果
dataTransfer in jquery