演示地址
源码地址
首先从元素拖拽开始,大概包含以下几个步骤
1.设置可拖拽目标(就是右边那两张图),设置它的draggable属性为true,实现元素的可拖拽
2.监听dragstart : 当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖拽的元素上
3.可以为拖拽操作设置反馈图标(可选),setDragImage,我这里图方便,就没有设置
4.监听dragenter:当拖拽元素进入目标元素时候触发(目标元素就是左边的框),这个事件作用于目标元素上
5.然后继续监听dragover:拖拽元素在目标元素上移动的时候触发,也是作用在目标元素上
6.drop事件:被拖拽的元素在目标元素上,并且鼠标松开鼠标时触发,这个作用在目标元素上
7.dragend:当拖拽完成后触发的事件,此事件作用在被拖拽元素上
8.event.preventDefault()方法:阻止默认的某些事件方法执行。在dragover中一定要执行preventDefault(),否则drop事件不会被触发。另外,如果是从其它引用软件或是文件夹中拖东西进来,尤其是图片的时候,默认的动作是显示这个图片或是相关信息,并不是真的执行drop。此时需要用document的dragover事件把它干掉
9.enevt.effectAllowed:拖拽的效果
源码如下:
// 图片拖拽功能
var $container = $('#ele'); //目标元素
var $dragItem = $('.drag-item'); // 可以拖动的元素
var eleDrag = null; //缓存当前被拖动的元素
var endPosition = {left : '', top : ''}; // 放开元素时的鼠标坐标,为了给在放开鼠标时定位用
监听拖拽元素
$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;//记录当前被拖动的元素
return true;
}).on('dragend',function(ev){
// 拖拽结束,清空缓存元素
eleDrag = null;
return false;
});
监听目标元素
$container.on('dragover',function(ev){
ev.preventDefault();
return true;
}).on('dragenter',function(ev){
// 给目标元素设置边框效果,提示元素进入
$(this).toggleClass('active');
return true;
}).on('drop',function(ev){
// 记录当前的坐标,为拖拽结束时,拉伸框定位用
endPosition.left = ev.originalEvent.x;
endPosition.top = ev.originalEvent.y;
if(eleDrag){
setHtml(eleDrag)
}
$(this).toggleClass('active');
});
// 这里是把拖拽元素,加上一些编辑效果,然后加入到目标元素里面
function setHtml(eleDrag){
// 这里用的是attr拿图片地址
// 其实也可以用 src = ev.originalEvent.dataTransfer.getData('url') getData来拿拖拽元素的url,不过这个就要放到drop事件里面才能拿到了
// https://developer.mozilla.org/zh-CN/docs/Web/API/DataTransfer/getData
var src = $(eleDrag).attr('src');
var $img = $('');
var $dragEle = $('');
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);
}
拖拽的效果到这里就结束了
接着说说图片移动,拉伸的实现
其实这个地方实现这个外框就行了,里面的图片根据外框拉伸
首先是布局,就是需要一个框,然后8个点,后面控制这8个点来进行拉伸。其实我们是没有必要为4个顶角单独来写方法,我们只需要同时调用左右移动&上下移动的方法就行了,所以这里只需要两个方法(左右移动,上下移动),详细的解释在源码里面有标示出来
最后就是把我们刚才做出来的效果,生成图片并且上传了
这个地方我使用了html2canvas这个库,它会先把dom节点转换成canvas,然后我们通过canvas的toDataURL返回包含图片展示的 data URI。并且这个方法还支持压缩,不过只能转换为jpeg的时候生效
然后我们就可以把这个data URI上传给后台了,下面是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文件夹的权限
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两个数之间的一个随机整数
}
return $str;
}
参考资料:
HTML5 drag & drop 拖拽与拖放简介
JS原生拖拽拖放事件
原生 JavaScript 图片裁剪效果
dataTransfer in jquery