国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網(wǎng)站 > WEB開發(fā) > 正文

HTML5自助切圖

2024-04-27 14:59:04
字體:
供稿:網(wǎng)友
HTML5自助切圖   三聯(lián)教程

  享受生活,熱愛重構(gòu),大家好,我是Json。

  在現(xiàn)在這個(gè)到處是HTML5話題的時(shí)代,好像不懂點(diǎn)HTML5都有點(diǎn)落伍。那我也跟上潮流一把吧,今天給大家分享的是基于HTML5的自助切圖。

  在組里經(jīng)常會(huì)被某設(shè)計(jì)師叫切板仔,確實(shí)重構(gòu)很大一部分工作都花在切圖上,而如何提高切圖效率或者讓切圖自助化也是我們重構(gòu)師的追求。基于這個(gè)前提我自己抱著研究的心態(tài),使用HTML5大致實(shí)現(xiàn)了一下。一開始覺得HTML5是個(gè)很神秘很高深的東西,其實(shí)當(dāng)你去了解他,你會(huì)發(fā)現(xiàn)他是很空虛,且很容易上…………….手的。

  這里使用到的HTML5技術(shù)包括:

  本地預(yù)覽(FileReader)

  拖拽(drag & drop)

  切圖(canvas)

  拖拽:

  拖拽基本事件如下:

DataTransfer 對(duì)象 退拽對(duì)象用來傳遞的媒介,使用一般為Event.dataTransfer。
draggable 屬性 就是標(biāo)簽元素要設(shè)置draggable=true,否則不會(huì)有效果,例如: <div title=”拖拽我” draggable=”true”&rt;列表1</div:rt;</td&rt;
ondragstart 事件 當(dāng)拖拽元素開始被拖拽的時(shí)候觸發(fā)的事件,此事件作用在被拖曳元素上
ondragenter 事件 當(dāng)拖曳元素進(jìn)入目標(biāo)元素的時(shí)候觸發(fā)的事件,此事件作用在目標(biāo)元素上
ondragover 事件 拖拽元素在目標(biāo)元素上移動(dòng)的時(shí)候觸發(fā)的事件,此事件作用在目標(biāo)元素上
ondrop 事件 被拖拽的元素在目標(biāo)元素上同時(shí)鼠標(biāo)放開觸發(fā)的事件,此事件作用在目標(biāo)元素上
ondragend 事件 當(dāng)拖拽完成后觸發(fā)的事件,此事件作用在被拖曳元素上
drageleave事件 當(dāng)拖拽離開此處時(shí)觸發(fā),只在離開這個(gè)對(duì)象時(shí)觸發(fā)一次,此事件作用在目標(biāo)元素上
Event.PReventDefault() 方法 阻止默認(rèn)的些事件方法等執(zhí)行。在ondragover中一定要執(zhí)行preventDefault(),否則ondrop事件不會(huì)被觸發(fā)。另外,如果是從其他應(yīng)用軟件或是文件中拖東西進(jìn)來,尤其是圖片的時(shí)候,默認(rèn)的動(dòng)作是顯示這個(gè)圖片或是相關(guān)信息,并不是真的執(zhí)行drop。此時(shí)需要用用document的ondragover事件把它直接干掉。
Event.effectAllowed 屬性 就是拖拽的效果。

  圖1是頁面上所使用到拖拽的地方。左圖為拖拽上傳圖片,右圖為拖拽參考線。

  介紹完拖拽基本事件后,再來看下頁面是如何通過拖拽將本地圖片通過拖拽的方式拖到頁面指定區(qū)域使用圖片上傳,這也是拖拽現(xiàn)在比較常用到的功能。

  給document增加拖拽事件,當(dāng)拖拽元素進(jìn)入頁面時(shí)改變目標(biāo)元素樣式提示用戶目標(biāo)元素位置,當(dāng)拖拽元素離開頁面后還原樣式。代碼如下:

  document.ondragleave = function(e){

  e.preventDefault();

  var el = document.getElementById('target_box');

  el.className = el.className.replace(/over/g,'');

  }

  document.ondrop = function(e){

  e.preventDefault();

  }

  document.ondragenter = function(e){

  e.preventDefault();

  var el = document.getElementById('target_box');

  el.className = el.className + ' over';

  }

  document.ondragover = function(e){

  e.preventDefault();

  var el = document.getElementById('target_box');

  el.className = el.className + ' over';

  }

  當(dāng)圖片被拖到上傳區(qū)域后通過FileReader方法讀取本地文件,然后將圖片通過canvas來繪制,如果圖片的寬度是大于畫布1000px將水平居中處理,這里因?yàn)榍袌D的時(shí)候需要將圖片完整切出來,所以在設(shè)置canvas寬度時(shí)需要顯示成圖片的大小,所以這里使用了負(fù)marginLeft(這里將圖片寬度減1000得出超出1000的區(qū)域,然后再除于2得出marginLeft的值)外面套一層1000px的方式來實(shí)現(xiàn)水平居中。代碼如下:

  var box = document.getElementById('target_box');

  box.ondrop = function(e){

  e.preventDefault();

  //獲取文件列表

  var fileList = e.dataTransfer.files;

  var reader = new FileReader();

  reader.onload = function(e){

  var img = new Image();

  img.src = this.result;

  img.onload = function(){

  if(this.width>1000){

  canvas.style.marginLeft = ((this.width - 1000)/2) * -1 + 'px';

  }

  canvas.width = this.width;

  canvas.height = this.height;

  ctx.drawImage(this,0,0);

  }

  }

  reader.readAsDataURL(fileList[0]);

  document.getElementById('target_box').style.display = 'none';

  document.getElementById('doc').style.display = 'display';

  };

  本地預(yù)覽(FileReader)

FileReader接口的方法
readAsBinaryString(file) 將文件讀取二進(jìn)制碼
通常我們將它傳送到后端,后端可以通過這段字符串存儲(chǔ)文件
readAsText(file,[encoding]) 將文件讀取文本
第二個(gè)參數(shù)是文本的編碼方式,默認(rèn)UTF-8
readAsDataURL(file) 將文件讀取為DataURL
將文件讀取為一串Data URL字符串,將小文件以一種特殊格式的URL地址直接讀入頁面。小文件指圖像與html等格式的文件。
FileReader接口的事件
onabort 數(shù)據(jù)讀取中斷時(shí)觸發(fā)
onerror 數(shù)據(jù)讀取出錯(cuò)時(shí)觸發(fā)
onloadstart 數(shù)據(jù)讀取開始時(shí)觸發(fā)
onprocess 數(shù)據(jù)讀取中
onload 數(shù)據(jù)讀取成功完成時(shí)觸發(fā)
onloadend 數(shù)據(jù)讀取完成時(shí)觸發(fā),無論成功失敗

  這里因?yàn)闃?biāo)尺不需要做任何事情處理只需要拖拽效果,所以只需要增加draggable屬性就可以,代碼如下:

  然后給目標(biāo)元素增加Drop事件,當(dāng)拖拽的標(biāo)尺在目標(biāo)元素上放開時(shí)新建一個(gè)參考線并通過offsetY來獲取鼠標(biāo)釋放時(shí)的Y坐標(biāo),然后再將這個(gè)Y坐標(biāo)存到數(shù)組里。

  //增加標(biāo)尺目標(biāo)事件

  document.getElementById('cvs').ondrop = function(ev){

  var div = document.createElement('div');

  div.style.width = '100%'

  div.style.height = '1px';

  div.style.background = '#4affff';

  div.style.position = 'absolute'

  div.style.top = ev.offsetY + 18 + 'px';

  document.getElementById('screen').appendChild(div);

  rulerTop.push(ev.offsetY);

  return false;

  }

  Canvas:

  這里先介紹下canvas的drawImage方法,切圖的核心方法就是這個(gè),我們先來看看官方給出的使用方法與解釋:

  drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight)

image 所要繪制的圖像。這必須是表示 #FormatImgID_3# 標(biāo)記或者屏幕外圖像的 Image 對(duì)象,或者是 Canvas 元素。
sourceX, sourceY 圖像將要被繪制的區(qū)域的左上角。這些整數(shù)參數(shù)用圖像像素來度量。
sourceWidth, sourceHeight 圖像所要繪制區(qū)域的大小,用圖像像素表示。
destX, destY 所要繪制的圖像區(qū)域的左上角的畫布坐標(biāo)。
destWidth, destHeight 圖像區(qū)域所要繪制的畫布大小。

  了解了drawImage方法后我們來看下,如何通過drawImage達(dá)到切圖效果,其實(shí)這里的切圖,只是通過drawImage加上高寬和偏移量來實(shí)現(xiàn)所謂的切圖效果,代碼如下:

  //繪制圖片

  function scaleCanvas (canvas, width, height, destX, destY) {

  var w = canvas.width,

  h = canvas.height;

  var cutCanvas = document.createElement('canvas');

  var cutCtx = cutCanvas.getContext('2d');

  cutCanvas.width = width;

  cutCanvas.height = height;

  cutCtx.drawImage(canvas, 0, 0, w, h, destX, destY, w, h);

  return cutCanvas;

  }

  //獲取圖片URL

  function getDataURL (canvas, width, height, destX, destY) {

  canvas = scaleCanvas(canvas, width, height, destX, destY);

  return canvas.toDataURL('image/jpeg');

  }

  //將conver轉(zhuǎn)成IMG格式

  var convertToImage = function (canvas, width, height, destX, destY) {

  var strData = getDataURL(canvas, width, height, destX, destY);

  return encodeURIComponent(strData);

  }

  這里先說下大致實(shí)現(xiàn)的原理,首先先創(chuàng)建一個(gè)新的canvas然后設(shè)置好寬高,而這個(gè)寬高就是參考線分隔的每一塊寬高,然后過通drawImage將原圖上某塊局域復(fù)制一份出來,再通過toDataURL轉(zhuǎn)成base64編碼方便本地顯示。

  所在在這個(gè)Demo中image就是我們剛上傳的那個(gè)圖片,sourceX、sourceY和destWidth、destHeight取圖片的原始高寬,而我們要復(fù)制的局域也是從新的canvas上的左上角開始,所以這里的sourceX、sourceY為0,0。這里最主要的就是destX、destY,就是他們來控制復(fù)制局域的起始坐標(biāo),因?yàn)樾聢D片是需要從最左邊開始復(fù)制,所以destX為0,而destY將根據(jù)參考線的縱坐標(biāo)來定值。

  這里要注意一下,因?yàn)橛虻膯栴},所以如果頁面不是放到服務(wù)器上運(yùn)行而是本地運(yùn)行的話會(huì)出現(xiàn)權(quán)限報(bào)錯(cuò)情況

  最后附上Demo一枚,歡迎大家盡情的暴、使勁暴。(Demo只支持Chrome瀏覽器,其他瀏覽器會(huì)有不良反應(yīng),請(qǐng)見諒)

  好了,整個(gè)HTML5自助化切圖的主要代碼就這些,這里第一次嘗試用HTML5去做一些實(shí)實(shí)在在的東西,可能代碼并不是最優(yōu),還能繼續(xù)優(yōu)化,大家如果對(duì)于文章有什么建議或不明白的地方歡迎討論。

  在舊版的切圖工具里,我們的做法是將圖片上傳到服務(wù)器,然后通過服務(wù)器端把圖片切好后把對(duì)應(yīng)的地址返回,前端再把頁面顯示出來。這樣的做法會(huì)導(dǎo)致在網(wǎng)絡(luò)慢時(shí)出現(xiàn)長(zhǎng)時(shí)間的等待,而如果頁面放棄這里的操作,還需要將圖片從服務(wù)器端刪除掉。在拖拽參考線時(shí)也只能通過大量的代碼去實(shí)現(xiàn),還需要編寫一些服務(wù)器端代碼。

  HTML5版相對(duì)有響應(yīng)速度快(本地讀取)、拖拽功能簡(jiǎn)單、前端切圖不需要依賴服務(wù)器,減少開發(fā)成本。

  反正HTML5是個(gè)上流、好玩、有趣、簡(jiǎn)單的好東西,值得你一生擁有。

  寫完文章已經(jīng)凌晨?jī)牲c(diǎn)半,根據(jù)官方和非官方統(tǒng)計(jì),這個(gè)時(shí)間段被坑機(jī)率是平時(shí)的0.000001%,實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)。而為了檢驗(yàn)這個(gè)標(biāo)準(zhǔn)我?guī)еv的身軀,打開客戶端進(jìn)入匹配模式。

  裸多蘭一級(jí)升E下路孤獨(dú)神級(jí)大嘴再次上路,德瑪西亞。。。

:更多精彩教程請(qǐng)關(guān)注三聯(lián)網(wǎng)頁設(shè)計(jì)教程 欄目,


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 英吉沙县| 灵丘县| 当雄县| 平和县| 平阳县| 油尖旺区| 城口县| 太和县| 高安市| 盈江县| 龙山县| 乐业县| 西乌珠穆沁旗| 开原市| 怀化市| 金湖县| 新乡县| 织金县| 乐至县| 福清市| 绥中县| 自贡市| 绩溪县| 桃源县| 中阳县| 和林格尔县| 克拉玛依市| 千阳县| 长乐市| 威海市| 佛冈县| 丁青县| 泸水县| 西乡县| 忻州市| 太保市| 佛山市| 白城市| 古田县| 大渡口区| 离岛区|