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弹性盒模型开发笔记(三)
Apr 26 HTML / CSS
详解CSS3 用border写 空心三角箭头 (两种写法)
Sep 29 HTML / CSS
css3动画效果抖动解决方法
Sep 03 HTML / CSS
收集的22款给力的HTML5和CSS3帮助工具
Sep 14 HTML / CSS
CSS3等相关属性制作分页导航实现代码
Dec 24 HTML / CSS
CSS3的Border-radius轻松制作圆角
Dec 24 HTML / CSS
CSS3 animation ? steps 函数详解
Aug 30 HTML / CSS
HTML5中微数据概述及在搜索引擎中的使用举例
Feb 07 HTML / CSS
仿CSDN Blog返回页面顶部功能实现原理及代码
Jun 30 HTML / CSS
HTML5 canvas绘制的玫瑰花效果
May 29 HTML / CSS
html5+svg学习指南之SVG基础知识
Dec 17 HTML / CSS
AmazeUI 平滑滚动效果的示例代码
Aug 20 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
win7系统配置php+Apache+mysql环境的方法
2015/08/21 PHP
动态加载脚本提升javascript性能
2014/02/24 Javascript
json中换行符的处理方法示例介绍
2014/06/10 Javascript
JavaScript利用append添加元素报错的解决方法
2014/07/01 Javascript
jQuery控制元素显示、隐藏、切换、滑动的方法总结
2015/04/16 Javascript
javascript相关事件的几个概念
2015/05/21 Javascript
JavaScript中使用指数方法Math.exp()的简介
2015/06/15 Javascript
四种参数传递的形式——URL,超链接,js,form表单
2015/07/24 Javascript
深入理解JS中的Function.prototype.bind()方法
2016/10/11 Javascript
Angular路由简单学习
2016/12/26 Javascript
原生javascript实现图片放大镜效果
2017/01/18 Javascript
用Vue.extend构建消息提示组件的方法实例
2017/08/08 Javascript
JavaScript表单即时验证 验证不成功不能提交
2017/08/31 Javascript
使用vue-router与v-if实现tab切换遇到的问题及解决方法
2018/09/07 Javascript
如何使用vue slot创建一个模态框的实例代码
2020/05/24 Javascript
[01:03:09]完美世界DOTA2联赛PWL S2 Forest vs SZ 第二场 11.25
2020/11/26 DOTA
Python程序语言快速上手教程
2012/07/18 Python
python实现在无须过多援引的情况下创建字典的方法
2014/09/25 Python
python字符串对其居中显示的方法
2015/07/11 Python
python中函数默认值使用注意点详解
2016/06/01 Python
Python Queue模块详细介绍及实例
2016/12/27 Python
python决策树之C4.5算法详解
2017/12/20 Python
Numpy中的mask的使用
2018/07/21 Python
详解python中的Turtle函数库
2018/11/19 Python
python自动分箱,计算woe,iv的实例代码
2019/11/22 Python
泰国综合购物网站:Lazada泰国
2018/04/09 全球购物
什么是封装
2013/03/26 面试题
中文系师范生自荐信
2013/10/01 职场文书
营销总经理的岗位职责
2013/12/15 职场文书
后进生转化工作制度
2014/01/17 职场文书
优秀小学生家长评语
2014/01/30 职场文书
大学生秋游活动方案
2014/02/17 职场文书
《我不是最弱小的》教学反思
2014/02/23 职场文书
工商管理本科生求职信
2014/07/13 职场文书
信用卡逾期证明示例
2014/09/13 职场文书
SpringCloud Function SpEL注入漏洞分析及环境搭建
2022/04/08 Java/Android