canvas实现图片缩放、移动、旋转功能基于两个方面:1. canvas图像变换; 2. drawImage()方法。其他就是一些坐标点的计算了。
html部分:
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <style> 6 *{margin:0;padding:0;} 7 body{background-color:#000;} 8 canvas{display:block;border:1px solid #eee; margin:10px auto;} 9 .btn-box{margin:10px auto;width:800px;text-align:center;} 10 .btn-box a{ display: inline-block; width: 80px; height: 32px; line-height: 32px; text-decoration: none; color: #ddd; border: 1px solid #fff; } 11 .btn-box a:hover{background-color: #333;color:#eee;} 12 </style> 13 <title>demo</title> 14 </head> 15 <body> 16 <canvas id="canvas"></canvas> 17 <!-- 按钮区 --> 18 <div class="btn-box"> 19 <a href="javascript:void(0);" id="bigBtn">点击放大</a> 20 <a href="javascript:void(0);" id="smallBtn">点击缩小</a> 21 <a href="javascript:void(0);" id="leftRotate">点击左旋</a> 22 <a href="javascript:void(0);" id="rightRotate">点击右旋</a> 23 </div> 24 <script> 25 // js 部分 26 </script> 27 </body> 28 </html>
js部分:
1 (function(){ 2 // 基础配置 3 var config = { 4 width : 900, // 设置canvas的宽 5 height : 600, // 设置canvas的高 6 imgSrc : '../images/001.jpg', // 图片路径 7 maxScale : 4.0, // 最大放大倍数 8 minScale : 0.1, // 最小放大倍数 9 step : 0.1 // 每次放大、缩小 倍数的变化值 10 }; 11 12 // 标记是否移动事件 13 var isMove = false; 14 15 var imgStatus = { 16 'scale' : 1.0, 17 'rotate' : 0 18 }; 19 var lastStatus = {}; 20 var currentStatus = {}; 21 22 var bigBtn = document.getElementById("bigBtn"); 23 var smallBtn = document.getElementById("smallBtn"); 24 var leftRotate = document.getElementById("leftRotate"); 25 var rightRotate = document.getElementById("rightRotate"); 26 var canvas = document.getElementById("canvas"); 27 canvas.width = config.width; 28 canvas.height = config.height; 29 var ctx = canvas.getContext("2d"); 30 31 var img = new Image(); 32 img.src = config.imgSrc; 33 34 img.onload = function() { 35 lastStatus = { 36 "imgX" : -1 * img.width / 2, 37 "imgY" : -1 * img.height / 2, 38 'mouseX' : 0, 39 'mouseY' : 0, 40 'translateX' : canvas.width / 2, 41 'translateY' : canvas.height /2, 42 'scale' : 1.0, 43 'rotate' : 0 44 }; 45 drawImgByStatus(canvas.width / 2, canvas.height / 2); 46 }; 47 48 bigBtn.onclick = function() { 49 imgStatus.scale = (imgStatus.scale >= config.maxScale) ? config.maxScale : imgStatus.scale + config.step; 50 drawImgByStatus(canvas.width / 2, canvas.height / 2); 51 } 52 53 smallBtn.onclick = function() { 54 imgStatus.scale = (imgStatus.scale <= config.minScale) ? config.minScale : imgStatus.scale - config.step; 55 drawImgByStatus(canvas.width / 2, canvas.height / 2); 56 } 57 58 leftRotate.onclick = function() { 59 var rotate = parseInt(imgStatus.rotate / 90) * 90 - 90; 60 imgStatus.rotate = rotate; 61 drawImgByStatus(canvas.width / 2, canvas.height / 2); 62 } 63 64 rightRotate.onclick = function() { 65 var rotate = parseInt(imgStatus.rotate / 90) * 90 + 90; 66 imgStatus.rotate = rotate; 67 drawImgByStatus(canvas.width / 2, canvas.height / 2); 68 } 69 70 canvas.onmousedown = function(e) { 71 isMove = true; 72 canvas.style.cursor = "move"; 73 74 var box = windowToCanvas(e.clientX, e.clientY); 75 lastStatus.mouseX = box.x; 76 lastStatus.mouseY = box.y; 77 } 78 79 canvas.onmouseout = function(e) { 80 isMove = false; 81 canvas.style.cursor = "default"; 82 } 83 84 canvas.onmouseup = function(e) { 85 isMove = false; 86 canvas.style.cursor = "default"; 87 } 88 89 canvas.onmousemove = function(e) { 90 if(isMove) { 91 var box = windowToCanvas(e.clientX, e.clientY); 92 drawImgByMove(box.x, box.y); 93 } 94 } 95 96 canvas.onmousewheel = function(e) { 97 if(e.wheelDelta > 0) { 98 imgStatus.scale = (imgStatus.scale >= config.maxScale) ? config.maxScale : imgStatus.scale + config.step; 99 } else { 100 imgStatus.scale = (imgStatus.scale <= config.minScale) ? config.minScale : imgStatus.scale - config.step; 101 } 102 var mXY = windowToCanvas(e.clientX, e.clientY); 103 drawImgByStatus(mXY.x, mXY.y); 104 } 105 106 function drawImgByMove(x, y) { 107 lastStatus.translateX = lastStatus.translateX + (x - lastStatus.mouseX); 108 lastStatus.translateY = lastStatus.translateY + (y - lastStatus.mouseY); 109 ctx.clearRect(0, 0, canvas.width, canvas.height); 110 ctx.save(); 111 ctx.translate(lastStatus.translateX, lastStatus.translateY); 112 ctx.rotate(imgStatus.rotate * Math.PI / 180); 113 ctx.scale(imgStatus.scale, imgStatus.scale); 114 ctx.drawImage(img, lastStatus.imgX, lastStatus.imgY, img.width, img.height); 115 ctx.restore(); 116 117 lastStatus.mouseX = x; 118 lastStatus.mouseY = y; 119 } 120 121 function drawImgByStatus(x, y) { 122 var imgX = lastStatus.imgX - (x - lastStatus.translateX) / lastStatus.scale; 123 var imgY = lastStatus.imgY - (y - lastStatus.translateY) / lastStatus.scale; 124 ctx.clearRect(0, 0, canvas.width, canvas.height); 125 ctx.save(); 126 ctx.translate(x, y); 127 ctx.rotate(imgStatus.rotate * Math.PI / 180); 128 ctx.scale(imgStatus.scale, imgStatus.scale); 129 ctx.drawImage(img, imgX, imgY, img.width, img.height); 130 ctx.restore(); 131 132 lastStatus = { 133 'imgX' : imgX, 134 'imgY' : imgY, 135 'translateX' : x, 136 'translateY' : y, 137 'scale' : imgStatus.scale, 138 'rotate' : imgStatus.rotate 139 }; 140 } 141 142 /** 143 * 计算相对于canvas左上角的坐标值 144 */ 145 function windowToCanvas(x, y) { 146 var box = canvas.getBoundingClientRect(); 147 return { 148 'x' : x - box.left, 149 'y' : y - box.top 150 }; 151 } 152 })();