利用拖拽&html转canvas,实现一个图片生成的小功能

利用拖拽&html转canvas,实现一个图片生成的小功能_第1张图片
最终效果

演示地址
源码地址

首先从元素拖拽开始,大概包含以下几个步骤

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); }

拖拽的效果到这里就结束了

接着说说图片移动,拉伸的实现

其实这个地方实现这个外框就行了,里面的图片根据外框拉伸

利用拖拽&html转canvas,实现一个图片生成的小功能_第2张图片

首先是布局,就是需要一个框,然后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

你可能感兴趣的:(利用拖拽&html转canvas,实现一个图片生成的小功能)