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 text shadow字体阴影效果
Jan 08 HTML / CSS
CSS3实现翘边的阴影效果的代码示例
Jun 13 HTML / CSS
HTML5 Geolocation API的正确使用方法
Dec 04 HTML / CSS
html5 canvas 画图教程案例分析
Nov 23 HTML / CSS
如何使用html5与css3完成google涂鸦动画
Dec 16 HTML / CSS
HTML5 video标签(播放器)学习笔记(二):播放控制
Apr 24 HTML / CSS
canvas之自定义头像功能实现代码示例
Sep 29 HTML / CSS
详解移动端Html5页面中1px边框的几种解决方法
Jul 24 HTML / CSS
HTML5中的Web Notification桌面通知功能的实现方法
Jul 29 HTML / CSS
html5默认气泡修改的代码详解
Mar 13 HTML / CSS
html5中嵌入视频自动播放的问题解决
May 25 HTML / CSS
CSS3实现三角形不断放大效果
Apr 13 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
海河写的 Discuz论坛帖子调用js的php代码
2007/08/23 PHP
laravel 5 实现模板主题功能(续)
2015/03/02 PHP
php发送邮件的问题详解
2015/06/22 PHP
PHP使用curl函数发送Post请求的注意事项
2016/11/26 PHP
php ActiveMQ的安装与使用方法图文教程
2020/02/23 PHP
无缝滚动改进版支持上下左右滚动(封装成函数)
2012/12/04 Javascript
下拉菜单点击实现连接跳转功能的js代码
2013/05/19 Javascript
$.each遍历对象、数组的属性值并进行处理
2014/07/18 Javascript
js正则匹配出所有图片及图片地址src的方法
2015/06/08 Javascript
JavaScript过滤字符串中的中文与空格方法汇总
2016/03/07 Javascript
Node.js项目中调用JavaScript的EJS模板库的方法
2016/03/11 Javascript
深入解析Backbone.js框架的依赖库Underscore.js的作用
2016/05/07 Javascript
在点击div中的p时,如何阻止事件冒泡
2017/02/07 Javascript
无法获取隐藏元素宽度和高度的解决方案
2017/03/07 Javascript
详解vue-cli + webpack 多页面实例应用
2017/04/25 Javascript
浅析Vue 生命周期
2018/06/21 Javascript
vue-for循环嵌套操作示例
2019/01/28 Javascript
使用express获取微信小程序二维码小记
2019/05/21 Javascript
Vue 解决通过this.$refs来获取DOM或者组件报错问题
2020/07/28 Javascript
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
python数据结构之二叉树的统计与转换实例
2014/04/29 Python
Python进程间通信用法实例
2015/06/04 Python
浅谈Python的异常处理
2016/06/19 Python
Python 专题三 字符串的基础知识
2017/03/19 Python
Python编程中类与类的关系详解
2019/08/08 Python
Python SMTP配置参数并发送邮件
2020/06/16 Python
python利用google翻译方法实例(翻译字幕文件)
2020/09/21 Python
python定时截屏实现
2020/11/02 Python
《老山界》教学反思
2014/04/08 职场文书
给校长的一封检讨书
2014/09/20 职场文书
2014年幼儿园园务工作总结
2014/12/05 职场文书
求职简历自荐信怎么写
2015/03/26 职场文书
装修公司管理制度
2015/08/05 职场文书
2016年4月份红领巾广播稿
2015/12/21 职场文书
导游词之日本富士山
2020/01/06 职场文书
Python循环之while无限迭代
2022/04/30 Python