利用拖拽&html轉(zhuǎn)canvas垮刹,實(shí)現(xiàn)一個(gè)圖片生成的小功能

最終效果

演示地址
源碼地址

首先從元素拖拽開始祥国,大概包含以下幾個(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末认烁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌却嗡,老刑警劉巖舶沛,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異窗价,居然都是意外死亡如庭,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門撼港,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)坪它,“玉大人,你說(shuō)我怎么就攤上這事帝牡⊥保” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵靶溜,是天一觀的道長(zhǎng)开瞭。 經(jīng)常有香客問(wèn)我,道長(zhǎng)罩息,這世上最難降的妖魔是什么嗤详? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮瓷炮,結(jié)果婚禮上葱色,老公的妹妹穿的比我還像新娘。我一直安慰自己娘香,他們只是感情好冬筒,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著茅主,像睡著了一般舞痰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诀姚,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天响牛,我揣著相機(jī)與錄音,去河邊找鬼赫段。 笑死呀打,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的糯笙。 我是一名探鬼主播贬丛,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼给涕!你這毒婦竟也來(lái)了豺憔?” 一聲冷哼從身側(cè)響起额获,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎恭应,沒(méi)想到半個(gè)月后抄邀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昼榛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年境肾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胆屿。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奥喻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出非迹,到底是詐尸還是另有隱情衫嵌,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布彻秆,位于F島的核電站楔绞,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏唇兑。R本人自食惡果不足惜酒朵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扎附。 院中可真熱鬧蔫耽,春花似錦、人聲如沸留夜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)碍粥。三九已至鳖眼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嚼摩,已是汗流浹背钦讳。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枕面,地道東北人愿卒。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像潮秘,于是被迫代替她去往敵國(guó)和親琼开。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 之前寫過(guò)一篇瀏覽器事件的相關(guān)操作和事件運(yùn)行的原理——JavaScript瀏覽器事件解析枕荞。這一篇主要寫一些常用的事件...
    faremax閱讀 1,605評(píng)論 0 0
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,734評(píng)論 25 707
  • 有人說(shuō)柜候,青春是灰色的搞动。整天在輔導(dǎo)書、試卷中埋頭苦學(xué)改橘,看不見前方的道路……有人說(shuō),青春是紅色的玉控。整天吃喝玩樂(lè)飞主,醉生夢(mèng)...
    1望天涯1閱讀 571評(píng)論 0 3
  • 人,總在安靜時(shí)高诺,想的很多碌识。或許虱而,生活中遭遇了冷落或挫折筏餐,浮躁糾結(jié),但一個(gè)人的時(shí)候牡拇,在閉上眼睛的瞬間魁瞪,你總能聽到心的...
    茉言心語(yǔ)閱讀 356評(píng)論 0 2
  • 婦女節(jié)畫個(gè)美好的姑娘~
    趙蓮貴閱讀 640評(píng)論 0 4