js图片随鼠标移动,旋转,缩放(实现方法一)
// 元素移动 var moveMouse = false; $(\'.img\').mousedown(function (e) { e.preventDefault() e.stopPropagation() moveMouse = true var dis = { X: e.pageX - $(\'.box\').position().left, Y: e.pageY - $(\'.box\').position().top } $(document).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 }) } }) }) $(document).on(\'mouseup\', function (e) { moveMouse = false });
var pointA = { // 元素中心点 元素1/2自身宽高 + 元素的定位 X: $(\'.box\').width() / 2 + $(\'.box\').offset().left, Y: $(\'.box\').height() / 2 + $(\'.box\').offset().top }; console.log(pointA) var pointB = {}; var pointC = {}; // A,B,C分别代表中心点,起始点,结束点坐标 // 这里通过鼠标的移动获取起始点和结束点 var typeMouse = false; var allA = 0; // 存放鼠标旋转总共的度数 var count = 0; // 元素跟随鼠标移动旋转 $(".rotate").on(\'mousedown\', function (e) { e.preventDefault() e.stopPropagation() typeMouse = true; //获取起始点坐标 if (count < 1) { // 以鼠标第一次落下的点为起点 pointB.X = e.pageX; pointB.Y = e.pageY; count++ } console.log(5, pointA, pointB) $(document).on(\'mousemove\', function (e) { e.preventDefault() if (typeMouse) { pointC.X = e.pageX; pointC.Y = e.pageY; // 获取结束点坐标 // 计算出旋转角度 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); if (direct < 0) { allA = -angleA; //叉乘结果为负表示逆时针旋转, 逆时针旋转减度数 } else { allA = angleA; //叉乘结果为正表示顺时针旋转,顺时针旋转加度数 } // console.log(allA) $(\'.img-box\').css(\'transform\', \'rotate(\'+allA+\'deg)\') } }); }); $(document).on(\'mouseup\', function (e) { typeMouse = false; });
// 元素跟随鼠标移动拉伸 $(".rotate, .rotate1").on(\'mousedown\', function (e) { e.preventDefault() e.stopPropagation() typeMouse = true; //获取起始点坐标 if (count < 1) { // 以鼠标第一次落下的点为起点 pointB.X = e.pageX; pointB.Y = e.pageY; count++ } console.log(5, pointA, pointB) $(document).on(\'mousemove\', function (e) { e.preventDefault() if (typeMouse) { pointC.X = e.pageX; pointC.Y = e.pageY; // 获取结束点坐标 // 计算每次移动元素的半径变化,用作拉伸 var scalX1 = pointB.X - pointA.X var scalY1 = pointB.Y - pointA.Y var scalX = pointC.X - pointA.X var scalY = pointC.Y - pointA.Y // 计算出拉伸比例 var sa = Math.sqrt(scalX1 * scalX1 + scalY1 * scalY1) var ss = Math.sqrt(scalX * scalX + scalY * scalY) var sc = ss / sa // console.log(sc) $(\'.img-box\').css(\'transform\', \'scale(\'+sc+\')\') } }); }); $(document).on(\'mouseup\', function (e) { typeMouse = false; });
html代码
<div class="container"> <div class="box"> <div class="img-box"> <div class="flat">翻转</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>
<!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; } .box { position: absolute; left: 200px; top: 100px; width: 400px; height: 400px; color: #fff; /* background-color: rosybrown; */ } .img-box { position: absolute; /* left: 30px; top: 30px; */ width: 400px; height: 400px; 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, .rotate1 { position: absolute; right: -20px; bottom: -20px; width: 40px; height: 40px; background-color: royalblue; z-index: 3; cursor: se-resize; line-height: 40px; text-align: center; } .rotate1 { left: -20px; right: auto; } .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="rotate1">旋转</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="http://code.jquery.com/jquery-2.1.4.min.js"></script> --> <script src="./jquery-3.1.1.min.js"></script> <script src="./common-validate/index.js"></script> <script> console.log(commonValidate) 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 allA = 0; // 存放鼠标旋转总共的度数 var count = 0; var mPointB = {} // 移动的B点距离 var init = { count: 0 } var oldTarget = { target: null, angle: 0 } // 元素跟随鼠标移动旋转拉伸 $(".rotate, .rotate1").on(\'mousedown\', function (e) { e.preventDefault() e.stopPropagation() // 计算两个旋转方块之间的角度 var tanA = $(\'.box\').width() / $(\'.box\').height() var d = Math.round(Math.atan(tanA) * 180 / Math.PI) if (oldTarget.target && oldTarget.target != e.currentTarget) { if (e.currentTarget == $(\'.rotate\')[0]) { oldTarget.angle = 2 * d } else { oldTarget.angle = -2 * d } } else { oldTarget.angle = 0 } typeMouse = true; //获取起始点坐标 if (count < 1) { // 以鼠标第一次落下的点为起点 pointB.X = e.pageX; pointB.Y = e.pageY; init.count = 0 oldTarget.target = e.currentTarget count++ } if (mPointB.flag) { // 如果移动后,元素的B点也需要加上平移的距离 pointB.X += mPointB.X pointB.Y += mPointB.Y mPointB.flag = false init.count = 0 } console.log(\'pointA\', pointA, \'pointB\', pointB) $(document).on(\'mousemove\', function (e) { e.preventDefault() if (typeMouse) { pointC.X = e.pageX; pointC.Y = e.pageY; // 获取结束点坐标 // 计算每次移动元素的半径变化,用作拉伸 var scalX1 = pointB.X - pointA.X var scalY1 = pointB.Y - pointA.Y 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); if (direct < 0) { allA = -angleA; //叉乘结果为负表示逆时针旋转, 逆时针旋转减度数 } else { allA = angleA; //叉乘结果为正表示顺时针旋转,顺时针旋转加度数 } allA += oldTarget.angle // $(\'.img-box\').css(\'transform\', \'rotate(\'+allA+\'deg)\') // 计算出拉伸比例 var sa = Math.sqrt(scalX1 * scalX1 + scalY1 * scalY1) var ss = Math.sqrt(scalX * scalX + scalY * scalY) var sc = ss / sa // console.log(sa, ss, sc) $(\'.img-box\').css(\'transform\', \'rotate(\'+allA+\'deg) scale(\'+sc+\')\') // $(\'.img-box\').css(\'transform\', \'scale(\'+sc+\')\') } }); }); // 元素移动 $(\'.img\').mousedown(function (e) { e.preventDefault() e.stopPropagation() moveMouse = true if (init.count < 1) { init = { // X: e.pageX, // Y: e.pageY, X: pointA.X, Y: pointA.Y, count: 1 } } var dis = { X: e.pageX - $(\'.box\').position().left, Y: e.pageY - $(\'.box\').position().top } $(document).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 }) // console.log($(\'.box\').offset(), $(\'.box\').position(), end, dis) pointA = { // 移动后,重新计算元素中心点 元素1/2自身宽高 + 元素的定位 X: $(\'.box\').width() / 2 + $(\'.box\').offset().left, Y: $(\'.box\').height() / 2 + $(\'.box\').offset().top }; if (count > 0) { // 每次移动按下的点不一致,有误差,使用中心点来计算 // mPointB.X = event.pageX - init.X // mPointB.Y = event.pageY - init.Y mPointB.X = pointA.X - init.X mPointB.Y = pointA.Y - init.Y mPointB.flag = true } // console.log(pointA, mPointB) } }) }) $(document).on(\'mouseup\', function (e) { typeMouse = false; moveMouse = false }); </script> </html>
补充内容:
感谢博友提出问题,在平移时,由于每次鼠标按下的位置不一样,我是用最后一次鼠标移动的位置减去第一次鼠标按下的位置, 如果多次移动,伸缩计算就会有误差
而元素的中心点是一直保持在元素中心,每次移动后都会改变,所以改成使用最后一次移动的元素中心点减去第一次移动时的中心点,能消除误差
代码里红色的是修改后的
这个方法中pointB的计算有些麻烦,特别是四个角都以旋转时. 之后又试了一种方法,比较简单一些.第二种实现方法可以看这篇https://www.cnblogs.com/steamed-twisted-roll/p/14292478.html