1,首先给div.photoWrap_canvas监听鼠标事件,有些人可能会问了,为什么要给div注册事件呢?我们操作的可是 canvas啊,刚刚我们说过我们为了能达到随意的切换相框的效果就给canvas上面蒙一个层,这样的话,我们可能就没法直接给canvas添加事件,希望大家理解。
2,在鼠标刚开始点击的时候执行 start()方法,他记住鼠标在div内部起点的位置,并告诉浏览器我们可以滑动了(bStart = 1)。
3,在鼠标移动的时候会先判断 是否执行过 start(),如果有的话,计算移动位置和开始位置的偏移值,然后赋值给 translate()方法。图片就可移动了
4,结束移动的时候,可以设置bStart = 0,等待下次启动
4,如何消除移动痕迹?以上讲述的能让我们的图片随之鼠标的移动而移动,不过在移动的过程中,我们会发现,移动方向的相反位置会留下,很多痕迹。
上面的图片可以看到,很多痕迹,就像电脑卡顿住了一样,,那如何去除呢?
我们想明白造成这样的原因是什么?随着我们的移动,图片的位置也在做相应的改变,注意,我们调用drawImage()的时候,我是画上去,就像画画一样,当然有痕迹,幸好,canvas对象也给我们提供了清除的方法 clearRect()--清除矩形,没错使用这个方法,我们就能清除痕迹了。
让我们重写onDraw()方法:
function onDraw(){ ctx.clearRect(- ctxW,-ctxH, 2 * ctxW, 2 * ctxH); ctx.drawImage(img,0,0,300,400); }重写之后的效果:
但是,当我们想左移动的时候会发现,还是会有痕迹,怎么回事呢?
在已上代码是指,在图片右下角的相反方向,清除一个是当前canvas大小2的范围。(在这里需要大家注意一点,外面的那个框是 c 这个dome元素,而我们现在对canvas做的任何操作,都是有 c 这个元素生成的 ctx对象上,所以,图像移动,那么图片的右下角也移动,当然它本身还是图片的右下角)其实不难理解,canvas初始化的时候,ctxW和ctxH这个就作为画布的右下角,为什么要用负号呢,因为clearRect(x,y,width,height)这个方法的使用是以(x,y)为起点,向右清除一个矩形范围的,注意是向右,那我们肯定是不能向右的(再向右的话,就什么也没有了),当然向左也不行,那怎么办呢?
在这里呢,我也通过查找博文找到了方案,就是我们用图片的的中心点,当然我们canvas的原点,什么意思呢?让我们来修改下代码:
img.onload=function(){ imgW = 300 || img.width, imgH = 400 || img.height; // 把canvas的原点设置为图片的中心点,但是现实的时候,要还原,否则图片会已左上角钉在canvas的中心点上 ctx.translate(imgW /2,imgH/2); onDraw(); ctx.save(); }以上代码,修改了图片刚加载完毕之后,我们做的操作,就是给canvas先平移下位置,平移的位置就是图片大小的中心点上,这就完成了图片中心点偏移。
偏移之后,我们页面刚开始的时候,不能就这么显示对吧?不然会被客户骂的,那我们要进行显示还原。
function onDraw(){ // 这是清除图片因为平移而造成的痕迹,-ctxw是图片平移的反方向的位置,2*ctxW,是清除的面积 ctx.clearRect(- ctxW,-ctxH, 2 * ctxW, 2 * ctxH); // -imgW/2 是为了让图片显示的回复正常,因为上面显示的时候做了旋转 ctx.drawImage(img,-imgW / 2, -imgH / 2,300,400); }代码:drawImage()的时候,(x,y)的值,本来是(0,0)的,也就是canvas的左上角,但是,我们把原点偏移了,通过显示的时候把这个偏移量给补回来就好了,所有就是(-imgW/2,-imgH/2);
好了,写到这儿,我们这个功能算是完成了一半,我们实现了相框的切换和图片的平移,下面就是图的缩放和图片合并了。
5,图片缩放 // 注册鼠标滚轮事件,,暂时只做除去 firfox之外的浏览器 window.onmousewheel = document.onmousewheel = scrollFnc; var scale = 1; function scrollFnc(ev){ var delta = ev.wheelDelta; if(delta > 0 && scale <= 5){ //滚轮向上 scale += 0.1; }else if(delta < 0 && scale >= 1){ scale -= 0.2; } ctx.scale(scale,scale); onDraw(); }注意,我们这边缩放是通过鼠标的滚轮来做的,当然了,如果使用手机来的话,那就需要手势的操作了,通过计算两个手指或则三个手指之间的距离来进行缩放操作,以后我会补上,现在先这么做吧。
代码很简单,获取鼠标在元素上滚轮的动作如果是负数就缩小,正数就放大,scale(w,h),放大缩小的函数。
6,图片和相框的合并
我们可以进行图片的缩放和平移了,那么下步就是把图片和相框进行合并,我刚才说了,为了能够随意的切换相框,那我就先用div的背景来做,并不是直接加入到canvas中,那样会很麻烦。
// 完成 var newxCtx; $('#btnOk').click(function(){ newCanvas = document.createElement('canvas'); newCanvas.width = 300; newCanvas.height = 400; newxCtx = newCanvas.getContext('2d'); var img = new Image(); img.src = $('.photoWrap_canvas').attr('data-url'); img.onload=function(){ $('.photoWrap_canvas').hide(); // var x = (-ctxW / 2) - offsetX_ctx, // y = (-ctxH / 2) - offsetY_ctx; // console.log(offsetX_ctx,offsetY_ctx); newxCtx.drawImage(c,0,0); newxCtx.drawImage(img,0,0,300,400); //-ctxW /2, -ctxH / 2 $('.wrap').prepend(newCanvas); } })其实大家看看到了,我是把相框和canvas(图片)再重新drawImage到一个新的canvas里面去的,那为什么这么做呢?直接把相框draw到原有的canvas不久行了吗?
我先给大家看下如果这么做的效果是什么: