DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> 基於原生JS實現圖片裁剪
基於原生JS實現圖片裁剪
編輯:關於JavaScript     

下面是我自己寫的圖片裁剪的功能介紹:

可以利用鼠標拖拉,產生裁剪框

可以改變裁剪框大小

點擊確定,返回裁剪數據

原理

完成裁剪的方法有兩種:

1、利用HTML5新增拖拽事件drag drop等

2、傳統方法,利用鼠標事件,mousedown、mousemove等

在這裡,我們采用方法2。

裁剪區域的形成

要進行裁剪首先要形成裁剪區域,這個裁剪區域的形成我們可以與鼠標移動的距離相關聯。鼠標移動多遠,裁剪區域就有多大。如下圖:


如上圖所示鼠標的橫向移動距離與縱向移動距離共同組成了裁剪區域的寬和高。

而這橫向與縱向移動的距離如何計算呢?當我們點下鼠標時,就能夠通過event事件對象獲取鼠標點擊位置,而移動鼠標時,也能夠通過event獲取鼠標的位置,通過兩次鼠標位置的改變,就能夠獲得鼠標的移動距離。

獲取鼠標位置的屬性是clientX以及clientY

陰影區域的形成

接下來就是繪制陰影區域。被裁剪圖片中除裁剪區域以外的部分,都屬於陰影部分,也可以不繪制該區域,繪制該區域是為了讓用戶更清晰的看清裁剪區域。

我將該區域分成了上下左右四個部分,見下圖分布:

那麼該區域如果計算呢?這時就要用到Dom元素的偏移值了,利用裁剪區域的左偏移值減去圖片本身的左偏移值就是左陰影的寬,利用裁剪區域的上偏移值減去圖片的上偏移值,等於上陰影的高度值。如下圖:

獲取到左陰影、上陰影的值後,就能夠通過這兩個將其他陰影的屬性計算出來。

圖片的偏移值有兩種取法

    1.利用offsetLeft 與 offsetTop 值 弊端 如果dom元素有border margin等值會將這些值計算在內

    2.獲取dom的css屬性 弊端 預定義的css有關 如果沒定義left top就無法獲取

這兩種方法都有各自的弊端,視不同情況來使用

裁剪越界的阻止

裁剪區域的計算是通過鼠標的移動距離來計算的,因此會出現裁剪區域越界的情況,而這情況又分成兩種:

    1.裁剪過程中越界

    2.移動裁剪區域時越界

那麼下面就來說說如何防止越界。

裁剪越界

什麼是裁剪時越界?就是鼠標拖動區域超出了圖片的返回,形成了越界,如下圖:

對於這種越界需要判斷裁剪區域的右側相對於浏覽器左側的位置 不能夠超過 圖片右側的位置相當於浏覽器左側的位置;同時裁剪區域底部相對於浏覽器頂部位置 不能夠超過 圖片底部相對應浏覽器頂部的位置。還是畫圖來說明:

TX >= PX 時就讓TX的值強制為一固定值。

TX與PX的計算方法,假設裁剪區域為oTailor,圖片區域oPicture:

TX = oTailor.offsetWidth + oTailor.offsetLeft;
PX = oPicture.offsetWidth + oPicture.offsetLeft;

同理,可以按照上述方法對左側越界,上側越界,下側越界進行限制,就不多贅述。

移動越界

移動越界指的是已經形成了裁剪區域了,但通過鼠標移動裁剪區域時產生了越界。這個理解比較簡單,就不畫圖介紹了。這種越界與dom拖拽越界限制一致,通過判斷鼠標移動距離是否超過了圖片區域來判斷。

原理與問題解決了,現在開始來完成實際功能。

准備工作

在做之前,先做一些准備工作,磨刀不誤砍柴功。

網頁布局准備

網頁布局部分關鍵代碼如下:

<img src="./images/img_2.jpg" alt="">
<div class="img_box">
  <div class="box_border1"></div>
  <div class="box_border2"></div>
  <div class="box_border3"></div>
  <div class="box_border4"></div>
  <div class="box_handle" id="box_1"></div>
  <div class="box_handle" id="box_2"></div>
  <div class="box_handle" id="box_3"></div>
  <div class="box_handle" id="box_4"></div>
  <div class="box_handle" id="box_5"></div>
  <div class="box_handle" id="box_6"></div>
  <div class="box_handle" id="box_7"></div>
  <div class="box_handle" id="box_8"></div>
</div>
<!-- 左 -->
<div class="outer"></div>
<!-- 上 -->    
<div class="outer"></div>
<!-- 右 -->    
<div class="outer"></div>
<!-- 下 -->    
<div class="outer"></div>

<button class="confirm">確定</button>

其中img_box表示的是裁剪區域,outer表示陰影區域,而img_box中的div是裁剪區域的邊框

樣式控制如下:

* {
  padding:0;
  margin:0;
}
body {

  background: #454545;    
}          
.main {
  width: 500px;
  margin:50px auto;
}
.main img {
  width: 500px;
  position: absolute;
  left: 450px;
  top: 50px;
}
.img_box {    
  overflow: hidden;
  position: absolute;
  top:0px;
  left: 0px;
  z-index: 2;
}
.outer {
  overflow: hidden;
  background: #000;
  opacity: 0.4;
  position: absolute;
  top:0px;
  left: 0px;
  z-index: 0;
}
.box_border1 ,
.box_border2 ,
.box_border3 ,
.box_border4 {
  opacity: 0.5;
}
.box_border1 {
  background: url(./images/border-anim-v.gif) repeat-y left top;
} 
.box_border2 {
  background: url(./images/border-anim-h.gif) repeat-x left top;
}
.box_border3 {
  background: url(./images/border-anim-v.gif) repeat-y right top;
} 
.box_border4 {
  background: url(./images/border-anim-h.gif) repeat-x right bottom;
} 
.box_handle {    
  background: #fff;
  border: 1px solid #000;
  opacity: 0.5;
}
.confrim {
  width: 80px;
  height: 35px;
}

布局效果如下:

通用函數

完成圖片裁剪,通過上述原理,可以知道需要大量獲取標簽對象以及標簽的css屬性等,所以可以編寫通用函數,更好的獲取這些值。如下:

Dom獲取函數

/*   仿JqueryDom獲取   */
function $(dom) {

   function getDom(dom) {

    var str = dom.charAt(0);    
    switch( str ) {
      case '.' :
        this.ele = document.getElementsByClassName(dom.substring(1))||null;  

        break;

      case '#' :

        this.ele = document.getElementById(dom.substring(1)) || null;

        break;

      default : 

        if(document.getElementsByTagName(dom).length) {

          this.ele = document.getElementsByTagName(dom);                

        } else if(document.getElementsByName(dom).length) {

          this.ele = document.getElementsByName(dom);                  

        } else {          
          this.ele = null;
        }
    }
    return this;      
  };


  getDom.prototype.get = function(num) {
    return this.ele[num]||this.ele;
  }

  getDom.prototype.insert = function(value , num) {
    this.ele[num].innerHTML = value;      
  }

  return new getDom(dom);
}

Css屬性獲取函數

Css屬性的獲取分成兩種,一種是IE的,使用currentStyle;另一種是其他主流浏覽器,使用getComputedStyle,以下是兼容版本:

/* Css獲取 */
function getCss(o , key){
  return o.currentStyle? o.currentStyle[key] : document.defaultView.getComputedStyle(o,false)[key];   
};

賦值函數

編寫時經常遇到對Dom的樣式進行賦值,為方便,我專門編寫了一個函數用於賦值:

/**
 - 賦值函數 
 - @param : obj     被賦值對象
 - @param : option  進行的操作
 - @parma : value  賦值內容
 */
function setAssign(obj , option , value) {  

  switch(option) {
    case 'width':
      obj.style.width = value;
      break;
    case 'height':
      obj.style.height = value;
      break;
    case 'top':
      obj.style.top = value;
      break;
    case 'left':
      obj.style.left = value;
      break;
    case 'position':
      obj.style.position = value;
      break;
    case 'cursor':
      obj.style.cursor = value;
  }
}

好了准備工作基本完成,現在就正式開始編寫。

通過點擊與移動事件完成裁剪區域繪制

對圖片設置mousedown以及mousemove事件監視,如下:

// 鼠標點擊圖片觸發
oPicture.onmousedown = function(ev) {
  // 事件對象
  var oEvent = ev || window.event;

  // 初始鼠標位置
  var tempX = oEvent.clientX;
  var tempY = oEvent.clientY;      

  // 調整裁剪區域位置
  oTailor.style.left = oEvent.clientX + 'px';
  oTailor.style.top = oEvent.clientY + 'px';

  // 鼠標在圖片上移動 繪制裁剪區域 陰影區域
  document.onmousemove = function(ev) {

    // 鼠標移動事件對象
    var oEvent = ev || window.event;

    // 當前鼠標位置減去鼠標之前的鼠標位置 等於 鼠標移動距離
    var sLeft = oEvent.clientX - tempX;
    var sTop = oEvent.clientY - tempY;

    // 裁剪越界限制 只需限制右側 與 下側
    if((oTailor.offsetLeft+oTailor.offsetWidth) >= (oPicture.offsetLeft+oPicture.offsetWidth)) {
      sLeft = oPicture.offsetLeft+oPicture.offsetWidth - oTailor.offsetLeft;
    }  
    if((oTailor.offsetTop+oTailor.offsetHeight) >= (oPicture.offsetTop+oPicture.offsetHeight)) {
      sTop = oPicture.offsetTop+oPicture.offsetHeight - oTailor.offsetTop;
    }

    // 裁剪區域繪制
    oTailor.style.width = sLeft + 'px';
    oTailor.style.height = sTop + 'px';

    // 裁剪區域顯示
    oTailor.style.display = 'block';

    // 陰影區域顯示
    for (var i = 0; i < oShadow.length; i++) {
      oShadow[i].style.display = 'block';
    }

    // 陰影區域繪制
    shadow(oPicture , oTailor , oShadow);

    // 添加裁剪邊框
    tailorBorder(oDiv , oHandle , oTailor);

    // 阻止默認事件
    oEvent.preventDefault();
  };

  // 鼠標松開 將移動事件取消
  document.onmouseup = function(ev) {
    var oEvent = ev || window.event;

    // 移動事件取消
    document.onmousemove = null;

    // 阻止默認事件
    oEvent.preventDefault();
  };

  // 阻止默認事件
  oEvent.preventDefault();
}

陰影區域繪制

/** 
 * @param:oPicture    圖片dom對象
 * @param:oTailor    裁剪區域dom對象
 * @param:oShadow    陰影區域dom對象
 */ 
function shadow(oPicture , oTailor , oShadow) {  

  // 左側陰影區
  setAssign(oShadow[0] , 'width' , (parseInt(getCss(oTailor , 'left')) - parseInt(getCss(oPicture , 'left'))) + 'px');
  setAssign(oShadow[0] , 'height' , parseInt(getCss(oPicture , 'height')) + 'px');
  setAssign(oShadow[0] , 'left'  , parseInt(getCss(oPicture , 'left')) + 'px')
  setAssign(oShadow[0] , 'top'  , parseInt(getCss(oPicture , 'top')) + 'px')

  //右側陰影區
  setAssign(oShadow[2] , 'width' , (parseInt(getCss(oPicture , 'width')) - parseInt(getCss(oTailor ,'width')) - parseInt(getCss(oShadow[0] , 'width'))) + 'px');
  setAssign(oShadow[2] , 'height' , parseInt(getCss(oPicture , 'height')) + 'px');
  setAssign(oShadow[2] , 'left'  , (parseInt(getCss(oTailor , 'left')) + parseInt(getCss(oTailor , 'width'))) + 'px');
  setAssign(oShadow[2] , 'top'  , parseInt(getCss(oPicture , 'top')) + 'px');

  // 上側陰影區
  setAssign(oShadow[1] , 'width' , parseInt(getCss(oTailor , 'width')) + 'px');
  setAssign(oShadow[1] , 'height' , (parseInt(getCss(oTailor , 'top')) - parseInt(getCss(oPicture , 'top'))) + 'px');
  setAssign(oShadow[1] , 'left'  , (parseInt(getCss(oPicture , 'left')) + parseInt(getCss(oShadow[0] , 'width'))) + 'px');
  setAssign(oShadow[1] , 'top'  , parseInt(getCss(oPicture , 'top')) + 'px');

  // 下側陰影區
  setAssign(oShadow[3] , 'width' , parseInt(getCss(oTailor , 'width')) + 'px');
  setAssign(oShadow[3] , 'height' , (parseInt(getCss(oPicture , 'height')) - parseInt(getCss(oTailor , 'height')) - parseInt(getCss(oShadow[1] , 'height'))) + 'px');
  setAssign(oShadow[3] , 'left'  , (parseInt(getCss(oPicture , 'left' )) + parseInt(getCss(oShadow[0] , 'width'))) + 'px');
  setAssign(oShadow[3] , 'top'  , (parseInt(getCss(oTailor , 'top' )) + parseInt(getCss(oTailor , 'height'))) + 'px');
}

注意在網頁實際運用中,如果布局中圖片css中沒有left或top屬性,那麼上面代碼會產生錯誤。應該使用offsetLeft與offsetTop代替之。

添加裁剪邊框

在放出的布局圖中,可以看見裁剪的邊沿,四角及四邊各有一個小正方形的形狀,添加不僅是為了區分裁剪區與非裁剪區,還為下一步添加拉伸裁剪區域提供方便。下面開始編寫代碼:

/**
 *   裁剪邊框繪制
 *   @param : oDIv    所有邊框對象
 *   @param : oHandle   點狀邊沿
 * @param : oTailor  裁剪對象
 */
function tailorBorder(oDiv , oHandle , oTailor) {
  // 對邊框進行初始化
  for (var i = 0; i < oDiv.length; i++) {
    setAssign(oDiv[i] , 'position' , 'absolute');
    setAssign(oDiv[i] , 'top'    , '0px');
    setAssign(oDiv[i] , 'left'    , '0px');
    setAssign(oDiv[i] , 'width'  , parseInt(getCss(oTailor , 'width')) + 'px');
    setAssign(oDiv[i] , 'height'  , parseInt(getCss(oTailor , 'height')) + 'px');
  }

  /* 點狀邊沿繪制 */  
  // 四角點狀邊沿繪制
  for (var i = 0; i < 4; i++) {  

    // 點狀繪制
    setAssign(oHandle[i] , 'position' , 'absolute');
    setAssign(oHandle[i] , 'width'    , '5px');
    setAssign(oHandle[i] , 'height'  , '5px');

    // 0 2 表示左側點狀
    if(i % 2 == 0) {
      setAssign(oHandle[i] , 'left' , '0px');

      setAssign(oHandle[i] , 'top'  , (i == 0?'0px' : (parseInt(getCss(oTailor , 'height')) - 8) + 'px'));      

    } else {
      // 右側點狀
      setAssign(oHandle[i] , 'left' , ( parseInt(getCss(oTailor , 'width')) - 6 ) + 'px');

      setAssign(oHandle[i] , 'top'  , (i == 1?'0px' : parseInt(getCss(oTailor , 'height')) - 8 ) + 'px');          
    }                              
  }

  // 四邊點狀邊框
  for (var i = 4; i < oHandle.length; i++) {
    setAssign(oHandle[i] , 'position' , 'absolute');
    setAssign(oHandle[i] , 'width'    , '5px');
    setAssign(oHandle[i] , 'height'  , '5px');

    // 4 6 表示上 下 點狀邊框
    if(i % 2 == 0) {

      setAssign(oHandle[i] , 'left' , parseInt(getCss(oTailor , 'width')) / 2 + 'px');

      setAssign(oHandle[i] , 'top'  , (i == 4 ? '0px' : (parseInt(getCss(oTailor , 'height')) - 8) + 'px'));

    } else {

      // 左右點狀
      setAssign(oHandle[i] , 'top'  , parseInt(getCss(oTailor , 'height')) / 2 + 'px');

      setAssign(oHandle[i] , 'left' ,(i == 5 ? '0px' : parseInt(getCss(oTailor , 'width')) - 8 ) + 'px');

    }
  }
}

布局中,裁剪區域類名為box_handle的div前四個代表四角的點狀,後四個表示邊沿中間的點狀,都按照順時針分布。完成後效果如下:

監視陰影區域

裁剪區域與陰影區域繪制完成,現在添加一個小功能,當鼠標點擊到非裁剪區時(即陰影區),取消裁剪區域。

// 對陰影區域設置時間 點擊到陰影區時 裁剪區域消失 陰影區消失
for (var i = 0; i < oShadow.length; i++) {
  oShadow[i].index = i;
  oShadow[i].onmousedown = function() {

    oTailor.style.display = 'none';
    oTailor.style.width = '0px';
    oTailor.style.hegiht = '0px';
    for (var i = 0; i < oShadow.length; i++) {
      oShadow[i].style.display = 'none';
      oShadow[i].style.left = '0px';
      oShadow[i].style.top = '0px';
    }                      
  }
}

監視鼠標移動位置

接下來添加裁剪區域拉伸的功能,當鼠標移動到邊沿的點狀邊框時呈現不同的效果

添加鼠標顯示效果

// 點狀邊框監視 設置相應操作
oTailor.onmousemove = function(ev) {
  var oTarget = oEvent.target;  
  switch(oTarget.id) {
    case 'box_1':              // 左上

      setAssign(oTailor , 'cursor' , 'nw-resize');        

      break;
    case 'box_2':              // 右上 

      setAssign(oTailor , 'cursor' , 'ne-resize');        

      break;
    case 'box_3':              // 左下

      setAssign(oTailor , 'cursor' , 'sw-resize');

      break;
    case 'box_4':              // 右下
      setAssign(oTailor , 'cursor' , 'se-resize');

      break;
    case 'box_5':              // 上      
      setAssign(oTailor , 'cursor' , 'n-resize');

      break;
    case 'box_6':              // 左
      setAssign(oTailor , 'cursor' , 'w-resize');

      break;
    case 'box_7':              // 下      
      setAssign(oTailor , 'cursor' , 's-resize');

      break;
    case 'box_8':              // 右      
      setAssign(oTailor , 'cursor' , 'e-resize');

      break;
    default :                // 裁剪區域 顯示可移動提示
      setAssign(oTailor , 'cursor' , 'move');
      break;
  }
}

由於監視的div較多,因此采用事件委托的方式添加,效果不方便演示,有興趣的同學可以自己測試,

添加拉伸效果

代碼

// 裁剪區域的移動事件
oTailor.onmousedown = function(ev) {
  // event事件對象
  var oEvent = ev || window.event;
  // 獲取cursor狀態
  var oCur = getCss(oTailor , 'cursor');    
  // 鼠標初始位置
  var sTmpX = oEvent.clientX;
  var sTmpY = oEvent.clientY;

  // 獲取裁剪區域的屬性 用一個對象保存起來方便調用
  oAttrs.left = getCss(oTailor , 'left');
  oAttrs.top = getCss(oTailor , 'top');
  oAttrs.width = getCss(oTailor , 'width');
  oAttrs.height = getCss(oTailor , 'height');    

  document.onmousemove = function(ev) {
    // 移動事件對象
    var oEvent = ev || window.event;
    // 當前鼠標位置減去初始鼠標位置 等於 鼠標移動距離
    var sLeftT = oEvent.clientX - sTmpX;
    var sTopT = oEvent.clientY - sTmpY ;

    // 表示鼠標移動的距離
    var oTmpHeight = '';
    var oTmpTop = '';
    var oTmpWidth = '';
    var oTmpLeft = '';

    switch(oCur) {
      case 'nw-resize' :       // 左上

        oTmpWidth = parseInt(oAttrs.width) - sLeftT ; 
        oTmpHeight = parseInt(oAttrs.height) - sTopT ; 
        oTmpLeft = parseInt(oAttrs.left) + sLeftT ; 
        oTmpTop = parseInt(oAttrs.top) + sTopT ;                   

        break;
      case 'ne-resize' :       // 右上
        // 此時width不能減去鼠標移動距離 因為此時移動距離為正值
        oTmpWidth = parseInt(oAttrs.width) + sLeftT ; 
        oTmpHeight = parseInt(oAttrs.height) - sTopT ; 
        // 右上角移動不需要left值 因為默認響右移動
        oTmpTop = parseInt(oAttrs.top) + sTopT ;                                     

        break;
      case 'sw-resize' :       // 左下
        // 同右上 height 必須是加上鼠標移動距離
        oTmpWidth = parseInt(oAttrs.width) - sLeftT ; 
        oTmpHeight = parseInt(oAttrs.height) + sTopT ; 
        oTmpLeft = parseInt(oAttrs.left) + sLeftT ;                   

        break;
      case 'se-resize' :       // 右下
        // 左下與右上的結合 同時去除left與top
        oTmpWidth = parseInt(oAttrs.width) + sLeftT ; 
        oTmpHeight = parseInt(oAttrs.height) + sTopT ;           

        break;
      case 'n-resize' :       // 上

        oTmpHeight = parseInt(oAttrs.height) - sTopT;
        oTmpTop = parseInt(oAttrs.top) + sTopT;        

        break;
      case 'w-resize' :       // 左

        oTmpWidth = parseInt(oAttrs.width) - sLeftT ;
        oTmpLeft = parseInt(oAttrs.left) + sLeftT;   

        break;
      case 's-resize' :     // 下

        oTmpHeight = parseInt(oAttrs.height) + sTopT;

        break;
      case 'e-resize' :       // 右

        var oTmpWidth = parseInt(oAttrs.width) + sLeftT;

        break;
      default :                      
        // 否則是移動裁剪區域
        tailorMove(oEvent , oTailor , oPicture , oShadow);

        break;
    }  

 

    // 向上拉到邊界
    if(parseInt(getCss(oTailor , 'top')) <= oPicture.offsetTop) {
      oTmpHeight = parseInt(getCss(oPicture,'height')) - (oPicture.offsetTop+parseInt(getCss(oPicture,'height'))-parseInt(getCss(oTailor,'top'))-parseInt(getCss(oTailor,'height')));
      oTmpTop = oPicture.offsetTop;
    }else if(oPicture.offsetTop+parseInt(getCss(oPicture,'height')) <= (parseInt(getCss(oTailor,'top'))+parseInt(getCss(oTailor,'height')))){
      // 向下拉到邊界
      oTmpHeight = oPicture.offsetTop+parseInt(getCss(oPicture,'height')) - parseInt(getCss(oTailor,'top'));
    }
    // 向左拉到邊界
    if((parseInt(getCss(oTailor , 'left'))) <= oPicture.offsetLeft) {
      oTmpWidth = parseInt(getCss(oPicture,'width')) - (oPicture.offsetLeft+parseInt(getCss(oPicture),'width')-parseInt(getCss(oTailor,'left'))-parseInt(getCss(oTailor,'width')))
      oTmpLeft = oPicture.offsetLeft;
    } else if(parseInt(getCss(oTailor , 'width')) + parseInt(getCss(oTailor,'left')) >= (oPicture.offsetLeft+oPicture.offsetWidth)) {
      // 向右拉到邊界    
      oTmpWidth = oPicture.offsetLeft+oPicture.offsetWidth - parseInt(getCss(oTailor,'left'));            
    }

    // 賦值
    if(oTmpWidth){
      setAssign(oTailor , 'width' , oTmpWidth + 'px');
    }
    if(oTmpHeight) {
      setAssign(oTailor , 'height' , oTmpHeight + 'px');
    }
    if (oTmpLeft) {
      setAssign(oTailor , 'left' , oTmpLeft + 'px');
    }
    if (oTmpTop) {
      setAssign(oTailor , 'top' , oTmpTop + 'px');        
    }      

    // 陰影區域繪制
    shadow(oPicture , oTailor , oShadow);

    // 添加裁剪邊框
    tailorBorder(oDiv , oHandle , oTailor);
  };

  // 當松開鼠標時注意取消移動事件
  document.onmouseup = function(ev) {
    // event事件對象
    var oEvent = ev || window.event;

    document.onmousemove = null;      
    oEvent.preventDefault();
  }

  oEvent.preventDefault();  
};

拉伸時注意移動距離的計算,特別是向上及向左移動時,要注意同時改變裁剪區域的left、top值,否則它只會向下、向右增大。來具體說一下如何計算:

原理

以鼠標向左上角拉伸為例,鼠標的移動距離與上面所講的一致,但此時注意計算出的值是一個負數,所以在計算裁剪區域的增加值時,要用原裁剪區的寬度或高度減去該值,同時,增加多少寬度,裁剪區的左偏移值就要減去多少,否則顯示的效果是裁剪區域向右增大,如下圖:

上圖中,綠色區域是拉伸時增加寬、高後的裁剪區域,如果沒進行偏移調整後的效果既是這樣,黃色區域是進行偏移跳轉後的裁剪區域,兩個的疊加區就是原來的裁剪區了。

這是左上角拉伸,左下角拉伸即其他與之類似,可依照向上套。

而另一關鍵,拉伸越界在上面已經說過,就不再敘述了。

裁剪區域的移動

現在來說最後一個功能,裁剪區域的移動。當鼠標移動到裁剪區域內部時,就會觸發移動事件,此時可以移動裁剪區域,代碼如下:

/* 裁剪區域的移動 */
function tailorMove(ev ,oTailor , oPicture ,oShadow) {
  var oEvent = ev || window.event;

  var oTmpx = oEvent.clientX - oTailor.offsetLeft;
  var oTmpy = oEvent.clientY - oTailor.offsetTop;    

  document.onmousemove = function(ev) {
    var oEvent = ev || window.event;              

    oLeft = oEvent.clientX - oTmpx;
    oTop = oEvent.clientY - oTmpy;  


    if(oLeft < oPicture.offsetLeft ) {
      oLeft = oPicture.offsetLeft ;  
    } else if(oLeft > (oPicture.offsetLeft + oPicture.offsetWidth - oTailor.offsetWidth)) {
      oLeft = oPicture.offsetLeft + oPicture.offsetWidth - oTailor.offsetWidth;
    }      
    if(oTop < oPicture.offsetTop) {
      oTop = oPicture.offsetTop;  
    } else if (oTop > (oPicture.offsetTop + oPicture.offsetHeight - oTailor.offsetHeight)) {
      oTop = oPicture.offsetTop + oPicture.offsetHeight - oTailor.offsetHeight;
    }        

    oTailor.style.left = ( oLeft)+ 'px';
    oTailor.style.top = (oTop) + 'px';    
    shadow(oPicture , oTailor , oShadow);
  }
}

獲取裁剪的位置

裁剪效果的功能基本完成,那麼就要獲取裁剪的位置,首先要知道需要獲取那些屬性。根據PHPGD庫操作,進行圖片裁剪需要知道,裁剪的起點坐標以及裁剪的寬高。我用一個函數來獲取這些數據,並將其封裝後返回:

function getEle() {
  var oPicture = $('img').get(0);
  var oTailor = $('.img_box').get(0);

  oAttrs.LeftX = (parseInt(getCss(oTailor,'left')) - oPicture.offsetLeft);
  oAttrs.LeftY = (parseInt(getCss(oTailor,'top')) - oPicture.offsetTop);
  oAttrs.Twidth = (parseInt(getCss(oTailor,'width')));
  oAttrs.Theight = (parseInt(getCss(oTailor,'height')));
  return oAttrs;
}

還有一個問題,如果網頁上的圖片是使用css壓縮後的圖片,那麼在此獲得的位置與裁剪大小會與你想像的有區別,可能裁剪後的圖片范圍會變大(原圖較大),也有可能會變小(原圖較小)。

如果能夠獲得原圖的大小,可以根據壓縮圖與原圖的比例來進行裁剪,這樣可以獲得正確的裁剪圖。

好了,一個簡單的圖片裁剪功能就完成了,可以利用ajax傳遞到後台進行處理了。

本文內容到此就結束了,有問題的話歡迎大家留言討論,希望本文對大家學習javascript有所幫助。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved