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 translate导致字体模糊的实例代码
Aug 30 HTML / CSS
网页切图的CSS和布局经验与要点
Apr 09 HTML / CSS
初探CSS3中的calc()功能
Jul 14 HTML / CSS
在HTML5 canvas里用卷积核进行图像处理的方法
May 02 HTML / CSS
HTML5引入的新数组TypedArray介绍
Dec 24 HTML / CSS
关于HTML5语义标签的实践(blog页面)
Jul 12 HTML / CSS
解决html5中video标签无法播放mp4问题的办法
May 07 HTML / CSS
canvas如何绘制钟表的方法
Dec 13 HTML / CSS
HTML利用九宫格原理进行网页布局
Mar 13 HTML / CSS
html5小程序飞入购物车(抛物线绘制运动轨迹点)
Oct 19 HTML / CSS
CSS实现两列布局的N种方法
Aug 02 HTML / CSS
CSS中理解层叠性及权重如何分配
Dec 24 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
PHP为表单获取的URL 地址预设 http 字符串函数代码
2010/05/26 PHP
ThinkPHP、ZF2、Yaf、Laravel框架路由大比拼
2015/03/25 PHP
关于php 高并发解决的一点思路
2017/04/16 PHP
[原创]php token使用与验证示例【测试可用】
2017/08/30 PHP
使用PHP开发留言板功能
2019/11/19 PHP
一页面多XMLHttpRequest对象
2007/01/22 Javascript
js实现点击图片将图片地址复制到粘贴板的方法
2015/02/16 Javascript
JavaScript中this详解
2015/09/01 Javascript
jquery判断复选框是否选中进行答题提示特效
2015/12/10 Javascript
详解JS面向对象编程
2016/01/24 Javascript
javascript+HTML5 Canvas绘制转盘抽奖
2020/05/16 Javascript
JS实现简易的图片拖拽排序实例代码
2017/06/09 Javascript
vue渲染时闪烁{{}}的问题及解决方法
2018/03/28 Javascript
微信小程序canvas实现刮刮乐效果
2018/07/09 Javascript
基于vue实现一个神奇的动态按钮效果
2019/05/15 Javascript
React中使用Vditor自定义图片详解
2020/12/25 Javascript
[57:09]DOTA2-DPC中国联赛 正赛 Phoenix vs Dynasty BO3 第一场 1月26日
2021/03/11 DOTA
使用anaconda的pip安装第三方python包的操作步骤
2018/06/11 Python
python实现监控某个服务 服务崩溃即发送邮件报告
2018/06/21 Python
python Dijkstra算法实现最短路径问题的方法
2019/09/19 Python
解决python中import文件夹下面py文件报错问题
2020/06/01 Python
HTML5实现移动端复制功能
2018/04/19 HTML / CSS
麦德龙官方海外旗舰店:德国麦德龙超市
2017/12/23 全球购物
用Python写一个for循环的例子
2016/07/19 面试题
旅游管理本科生求职信
2013/10/14 职场文书
大学自主招生自荐信
2013/12/16 职场文书
母亲80寿诞答谢词
2014/01/16 职场文书
劳动实践课感言
2014/02/01 职场文书
农业局学习党的群众路线教育实践活动心得体会
2014/03/07 职场文书
法制宣传月活动总结
2014/04/29 职场文书
小学学校门卫岗位职责
2014/08/03 职场文书
监考失职检讨书
2015/01/26 职场文书
爱国主义教育主题班会
2015/08/13 职场文书
2016医师资格考试考生诚信考试承诺书
2016/03/25 职场文书
大学生暑期社会实践的个人总结!
2019/07/17 职场文书
深入解析NumPy中的Broadcasting广播机制
2021/05/30 Python