canvas绘图按照contain或者cover方式适配并居中显示


Posted in HTML / CSS onFebruary 18, 2019

canvas绘图时drawImage,需要绘制的图片大小不同,比例各异,所以就需要像html+css布局那样,需要contain和cover来满足不同的需求。

contain

保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。

图片按照contain模式放到固定盒子的矩形内,则需要对图片进行一定的缩放。

原则是:

如果图片宽高不等,使图片的长边能完全显示出来,则原图片高的一边缩放后等于固定盒子对应的一边,等比例求出另外一边,

如果图片宽高相等,则根据固定盒子的宽高来决定缩放后图片的宽高,固定盒子的宽大于高,则缩放后的图片高等于固定盒子的高度,对应求出另外一边即可,反之亦然。

/**
         * @param {Number} sx 固定盒子的x坐标,sy 固定盒子的y左标
         * @param {Number} box_w 固定盒子的宽, box_h 固定盒子的高
         * @param {Number} source_w 原图片的宽, source_h 原图片的高
         * @return {Object} {drawImage的参数,缩放后图片的x坐标,y坐标,宽和高},对应drawImage(imageResource, dx, dy, dWidth, dHeight)
         */
        function containImg(sx, sy , box_w, box_h, source_w, source_h){
            var dx = sx,
                dy = sy,
                dWidth = box_w,
                dHeight = box_h;
            if(source_w > source_h || (source_w == source_h && box_w < box_h)){
                dHeight = source_h*dWidth/source_w;
            dy =  sy + (box_h-dHeight)/2;

            }else if(source_w < source_h || (source_w == source_h && box_w > box_h)){
                dWidth = source_w*dHeight/source_h;
                dx = sx + (box_w-dWidth)/2;
            }
            return{
                dx,
                dy,
                dWidth,
                dHeight
            }
        }


        var c=document.getElementById("myCanvas");
        var ctx=c.getContext("2d");
        ctx.fillStyle = '#e1f0ff';
        //固定盒子的位置和大小--图片需要放在这个盒子内
        ctx.fillRect(30, 30, 150, 200);

        var img = new Image();
        img.onload = function () {
            console.log(img.width,img.height);
            
            var imgRect = containImg(30,30,150,200,img.width,img.height);
            console.log('imgRect',imgRect);
            ctx.drawImage(img, imgRect.dx, imgRect.dy, imgRect.dWidth, imgRect.dHeight); 
            
        }
        img.src = "./timg2.jpg";  
        //注:img预加载模式下,onload应该放在为src赋值的上面,以避免已有缓存的情况下无法触发onload事件从而导致onload中的事件不执行的情况发生

cover

保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。

原理:

按照固定盒子的比例截取图片的部分

/**
         * @param {Number} box_w 固定盒子的宽, box_h 固定盒子的高
         * @param {Number} source_w 原图片的宽, source_h 原图片的高
         * @return {Object} {截取的图片信息},对应drawImage(imageResource, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)参数
        */
        function coverImg(box_w, box_h, source_w, source_h){
            var sx = 0,
                sy = 0,
                sWidth = source_w,
                sHeight = source_h;
            if(source_w > source_h || (source_w == source_h && box_w < box_h)){
                sWidth = box_w*sHeight/box_h;
                sx = (source_w-sWidth)/2;
            }else if(source_w < source_h || (source_w == source_h && box_w > box_h)){
                sHeight = box_h*sWidth/box_w;
                sy = (source_h-sHeight)/2;
            }
            return{
                sx,
                sy,
                sWidth,
                sHeight
            }
        }


        var c=document.getElementById("myCanvas");
        var ctx=c.getContext("2d");
        ctx.fillStyle = '#e1f0ff';
        //固定盒子的位置和大小--图片需要放在这个盒子内
        ctx.fillRect(30, 30, 150, 200);

        var img = new Image();
        img.onload = function () {
            console.log(img.width,img.height);
            
            var imgRect = coverImg(150,200,img.width,img.height);
            console.log('imgRect',imgRect);
            ctx.drawImage(img, imgRect.sx, imgRect.sy, imgRect.sWidth, imgRect.sHeight, 30, 30, 150, 200); 
        }
        img.src = "./timg2.jpg";  
        //注:img预加载模式下,onload应该放在为src赋值的上面,以避免已有缓存的情况下无法触发onload事件从而导致onload中的事件不执行的情况发生

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
CSS3 please 跨浏览器的CSS3产生器
Mar 14 HTML / CSS
利用CSS3实现圆角的outline效果的教程
Jun 05 HTML / CSS
深入浅析css3 border-image边框图像详解
Nov 24 HTML / CSS
纯css3制作煽动翅膀的蝴蝶的示例
Apr 23 HTML / CSS
css3实现可拖动的魔方3d效果
May 07 HTML / CSS
HTML5 Canvas实现文本对齐的方法总结
Mar 24 HTML / CSS
整理的15个非常有用的 HTML5 开发教程和速查手册
Oct 18 HTML / CSS
html5适合移动应用开发的12大特性
Mar 19 HTML / CSS
HTML5实现简单图片上传所遇到的问题及解决办法
Jan 20 HTML / CSS
基于 HTML5 WebGL 实现的医疗物流系统
Oct 08 HTML / CSS
深入理解margin塌陷和margin合并的解决方案
Jun 26 HTML / CSS
Unicode中的CJK(中日韩统一表意文字)字符小结
Dec 06 HTML / CSS
canvas 橡皮筋式线条绘图应用方法
Feb 13 #HTML / CSS
Canvas系列之滤镜效果
Feb 12 #HTML / CSS
canvas学习总结三之绘制路径-线段
Jan 31 #HTML / CSS
移动端Html5中百度地图的点击事件
Jan 31 #HTML / CSS
Html5页面内使用JSON动画的实现
Jan 29 #HTML / CSS
HTML5拍照和摄像机功能实战详解
Jan 24 #HTML / CSS
解锁canvas导出图片跨域的N种姿势小结
Jan 24 #HTML / CSS
You might like
新52大事件
2020/03/03 欧美动漫
在WordPress中使用wp-cron插件来设置定时任务
2015/12/10 PHP
PHP对象实例化单例方法
2017/01/19 PHP
ThinkPHP实现的rsa非对称加密类示例
2018/05/29 PHP
PHP7中I/O模型内核剖析详解
2019/04/14 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
2020/05/02 PHP
让textarea控件的滚动条怎是位与最下方
2007/04/20 Javascript
一个js封装的不错的选项卡效果代码
2008/02/15 Javascript
js常用代码段整理
2011/11/30 Javascript
js中根据字数截取字符串,不能截断url
2012/01/12 Javascript
jquery toolbar与网页浮动工具条具体实现代码
2014/01/12 Javascript
jquery.mobile 共同布局遇到的问题小结
2015/02/10 Javascript
JavaScript事件类型中UI事件详解
2016/01/14 Javascript
AngularJS国际化详解及示例代码
2016/08/18 Javascript
利用Vue.js+Node.js+MongoDB实现一个博客系统(附源码)
2017/04/24 Javascript
详解Angular2响应式表单
2017/06/14 Javascript
在vue项目中,将juery设置为全局变量的方法
2018/09/25 Javascript
vue刷新页面时去闪烁提升用户体验效果的实现方法
2018/12/10 Javascript
详解50行代码,Node爬虫练手项目
2019/04/22 Javascript
node命令行工具之实现项目工程自动初始化的标准流程
2019/08/12 Javascript
JS实现移动端在线签协议功能
2019/08/22 Javascript
jquery实现简单拖拽效果
2020/07/20 jQuery
django中模板的html自动转意方法
2018/05/27 Python
python实现反转部分单向链表
2018/09/27 Python
Python初学者常见错误详解
2019/07/02 Python
python程序运行进程、使用时间、剩余时间显示功能的实现代码
2019/07/11 Python
创建Shapefile文件并写入数据的例子
2019/11/26 Python
使用python-opencv读取视频,计算视频总帧数及FPS的实现
2019/12/10 Python
python通过nmap扫描在线设备并尝试AAA登录(实例代码)
2019/12/30 Python
Django的CVB实例详解
2020/02/10 Python
python转化excel数字日期为标准日期操作
2020/07/14 Python
意大利专业化妆品品牌:KIKO MILANO
2017/02/01 全球购物
应届生法律求职信
2013/10/22 职场文书
会议活动邀请函
2014/01/27 职场文书
搞笑欢迎词大全
2015/09/30 职场文书
2016年青少年禁毒宣传教育活动总结(学校)
2016/04/05 职场文书