jquery圖片隨鼠標移動,旋轉,縮放(實現方法二)


之前寫了一個關於圖片旋轉拉伸的實現,最近正好用到這個小功能,看了一下,發現之前寫的方法有一些復雜,自己在之前的基礎上簡化了一下,記錄下方法
 
效果圖
 
平移部分的代碼沒啥變化,主要是旋轉的方法

這里主要寫一下旋轉方法的實現

這里的旋轉,放大縮小都是以圖片的中心點計算

1.先計算出圖片的中心點A
2.鼠標按下的地方計為B
3.移動停止的地方計為C

旋轉的角度就是這3點,B-A-C cosA
知道這3點坐標,就可以求出角度

1.先算出三條邊的長度
2.利用兩點坐標求直線公式算出AB,AC,BC線段的長度
 
 var lengthAB = Math.sqrt(Math.pow(pointA.X - pointB.X, 2) +
            Math.pow(pointA.Y - pointB.Y, 2)),
          lengthAC = Math.sqrt(Math.pow(pointA.X - pointC.X, 2) +
            Math.pow(pointA.Y - pointC.Y, 2)),
          lengthBC = Math.sqrt(Math.pow(pointB.X - pointC.X, 2) +
            Math.pow(pointB.Y - pointC.Y, 2));

 

3.已知三角形的三邊長,求cos值的公式:cos A=(b²+c²-a²)/2bc
 
var cosA = (Math.pow(lengthAB, 2) + Math.pow(lengthAC, 2) - Math.pow(lengthBC, 2)) /
          (2 * lengthAB * lengthAC); //   余弦定理求出旋轉角

 

4.在根據公式,轉換成度數 var angle = Math.acos(cosA) * 180 / Math.PI

角度算出后,使用css3的rotate屬性設置

這里需要注意,第一次按下旋轉可以使用這個方法,但是第二次鼠標按下旋轉的度數是在第一次旋轉之后的基礎上,因此需要加上上一次已經旋轉的角度

這里是把旋轉的角度先存起來
$('.img-box').attr({rotate: allA})
下一次鼠標按下時取出
var rotate = $('.img-box').attr('rotate')

旋轉時,如果rotate有值就相加
if (rotate) {
  allA += Number(rotate)
}
旋轉角度設置:
$('.img-box').css('transform', 'rotate('+allA+'deg)')
 
 
 
縮放的實現

圖片的縮放有些不一樣,它是需要在原圖的距離上計算縮放比例,如圖
 
完整代碼:
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<style>
  html, body {
    margin: 0;
    font-size: 14px;
  }
  .container {
    /* padding: 20px;
    border: 1px solid sienna; */
    position: relative;
    width: 1000px;
    height: 800px;
    background-color: burlywood;
  }
  .box {
    position: absolute;
    left: 200px;
    top: 100px;
    width: 400px;
    height: 300px;
    color: #fff;
    /* background-color: rosybrown; */
  }
  .img-box {
    position: absolute;
    width: 100%;
    height: 100%;
    background-color: sandybrown;
  }
  .flat {
    position: absolute;
    right: -20px;
    top: -20px;
    width: 40px;
    height: 40px;
    background-color: seagreen;
    z-index: 3;
    line-height: 40px;
    text-align: center;
    cursor: default;
  }
  .rotate {
    position: absolute;
    width: 40px;
    height: 40px;
    background-color: royalblue;
    z-index: 3;
    cursor: se-resize;
    line-height: 40px;
    text-align: center;
  }
  .rotate:nth-child(2) {
    right: -20px;
    bottom: -20px;
  }
  .rotate:nth-child(3) {
    left: -20px;
    bottom: -20px;
  }
  .rotate:nth-child(4) {
    left: -20px;
    top: -20px;
  }
  .img {
    width: 100%;
    height: 100%;
    cursor: move;
  }
  .header {
    height: 50px;
  }
</style>
<body>
  <div class="header">
    <h1>圖形編輯</h1>
  </div>
  <div class="container">
    <div class="box">
      <div class="img-box">
        <div class="flat">翻轉</div>
        <div class="rotate">旋轉</div>
        <div class="rotate">旋轉</div>
        <div class="rotate">旋轉</div>
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1141259048,554497535&fm=26&gp=0.jpg" alt="" class="img">
      </div>
    </div>
  </div>
</body>
<script src="./jquery-3.1.1.min.js"></script>
<script>

  var flat = -1
  // 鏡像翻轉
  $(".flat").click(function() {
    $(".img").css("transform", "scaleX("+flat+")")
    flat = -flat
  })

  var pointA = { // 元素中心點 元素1/2自身寬高 + 元素的定位
    X: $('.box').width() / 2 + $('.box').offset().left,
    Y: $('.box').height() / 2 + $('.box').offset().top
  };
  console.log(pointA, $('.box').position())

  var pointB = {};
  var pointC = {}; // A,B,C分別代表中心點,起始點,結束點坐標
  // 這里通過鼠標的移動獲取起始點和結束點
  var typeMouse = false;
  var moveMouse = false;
  var sa = 1 // 初始拉伸比例
  var count = 0

  // 元素跟隨鼠標移動旋轉拉伸
  $(".rotate").on('mousedown', function (e) {
    e.preventDefault()
    e.stopPropagation()

    typeMouse = true; 
    //獲取起始點坐標
    pointB.X = e.pageX;
    pointB.Y = e.pageY;
    console.log('pointA', pointA, 'pointB', pointB)

    // 計算出初始拉伸比例 
    if (count < 1) {
      var scalX1 = pointB.X - pointA.X
      var scalY1 = pointB.Y - pointA.Y
      sa = Math.sqrt(scalX1 * scalX1 + scalY1 * scalY1)
      count++
    }

    // 取出當前選轉的角度
    var rotate = $('.img-box').attr('rotate')
    // console.log(rotate, scale)

    $('.container').on('mousemove', function (e) {
      e.preventDefault()
      e.stopPropagation()
      if (typeMouse) {

        pointC.X = e.pageX;
        pointC.Y = e.pageY; // 獲取結束點坐標
        // console.log(pointC)
        // 計算每次移動元素的半徑變化,用作拉伸
        var scalX = pointC.X - pointA.X
        var scalY = pointC.Y - pointA.Y

        // 計算出旋轉角度
        var AB = {};
        var AC = {};
        AB.X = (pointB.X - pointA.X);
        AB.Y = (pointB.Y - pointA.Y);
        AC.X = (pointC.X - pointA.X);
        AC.Y = (pointC.Y - pointA.Y); // 分別求出AB,AC的向量坐標表示
        var direct = (AB.X * AC.Y) - (AB.Y * AC.X); // AB與AC叉乘求出逆時針還是順時針旋轉
        var lengthAB = Math.sqrt(Math.pow(pointA.X - pointB.X, 2) +
            Math.pow(pointA.Y - pointB.Y, 2)),
          lengthAC = Math.sqrt(Math.pow(pointA.X - pointC.X, 2) +
            Math.pow(pointA.Y - pointC.Y, 2)),
          lengthBC = Math.sqrt(Math.pow(pointB.X - pointC.X, 2) +
            Math.pow(pointB.Y - pointC.Y, 2));
        var cosA = (Math.pow(lengthAB, 2) + Math.pow(lengthAC, 2) - Math.pow(lengthBC, 2)) /
          (2 * lengthAB * lengthAC); //   余弦定理求出旋轉角
        var angleA = Math.round(Math.acos(cosA) * 180 / Math.PI);
        var allA = 0
        if (direct < 0) {
          allA = -angleA; //叉乘結果為負表示逆時針旋轉, 逆時針旋轉減度數
        } else {
          allA = angleA; //叉乘結果為正表示順時針旋轉,順時針旋轉加度數
        }

        // 如果上一次按下旋轉已經有度數,需要加上上一次的度數
        if (rotate) {
          allA += Number(rotate)
        }
        // console.log(allA, rotate)

        // 計算出拉伸比例
        var ss = Math.sqrt(scalX * scalX + scalY * scalY)
        var sc = ss / sa                                                                                                                             
        // console.log(sc)

        $('.img-box').css('transform', 'rotate('+allA+'deg) scale('+sc+')')
        $('.img-box').attr({rotate: allA})
      }
    });
  });

  // 元素移動
  $('.img').on('mousedown', function (e) {
    e.preventDefault()
    e.stopPropagation()
    moveMouse = true

    var dis = {
      X: e.pageX - $('.box').position().left,
      Y: e.pageY - $('.box').position().top
    }
    $('.container').on('mousemove', function (event) {
      event.preventDefault()
      event.stopPropagation()
      if (moveMouse) {
        var end = {}
        end.X = event.pageX - dis.X
        end.Y = event.pageY - dis.Y

        $('.box').css({
          'left': end.X,
          'top': end.Y
        })

        pointA = { // 移動后,重新計算元素中心點 元素1/2自身寬高 + 元素的定位
          X: $('.box').width() / 2 + $('.box').offset().left,
          Y: $('.box').height() / 2 + $('.box').offset().top
        };
        // console.log(pointA, mPointB)
      }
    })
  })
  $(document).on('mouseup', function (e) {
    typeMouse = false;
    moveMouse = false
  });


</script>

</html>

 

這里說一下,這個方法是用在自己的項目,沒有經過多種場景的測試.主要是提供一種思路,如果你放在項目中有出現問題,可以留言探討
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM