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实现表单验证效果(非常不错)
Jan 18 HTML / CSS
css3 media 响应式布局的简单实例
Aug 03 HTML / CSS
css3 pointer-events 介绍详解
Sep 18 HTML / CSS
详解利用css3的var()实现运行时改变scss的变量值
Mar 02 HTML / CSS
HTML5 device access 设备访问详解
May 24 HTML / CSS
HTML5样式控制示例代码
Nov 27 HTML / CSS
实例教程 利用html5和css3打造一款创意404页面
Oct 20 HTML / CSS
Adobe Html5 Extension开发初体验图文教程
Nov 14 HTML / CSS
用canvas显示验证码的实现
Apr 10 HTML / CSS
html5移动端禁止长按图片保存的实现
Apr 20 HTML / CSS
CSS 新特性 contain控制页面的重绘与重排问题
Apr 30 HTML / CSS
在CSS中使用when/else的方法
Jan 18 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性能优化 产生高度优化代码
2011/07/22 PHP
PHP数据库调用类调用实例(详细注释)
2012/07/12 PHP
php中++i 与 i++ 的区别
2012/08/08 PHP
基于curl数据采集之单页面并行采集函数get_htmls的使用
2013/04/28 PHP
CSS中简写属性要注意TRouBLe的顺序问题(避免踩坑)
2021/03/09 HTML / CSS
JavaScript constructor和instanceof,JSOO中的一对欢喜冤家
2009/05/25 Javascript
node.js中的fs.futimesSync方法使用说明
2014/12/17 Javascript
jQuery中wrapAll()方法用法实例
2015/01/16 Javascript
JavaScript 动态加载脚本和样式的方法
2015/04/13 Javascript
详解js中class的多种函数封装方法
2016/01/03 Javascript
js仿百度登录页实现拖动窗口效果
2016/03/11 Javascript
浅析Bootstrap缩略图组件与警示框组件
2016/04/29 Javascript
javascript事件冒泡简单示例
2016/06/20 Javascript
微信QQ的二维码登录原理js代码解析
2016/06/23 Javascript
js中获取 table节点各tr及td的内容简单实例
2016/10/14 Javascript
ES6中Math对象的部分扩展
2017/02/20 Javascript
js实现简易聊天对话框
2017/08/17 Javascript
基于vue.js路由参数的实例讲解——简单易懂
2017/09/07 Javascript
深入浅析JSONAPI在PHP中的应用
2017/12/24 Javascript
jQuery与vue实现拖动验证码功能
2018/01/30 jQuery
基于vue-router 多级路由redirect 重定向的问题
2018/09/03 Javascript
axios对请求各种异常情况处理的封装方法
2018/09/25 Javascript
Python聚类算法之凝聚层次聚类实例分析
2015/11/20 Python
Python3中的列表,元组,字典,字符串相关知识小结
2017/11/10 Python
一文带你了解Python中的字符串是什么
2018/11/20 Python
python+opencv像素的加减和加权操作的实现
2019/07/14 Python
python 画出使用分类器得到的决策边界
2019/08/21 Python
Python3 无重复字符的最长子串的实现
2019/10/08 Python
python pandas移动窗口函数rolling的用法
2020/02/29 Python
python 连续不等式语法糖实例
2020/04/15 Python
监理员的岗位职责
2013/11/13 职场文书
银行见习期自我鉴定
2014/01/29 职场文书
大学国际贸易专业自荐信
2014/06/05 职场文书
道歉的话怎么说
2015/05/12 职场文书
小学秋季运动会通讯稿
2015/11/25 职场文书
Nginx 502 Bad Gateway错误原因及解决方案
2021/03/31 Servers