基于JavaScript實(shí)現(xiàn)圖片剪切效果
學(xué)會如何獲取鼠標(biāo)的坐標(biāo)位置以及監(jiān)聽鼠標(biāo)的按下、拖動、松開等動作事件,從而實(shí)現(xiàn)拖動鼠標(biāo)來改變圖片大小。
還可以學(xué)習(xí)css中的clip屬性。
一、CSS實(shí)現(xiàn)圖片不透明及裁剪效果。
圖片剪切三層結(jié)構(gòu)
1、第一層opacity,給圖層設(shè)置透明度
2、第二層clip,clip屬性:對圖片進(jìn)行裁剪,實(shí)現(xiàn)圖像的一部分顯示,其他部分進(jìn)行隱藏
3、第三層選取框absolute(與第二層重疊的),包括八個觸點(diǎn)的效果
html代碼:
<div id="box"> <img src="img/1.jpg" id="img1" /> <img src="img/1.jpg" id="img2" /> <div id="main"> <div class="Divmin up-left"></div> <div class="Divmin up"></div> <div class="Divmin up-right"></div> <div class="Divmin right"></div> <div class="Divmin right-down"></div> <div class="Divmin down"></div> <div class="Divmin left-down"></div> <div class="Divmin left"></div> </div> </div>
css代碼:
body{ background: #333; } #box{ width: 500px; height: 380px; position: absolute; top: 100px; left: 200px; } #img1,#img2{ position: absolute; top: 0; left: 0; } #img1{ opacity: 0.3; } #img2{ clip: rect(0,200px,200px,0); } #main{ position: absolute;/*第三層需用絕對定位浮在上面*/ width: 200px; height: 200px; border: 1px solid #fff; } .Divmin{ position: absolute; width: 8px; height: 8px; background: #fff; } .up-left{margin-top: -4px;margin-left: -4px;cursor: nw-resize;} .up{ left: 50%;/*父元素盒子main寬度的一半,注意要有絕對定位*/ margin-left:-4px; top: -4px; cursor: n-resize; } .up-right{top: -4px;right: -4px;cursor: ne-resize;} .right{top: 50%;margin-top: -4px;right: -4px;cursor: e-resize;} .right-down{right: -4px;bottom: -4px;cursor: se-resize;} .down{bottom: -4px;left: 50%;margin-left: -4px;cursor: s-resize;} .left-down{left: -4px;bottom: -4px;cursor: sw-resize;} .left{left: -4px;top: 50%;margin-top: -4px;cursor: w-resize;}
二、javascript獲取選擇框偏移量
選擇框鼠標(biāo)拖動位置詳解:
offsetLeft:元素相對于其父元素左邊界的距離;
clientX:鼠標(biāo)位置的橫坐標(biāo);
clientWidth:元素的寬度;
offsetXY:是該事件發(fā)生的盒子模型里的坐標(biāo),與滾動條無關(guān)。
clientXY:是整個瀏覽器可用部分里的坐標(biāo),與滾動條無關(guān),即需要拖動滾動條才能看到的區(qū)域不考慮。
pageXY:是整個網(wǎng)頁里的坐標(biāo),與滾動條有關(guān)。
構(gòu)造一個getPosition()函數(shù),用于獲取元素相對于屏幕左邊及上邊的距離
js代碼如下:
//獲取元素相對于屏幕左邊及上邊的距離,利用offsetLeft function getPosition(el){ var left = el.offsetLeft; var top = el.offsetTop; var parent = el.offsetParent; while(parent != null){ left += parent.offsetLeft; top += parent.offsetTop; parent = parent.offsetParent; } return {"left":left,"top":top}; }
三、javascript實(shí)現(xiàn)控制觸點(diǎn)
監(jiān)聽鼠標(biāo)的按下、拖動、松開的事件控制選取框的大小。
注意區(qū)別:
Element.clientWidth 屬性表示元素的內(nèi)部寬度,以像素計。該屬性包括內(nèi)邊距,但不包括垂直滾動條(如果有的話)、邊框和外邊距。
即clientWidth不包括邊框,offsetWidth包括邊框
1)點(diǎn)擊右面的觸點(diǎn)
js代碼:
var mainDiv = $('main'); var rightDiv = $('right'); var isDraging = false; var contact = "";//表示被按下的觸點(diǎn) //鼠標(biāo)按下時 rightDiv.onmousedown = function(){ isDraging = true; contact = "right"; } //鼠標(biāo)松開時 window.onmouseup = function(){ isDraging = false; } //鼠標(biāo)移動時 window.onmousemove = function(e){ if(isDraging == true){ if(contact == "right"){ var e = e||window.event; var x = e.clientX;//鼠標(biāo)位置的橫坐標(biāo) var widthBefore = mainDiv.offsetWidth - 2;//選取框變化前的寬度 //var widthBefore = mainDiv.clientWidth; var addWidth = x - getPosition(mainDiv).left - widthBefore;//鼠標(biāo)移動后選取框增加的寬度 mainDiv.style.width = widthBefore + addWidth + 'px';//選取框變化后的寬度 } } } //獲取id的函數(shù) function $(id){ return document.getElementById(id); }
2)點(diǎn)擊上面觸點(diǎn)
點(diǎn)擊上面中間的觸點(diǎn)移動時,選取框的高度和左上角的位置都需要變化。
增加的高度=選取框相對于屏幕上面的距離 - 鼠標(biāo)位置的縱坐標(biāo)
選取框左上角的top值要減去增加的高度,因?yàn)槭髽?biāo)向上移動時高度增加,top值減小,下移時高度減小,top增大。
變化示意圖:
js代碼:
else if(contact == "up"){ var y = e.clientY;//鼠標(biāo)位置的縱坐標(biāo) var heightBefore = mainDiv.offsetHeight - 2;//選取框變化前的高度 var addHeight = getPosition(mainDiv).top - y;//增加的高度 mainDiv.style.height = heightBefore + addHeight + 'px';//選取框變化后的寬度 mainDiv.style.top = mainDiv.offsetTop - addHeight + 'px';//相當(dāng)于變化后左上角的縱坐標(biāo),鼠標(biāo)向上移縱坐標(biāo)減小,下移增大 }
3)點(diǎn)擊左邊觸點(diǎn)
原理同點(diǎn)擊上面觸點(diǎn),寬度和左邊的位置都會變化
變化示意圖:
js代碼:
else if(contact == "left"){ var widthBefore = mainDiv.offsetWidth - 2; var addWidth = getPosition(mainDiv).left - e.clientX;//增加的寬度等于距離屏幕左邊的距離減去鼠標(biāo)位置橫坐標(biāo) mainDiv.style.width = widthBefore + addWidth + 'px'; mainDiv.style.left = mainDiv.offsetLeft - addWidth + 'px';//左邊的距離(相當(dāng)于左邊位置橫坐標(biāo))等于選取框距父級元素的距離減去增加的寬度 }
4)點(diǎn)擊下面觸點(diǎn)
增加的寬度 = 鼠標(biāo)位置縱坐標(biāo) - 距屏幕上邊的距離 - 原先的寬度
左上角的位置不需改變
js代碼:
else if(contact = "down"){ var heightBefore = mainDiv.offsetHeight - 2; var addHeight = e.clientY - getPosition(mainDiv).top - mainDiv.offsetHeight; mainDiv.style.height = heightBefore + addHeight + 'px'; }
5)點(diǎn)四個角時的變化是高度和寬度變化的疊加,所以最好將上面四個變化的過程封裝成函數(shù),便于維護(hù)和代碼復(fù)用。
如果用if else 需要判斷8次,所以改為switch語句來簡化代碼
修改后的js代碼如下:
window.onmousemove = function(e){ var e = e||window.event; if(isDraging == true){ switch (contact){ case "up" : upMove(e);break; case "right" : rightMove(e);break; case "down" : downMove(e);break; case "left" : leftMove(e);break; case "up-right" : upMove(e);rightMove(e);break; case "down-right" : downMove(e);rightMove(e);break; case "down-left" : downMove(e);leftMove(e);break; case "up-left" : upMove(e);leftMove(e);break; } } } //獲取id的函數(shù) function $(id){ return document.getElementById(id); } //獲取元素相對于屏幕左邊及上邊的距離,利用offsetLeft function getPosition(el){ var left = el.offsetLeft; var top = el.offsetTop; var parent = el.offsetParent; while(parent != null){ left += parent.offsetLeft; top += parent.offsetTop; parent = parent.offsetParent; } return {"left":left,"top":top}; } //up移動 function upMove(e){ var y = e.clientY;//鼠標(biāo)位置的縱坐標(biāo) var heightBefore = mainDiv.offsetHeight - 2;//選取框變化前的高度 var addHeight = getPosition(mainDiv).top - y;//增加的高度 mainDiv.style.height = heightBefore + addHeight + 'px';//選取框變化后的寬度 mainDiv.style.top = mainDiv.offsetTop - addHeight + 'px';//相當(dāng)于變化后左上角的縱坐標(biāo),鼠標(biāo)向上移縱坐標(biāo)減小,下移增大 } //right移動 function rightMove(e){ var x = e.clientX;//鼠標(biāo)位置的橫坐標(biāo) var widthBefore = mainDiv.offsetWidth - 2;//選取框變化前的寬度 //var widthBefore = mainDiv.clientWidth; var addWidth = x - getPosition(mainDiv).left - widthBefore;//鼠標(biāo)移動后選取框增加的寬度 mainDiv.style.width = widthBefore + addWidth + 'px';//選取框變化后的寬度 } //down移動 function downMove(e){ var heightBefore = mainDiv.offsetHeight - 2; var addHeight = e.clientY - getPosition(mainDiv).top - mainDiv.offsetHeight; mainDiv.style.height = heightBefore + addHeight + 'px'; } //left移動 function leftMove(e){ var widthBefore = mainDiv.offsetWidth - 2; var addWidth = getPosition(mainDiv).left - e.clientX;//增加的寬度等于距離屏幕左邊的距離減去鼠標(biāo)位置橫坐標(biāo) mainDiv.style.width = widthBefore + addWidth + 'px'; mainDiv.style.left = mainDiv.offsetLeft - addWidth + 'px';//左邊的距離(相當(dāng)于左邊位置橫坐標(biāo))等于選取框距父級元素的距離減去增加的寬度 }
四、實(shí)現(xiàn)選取框區(qū)域明亮顯示
1)選取框內(nèi)的第二層圖片需重新設(shè)置其clip屬性
四個方面圖示:
js代碼:
//設(shè)置選取框圖片區(qū)域明亮顯示 function setChoice(){ var top = mainDiv.offsetTop; var right = mainDiv.offsetLeft + mainDiv.offsetWidth; var bottom = mainDiv.offsetTop + mainDiv.offsetHeight; var left = mainDiv.offsetLeft; img2.style.clip = "rect("+top+"px,"+right+"px,"+bottom+"px,"+left+"px)"; }
2)鼠標(biāo)移動時會導(dǎo)致圖片被選中,可在js代碼中添加一行代碼使其禁止圖片被選中
//禁止圖片被選中 document.onselectstart = new Function('event.returnValue = false;');
也可以在css樣式里添加 *{user-select:none}
意思是文本不可選中,對圖片跟div有一樣的效果。
五、實(shí)現(xiàn)選取框位置可拖動
首先要阻止事件冒泡
js代碼如下:
//鼠標(biāo)按下觸點(diǎn)時 rightDiv.onmousedown = function(e){ e.stopPropagation(); isDraging = true; contact = "right"; }
鼠標(biāo)拖拽效果的實(shí)現(xiàn)可見另一篇隨筆http://www.cnblogs.com/vampire170204/p/6422914.html
六、實(shí)現(xiàn)圖片剪切區(qū)域預(yù)覽
新增一個圖片預(yù)覽區(qū)域的div
html代碼:
<div id="preview"> <img src="img/1.jpg" id="img3" /> </div>
css代碼:
#preview{ position: absolute; width: 500px; height: 380px; top: 100px; left:710px ; } #preview #img3{position: absolute;}
注意:要讓clip:rect(top,right,bottom,left) 起作用,必須讓作用元素為相對/絕對定位。
js部分同樣是利用clip屬性,和setChoice()函數(shù)同時被調(diào)用
同時為了讓右邊預(yù)覽區(qū)的左上角位置固定,需要設(shè)置其top和left的值
//右邊圖片預(yù)覽函數(shù) function setPreview(){ var top = mainDiv.offsetTop; var right = mainDiv.offsetLeft + mainDiv.offsetWidth; var bottom = mainDiv.offsetTop + mainDiv.offsetHeight; var left = mainDiv.offsetLeft; var img3 = $('img3'); img3.style.top = -top + 'px'; img3.style.left = -left + 'px'; img3.style.clip = "rect("+top+"px,"+right+"px,"+bottom+"px,"+left+"px)"; }
以上所述是小編給大家介紹的基于JavaScript實(shí)現(xiàn)圖片剪切效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- js實(shí)現(xiàn)點(diǎn)擊后將文字或圖片復(fù)制到剪貼板的方法
- php+js實(shí)現(xiàn)圖片的上傳、裁剪、預(yù)覽、提交示例
- js+jquery實(shí)現(xiàn)圖片裁剪功能
- jquery imgareaselect 使用利用js與程序結(jié)合實(shí)現(xiàn)圖片剪切
- 使用JavaScript+canvas實(shí)現(xiàn)圖片裁剪
- 基于原生JS實(shí)現(xiàn)圖片裁剪
- javascript 圖片裁剪技巧解讀
- JS實(shí)現(xiàn)圖片剪裁并預(yù)覽效果
- 利用Javascript裁剪圖片并存儲的簡單實(shí)現(xiàn)
相關(guān)文章
js實(shí)現(xiàn)頁面轉(zhuǎn)發(fā)功能示例代碼
本文為大家介紹的是使用js實(shí)現(xiàn)頁面轉(zhuǎn)發(fā),具體實(shí)現(xiàn)如下,感興趣的朋友可以參考下,希望對大家有所幫助2013-08-08微信小程序?qū)崿F(xiàn)的動態(tài)設(shè)置導(dǎo)航欄標(biāo)題功能示例
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)的動態(tài)設(shè)置導(dǎo)航欄標(biāo)題功能,結(jié)合實(shí)例形式分析了微信小程序使用wx.setNavigationBarTitle接口動態(tài)設(shè)置導(dǎo)航欄標(biāo)題的相關(guān)操作技巧,需要的朋友可以參考下2019-01-01