如何在画布对象中保持图像的宽高比 [英] How to maintain aspect ratio of an image within a canvas object
问题描述
关于长宽比的快速问题,这让我有点头疼。我的画布元素的尺寸固定为250x250(1:1的比例)。然而,我绘制到画布中的图像可能是任何大小/比率。显然,如果我试图强制图像为250x250它看起来扭曲。
Quick question regarding aspect ratios that are driving me a bit nuts. My canvas element has fixed dimensions of 250x250 (1:1 ratio). The image that I'm drawing into the canvas however could possibly be any size/ratio. Obviously if I try to force the image to be 250x250 it looks distorted.
我试图让它尊重宽高比,但我现在在画布对象有一个奇怪的重叠,我的悬停效果是有点关闭。我的数学是错误的或我如何应用它的图像/画布是错误的。任何帮助或建议将非常感谢。
I've attempted to make it respect the aspect ratio but I get a strange overlap in the canvas object now and my hover effect is a bit off because of it. My math is either wrong or how I'm applying it to the image/canvas is wrong. Any help or suggestions would be greatly appreciated.
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();
推荐答案
您的代码示例 w *
_config.canvasWidth * _config.canvasHeight
区域,它是正方形。以下更改似乎为我修复了您的示例:
Your code samples w*h
region, which is not square, into _config.canvasWidth*_config.canvasHeight
region, which is square. Following change seems to fix your example for me:
// old code
_cache.ctx.drawImage(_cache.canvas, 0, 0, w, h, 0, 0, _config.canvasWidth, _config.canvasHeight);
// new code
_cache.ctx.drawImage(_cache.canvas, 0, 0, w, h, 0, 0, _config.newImgWidth, _config.newImgHeight);
这篇关于如何在画布对象中保持图像的宽高比的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!