Javascript 如何在画布对象中保持图像的纵横比

Javascript 如何在画布对象中保持图像的纵横比,javascript,html,canvas,Javascript,Html,Canvas,关于纵横比的快速问题让我有点发疯。我的画布元素的固定尺寸为250x250(1:1)。然而,我正在画布上绘制的图像可能是任何大小/比例。显然,如果我试图强制图像为250x250,它看起来会失真 我试图使它尊重纵横比,但我得到了一个奇怪的画布对象重叠现在,我的悬停效果是有点关闭,因为它。我的数学是错误的,或者我将其应用于图像/画布的方式是错误的。如有任何帮助或建议,将不胜感激 var NameSpace=NameSpace | |{}; NameSpace.Pixelator=(函数(){ 变量_

关于纵横比的快速问题让我有点发疯。我的画布元素的固定尺寸为250x250(1:1)。然而,我正在画布上绘制的图像可能是任何大小/比例。显然,如果我试图强制图像为250x250,它看起来会失真

我试图使它尊重纵横比,但我得到了一个奇怪的画布对象重叠现在,我的悬停效果是有点关闭,因为它。我的数学是错误的,或者我将其应用于图像/画布的方式是错误的。如有任何帮助或建议,将不胜感激

var NameSpace=NameSpace | |{};
NameSpace.Pixelator=(函数(){
变量_缓存={
“包装器”:null,
“画布”:null,
“ctx”:null,
“img”:新图像()
},
_配置={
“画布宽度”:250,
“画布高度”:250,
“iPlaying”:错误,
"明":3,,
“最大值”:100,
“扭曲值”:100,//默认情况下与扭曲最大值匹配
“初始值”:3,
“速度”:2.5,
“delta”:2.5,//delta(+/-step),默认情况下与速度匹配
“动画”:null,
“origImgWidth”:null,
“OrigighHeight”:null,
“imgHeightRatio”:null,
“imgWidthRatio”:null,
“newImgWidth”:null,
“newImgHeight”:null
},
_init=函数_init(){
_setupCache();
_setupCanvas();
_setupImage();
},
_setupCache=函数_setupCache(){
_cache.wrapper=$(“#虚拟包装器”);
_cache.canvas=document.getElementById('dummy-canvas');
_cache.ctx=_cache.canvas.getContext('2d');
},
_setupCanvas=函数_setupCanvas(){
_cache.ctx.mozimagesoothingEnabled=false;
_cache.ctx.webkitmagesmoothingEnabled=false;
_cache.ctx.imageSmoothingEnabled=false;
},
_setupImage=函数_setupImage(){
$(_cache.img).on('load',function()){
_调整图像比例();
_像素();
_赋值事件();
});
_cache.img.src=_cache.canvas.getAttribute('data-src');
},
_adjustImageScale=功能_adjustImageScale(){
var标度高度,
标度宽度;
_config.origImgWidth=\u cache.img.width;
_config.origImgHeight=\u cache.img.height;
_config.imghlightratio=\u config.origImgHeight/\u config.origImgWidth;
_config.imgWidthRatio=\u config.origImgWidth/\u config.origImgHeight;
scaledHeight=数学圆(250*_config.imghtRatio);
scaledWidth=Math.round(250*_config.imgWidthRatio);
如果(标度高度<250){
_config.newImgHeight=250;
_config.newImgWidth=Math.round(_config.newImgHeight*_config.imgWidthRatio);
}否则如果(缩放宽度<250){
_config.newImgWidth=250;
_config.newImgHeight=Math.round(_config.newImgWidth*_config.imgheight比率);
}
},
_assignEvents=函数_assignEvents(){
_cache.wrapper.on('mouseenter',_mouseEnterHandler);
_cache.wrapper.on('mouseleave',_mouseLeaveHandler);
},
_mouseEnterHandler=函数_mouseEnterHandler(e){
_config.delta=--u config.speed;
如果(_config.isPlaying==false){
_config.isplay=true;
_制作动画();
}
},
_mouseLeaveHandler=函数_mouseLeaveHandler(e){
_config.delta=_config.speed;
如果(_config.isPlaying==false){
_config.isplay=true;
_制作动画();
}
},
_像素=函数_像素(val){
变量大小=val?val*0.01:1,
w=Math.ceil(_config.newImgWidth*size),
h=Math.ceil(_config.newImgHeight*size);
_cache.ctx.drawImage(_cache.img,0,0,w,h);
_cache.ctx.drawImage(_cache.canvas,0,0,w,h,0,0,_config.canvaswitch,_config.canvaswitch);
},
_动画=函数_animate(){
//通过鼠标移过/移出增量设置增加/减少
_config.value+=\u config.delta;

如果(_config.trunteValue>=_config.truntemax | | | | | u config.trunteValue您的代码将
w*h
区域(非方形)采样到
\u config.canvasWidth*\u config.canvashight
区域(方形)。以下更改似乎为我修复了您的示例:

//旧代码
_cache.ctx.drawImage(_cache.canvas,0,0,w,h,0,0,_config.canvaswitch,_config.canvaswitch);
//新代码
_cache.ctx.drawImage(_cache.canvas,0,0,w,h,0,0,_config.newImgWidth,_config.newImgHeight);

DOH!这正是我需要另一双眼睛的原因。非常感谢!
var NameSpace = NameSpace || {};

NameSpace.Pixelator = (function() {

    var _cache = {
        'wrapper' : null,
        'canvas'  : null,
        'ctx'     : null,
        'img'     : new Image()
    },

    _config = {
        'canvasWidth'      : 250,
        'canvasHeight'     : 250,
        'isPlaying'        : false,
        'distortMin'       : 3,
        'distortMax'       : 100,
        'distortValue'     : 100, // matches distortMax by default
        'initDistortValue' : 3,
        'speed'            : 2.5,
        'delta'            : 2.5,   // delta (+/- step), matches speed by default
        'animation'        : null,
        'origImgWidth'     : null,
        'origImgHeight'    : null,
        'imgHeightRatio'   : null,
        'imgWidthRatio'    : null,
        'newImgWidth'      : null,
        'newImgHeight'     : null
    },

    _init = function _init() {

        _setupCache();
        _setupCanvas();
        _setupImage();

    },

    _setupCache = function _setupCache() {

        _cache.wrapper = $('#dummy-wrapper');
        _cache.canvas = document.getElementById('dummy-canvas');
        _cache.ctx = _cache.canvas.getContext('2d');

    },

    _setupCanvas = function _setupCanvas() {

        _cache.ctx.mozImageSmoothingEnabled = false;
        _cache.ctx.webkitImageSmoothingEnabled = false;
        _cache.ctx.imageSmoothingEnabled = false;

    },

    _setupImage = function _setupImage() {

        $(_cache.img).on('load', function() {

            _adjustImageScale();
            _pixelate();
            _assignEvents();

        });

        _cache.img.src = _cache.canvas.getAttribute('data-src');

    },

    _adjustImageScale = function _adjustImageScale() {

        var scaledHeight,
            scaledWidth;

        _config.origImgWidth = _cache.img.width;
        _config.origImgHeight = _cache.img.height;
        _config.imgHeightRatio = _config.origImgHeight / _config.origImgWidth;
        _config.imgWidthRatio = _config.origImgWidth / _config.origImgHeight;

        scaledHeight = Math.round(250 * _config.imgHeightRatio);
        scaledWidth = Math.round(250 * _config.imgWidthRatio);

        if (scaledHeight < 250) {

            _config.newImgHeight = 250;
            _config.newImgWidth = Math.round(_config.newImgHeight * _config.imgWidthRatio);

        } else if (scaledWidth < 250) {

            _config.newImgWidth = 250;
            _config.newImgHeight = Math.round(_config.newImgWidth * _config.imgHeightRatio);

        }

    },

    _assignEvents = function _assignEvents() {

        _cache.wrapper.on('mouseenter', _mouseEnterHandler);
        _cache.wrapper.on('mouseleave', _mouseLeaveHandler);

    },

    _mouseEnterHandler = function _mouseEnterHandler(e) {

        _config.delta = -_config.speed;

        if (_config.isPlaying === false) {
            _config.isPlaying = true;
            _animate();
        }

    },

    _mouseLeaveHandler = function _mouseLeaveHandler(e) {

        _config.delta = _config.speed;

        if (_config.isPlaying === false) {
            _config.isPlaying = true;
            _animate();
        }

    },

    _pixelate = function _pixelate(val) {

        var size = val ? val * 0.01 : 1,
            w = Math.ceil(_config.newImgWidth * size),
            h = Math.ceil(_config.newImgHeight * size);

        _cache.ctx.drawImage(_cache.img, 0, 0, w, h);

        _cache.ctx.drawImage(_cache.canvas, 0, 0, w, h, 0, 0, _config.canvasWidth, _config.canvasHeight);

    },

    _animate = function _animate() {

        // increase/decrese with delta set by mouse over/out
        _config.distortValue += _config.delta;

        if (_config.distortValue >= _config.distortMax || _config.distortValue <= _config.distortMin) {

            _config.isPlaying = false;
            cancelAnimationFrame(_config.animation);
            return;

        } else {

            // pixelate
            _pixelate(_config.distortValue);
            _config.animation = requestAnimationFrame(_animate);

        }

    };

    return {
        init: _init
    };

})();

NameSpace.Pixelator.init();