如图,代码在最下面
实现目标:使用canvas画出地图,且可以缩放,拖拽
个人理解:其实canvas动画就是一次次的擦除重绘,就像是小时候看的动画片,每一帧播的很快,因为视觉停留,看起来像是连续动画而已。
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) //下面的变量名以此为准
后面8个参数比较重要了:前 4 个是定义图像源的切片位置和大小,后 4 个则是定义切片的目标显示位置和大小。
贴个菜鸟链接 大概回顾下canvas drawImage
或者直接看下图
三个事件:onmousedown,onmousemove,onmouseup
大概讲下思路,后面上代码
当拖拽的时候不能无限的拖动,否则会超出画布,所以需要限制一下 dx, dy, 两个参数
监听滚轮事件:onmousewheel
如图:红色框是画布, 画布是不动的,我们根据这个看图片怎么放大。
定义变量:
以下是公式:
imgXN = (1-imgScale)*(pos.x-imgX)/imgScale+(pos.x-(pos.x-imgX)/imgScale);
imgYN = (1-imgScale)*(pos.y-imgY)/imgScale+(pos.y-(pos.y-imgY)/imgScale);
上面公式没有简化,其实如下
var newPos = {x:((pos.x-imgX)/imgScale).toFixed(2) , y:((pos.y-imgY)/imgScale).toFixed(2)};
imgXN = (1-imgScale)*newPos.x+(pos.x-newPos.x);
imgYN = (1-imgScale)*newPos.y+(pos.y-newPos.y);
以上公式不详解了,大意就是:先把鼠标位置相对原图的位置计算出来,然后以该点为中心重新进行缩放(不知道有没有更好的思路呢)
以下源码:
var canvas, context;
var img, imgX = 0, imgY = 0, imgScale = 1;
var MINIMUM_SCALE = 1.0 ,pos={},posl={},dragging = false;
(function int() {
canvas = document.getElementById('scaleDragCanvas'); //画布对象
context = canvas.getContext('2d');//画布显示二维图片
loadImg();
canvasEventsInit();
})();
function loadImg() {
img = new Image();
img.onload = function () {
drawImage();
}
img.src = 'https://static.zhihu.com/liukanshan/images/comics/bg-89c9bdc3.jpg';//刘看山
}
function drawImage() {
context.clearRect(0, 0, canvas.width, canvas.height);
// 保证 imgX 在 [img.width*(1-imgScale),0] 区间内
if(imgX0) {
imgX=0
}
// 保证 imgY 在 [img.height*(1-imgScale),0] 区间内
if(imgY0) {
imgY=0
}
context.drawImage(
img, //规定要使用的图像、画布或视频。
0, 0, //开始剪切的 x 坐标位置。
img.width, img.height, //被剪切图像的高度。
imgX, imgY,//在画布上放置图像的 x 、y坐标位置。
img.width * imgScale, img.height * imgScale //要使用的图像的宽度、高度
);
}
/*事件注册*/
function canvasEventsInit() {
canvas.onmousedown = function (event) {
dragging = true;
pos = windowToCanvas(event.clientX, event.clientY); //坐标转换,将窗口坐标转换成canvas的坐标
};
canvas.onmousemove = function (evt) { //移动
if(dragging){
posl = windowToCanvas(evt.clientX, evt.clientY);
var x = posl.x - pos.x, y = posl.y - pos.y;
imgX += x;
imgY += y;
pos = JSON.parse(JSON.stringify(posl));
drawImage(); //重新绘制图片
}
};
canvas.onmouseup = function () {
dragging = false;
};
canvas.onmousewheel = canvas.onwheel = function (event) { //滚轮放大缩小
var pos = windowToCanvas (event.clientX, event.clientY);
event.wheelDelta = event.wheelDelta ? event.wheelDelta : (event.deltalY * (-40)); //获取当前鼠标的滚动情况
var newPos = {x:((pos.x-imgX)/imgScale).toFixed(2) , y:((pos.y-imgY)/imgScale).toFixed(2)};
if (event.wheelDelta > 0) {// 放大
imgScale +=0.1;
imgX = (1-imgScale)*newPos.x+(pos.x-newPos.x);
imgY = (1-imgScale)*newPos.y+(pos.y-newPos.y);
} else {// 缩小
imgScale -=0.1;
if(imgScale
立个flag,有空封装一下