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 Columns分列式布局方法简介
May 03 HTML / CSS
前端canvas水印快速制作(附完整代码)
Sep 19 HTML / CSS
HTML5 Canvas 起步(2) - 路径
May 12 HTML / CSS
关于HTML5 Placeholder新标签低版本浏览器下不兼容的问题分析及解决办法
Jan 27 HTML / CSS
HTML5 canvas基本绘图之图形变换
Jun 27 HTML / CSS
使用Html5实现异步上传文件,支持跨域,带有上传进度条
Sep 17 HTML / CSS
使用phonegap获取位置信息的实现方法
Mar 31 HTML / CSS
HTML5新特性之type=file文件上传功能
Feb 02 HTML / CSS
canvas绘制太极图的实现示例
Apr 29 HTML / CSS
uniapp+Html5端实现PC端适配
Jul 15 HTML / CSS
详解如何使用rem或viewport进行移动端适配
Aug 14 HTML / CSS
使用CSS实现小三角边框原理解析
Nov 07 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 开源框架22个简单简介
2009/08/24 PHP
php ci框架中加载css和js文件失败的原因及解决方法
2014/07/29 PHP
PHP 年月日的三级联动实例代码
2017/05/24 PHP
Laravel 使用查询构造器配合原生sql语句查询的例子
2019/10/12 PHP
使用户点击后退按钮使效三行代码
2007/07/07 Javascript
javascript 建设银行登陆键盘
2008/06/10 Javascript
DOM 脚本编程中的兄弟节点
2009/10/31 Javascript
基于jquery的拖动布局插件
2011/11/25 Javascript
对js中回调函数的一些看法
2016/08/29 Javascript
获取JavaScript异步函数的返回值
2016/12/21 Javascript
使用D3.js创建物流地图的示例代码
2018/01/27 Javascript
基于ionic实现下拉刷新功能
2018/05/10 Javascript
Nodejs 发布自己的npm包并制作成命令行工具的实例讲解
2018/05/15 NodeJs
关于js对textarea换行符的处理方法浅析
2018/08/03 Javascript
vue实现商品加减计算总价的实例代码
2018/08/12 Javascript
微信小程序收货地址API兼容低版本解决方法
2019/05/18 Javascript
对layui中table组件工具栏的使用详解
2019/09/19 Javascript
vue实现下载文件流完整前后端代码
2020/11/17 Vue.js
[38:40]2018DOTA2亚洲邀请赛 4.6淘汰赛 mineski vs LGD 第一场
2018/04/10 DOTA
python中getaddrinfo()基本用法实例分析
2015/06/28 Python
使用coverage统计python web项目代码覆盖率的方法详解
2019/08/05 Python
TensorFlow设置日志级别的几种方式小结
2020/02/04 Python
5行Python代码实现图像分割的步骤详解
2020/05/25 Python
python接入支付宝的实例操作
2020/07/20 Python
Python析构函数__del__定义原理解析
2020/11/20 Python
kmart凯马特官网:美国最大的打折零售商和全球最大的批发商之一
2016/11/17 全球购物
医学生自我评价
2014/01/27 职场文书
欢迎标语大全
2014/06/21 职场文书
纪念一二九运动演讲稿
2014/09/16 职场文书
优秀班主任材料
2014/12/16 职场文书
开除通知书范本
2015/04/25 职场文书
首席执行官观后感
2015/06/03 职场文书
初中语文教学随笔
2015/08/15 职场文书
大学三好学生主要事迹范文
2015/11/03 职场文书
详解盒子端CSS动画性能提升
2021/05/24 HTML / CSS
对Keras自带Loss Function的深入研究
2021/05/25 Python