canvas 旋转图片并展示图片中的小部分

canvas 旋转图片并展示图片中的小部分

月光魔力鸭

2019-09-23 11:08 阅读 1137 喜欢 0 canvas 图片旋转

需求如下:有一张大图,需要显示大图中的一小部分,目前能知道的时候小图的宽高和坐标,同时大图有一个旋转角度可以知道,目标就是把小图正确的显示出来。

实际上,如果只针对大图的显示和旋转,可以通过css就能搞定,但是这里面有个问题,旋转后实际上他原来的空间不变,会导致并不美观,最终还是决定通过canvas来实现。

大图的旋转显示

image.onload = function(){
    var img = this;
    var width = img.width;
    var height = img.height;
    
    //针对角度来算
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    var direction = ((parseInt(rotate,10) + 360) % 360) / 90;
    switch (direction) {
      case 1: {
        canvas.width = height;
        canvas.height = width;
        ctx.rotate(90*Math.PI/180);
        ctx.drawImage(img, 0, -height,width,height);
        break;
      }
      case 2: {
        canvas.width = width;
        canvas.height = height;
        ctx.rotate(180*Math.PI/180);
        ctx.drawImage(img, -width, -height,width,height);
        break;
      }
      case 3: {
        canvas.width = height;
        canvas.height = width;
        ctx.rotate(270*Math.PI/180);
        ctx.drawImage(img, -width, 0,width,height);
        break;
      }
      case 0:
      case 4:
      default: {
        canvas.width = width;
        canvas.height = height;
        ctx.rotate(0);
        ctx.drawImage(img, 0, 0,width,height);
        break;
      }
    }
    $item.get(0).appendChild(canvas);
}

大图旋转和小图展示旋转其实是一样的,只是在canvas drawImage 的时候多几个参数而已。

小图展示旋转

image.onload = (function(direction,filePath,div,showwidth,showheight,sshowwidth,sshowheight,x,y,imgIndex){
    return function(){
    var img = this;
    var thiz = img;
    var width = img.width;
    var height = img.height;
    var canvas = document.createElement('canvas');
    canvas.style.position='relative';
    var ctx = canvas.getContext('2d');
    console.log(direction);
    var canvasX = 0,canvasY = 0;
    switch (direction) {
      case 1: {
        canvas.width = showheight;
        canvas.height = showwidth;
        ctx.rotate(90*Math.PI/180);
        ctx.drawImage(thiz,x,y,showwidth,showheight,0,-showheight,showwidth,showheight);
        break;
      }
      case 2: {
        canvas.width = showwidth;
        canvas.height = showheight;
        ctx.rotate(180*Math.PI/180);
        ctx.drawImage(thiz,x,y,showwidth,showheight,-showwidth,-showheight,showwidth,showheight);
        break;
      }
      case 3: {
        canvas.width = showheight;
        canvas.height = showwidth;
        ctx.rotate(270*Math.PI/180);
        ctx.drawImage(thiz,x,y,showwidth,showheight,-showwidth,0,showwidth,showheight);
        break;
      }
      case 0:
      case 4:
      default: {
        canvas.width = showwidth;
        canvas.height = showheight;
        ctx.rotate(0);
        ctx.drawImage(thiz,x,y,showwidth,showheight,0,0,finalWidth,finalHeight);
        break;
      }
    }
    div.appendChild(canvas);

    div.setAttribute('index',imgIndex);//设置索引
    div.style.width = sshowwidth+'px';
    div.style.height = sshowheight+'px';
    //根据index 查找比对前后插入。
    var sd = document.getElementById('showDetail');
    var cn = sd.childNodes;
    if(cn.length == 0){
        sd.appendChild(div);
    }else{
        //循环找到
        var diff = 10,nearNode = null,isBefore = false;
        cn.forEach(function(tempNode,nodeIndexL){
            var nodeIndex = parseInt(tempNode.getAttribute('index'),10);
            //比对哪个更接近imgIndex
            var currentDiff = Math.abs(nodeIndex - imgIndex);
            if(currentDiff < diff && nodeIndex > imgIndex){
                diff = currentDiff;
                nearNode = tempNode;
                isBefore = true;
            }
        })
        if(isBefore){
            sd.insertBefore(div,nearNode);
        }else{
            sd.appendChild(div);
        }
    }
    
    }
})(direction,filePath,div,showwidth,showheight,sshowwidth,sshowheight,x,y,i);
                        

我这里参数比较多,主要就看switch 里面的那一部分就可以。 我这边的需求是需要显示多个大图的里面的小图,有小图的坐标,然后根据小图坐标展示每个小图图片,并正常显示。

最终的原理就是,旋转canvas,然后将图片渲染并显示部分坐标的内容,最终旋转回来展示。 具体可以查看drawImage的参数说明。

参数说明

转载请注明出处: https://chrunlee.cn/article/canvas-pic-rotate-show.html


感谢支持!

赞赏支持
提交评论
评论信息 (请文明评论)
暂无评论,快来快来写想法...
推荐
jsQR 是一款纯粹的由javascript实现的二维码识别库,可以在浏览器端使用,也可以在后端node.js环境使用。我之前使用过其他的识别库,例如:qrcode-reader 或其他,在使用上都比较麻烦,而且识别率并不高。jsQR是后来发现的,感觉(没有实际对比验证)jsQR识别率要更高些,使用起来也更简单,不需要安装其他依赖软件。
最近一直在想着抓一些网盘数据,进行资料归拢,可是当我真正开始的时候.. 还是遇到了反爬,当然我本身就有心理预期,这是肯定会碰到的,只是没想到会在代理IP上耗费这么久,之前的时候也处理过代理IP ,可是由于一知半解,导致很多配置都不理解,debug全靠猜...
在页面中不同的frame之间进行相互调用的话,我们可以通过frame获取对应的window然后进行调用,但是如果是浏览器不同的tab之间呢?
现象:在IOS中,jsp页面绑定的点击事件,点击后延迟很大,接近1000ms,反应很慢
突然来了一个调研任务,想要实现一个类似3D虚拟展厅类似的需求,主要就是放一些学生的作品,然后预览啥的,效果还是要全景的效果。 经过一番调查,最终锁定了以前从未接触过的krpano。
通过jspdf ,我们可以将页面或图片生成pdf下载下来,如果是一些复杂的页面,我们可以将页面转成图片,然后把图片加入到pdf中,生成并下载。
今天小程序上传体验版本后莫名无法获取用户数据,但是本地开发环境是正常的,通过开发工具的真机进行测试也正常,但是通过开发工具的预览又不正常,初步来看代码是没有问题的,可能是哪里设置有问题。
对于web开发过程中的JS对象 Array ,我们真的充分使用了么?是不是理解了Array的全部?能够在合适的地点调用合适的函数,使用合适的属性?