欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

jQuery實(shí)現(xiàn)模擬flash頭像裁切上傳功能示例

 更新時(shí)間:2016年12月11日 14:25:26   作者:wangmeijian  
這篇文章主要介紹了jQuery實(shí)現(xiàn)模擬flash頭像裁切上傳功能,結(jié)合實(shí)例形式分析了jQuery圖像剪切與文件傳輸相關(guān)操作技巧,需要的朋友可以參考下

本文實(shí)例講述了jQuery實(shí)現(xiàn)模擬flash頭像裁切上傳功能。分享給大家供大家參考,具體如下:

是的,jq已經(jīng)有類(lèi)似的插件了,或者干脆用flash算了,為什么我還要自己寫(xiě)?因?yàn)樵欤╳o)輪(bu)子(hui)也(flash)是一個(gè)學(xué)習(xí)的過(guò)程,輪子不會(huì)造,將來(lái)怎么造飛機(jī)?先來(lái)一張最終效果圖:

一、大概思路

用js來(lái)做這個(gè)效果,先得將圖片A上傳到服務(wù)器,關(guān)于異步上傳的插件有很多,不用插件也可以參考本人上一篇博客用純js的方式上傳,上傳之后顯示到頁(yè)面里,由于上傳的圖片尺寸各不相同,要完整地顯示圖片,就要將上傳后的圖片用css控制按比例縮放顯示,然后通過(guò)矩形選框選擇需要的部分,用js獲取矩形選框的左上角坐標(biāo),加上選框的寬高按比例計(jì)算后傳給后臺(tái),后臺(tái)程序根據(jù)所傳參數(shù)來(lái)裁切得到圖片B后返回到前臺(tái)并將上傳的原圖A刪除,節(jié)省空間。

二、分析

將效果圖分為左右兩部分,先看左邊,由一張圖片加一個(gè)矩形選區(qū)組成,圖片和選區(qū)之間有一層半透明的遮罩,但是這樣的話會(huì)連選區(qū)部分一塊遮住,就沒(méi)有上面這種框選出來(lái)的效果了,事實(shí)上結(jié)構(gòu)是這樣的:由下往上分別是1圖片層,2遮罩層,3選區(qū)層(一個(gè)div,絕對(duì)定位),4圖片層(絕對(duì)定位)。第1層和第4層的圖片是一樣的,大小及l(fā)eft、top值也一樣,給第3層選區(qū)層加個(gè)overflow:hidden,就呈現(xiàn)出了上面的效果,虛線邊框及拖拽的8個(gè)點(diǎn)后文會(huì)講到。下圖比較直觀地說(shuō)明的它們的層級(jí)關(guān)系,第3層灰色部分為overflow:hidden隱藏的部分:

做完圖發(fā)現(xiàn)左右兩邊框的位置不一樣,但重在說(shuō)明原理。接下來(lái),選區(qū)部分可以拖動(dòng),用到拖拽原理:鼠標(biāo)按下,記錄var disx=event.clientX,var disy=event.clientY,拖動(dòng),計(jì)算當(dāng)前event.clientX與disx的差值為x,當(dāng)前event.clientY與disy的差值為y,設(shè)置第4層圖片的left值為圖片當(dāng)前offsetLeft+disx,top值為offsetTop+disy。如選區(qū)往左移動(dòng)10px,由于第4層只能在第1層范圍內(nèi)移動(dòng),那么剛好第4層的left值等于負(fù)的第3層的left值,top值同理。拖拽原理圖:

選區(qū)大小是可以按比例改變的,這就需要用到選區(qū)周?chē)?個(gè)點(diǎn),如下圖可以分為4個(gè)部分:

每個(gè)部分里的點(diǎn)觸發(fā)的事件是一樣的,4個(gè)部分觸發(fā)的事件都是改變選區(qū)大小,不一樣的地方在于第1部分會(huì)同時(shí)改變選區(qū)的left和top值,第2和第4部分分別只改變的是選區(qū)的top、left值,第3部分不會(huì)改變選區(qū)的left和top值。4個(gè)部分原理都一樣,拿第1部分說(shuō)事,點(diǎn)擊第1部分的點(diǎn)往左上角拖動(dòng),選區(qū)變大的同時(shí)設(shè)置其left和top值(會(huì)減?。鴏eft減小的值剛好等于選區(qū)增大的值,這個(gè)值的計(jì)算方法同拖拽原理。拖拽過(guò)程中需要限制范圍,不能超出整個(gè)圖片的范圍。

選中需要截取的部分后,獲取當(dāng)前選區(qū)(第4層)的左上角的坐標(biāo),即第4層的offsetLeft、offsetTop值,再獲取選區(qū)的寬高,這4個(gè)值不能直接往后臺(tái)傳,因?yàn)榇藭r(shí)的圖片可能是被縮放過(guò)的,而后臺(tái)是根據(jù)原圖尺寸來(lái)截取的,那么需要在圖片上傳完之后獲取圖片原始寬高,與頁(yè)面中圖片顯示寬高得出一個(gè)比例,將這4個(gè)值乘以這個(gè)比例得出的值才是后臺(tái)需要的。

至于選區(qū)的邊框,做得簡(jiǎn)單點(diǎn)可以直接設(shè)置border:1px dashed #fff,更好的方法是放四個(gè)position:absolute的div,分別固定在選區(qū)的上下左右,上下寬100%,高1px,左右寬1px,高100%,背景設(shè)為一個(gè)波浪紋的gif圖片,repeat,出來(lái)的效果很是驚艷!

右邊部分3張圖片僅僅是展示用,顯示的內(nèi)容是左邊選區(qū)選中的部分,而選區(qū)的大小是可以改變的,所以右邊的圖片大小及位置是隨著選區(qū)的變化而變化。選擇圖片上傳后,選區(qū)有個(gè)默認(rèn)寬高,右邊3個(gè)框?qū)捀呤枪潭ǖ模鶕?jù)選區(qū)寬與右邊三個(gè)框的寬分別相除得出的比例可以算出右邊三個(gè)框內(nèi)的圖片應(yīng)該顯示的尺寸,顯示原理同左邊,相比左邊只是少了第1、2層。

這種方式的優(yōu)點(diǎn)是純js,兼容性也好,另外還可以做個(gè)特性檢測(cè),支持HTML5的瀏覽器可以直接在前端切割圖片,缺點(diǎn)是裁切之前要選將圖片上傳。源碼晚點(diǎn)貼上來(lái)。

三、源碼

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <script src="js/jquery.min.js"></script>
  <style>
  *{margin: 0;padding: 0}
  </style>
</head>
<body>
<style>
.uploadHead{max-width: 800px;}
.clearfix{clear: both;overflow: hidden;position: relative;zoom: 1;}
.l{float: left;}.r{float: right;}
.uploadHead h3{color: #19110a; text-decoration: none; border-bottom: #BFC9CB 1px solid; padding: 10px 0;margin-bottom: 30px;}
.preview{width: 400px; height: 400px;padding: 1px; border: #B8B8B8 1px dashed;margin-right: 18px; position: relative;}
.canvas{background-color: #E8F3F7;width:392px; height: 392px; margin: 4px; text-align: center; position: relative; overflow: hidden;}
.canvas .mask{width: 100%;height: 100%; background: #000; opacity: 0.7; filter:alpha(opacity=70); position: absolute;}
.photoBox p{width: 100px; padding-left: 16px; float: left; color: #aeacab;}
.photoBox .size{width: 100%;}
.p_180,.p_80,.p_70{position: relative;border: #B5B5B5 1px solid;overflow: hidden;}
.p_180 img,.p_80 img,.p_70 img{position: absolute; left: 0;top: 0;}
.p_180{width: 180px; height: 210px; margin-bottom: 20px;}
.p_80{width: 80px; height: 80px; margin-bottom: 20px;}
.p_70{width: 70px; height: 70px;}
.cutImg{text-align: center;margin-top: 10px;}
.cutImg input{width: 80px; height: 30px; border: none;margin: 10px 20px; font-size: 16px; color: #fff; cursor: pointer; border-radius: 2px;}
.cutImg .save{background-color: #e34128;}
.cutImg .cancel{background-color: #a19f9f;}
.checkImg{width: 192px; height: 192px;position: absolute; left: 50%; top: 50%; margin:-96px 0 0 -96px;z-index: 9; display: none;}
.checkImg p{color: #898989; font-size: 14px; text-align: center;}
.checkImg .checkLocalImg{width: 132px; height: 42px;margin:50px 30px 20px; background: url(img/checkImg.png) center; font-size: 14px; color: #fff; cursor: pointer;}
.imgBox{position: relative;margin: 0 auto;display: none1; overflow: hidden; }
.cutImgBox{ width: 180px; height: 210px; position: absolute; z-index: 2; }
.cutImgBox img{ position: absolute; left: 0px; top:0px;}
.imgCon{position: relative;width: 100%;height: 100%;overflow: hidden;cursor: pointer; z-index: 1;}
.imgCon .lineBg{background:#fff url(img/jcrop.gif) center repeat; opacity: 0.6; filter:alpha(opacity:60); position: absolute; z-index: 3;}
.imgCon .tandb{width: 100%;height: 1px;}
.imgCon .landr{height: 100%;width: 1px;}
.imgCon .right{right: 0;}
.imgCon .bottom{bottom: 0;}
.cSize{width: 100%; height: 100%; position: absolute;left: 0;top: 0; cursor: move; z-index: 8;}
.cSize .btn{width: 7px; height: 7px; border: #eee 1px solid; background-color: #333; opacity: 0.5;filter:alpha(opacity:50); position: absolute;}
.cSize .lt{left: -4px; top: -4px;cursor: nw-resize;}
.cSize .tc{left:50%; margin-left: -4px;top:-4px;cursor: n-resize;}
.cSize .rt{right: -4px; top:-4px;cursor: ne-resize;}
.cSize .rc{right: -4px; top:50%;margin-top: -4px;cursor: e-resize;}
.cSize .rb{right: -4px; bottom: -4px;cursor: se-resize;}
.cSize .bc{bottom: -4px; left: 50%;margin-left: -4px;cursor: n-resize;}
.cSize .lb{left: -4px; bottom: -4px;cursor: sw-resize;}
.cSize .lc{left: -4px;top:50%;margin-top: -4px;cursor: e-resize;}
.width_392{max-width: 392px; max-height: 392px; z-index: 1;}
.fileInput{width: 100%; height: 50px;top: 50px;font-size: 100px; position: absolute; opacity: 0; filter:alpha(opacity=0); cursor: pointer;}
.ie8Drag{width: 100%; height: 100%; position: absolute;left: 0;top: 0; z-index: 99; background-color: #000; opacity: 0; filter:alpha(opacity=0);}
</style>
<!-- 頭像上傳 By 王美建 2014-10-9 10:45:02 -->
<script type="text/javascript" >
//圖片裁切對(duì)象
function CutImg(){
  this.init();
};
CutImg.prototype.init=function(opt){
  var that=this;
  this.con=$('.cutImgBox')[0];this.img=$('.cutImgBox img:last')[0];
  this.imgBox=$('#imgBox');this.defaultWidth=180;this.defaultHeight=210;
  this.scalex=this.defaultWidth/this.defaultHeight;this.scaley=this.defaultHeight/this.defaultWidth;
  that.drag().setSize().cSize().cPosition();;
}
// 拖拽
CutImg.prototype.drag=function(){
  var that=this;
  this.con.onmousedown=function(e){
    var e=e||window.event,target=e.target||e.srcElement;
    if($(target).hasClass('btn')) return;
    var disx=e.clientX-that.con.offsetLeft,disy=e.clientY-that.con.offsetTop;
    document.onmousemove=function(ev){
      var ev=ev||event,L,T;
      L=ev.clientX-disx;
      T=ev.clientY-disy;
      if(L<0){
        L=0;
      }else if(L>that.con.parentNode.offsetWidth-that.con.offsetWidth){
        L=that.con.parentNode.offsetWidth-that.con.offsetWidth;
      };
      if(T<0){
        T=0;
      }else if(T>that.con.parentNode.offsetHeight-that.con.offsetHeight){
        T=that.con.parentNode.offsetHeight-that.con.offsetHeight;
      };
      that.con.style.left=L+'px';
      that.con.style.top=T+'px';
      that.img.style.left=-that.con.offsetLeft+'px';
      that.img.style.top=-that.con.offsetTop+'px';
      that.cPosition();
    }
    document.onmouseup=function(){
      document.onmousemove=null;
      document.onmouseup=null;
    }
    return false;
  }
  return this;
};
// 改變圖片尺寸
CutImg.prototype.setSize=function(){
  var that=this.con;
  $('.p_180 img').css('width',that.parentNode.offsetWidth*180/that.offsetWidth);
  $('.p_80 img').css('width',that.parentNode.offsetWidth*80/that.offsetWidth);
  $('.p_70 img').css('width',that.parentNode.offsetWidth*70/that.offsetWidth);
  return this;
};
// 改變圖片位置
CutImg.prototype.cPosition=function(){
  this.setPosition( $('.p_180'),180,210 );
  this.setPosition( $('.p_80'),80,80 );
  this.setPosition( $('.p_70'),70,70 );
  return this;
};
// 設(shè)置三幅圖片顯示位置
CutImg.prototype.setPosition=function(obj,w,h){
  var that=this.con;
  obj.find('img').css({
    'left':-w*that.offsetLeft/that.offsetWidth,
    'top':-h*that.offsetTop/that.offsetHeight
  });
  return this;
};
// 保存截取后的頭像
CutImg.prototype.saveImg=function() {
  var x=0,y=0,w=180,h=210,that=this,cutObj=$('.cutImgBox')[0];
  w=parseInt( this.oldW*cutObj.offsetWidth/that.imgBox.width() );
  h=parseInt( w*that.scaley );
  x=parseInt(cutObj.offsetLeft/(that.imgBox.width()-that.con.offsetWidth)*(this.oldW-w));
  y=parseInt(cutObj.offsetTop/(that.imgBox.height()-that.con.offsetHeight)*(this.oldH-h));
  x=x?x=x:x=0;y=y?y=y:y=0; //x/y可能為NaN
  //x,y,w,h分別為后端需要的坐標(biāo)及寬高
}
// 改變選區(qū)大小
CutImg.prototype.cSize=function(){
  var that=this.con,This=this;
  var thatImg=this.img;
  $('.cSize .btn').each(function() {
    var obj=this;
    obj.onmousedown=function(e) {
      var e=e||window.event;
      var disx=e.clientX,disy=e.clientY;
      var disw=that.offsetWidth,dish=that.offsetHeight,disl=that.offsetLeft,dist=that.offsetTop;
      document.onmousemove=function(ev) {
        var ev=ev||window.event,dirx=ev.clientX-disx,diry=ev.clientY-disy;
        var minW=6,minH=7,L,T;
        //點(diǎn)擊第1部分改變選取尺寸
        if( $(obj).hasClass('t1') ){
          L=disl+dirx;T=dish-(disw-dirx)*This.scaley+dist;
          if( L<0||T<0 ||disw-dirx<minW||(disw-dirx)*This.scaley<minH) return;
          $(that).css({
            'left':L,
            'top':T,
            'width':disw-dirx,
            'height':(disw-dirx)*This.scaley
          })
          $(thatImg).css({
            'left':-L,
            'top':-that.offsetTop
          })
        }
        //點(diǎn)擊第2部分改變選取尺寸
        if( $(obj).hasClass('t2') ){
          if( dist+diry<0||(dish-diry)*This.scalex<minW||dish-diry<minH||(dish-diry)*This.scalex+that.offsetLeft>that.parentNode.offsetWidth )return;
          $(that).css({
            'top':dist+diry,
            'width':(dish-diry)*This.scalex,
            'height':dish-diry
          })
          $(thatImg).css({
            'top':-that.offsetTop
          })
        }
        //點(diǎn)擊第3部分改變選取尺寸
        if( $(obj).hasClass('t3') ){
          if( disw+dirx+that.offsetLeft>that.parentNode.offsetWidth||(disw+dirx)*This.scaley+that.offsetTop>that.parentNode.offsetHeight||disw+dirx<minW||(disw+dirx)*This.scaley<minH ) return;
          $(that).css({
            'width':disw+dirx,
            'height':(disw+dirx)*This.scaley
          })
        }
        //點(diǎn)擊第4部分改變選取尺寸
        if( $(obj).hasClass('t4') ){
          if( disl+dirx<0||(disw-dirx)*This.scaley+that.offsetTop>that.parentNode.offsetHeight||disw-dirx<minW||(disw-dirx)*This.scaley<minH ) return;
          $(that).css({
            'left':disl+dirx,
            'width':disw-dirx,
            'height':(disw-dirx)*This.scaley
          })
          $(thatImg).css({
            'left':-that.offsetLeft
          })
        }
        This.setSize().cPosition();
        return false;
      };
      document.onmouseup=function(e) {
        document.onmousemove=null;
        document.onmouseup=null;
      }
      return;
    };
  });
};
$(function(){
  var oCutImg=new CutImg();
})
</script>
<div class="e_box uploadHead" id="uploadHead">
  <h3>上傳真實(shí)頭像</h3>
  <div class="e_con">
    <div class="previewBox l">
      <div class="preview">
        <div class="checkImg" id="checkImg">
          <input type="file" id="headImgInput" name="img" accept="image/jpg,image/jpeg,image/png" dir="rtl" title="選擇本地照片" class="fileInput" />
           <input type="button" value="選擇本地照片" class="checkLocalImg" />
           <p>支持JPG/JPEG/PNG格式</p>
         </div>
        <div class="canvas">
          <div class="imgBox" id="imgBox">
            <div class="cutImgBox">
              <div class="imgCon">
                <div class="lineBg tandb"></div>
                <div class="lineBg tandb bottom"></div>
                <div class="lineBg landr"></div>
                <div class="lineBg landr right"></div>
                <img class="width_392 staPhoto" src="img/1.png" />
                <div class="ie8Drag"></div>
              </div>
              <div class="cSize">
                <div class="btn lt t1"></div><div class="btn tc t2"></div>
                <div class="btn rt t2"></div><div class="btn rc t3"></div>
                <div class="btn rb t3"></div><div class="btn bc t3"></div>
                <div class="btn lb t4"></div><div class="btn lc t4"></div>
              </div>
            </div>
            <div id="mask" class="mask"></div>
            <img class="width_392 staPhoto" src="img/1.png" />
          </div>
        </div>
      </div>
      <div class="cutImg">
        <input type="button" class="save" value="保存" >
        <input type="button" class="cancel" id="cancelUp" value="取消" >
      </div>
    </div>
    <div class="photoBox l">
      <div class="size">
        <div class="p_180 l"><img class="staPhoto" src="img/1.png" /></div><p>大尺寸頭像 180×210像素</p>
      </div>
      <div class="size clearfix">
        <div class="p_80 l"><img class="staPhoto" src="img/1.png" /></div><p>中尺寸頭像 80×80像素</p>
      </div>
      <div class="size">
        <div class="p_70 l"><img class="staPhoto" src="img/1.png" /></div><p>小尺寸頭像 70×70像素</p>
      </div>
    </div>
  </div>
</div>
</body>
</html>

更多關(guān)于jQuery相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《jQuery常用插件及用法總結(jié)》、《jQuery擴(kuò)展技巧總結(jié)》、《jQuery切換特效與技巧總結(jié)》、《jQuery遍歷算法與技巧總結(jié)》、《jQuery常見(jiàn)經(jīng)典特效匯總》、《jQuery動(dòng)畫(huà)與特效用法總結(jié)》及《jquery選擇器用法總結(jié)

希望本文所述對(duì)大家jQuery程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • jQuery filter函數(shù)使用方法

    jQuery filter函數(shù)使用方法

    利用filter函數(shù)可以從wrapper set中過(guò)濾符合條件的DOM元素,下面是其具體的用法,希望對(duì)大家有所幫助
    2014-05-05
  • jquery引用方法時(shí)傳遞參數(shù)原理分析

    jquery引用方法時(shí)傳遞參數(shù)原理分析

    只需將js引用并設(shè)置下變量就行了,但一直沒(méi)搞明白原理,這次弄清了如何傳遞、設(shè)置多個(gè)(很多個(gè))參數(shù),如果你也不明白可以看看
    2014-10-10
  • jquery+ajax實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)(封裝和不封裝兩種方式)

    jquery+ajax實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)(封裝和不封裝兩種方式)

    這篇文章主要為大家詳細(xì)介紹了jquery+ajax實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)的相關(guān)代碼,包括封裝和不封裝兩種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • jQuery DOM操作 基于命令改變頁(yè)面

    jQuery DOM操作 基于命令改變頁(yè)面

    每天都在與DOM打交道而且暈頭轉(zhuǎn)向,不過(guò),自打咱認(rèn)識(shí)了jQuery: 是操作屬性也不煩了,插入新元素也不暈了,連移動(dòng)元素及包裝元素咱也不抽筋了。。
    2010-01-01
  • 分享我的jquery實(shí)現(xiàn)下拉菜單心的

    分享我的jquery實(shí)現(xiàn)下拉菜單心的

    jquery庫(kù)給我們帶來(lái)了很多方便的地方,使用jquery實(shí)現(xiàn)一個(gè)簡(jiǎn)單的下拉菜單已經(jīng)是很簡(jiǎn)單了,但也有不同的實(shí)現(xiàn)方法。今天自己使用jquery寫(xiě)了一個(gè)下拉菜單,參考了Xiaofeng Wang的SexyDropDownMenu2010,其中還是有一些東西感覺(jué)值得記錄一下。
    2015-11-11
  • EasyUi 打開(kāi)對(duì)話框后控件賦值及賦值后不顯示的問(wèn)題解決辦法

    EasyUi 打開(kāi)對(duì)話框后控件賦值及賦值后不顯示的問(wèn)題解決辦法

    這篇文章主要介紹了easyUi 打開(kāi)對(duì)話框后控件賦值,以及賦值后不顯示的問(wèn)題解決辦法,解決方法非常簡(jiǎn)單,只需要將賦值語(yǔ)句修改下就好,下面小編給大家簡(jiǎn)單介紹下,需要的朋友參考下
    2017-01-01
  • jquery獲取checkbox的值并post提交

    jquery獲取checkbox的值并post提交

    這篇文章主要介紹了jquery獲取checkbox的值并post提交,需要的朋友可以參考下
    2015-01-01
  • jQuery中:button選擇器用法實(shí)例

    jQuery中:button選擇器用法實(shí)例

    這篇文章主要介紹了jQuery中:button選擇器用法,實(shí)例分析了:button選擇器的功能、定義及選取按鈕的使用技巧,需要的朋友可以參考下
    2015-01-01
  • jQuery實(shí)用函數(shù)用法總結(jié)

    jQuery實(shí)用函數(shù)用法總結(jié)

    這篇文章主要介紹了jQuery實(shí)用函數(shù)用法總結(jié),匯總了jQuery常用的函數(shù)及相關(guān)技巧,需要的朋友可以參考下
    2014-08-08
  • jQuery實(shí)現(xiàn)放大鏡案例

    jQuery實(shí)現(xiàn)放大鏡案例

    這篇文章主要為大家詳細(xì)介紹了jQuery實(shí)現(xiàn)放大鏡案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10

最新評(píng)論