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

最终效果

演示地址
源码地址

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

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 = $('<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);
}

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

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

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


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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 之前写过一篇浏览器事件的相关操作和事件运行的原理——JavaScript浏览器事件解析。这一篇主要写一些常用的事件...
    faremax阅读 1,644评论 0 0
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,820评论 25 708
  • 有人说,青春是灰色的。整天在辅导书、试卷中埋头苦学,看不见前方的道路……有人说,青春是红色的。整天吃喝玩乐,醉生梦...
    1望天涯1阅读 585评论 0 3
  • 人,总在安静时,想的很多。或许,生活中遭遇了冷落或挫折,浮躁纠结,但一个人的时候,在闭上眼睛的瞬间,你总能听到心的...
    茉言心语阅读 374评论 0 2
  • 妇女节画个美好的姑娘~
    赵莲贵阅读 647评论 0 4